Add some missing CFF opcodes and refactor a bit

This commit is contained in:
Patrick Walton 2017-02-16 20:39:25 -08:00
parent 6ac37c5085
commit e2014cff13
1 changed files with 98 additions and 126 deletions

View File

@ -170,29 +170,55 @@ impl<'a> CffTable<'a> {
8 => { 8 => {
// |- {dxa dya dxb dyb dxc dyc}+ rrcurveto (8) // |- {dxa dya dxb dyb dxc dyc}+ rrcurveto (8)
for chunk in stack.array[0..stack.size as usize].chunks(6) { for chunk in stack.array[0..stack.size as usize].chunks(6) {
add_curve(chunk[0] as i16, chunk[1] as i16,
chunk[2] as i16, chunk[3] as i16,
chunk[4] as i16, chunk[5] as i16,
&mut pos,
&mut index_in_contour,
&mut callback)
}
stack.clear()
}
24 => {
// |- {dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline (24)
for chunk in stack.array[0..stack.size as usize - 2].chunks(6) {
add_curve(chunk[0] as i16, chunk[1] as i16,
chunk[2] as i16, chunk[3] as i16,
chunk[4] as i16, chunk[5] as i16,
&mut pos,
&mut index_in_contour,
&mut callback)
}
pos = pos + Point2D::new(stack.array[stack.size as usize - 2] as i16,
stack.array[stack.size as usize - 1] as i16);
callback(&Point {
position: pos,
index_in_contour: index_in_contour,
kind: PointKind::OnCurve,
});
index_in_contour += 1;
stack.clear()
}
25 => {
// |- {dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve (25)
for chunk in stack.array[0..stack.size as usize - 6].chunks(2) {
pos = pos + Point2D::new(chunk[0] as i16, chunk[1] as i16); pos = pos + Point2D::new(chunk[0] as i16, chunk[1] as i16);
callback(&Point { callback(&Point {
position: pos, position: pos,
index_in_contour: index_in_contour + 0, index_in_contour: index_in_contour,
kind: PointKind::FirstCubicControl,
});
pos = pos + Point2D::new(chunk[2] as i16, chunk[3] as i16);
callback(&Point {
position: pos,
index_in_contour: index_in_contour + 1,
kind: PointKind::SecondCubicControl,
});
pos = pos + Point2D::new(chunk[4] as i16, chunk[5] as i16);
callback(&Point {
position: pos,
index_in_contour: index_in_contour + 2,
kind: PointKind::OnCurve, kind: PointKind::OnCurve,
}); });
index_in_contour += 1;
index_in_contour += 3
} }
add_curve(stack.array[stack.size as usize - 6] as i16,
stack.array[stack.size as usize - 5] as i16,
stack.array[stack.size as usize - 4] as i16,
stack.array[stack.size as usize - 3] as i16,
stack.array[stack.size as usize - 2] as i16,
stack.array[stack.size as usize - 1] as i16,
&mut pos,
&mut index_in_contour,
&mut callback);
stack.clear() stack.clear()
} }
30 => { 30 => {
@ -210,17 +236,19 @@ impl<'a> CffTable<'a> {
}; };
if i % 2 == 0 { if i % 2 == 0 {
process_hvcurveto_v(chunk, add_curve(0, chunk[0] as i16,
&mut pos, chunk[1] as i16, chunk[2] as i16,
dxyf, chunk[3] as i16, dxyf as i16,
&mut index_in_contour, &mut pos,
&mut callback); &mut index_in_contour,
&mut callback)
} else { } else {
process_hvcurveto_h(chunk, add_curve(chunk[0] as i16, 0,
&mut pos, chunk[1] as i16, chunk[2] as i16,
dxyf, dxyf as i16, chunk[3] as i16,
&mut index_in_contour, &mut pos,
&mut callback); &mut index_in_contour,
&mut callback)
} }
} }
stack.clear() stack.clear()
@ -240,17 +268,19 @@ impl<'a> CffTable<'a> {
}; };
if i % 2 == 0 { if i % 2 == 0 {
process_hvcurveto_h(chunk, add_curve(chunk[0] as i16, 0,
&mut pos, chunk[1] as i16, chunk[2] as i16,
dxyf, dxyf as i16, chunk[3] as i16,
&mut index_in_contour, &mut pos,
&mut callback); &mut index_in_contour,
&mut callback)
} else { } else {
process_hvcurveto_v(chunk, add_curve(0, chunk[0] as i16,
&mut pos, chunk[1] as i16, chunk[2] as i16,
dxyf, chunk[3] as i16, dxyf as i16,
&mut index_in_contour, &mut pos,
&mut callback); &mut index_in_contour,
&mut callback)
} }
} }
stack.clear() stack.clear()
@ -268,29 +298,12 @@ impl<'a> CffTable<'a> {
for (i, chunk) in stack.array[start..stack.size as usize] for (i, chunk) in stack.array[start..stack.size as usize]
.chunks(4) .chunks(4)
.enumerate() { .enumerate() {
pos.y += chunk[0] as i16; add_curve(0, chunk[0] as i16,
callback(&Point { chunk[1] as i16, chunk[2] as i16,
position: pos, 0, chunk[3] as i16,
index_in_contour: index_in_contour, &mut pos,
kind: PointKind::FirstCubicControl, &mut index_in_contour,
}); &mut callback)
pos.x += chunk[1] as i16;
pos.y += chunk[2] as i16;
callback(&Point {
position: pos,
index_in_contour: index_in_contour + 1,
kind: PointKind::SecondCubicControl,
});
pos.y += chunk[3] as i16;
callback(&Point {
position: pos,
index_in_contour: index_in_contour + 2,
kind: PointKind::OnCurve,
});
index_in_contour += 3
} }
stack.clear() stack.clear()
} }
@ -307,29 +320,12 @@ impl<'a> CffTable<'a> {
for (i, chunk) in stack.array[start..stack.size as usize] for (i, chunk) in stack.array[start..stack.size as usize]
.chunks(4) .chunks(4)
.enumerate() { .enumerate() {
pos.x += chunk[0] as i16; add_curve(chunk[0] as i16, 0,
callback(&Point { chunk[1] as i16, chunk[2] as i16,
position: pos, chunk[3] as i16, 0,
index_in_contour: index_in_contour, &mut pos,
kind: PointKind::FirstCubicControl, &mut index_in_contour,
}); &mut callback)
pos.x += chunk[1] as i16;
pos.y += chunk[2] as i16;
callback(&Point {
position: pos,
index_in_contour: index_in_contour + 1,
kind: PointKind::SecondCubicControl,
});
pos.x += chunk[3] as i16;
callback(&Point {
position: pos,
index_in_contour: index_in_contour + 2,
kind: PointKind::OnCurve,
});
index_in_contour += 3
} }
stack.clear() stack.clear()
} }
@ -360,6 +356,12 @@ impl<'a> CffTable<'a> {
let hint_byte_count = (hint_count as usize + 7) / 8; let hint_byte_count = (hint_count as usize + 7) / 8;
try!(reader.jump(hint_byte_count).map_err(Error::eof)); try!(reader.jump(hint_byte_count).map_err(Error::eof));
} }
20 => {
// Skip ⌈hint_count / 8⌉ bytes.
stack.clear();
let hint_byte_count = (hint_count as usize + 7) / 8;
try!(reader.jump(hint_byte_count).map_err(Error::eof));
}
21 => { 21 => {
// |- dx1 dy1 rmoveto // |- dx1 dy1 rmoveto
close_path_if_necessary(&mut pos, &start, index_in_contour, &mut callback); close_path_if_necessary(&mut pos, &start, index_in_contour, &mut callback);
@ -562,61 +564,31 @@ fn close_path_if_necessary<F>(pos: &mut Point2D<i16>,
}); });
} }
fn process_hvcurveto_h<F>(chunk: &[i32], fn add_curve<F>(dx0: i16, dy0: i16,
pos: &mut Point2D<i16>, dx1: i16, dy1: i16,
dxf: i32, dx2: i16, dy2: i16,
index_in_contour: &mut u16, pos: &mut Point2D<i16>,
mut callback: F) index_in_contour: &mut u16,
where F: FnMut(&Point) { mut callback: F)
pos.x += chunk[0] as i16; where F: FnMut(&Point) {
pos.x += dx0;
pos.y += dy0;
callback(&Point { callback(&Point {
position: *pos, position: *pos,
index_in_contour: *index_in_contour + 0, index_in_contour: *index_in_contour + 0,
kind: PointKind::FirstCubicControl, kind: PointKind::FirstCubicControl,
}); });
pos.x += chunk[1] as i16; pos.x += dx1;
pos.y += chunk[2] as i16; pos.y += dy1;
callback(&Point { callback(&Point {
position: *pos, position: *pos,
index_in_contour: *index_in_contour + 1, index_in_contour: *index_in_contour + 1,
kind: PointKind::SecondCubicControl, kind: PointKind::SecondCubicControl,
}); });
pos.x += dxf as i16; pos.x += dx2;
pos.y += chunk[3] as i16; pos.y += dy2;
callback(&Point {
position: *pos,
index_in_contour: *index_in_contour + 2,
kind: PointKind::OnCurve,
});
*index_in_contour += 3
}
fn process_hvcurveto_v<F>(chunk: &[i32],
pos: &mut Point2D<i16>,
dyf: i32,
index_in_contour: &mut u16,
mut callback: F)
where F: FnMut(&Point) {
pos.y += chunk[0] as i16;
callback(&Point {
position: *pos,
index_in_contour: *index_in_contour + 0,
kind: PointKind::FirstCubicControl,
});
pos.x += chunk[1] as i16;
pos.y += chunk[2] as i16;
callback(&Point {
position: *pos,
index_in_contour: *index_in_contour + 1,
kind: PointKind::SecondCubicControl,
});
pos.x += chunk[3] as i16;
pos.y += dyf as i16;
callback(&Point { callback(&Point {
position: *pos, position: *pos,
index_in_contour: *index_in_contour + 2, index_in_contour: *index_in_contour + 2,