Skip to content

Commit 927cb7f

Browse files
committed
Update OpenType description to read simple glyph coordinates
1 parent cc28bd2 commit 927cb7f

File tree

4 files changed

+197
-24
lines changed

4 files changed

+197
-24
lines changed

formats/data/opentype/woff/valid-005.snap

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,8 +756,115 @@ stdout = '''
756756
end_pts_of_contours = [ 7, 17, 23, 27, 30 ],
757757
instruction_length = 0,
758758
instructions = [],
759-
last_end_point_index = 30,
760759
number_of_coords = 31,
760+
flags = [
761+
{ flag = 33, repeat = 0 },
762+
{ flag = 1, repeat = 0 },
763+
{ flag = 33, repeat = 0 },
764+
{ flag = 1, repeat = 0 },
765+
{ flag = 33, repeat = 0 },
766+
{ flag = 39, repeat = 0 },
767+
{ flag = 33, repeat = 0 },
768+
{ flag = 7, repeat = 0 },
769+
{ flag = 1, repeat = 0 },
770+
{ flag = 33, repeat = 0 },
771+
{ flag = 17, repeat = 0 },
772+
{ flag = 33, repeat = 0 },
773+
{ flag = 17, repeat = 0 },
774+
{ flag = 33, repeat = 0 },
775+
{ flag = 17, repeat = 0 },
776+
{ flag = 33, repeat = 0 },
777+
{ flag = 17, repeat = 0 },
778+
{ flag = 33, repeat = 0 },
779+
{ flag = 1, repeat = 0 },
780+
{ flag = 33, repeat = 0 },
781+
{ flag = 17, repeat = 0 },
782+
{ flag = 33, repeat = 0 },
783+
{ flag = 17, repeat = 0 },
784+
{ flag = 33, repeat = 0 },
785+
{ flag = 1, repeat = 0 },
786+
{ flag = 33, repeat = 0 },
787+
{ flag = 17, repeat = 0 },
788+
{ flag = 33, repeat = 0 },
789+
{ flag = 1, repeat = 0 },
790+
{ flag = 51, repeat = 0 },
791+
{ flag = 3, repeat = 0 },
792+
],
793+
read_coord = fun is_short => fun is_same => fun f => {
794+
coord <- match (is_short f) {
795+
false => match (is_same f) {
796+
false => s16be,
797+
true => succeed S16 0,
798+
},
799+
true => u8,
800+
},
801+
},
802+
x_coordinates = [
803+
{ coord = 1182 },
804+
{ coord = 436 },
805+
{ coord = 606 },
806+
{ coord = 436 },
807+
{ coord = -503 },
808+
{ coord = 66 },
809+
{ coord = -416 },
810+
{ coord = 63 },
811+
{ coord = -1407 },
812+
{ coord = 1073 },
813+
{ coord = 0 },
814+
{ coord = -588 },
815+
{ coord = 0 },
816+
{ coord = 502 },
817+
{ coord = 0 },
818+
{ coord = -502 },
819+
{ coord = 0 },
820+
{ coord = -485 },
821+
{ coord = 3248 },
822+
{ coord = 485 },
823+
{ coord = 0 },
824+
{ coord = 576 },
825+
{ coord = 0 },
826+
{ coord = -1061 },
827+
{ coord = -680 },
828+
{ coord = 485 },
829+
{ coord = 0 },
830+
{ coord = -485 },
831+
{ coord = -1012 },
832+
{ coord = 246 },
833+
{ coord = 123 },
834+
],
835+
y_coordinates = [
836+
{ coord = 0 },
837+
{ coord = 1434 },
838+
{ coord = 0 },
839+
{ coord = -1434 },
840+
{ coord = 0 },
841+
{ coord = 244 },
842+
{ coord = 0 },
843+
{ coord = 244 },
844+
{ coord = 1434 },
845+
{ coord = 0 },
846+
{ coord = -336 },
847+
{ coord = 0 },
848+
{ coord = -267 },
849+
{ coord = 0 },
850+
{ coord = -331 },
851+
{ coord = 0 },
852+
{ coord = -500 },
853+
{ coord = 0 },
854+
{ coord = 1434 },
855+
{ coord = 0 },
856+
{ coord = -1065 },
857+
{ coord = 0 },
858+
{ coord = -369 },
859+
{ coord = 0 },
860+
{ coord = 1434 },
861+
{ coord = 0 },
862+
{ coord = -1434 },
863+
{ coord = 0 },
864+
{ coord = 565 },
865+
{ coord = 0 },
866+
{ coord = 467 },
867+
],
761868
},
762869
},
763870
],

formats/opentype.fathom

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,25 +2793,54 @@ def glyph_header = {
27932793
///
27942794
/// - [Microsoft's OpenType Spec: Glyph Headers](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#simple-glyph-description)
27952795
/// - [Apple's TrueType Reference Manual: The `'loca'` table](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html)
2796-
def simple_glyph = fun (number_of_contours : U16) => {
2797-
/// Array of point indices for the last point of each contour, in increasing numeric order.
2798-
end_pts_of_contours <- array16 number_of_contours u16be,
2799-
/// Total number of bytes for instructions. If instructionLength is zero, no instructions are
2800-
/// present for this glyph, and this field is followed directly by the flags field.
2801-
instruction_length <- u16be,
2802-
/// Array of instruction byte code for the glyph.
2803-
instructions <- array16 instruction_length u8,
2804-
let last_end_point_index = array16_index _ _ (number_of_contours - (1 : U16)) end_pts_of_contours,
2805-
let number_of_coords = last_end_point_index + (1 : U16),
2806-
/// Array of flag elements.
2807-
// flags[variable] <- uint8,
2808-
/// xCoordinates[variable] Contour point x-coordinates. Coordinate for the first point is relative to (0,0);
2809-
/// others are relative to previous point.
2810-
// or int16 <- uint8,
2811-
/// yCoordinates[variable] Contour point y-coordinates. Coordinate for the first point is relative to (0,0);
2812-
/// others are relative to previous point.
2813-
// or int16 <- uint8,
2814-
};
2796+
def simple_glyph = fun (number_of_contours : U16) => (
2797+
let flag = {
2798+
flag <- u8,
2799+
repeat <- or_succeed ((u8_and flag 8) != (0 : U8)) u8 0,
2800+
};
2801+
2802+
let flag_repeat = fun (f : Repr flag) => u16_from_u8 f.repeat + (1 : U16);
2803+
let flag_is_set = fun (bit : U8) => fun (f : Repr flag) => u8_and f.flag bit != (0 : U8);
2804+
let x_is_short = flag_is_set 2;
2805+
let x_is_same = flag_is_set 0x10;
2806+
let y_is_short = flag_is_set 4;
2807+
let y_is_same = flag_is_set 0x20;
2808+
2809+
{
2810+
/// Array of point indices for the last point of each contour, in increasing numeric order.
2811+
end_pts_of_contours <- array16 number_of_contours u16be,
2812+
/// Total number of bytes for instructions. If instructionLength is zero, no instructions are
2813+
/// present for this glyph, and this field is followed directly by the flags field.
2814+
instruction_length <- u16be,
2815+
/// Array of instruction byte code for the glyph.
2816+
instructions <- array16 instruction_length u8,
2817+
2818+
let number_of_coords = match (u16_gt number_of_contours (0 : U16)) {
2819+
true => array16_index _ _ (number_of_contours - (1 : U16)) end_pts_of_contours + (1 : U16),
2820+
false => 0
2821+
},
2822+
2823+
/// Array of flag elements.
2824+
flags <- repeat_until_full number_of_coords flag flag_repeat,
2825+
2826+
let read_coord = fun (is_short : Repr flag -> Bool) => fun (is_same : Repr flag -> Bool) => fun (f : Repr flag) => {
2827+
coord <- match (is_short f) {
2828+
true => u8,
2829+
false => match (is_same f) {
2830+
true => succeed S16 0,
2831+
false => s16be,
2832+
}
2833+
}
2834+
},
2835+
2836+
/// Contour point x-coordinates. Coordinate for the first point is relative to (0,0);
2837+
/// others are relative to previous point.
2838+
x_coordinates <- array16_map number_of_coords _ (read_coord x_is_short x_is_same) flags,
2839+
/// Contour point y-coordinates. Coordinate for the first point is relative to (0,0);
2840+
/// others are relative to previous point.
2841+
y_coordinates <- array16_map number_of_coords _ (read_coord y_is_short y_is_same) flags,
2842+
}
2843+
);
28152844

28162845
def args_are_signed = fun (flags : U16) =>
28172846
u16_and flags 0x0002 != (0 : U16);

formats/opentype.snap

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,44 @@ def composite_glyph : Format = {
380380
argument1 <- arg_format flags,
381381
argument2 <- arg_format flags,
382382
};
383-
def simple_glyph : U16 -> Format = fun number_of_contours => {
383+
def simple_glyph : U16 -> Format = fun number_of_contours => let flag :
384+
_ number_of_contours = {
385+
flag <- u8,
386+
repeat <- or_succeed (u8_and flag 8 != (0 : U8)) u8 0,
387+
};
388+
let flag_repeat : _ number_of_contours = fun f => u16_from_u8 f.repeat + (1 :
389+
U16);
390+
let flag_is_set : _ number_of_contours =
391+
fun bit => fun f => u8_and f.flag bit != (0 : U8);
392+
let x_is_short : _ number_of_contours = flag_is_set 2;
393+
let x_is_same : _ number_of_contours = flag_is_set 0x10;
394+
let y_is_short : _ number_of_contours = flag_is_set 4;
395+
let y_is_same : _ number_of_contours = flag_is_set 0x20;
396+
{
384397
end_pts_of_contours <- array16 number_of_contours u16be,
385398
instruction_length <- u16be,
386399
instructions <- array16 instruction_length u8,
387-
let last_end_point_index : U16 = array16_index (_ number_of_contours end_pts_of_contours instruction_length instructions) (_ number_of_contours end_pts_of_contours instruction_length instructions) (number_of_contours - (1 :
388-
U16)) end_pts_of_contours,
389-
let number_of_coords : U16 = last_end_point_index + (1 : U16),
400+
let number_of_coords : U16 = match (u16_gt number_of_contours 0) {
401+
false => 0,
402+
true => array16_index (_ number_of_contours end_pts_of_contours instruction_length instructions) (_ number_of_contours end_pts_of_contours instruction_length instructions) (number_of_contours - (1 :
403+
U16)) end_pts_of_contours + (1 : U16),
404+
},
405+
flags <- repeat_until_full number_of_coords flag flag_repeat,
406+
let read_coord : ({ flag : U8, repeat : U8 } -> Bool) -> ({
407+
flag : U8,
408+
repeat : U8,
409+
} -> Bool) -> { flag : U8, repeat : U8 } ->
410+
Format = fun is_short => fun is_same => fun f => {
411+
coord <- match (is_short f) {
412+
false => match (is_same f) {
413+
false => s16be,
414+
true => succeed S16 0,
415+
},
416+
true => u8,
417+
},
418+
},
419+
x_coordinates <- array16_map number_of_coords (_ number_of_contours end_pts_of_contours instruction_length instructions number_of_coords flags read_coord) (read_coord x_is_short x_is_same) flags,
420+
y_coordinates <- array16_map number_of_coords (_ number_of_contours end_pts_of_contours instruction_length instructions number_of_coords flags read_coord x_coordinates) (read_coord y_is_short y_is_same) flags,
390421
};
391422
def glyph : Format = {
392423
header <- glyph_header,

tests/succeed/primitives.snap

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,15 @@ let _ : _ = array16;
5353
let _ : _ = array32;
5454
let _ : _ = array64;
5555
let _ : _ = repeat_until_end;
56+
let _ : _ = repeat_until_full;
5657
let _ : _ = array8;
5758
let _ : _ = array16;
5859
let _ : _ = array32;
5960
let _ : _ = array64;
61+
let _ : _ = array8_map;
62+
let _ : _ = array16_map;
63+
let _ : _ = array32_map;
64+
let _ : _ = array64_map;
6065
let _ : _ = link;
6166
let _ : _ = deref;
6267
let _ : _ = stream_pos;
@@ -103,6 +108,7 @@ let _ : _ = u16_shr;
103108
let _ : _ = u16_and;
104109
let _ : _ = u16_or;
105110
let _ : _ = u16_xor;
111+
let _ : _ = u16_from_u8;
106112
let _ : _ = u32_eq;
107113
let _ : _ = u32_neq;
108114
let _ : _ = u32_gt;

0 commit comments

Comments
 (0)