aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-03-26 14:09:15 +0800
committerPo Lu2023-03-26 14:09:15 +0800
commitc0873f2382f575b08b5c9eb6663d7a7acf7ece65 (patch)
tree3ad999c79a7aeebeedb008261c5994ca9170e689 /src
parentd7457e1ce4eed211915a6666cc2e7f61516ed343 (diff)
downloademacs-c0873f2382f575b08b5c9eb6663d7a7acf7ece65.tar.gz
emacs-c0873f2382f575b08b5c9eb6663d7a7acf7ece65.zip
Update Android port
* src/sfnt.c (sfnt_table_names): Add avar. (sfnt_read_glyph): Clear distortion fields. (sfnt_build_glyph_outline): Calculate the outline origin point. (sfnt_prepare_raster): Apply the origin point to the X axis offset. (sfnt_scale_metrics_to_pixel_size): New function. (sfnt_build_instructed_outline): Use instructed origin phantom point to determine the outline origin. (sfnt_compute_phantom_points): Apply origin and advance distortion. (struct sfnt_variation_axis, struct sfnt_instance) (struct sfnt_fvar_table, sfnt_read_fvar_table) (struct sfnt_gvar_table, sfnt_read_gvar_table) (sfnt_read_avar_table, struct sfnt_blend, sfnt_init_blend) (sfnt_free_blend, sfnt_normalize_blend, struct sfnt_tuple_header) (struct sfnt_gvar_glyph_header, sfnt_read_packed_deltas) (sfnt_compute_tuple_scale, sfnt_read_cvar_table) (sfnt_infer_deltas_1, sfnt_vary_simple_glyph, sfnt_infer_deltas) (sfnt_vary_glyph, sfnt_vary_compound_glyph) (sfnt_vary_interpreter): New functions. Add structs to sfntfont.h. (struct sfnt_test_dcontext, sfnt_test_get_glyph, main): Test distortable font handling. * src/sfnt.h (SFNT_ENABLE_HINTING): (enum sfnt_table): (struct sfnt_glyph): (struct sfnt_glyph_outline): (struct sfnt_raster): (struct sfnt_default_uvs_table): (struct sfnt_unicode_value_range): (struct sfnt_nondefault_uvs_table): (struct sfnt_uvs_mapping): (struct sfnt_mapped_variation_selector_record): (struct sfnt_table_offset_rec): (struct sfnt_uvs_context): (struct sfnt_mapped_table): (struct sfnt_variation_axis): (struct sfnt_instance): (struct sfnt_fvar_table): (struct sfnt_short_frac_correspondence): (struct sfnt_short_frac_segment): (struct sfnt_avar_table): (struct sfnt_tuple_variation): (struct sfnt_cvar_table): (struct sfnt_gvar_table): (struct sfnt_blend): (struct sfnt_metrics_distortion): (PROTOTYPE): Update prototypes. * src/sfntfont.c (sfntfont_get_glyph_outline): (sfntfont_measure_pcm): Adjust calls.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.c1778
-rw-r--r--src/sfnt.h583
-rw-r--r--src/sfntfont.c36
3 files changed, 1848 insertions, 549 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index 21b2ea96e1c..8e7a30e3b05 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -153,6 +153,7 @@ static uint32_t sfnt_table_names[] =
153 [SFNT_TABLE_FVAR] = 0x66766172, 153 [SFNT_TABLE_FVAR] = 0x66766172,
154 [SFNT_TABLE_GVAR] = 0x67766172, 154 [SFNT_TABLE_GVAR] = 0x67766172,
155 [SFNT_TABLE_CVAR] = 0x63766172, 155 [SFNT_TABLE_CVAR] = 0x63766172,
156 [SFNT_TABLE_AVAR] = 0x61766172,
156 }; 157 };
157 158
158/* Swap values from TrueType to system byte order. */ 159/* Swap values from TrueType to system byte order. */
@@ -2377,6 +2378,10 @@ sfnt_read_glyph (sfnt_glyph glyph_code,
2377 sfnt_swap16 (&glyph.xmax); 2378 sfnt_swap16 (&glyph.xmax);
2378 sfnt_swap16 (&glyph.ymax); 2379 sfnt_swap16 (&glyph.ymax);
2379 2380
2381 /* This is set later on after `sfnt_vary_X_glyph'. */
2382 glyph.advance_distortion = 0;
2383 glyph.origin_distortion = 0;
2384
2380 /* Figure out what needs to be read based on 2385 /* Figure out what needs to be read based on
2381 glyph.number_of_contours. */ 2386 glyph.number_of_contours. */
2382 if (glyph.number_of_contours >= 0) 2387 if (glyph.number_of_contours >= 0)
@@ -3758,6 +3763,9 @@ sfnt_curve_to_and_build (struct sfnt_point control,
3758 given pixel size. Return the outline data with a refcount of 0 3763 given pixel size. Return the outline data with a refcount of 0
3759 upon success, or NULL upon failure. 3764 upon success, or NULL upon failure.
3760 3765
3766 Use the scaled glyph METRICS to determine the origin point of the
3767 outline.
3768
3761 Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain 3769 Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain
3762 glyphs for compound glyph subcomponents. 3770 glyphs for compound glyph subcomponents.
3763 3771
@@ -3767,12 +3775,14 @@ TEST_STATIC struct sfnt_glyph_outline *
3767sfnt_build_glyph_outline (struct sfnt_glyph *glyph, 3775sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3768 struct sfnt_head_table *head, 3776 struct sfnt_head_table *head,
3769 int pixel_size, 3777 int pixel_size,
3778 struct sfnt_glyph_metrics *metrics,
3770 sfnt_get_glyph_proc get_glyph, 3779 sfnt_get_glyph_proc get_glyph,
3771 sfnt_free_glyph_proc free_glyph, 3780 sfnt_free_glyph_proc free_glyph,
3772 void *dcontext) 3781 void *dcontext)
3773{ 3782{
3774 struct sfnt_glyph_outline *outline; 3783 struct sfnt_glyph_outline *outline;
3775 int rc; 3784 int rc;
3785 sfnt_fword origin;
3776 3786
3777 memset (&build_outline_context, 0, sizeof build_outline_context); 3787 memset (&build_outline_context, 0, sizeof build_outline_context);
3778 3788
@@ -3825,6 +3835,12 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3825 return NULL; 3835 return NULL;
3826 } 3836 }
3827 3837
3838 /* Compute the origin position. */
3839 origin = outline->xmin - metrics->lbearing;
3840 outline->origin
3841 = (origin + sfnt_mul_fixed (glyph->origin_distortion,
3842 build_outline_context.factor));
3843
3828 return outline; 3844 return outline;
3829} 3845}
3830 3846
@@ -3887,7 +3903,11 @@ sfnt_prepare_raster (struct sfnt_raster *raster,
3887 + (SFNT_POLY_ALIGNMENT - 1)) 3903 + (SFNT_POLY_ALIGNMENT - 1))
3888 & ~(SFNT_POLY_ALIGNMENT - 1)); 3904 & ~(SFNT_POLY_ALIGNMENT - 1));
3889 3905
3890 raster->offx = sfnt_floor_fixed (outline->xmin) >> 16; 3906 /* Apply outline->origin. This is 0 by convention in most fonts.
3907 However, variable fonts typically change this as variations are
3908 applied. */
3909 raster->offx = sfnt_floor_fixed (outline->xmin
3910 - outline->origin) >> 16;
3891 raster->offy = sfnt_floor_fixed (outline->ymin) >> 16; 3911 raster->offy = sfnt_floor_fixed (outline->ymin) >> 16;
3892} 3912}
3893 3913
@@ -4516,6 +4536,23 @@ sfnt_scale_metrics (struct sfnt_glyph_metrics *metrics,
4516 = sfnt_mul_fixed (metrics->advance * 65536, factor); 4536 = sfnt_mul_fixed (metrics->advance * 65536, factor);
4517} 4537}
4518 4538
4539/* Like `sfnt_scale_metrics', except it scales the specified metrics
4540 by a factor calculated using the given PPEM and HEAD table's UPEM
4541 value. */
4542
4543MAYBE_UNUSED TEST_STATIC void
4544sfnt_scale_metrics_to_pixel_size (struct sfnt_glyph_metrics *metrics,
4545 int ppem,
4546 struct sfnt_head_table *head)
4547{
4548 sfnt_fixed factor;
4549
4550 /* Now calculate the factor scale lbearing and advance up to the
4551 given PPEM size. */
4552 factor = sfnt_div_fixed (ppem, head->units_per_em);
4553 sfnt_scale_metrics (metrics, factor);
4554}
4555
4519 4556
4520 4557
4521/* Font style parsing. */ 4558/* Font style parsing. */
@@ -4949,8 +4986,6 @@ sfnt_read_ttc_header (int fd)
4949 4986
4950 4987
4951 4988
4952#ifdef SFNT_ENABLE_HINTING
4953
4954/* TrueType hinting support. 4989/* TrueType hinting support.
4955 4990
4956 If you do not read the code in this section in conjunction with 4991 If you do not read the code in this section in conjunction with
@@ -10897,6 +10932,15 @@ sfnt_build_instructed_outline (struct sfnt_instructed_outline *instructed)
10897 inside sfnt_decompose_glyph. */ 10932 inside sfnt_decompose_glyph. */
10898 outline = build_outline_context.outline; 10933 outline = build_outline_context.outline;
10899 10934
10935 /* Finally, obtain the origin point of the glyph after it has been
10936 instructed. */
10937
10938 if (instructed->num_points > 1)
10939 outline->origin
10940 = instructed->x_points[instructed->num_points - 2];
10941 else
10942 outline->origin = 0;
10943
10900 if (rc) 10944 if (rc)
10901 { 10945 {
10902 xfree (outline); 10946 xfree (outline);
@@ -10935,6 +10979,10 @@ sfnt_compute_phantom_points (struct sfnt_glyph *glyph,
10935 f1 = glyph->xmin - metrics->lbearing; 10979 f1 = glyph->xmin - metrics->lbearing;
10936 f2 = f1 + metrics->advance; 10980 f2 = f1 + metrics->advance;
10937 10981
10982 /* Apply the metrics distortion. */
10983 f1 += glyph->origin_distortion;
10984 f2 += glyph->advance_distortion;
10985
10938 /* Next, scale both up. */ 10986 /* Next, scale both up. */
10939 *x1 = sfnt_mul_f26dot6_fixed (f1 * 64, scale); 10987 *x1 = sfnt_mul_f26dot6_fixed (f1 * 64, scale);
10940 *x2 = sfnt_mul_f26dot6_fixed (f2 * 64, scale); 10988 *x2 = sfnt_mul_f26dot6_fixed (f2 * 64, scale);
@@ -11881,7 +11929,6 @@ sfnt_interpret_compound_glyph (struct sfnt_glyph *glyph,
11881 return NULL; 11929 return NULL;
11882} 11930}
11883 11931
11884#endif /* SFNT_ENABLE_HINTING */
11885 11932
11886 11933
11887 11934
@@ -12428,8 +12475,6 @@ sfnt_read_table (int fd, struct sfnt_offset_subtable *subtable,
12428 12475
12429#endif /* !TEST */ 12476#endif /* !TEST */
12430 12477
12431#ifdef TEST
12432
12433 12478
12434 12479
12435/* Glyph variations. Instead of defining separate fonts for each 12480/* Glyph variations. Instead of defining separate fonts for each
@@ -12442,83 +12487,12 @@ sfnt_read_table (int fd, struct sfnt_offset_subtable *subtable,
12442 variation), `gvar' (glyph variation) and `cvar' (CVT variation) 12487 variation), `gvar' (glyph variation) and `cvar' (CVT variation)
12443 tables in a font file. */ 12488 tables in a font file. */
12444 12489
12445struct sfnt_variation_axis
12446{
12447 /* The axis tag. */
12448 uint32_t axis_tag;
12449
12450 /* The minimum style coordinate for the axis. */
12451 sfnt_fixed min_value;
12452
12453 /* The default style coordinate for the axis. */
12454 sfnt_fixed default_value;
12455
12456 /* The maximum style coordinate for the axis. */
12457 sfnt_fixed max_value;
12458
12459 /* Set to zero. */
12460 uint16_t flags;
12461
12462 /* Identifier under which this axis's name will be found in the
12463 `name' table. */
12464 uint16_t name_id;
12465};
12466
12467struct sfnt_instance
12468{
12469 /* The instance name ID. */
12470 uint16_t name_id;
12471
12472 /* Flags. */
12473 uint16_t flags;
12474
12475 /* Optional PostScript name. */
12476 uint16_t ps_name_id;
12477
12478 /* Coordinates of each defined instance. */
12479 sfnt_fixed *coords;
12480};
12481
12482struct sfnt_fvar_table
12483{
12484 /* Major version; should be 1. */
12485 uint16_t major_version;
12486
12487 /* Minor version; should be 0. */
12488 uint16_t minor_version;
12489
12490 /* Offset in bytes from the beginning of the table to the beginning
12491 of the first axis data. */
12492 uint16_t offset_to_data;
12493
12494 /* Reserved field; always 2. */
12495 uint16_t count_size_pairs;
12496
12497 /* Number of style axes in this font. */
12498 uint16_t axis_count;
12499
12500 /* The number of bytes in each variation axis record. Currently 20
12501 bytes. */
12502 uint16_t axis_size;
12503
12504 /* The number of named instances for the font found in the
12505 instance array. */
12506 uint16_t instance_count;
12507
12508 /* The size of each instance record. */
12509 uint16_t instance_size;
12510
12511 /* Variable length data. */
12512 struct sfnt_variation_axis *axis;
12513 struct sfnt_instance *instance;
12514};
12515
12516/* Read an fvar table from the given font FD. Use the table directory 12490/* Read an fvar table from the given font FD. Use the table directory
12517 specified in SUBTABLE. 12491 specified in SUBTABLE.
12518 12492
12519 Return the fvar table upon success, else NULL. */ 12493 Return the fvar table upon success, else NULL. */
12520 12494
12521static struct sfnt_fvar_table * 12495TEST_STATIC struct sfnt_fvar_table *
12522sfnt_read_fvar_table (int fd, struct sfnt_offset_subtable *subtable) 12496sfnt_read_fvar_table (int fd, struct sfnt_offset_subtable *subtable)
12523{ 12497{
12524 struct sfnt_table_directory *directory; 12498 struct sfnt_table_directory *directory;
@@ -12745,60 +12719,12 @@ sfnt_read_fvar_table (int fd, struct sfnt_offset_subtable *subtable)
12745 12719
12746 12720
12747 12721
12748struct sfnt_gvar_table
12749{
12750 /* Version of the glyph variations table. */
12751 uint16_t version;
12752
12753 /* Reserved, currently 0. */
12754 uint16_t reserved;
12755
12756 /* The number of style axes for this font. This must be the same
12757 number as axisCount in the 'fvar' table. */
12758 uint16_t axis_count;
12759
12760 /* The number of shared coordinates. */
12761 uint16_t shared_coord_count;
12762
12763 /* Byte offset from the beginning of this table to the list of
12764 shared style coordinates. */
12765 uint32_t offset_to_coord;
12766
12767 /* The number of glyphs in this font; this should match the number
12768 of the glyphs store elsewhere in the font. */
12769 uint16_t glyph_count;
12770
12771 /* Bit-field that gives the format of the offset array that
12772 follows. If the flag is 0, the type is uint16. If the flag is 1,
12773 the type is unit 32. */
12774 uint16_t flags;
12775
12776 /* Byte offset from the beginning of this table to the first glyph
12777 glyphVariationData. */
12778 uint32_t offset_to_data;
12779
12780 /* Number of bytes in the glyph variation data. */
12781 size_t data_size;
12782
12783 /* Byte offsets from the beginning of the glyphVariationData array
12784 to the glyphVariationData for each glyph in the font. The format
12785 of this field is set by the flags field. */
12786 union {
12787 uint16_t *offset_word;
12788 uint32_t *offset_long;
12789 } u;
12790
12791 /* Other variable length data. */
12792 sfnt_f2dot14 *global_coords;
12793 unsigned char *glyph_variation_data;
12794};
12795
12796/* Read a gvar table from the given font FD. Use the table directory 12722/* Read a gvar table from the given font FD. Use the table directory
12797 specified in SUBTABLE. 12723 specified in SUBTABLE.
12798 12724
12799 Return the gvar table upon success, else NULL. */ 12725 Return the gvar table upon success, else NULL. */
12800 12726
12801static struct sfnt_gvar_table * 12727TEST_STATIC struct sfnt_gvar_table *
12802sfnt_read_gvar_table (int fd, struct sfnt_offset_subtable *subtable) 12728sfnt_read_gvar_table (int fd, struct sfnt_offset_subtable *subtable)
12803{ 12729{
12804 struct sfnt_table_directory *directory; 12730 struct sfnt_table_directory *directory;
@@ -12956,160 +12882,130 @@ sfnt_read_gvar_table (int fd, struct sfnt_offset_subtable *subtable)
12956 12882
12957 12883
12958 12884
12959/* Structure repesenting a set of axis coordinates and their 12885/* Read an avar table from the given font FD. Use the table directory
12960 normalized equivalents. 12886 specified in SUBTABLE.
12961 12887
12962 To use this structure, call 12888 Return the avar table upon success, else NULL. */
12963 12889
12964 sfnt_init_blend (&blend, fvar, gvar) 12890TEST_STATIC struct sfnt_avar_table *
12891sfnt_read_avar_table (int fd, struct sfnt_offset_subtable *subtable)
12892{
12893 struct sfnt_table_directory *directory;
12894 struct sfnt_avar_table *avar;
12895 ssize_t rc;
12896 size_t min_size, size, i, k, j;
12897 uint16_t *buffer;
12898 struct sfnt_short_frac_correspondence *correspondences;
12965 12899
12966 on a `struct sfnt_blend *', with an appropriate fvar and gvar 12900 /* Find the table in the directory. */
12967 table.
12968 12901
12969 Then, fill in blend.coords with the un-normalized coordinates, 12902 directory = sfnt_find_table (subtable, SFNT_TABLE_AVAR);
12970 and call
12971 12903
12972 sfnt_normalize_blend (&blend) 12904 if (!directory)
12905 return NULL;
12973 12906
12974 finally, call sfnt_vary_glyph and related functions. */ 12907 min_size = SFNT_ENDOF (struct sfnt_avar_table, axis_count, uint32_t);
12975 12908
12976struct sfnt_blend 12909 /* Check that the length is at least min_size. */
12977{ 12910 if (directory->length < min_size)
12978 /* The fvar table. This determines the number of elements in each 12911 return NULL;
12979 of the arrays below. */
12980 struct sfnt_fvar_table *fvar;
12981 12912
12982 /* The gvar table. This provides the glyph variation data. */ 12913 /* Seek to the location given in the directory. */
12983 struct sfnt_gvar_table *gvar; 12914 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
12915 return NULL;
12984 12916
12985 /* Un-normalized coordinates. */ 12917 /* Allocate enough to hold the avar table header. */
12986 sfnt_fixed *coords; 12918 avar = xmalloc (sizeof *avar);
12987 12919
12988 /* Normalized coordinates. */ 12920 /* Read the avar table header. */
12989 sfnt_fixed *norm_coords; 12921 rc = read (fd, avar, min_size);
12990}; 12922 if (rc != min_size)
12923 goto bail;
12991 12924
12992/* Initialize the specified BLEND with the given FVAR and GVAR 12925 /* Swap what was read. */
12993 tables. */ 12926 sfnt_swap32 (&avar->version);
12927 sfnt_swap32 (&avar->axis_count);
12994 12928
12995static void 12929 if (avar->version != 0x00010000)
12996sfnt_init_blend (struct sfnt_blend *blend, struct sfnt_fvar_table *fvar, 12930 goto bail;
12997 struct sfnt_gvar_table *gvar)
12998{
12999 size_t size;
13000 12931
13001 blend->fvar = fvar; 12932 if (avar->axis_count < 0)
13002 blend->gvar = gvar; 12933 goto bail;
13003 12934
13004 /* Allocate a single array to hold both coords and norm_coords. */ 12935 /* Allocate a buffer that holds the rest of the data. */
13005 size = (fvar->axis_count * sizeof *blend->coords * 2); 12936 size = directory->length - min_size;
13006 blend->coords = xmalloc (size); 12937 buffer = xmalloc (size);
13007 blend->norm_coords = blend->coords + fvar->axis_count; 12938 rc = read (fd, buffer, size);
13008} 12939 if (rc != size)
12940 goto bail1;
13009 12941
13010/* Free what was initialized in the specified BLEND. */ 12942 /* Swap each word. */
12943 for (i = 0; i < size / sizeof *buffer; ++i)
12944 sfnt_swap16 (&buffer[i]);
13011 12945
13012static void 12946 /* Now, determine how big the resulting data needs to be. Each
13013sfnt_free_blend (struct sfnt_blend *blend) 12947 struct has a pointer field, and that should be its alignment. */
13014{
13015 xfree (blend->coords);
13016}
13017 12948
13018/* Normalize BLEND->fvar->axis_count coordinates in BLEND->coords and 12949 k = 0;
13019 place the result in BLEND->norm_coords. */ 12950 min_size = sizeof *avar;
12951 for (i = 0; i < avar->axis_count; ++i)
12952 {
12953 /* Check that k remains within bounds. */
12954 if (k >= size / sizeof *buffer)
12955 goto bail1;
13020 12956
13021static void 12957 /* Now add one struct sfnt_short_frac_segment for each axis and
13022sfnt_normalize_blend (struct sfnt_blend *blend) 12958 each of its correspondences. */
13023{ 12959 if (INT_ADD_WRAPV (sizeof (struct sfnt_short_frac_segment),
13024 struct sfnt_variation_axis *axis; 12960 min_size, &min_size)
13025 int i; 12961 || INT_ADD_WRAPV (sizeof (struct sfnt_short_frac_correspondence)
13026 sfnt_fixed coord; 12962 * buffer[k], min_size, &min_size))
12963 goto bail1;
13027 12964
13028 /* For each axis... */ 12965 /* Verify that words from here to buffer[1 + buffer[k] * 2], the
13029 for (i = 0; i < blend->fvar->axis_count; ++i) 12966 next pairCount field, are within bounds. */
13030 { 12967 if (k + 1 + buffer[k] * 2 > size / sizeof *buffer)
13031 /* Normalize based on [min, default, max], into [-1, 0, 1]. */ 12968 goto bail1;
13032 axis = &blend->fvar->axis[i];
13033 12969
13034 /* Load the current design coordinate. */ 12970 /* Move to the next pairCount field. */
13035 coord = blend->coords[i]; 12971 k += 1 + buffer[k] * 2;
12972 }
13036 12973
13037 /* Keep it within bounds. */ 12974 /* Resize avar to min_size and start filling in various
12975 pointers. */
12976 avar = xrealloc (avar, min_size);
12977 avar->segments = (struct sfnt_short_frac_segment *) (avar + 1);
12978 correspondences
12979 = ((struct sfnt_short_frac_correspondence *) (avar->segments
12980 + avar->axis_count));
13038 12981
13039 if (coord > axis->max_value) 12982 k = 0;
13040 coord = axis->max_value; 12983 for (i = 0; i < avar->axis_count; ++i)
13041 else if (coord < axis->min_value) 12984 {
13042 coord = axis->min_value; 12985 avar->segments[i].pair_count = buffer[k++];
12986 avar->segments[i].correspondence = correspondences;
13043 12987
13044 if (coord > axis->default_value) 12988 for (j = 0; j < avar->segments[i].pair_count; ++j)
13045 {
13046 /* Avoid division by 0. */
13047 if (axis->max_value != axis->default_value)
13048 blend->norm_coords[i]
13049 = sfnt_div_fixed (sfnt_sub (coord, axis->default_value),
13050 sfnt_sub (axis->max_value,
13051 axis->default_value));
13052 else
13053 blend->norm_coords[i] = 0;
13054 }
13055 else if (coord < axis->default_value)
13056 { 12989 {
13057 if (axis->default_value != axis->min_value) 12990 correspondences->from_coord = buffer[k++];
13058 blend->norm_coords[i] 12991 correspondences->to_coord = buffer[k++];
13059 = sfnt_div_fixed (sfnt_sub (coord, axis->default_value), 12992 correspondences++;
13060 sfnt_sub (axis->default_value,
13061 axis->min_value));
13062 else
13063 blend->norm_coords[i] = 0;
13064 } 12993 }
13065 else
13066 blend->norm_coords[i] = 0;
13067 } 12994 }
13068 12995
13069 /* TODO: process avar tables. */ 12996 /* Return the read avar table. Free buffer. */
12997 xfree (buffer);
12998 return avar;
12999
13000 bail1:
13001 xfree (buffer);
13002 bail:
13003 xfree (avar);
13004 return NULL;
13070} 13005}
13071 13006
13072 13007
13073 13008
13074struct sfnt_tuple_header
13075{
13076 /* The size in bytes of the serialized data for this tuple variation
13077 table. */
13078 uint16_t variation_data_size;
13079
13080 /* A packed field. The high 4 bits are flags (see below). The low 12
13081 bits are an index into a shared tuple records array. */
13082 uint16_t tuple_index;
13083
13084 /* Embedded coordinate tuples, if any. */
13085 sfnt_f2dot14 *embedded_coord;
13086
13087 /* Intermediate coordinate tuples, if any. */
13088 sfnt_f2dot14 *intermediate_coord;
13089
13090 /* Number of points associated with this tuple.
13091 Times two, the number of deltas associated with this tuple. */
13092 uint16_t npoints;
13093
13094 /* Points associated with this tuple. */
13095 uint16_t *points;
13096
13097 /* Deltas associated with this tuple. */
13098 sfnt_fword *deltas;
13099};
13100
13101struct sfnt_gvar_glyph_header
13102{
13103 /* A packed field. The high 4 bits are flags and the low 12 bits are
13104 the number of tuples for this glyph. The number of tuples can be
13105 any number between 1 and 4095. */
13106 uint16_t tuple_count;
13107
13108 /* Offset from the start of the GlyphVariationData table to the
13109 serialized data. */
13110 uint16_t data_offset;
13111};
13112
13113/* Read a sequence of packed points starting from DATA. Return the 13009/* Read a sequence of packed points starting from DATA. Return the
13114 number of points read in *NPOINTS_RETURN and the array of unpacked 13010 number of points read in *NPOINTS_RETURN and the array of unpacked
13115 points, or NULL upon failure. 13011 points, or NULL upon failure.
@@ -13234,6 +13130,7 @@ sfnt_read_packed_deltas (unsigned char *restrict data,
13234 sfnt_fword *deltas; 13130 sfnt_fword *deltas;
13235 int i, count; 13131 int i, count;
13236 unsigned char control; 13132 unsigned char control;
13133 uint16_t value;
13237 13134
13238 if (data >= end) 13135 if (data >= end)
13239 return NULL; 13136 return NULL;
@@ -13258,9 +13155,9 @@ sfnt_read_packed_deltas (unsigned char *restrict data,
13258 if (data + 1 >= end) 13155 if (data + 1 >= end)
13259 goto fail; 13156 goto fail;
13260 13157
13261 deltas[i] = (signed char) *data++; 13158 value = *data++ << 8;
13262 deltas[i] *= 65536; 13159 value |= *data++;
13263 deltas[i++] |= *data++; 13160 deltas[i++] = value;
13264 } 13161 }
13265 else 13162 else
13266 { 13163 {
@@ -13282,6 +13179,465 @@ sfnt_read_packed_deltas (unsigned char *restrict data,
13282 return NULL; 13179 return NULL;
13283} 13180}
13284 13181
13182/* Read a cvar table from the given font FD. Use the table directory
13183 specified in SUBTABLE, axis information provided in the fvar table
13184 FVAR, and CVT information provided in the cvt table CVT.
13185
13186 Return the cvar table upon success, else NULL. */
13187
13188TEST_STATIC struct sfnt_cvar_table *
13189sfnt_read_cvar_table (int fd, struct sfnt_offset_subtable *subtable,
13190 struct sfnt_fvar_table *fvar,
13191 struct sfnt_cvt_table *cvt)
13192{
13193 struct sfnt_table_directory *directory;
13194 struct sfnt_cvar_table *cvar;
13195 ssize_t rc;
13196 size_t ntuples, size;
13197 int i, j;
13198 sfnt_f2dot14 *coords;
13199 uint16_t *local, *points, npoints, data_size, min_size, index;
13200 unsigned char *buffer, *data, *end, *tuple;
13201 ptrdiff_t data_offset;
13202 sfnt_fword *deltas;
13203
13204 /* Find the table in the directory. */
13205
13206 directory = sfnt_find_table (subtable, SFNT_TABLE_CVAR);
13207
13208 if (!directory)
13209 return NULL;
13210
13211 min_size = SFNT_ENDOF (struct sfnt_cvar_table, data_offset,
13212 uint16_t);
13213
13214 /* Check that the length is at least min_size. */
13215 if (directory->length < min_size)
13216 return NULL;
13217
13218 /* Seek to the location given in the directory. */
13219 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
13220 return NULL;
13221
13222 /* Allocate enough to hold the cvar table header. */
13223 cvar = xmalloc (sizeof *cvar);
13224
13225 /* Read the cvar table header. */
13226 rc = read (fd, cvar, min_size);
13227 if (rc != min_size)
13228 goto bail;
13229
13230 /* Swap what was read. */
13231 sfnt_swap32 (&cvar->version);
13232 sfnt_swap16 (&cvar->tuple_count);
13233 sfnt_swap16 (&cvar->data_offset);
13234
13235 /* Read the rest of the table. */
13236 size = directory->length - min_size;
13237 buffer = xmalloc (size);
13238 rc = read (fd, buffer, size);
13239 if (rc != size)
13240 goto bail;
13241
13242 /* Now figure out how large cvar must be by reading the tuples. */
13243
13244 ntuples = cvar->tuple_count & 0x0fff;
13245 data_offset = ((ptrdiff_t) cvar->data_offset
13246 - (ptrdiff_t) min_size);
13247 end = buffer + size;
13248
13249 if (data_offset < 0)
13250 goto bail1;
13251
13252 /* See if there are shared points, and read them if there are. */
13253
13254 data = buffer + data_offset;
13255 tuple = buffer;
13256 points = NULL;
13257
13258 if (cvar->tuple_count & 0x8000)
13259 {
13260 points = sfnt_read_packed_points (data, &npoints, end,
13261 &tuple);
13262 if (!points)
13263 goto bail1;
13264
13265 /* Add npoints words to the size. */
13266 size = npoints * sizeof *points;
13267 }
13268 else
13269 size = 0;
13270
13271 while (ntuples--)
13272 {
13273 data = buffer + data_offset;
13274
13275 /* Read the tuple. */
13276 if (tuple + 3 >= end)
13277 goto bail2;
13278
13279 memcpy (&data_size, tuple, sizeof data_size);
13280 tuple += sizeof data_size;
13281 memcpy (&index, tuple, sizeof index);
13282 tuple += sizeof index;
13283 sfnt_swap16 (&data_size);
13284 sfnt_swap16 (&index);
13285
13286 /* Increment the offset to the data by the data size specified
13287 here. */
13288 data_offset += data_size;
13289
13290 if (index & 0x8000)
13291 {
13292 /* Embedded coordinates are present. Read each
13293 coordinate and add it to the size. */
13294
13295 if (tuple + fvar->axis_count * sizeof *coords - 1 >= end)
13296 goto bail2;
13297
13298 tuple += sizeof *coords * fvar->axis_count;
13299 if (INT_ADD_WRAPV (size, sizeof *coords * fvar->axis_count,
13300 &size))
13301 goto bail2;
13302 }
13303 else
13304 /* This table is invalid, as cvar tables don't have global
13305 coordinates. */
13306 goto bail2;
13307
13308 /* Now read indeterminate tuples if required. */
13309 if (index & 0x4000)
13310 {
13311 tuple += fvar->axis_count * 4;
13312 if (INT_ADD_WRAPV (size, fvar->axis_count * 4, &size))
13313 goto bail2;
13314 }
13315
13316 /* Add one point and one delta for each CVT element. */
13317 if (INT_ADD_WRAPV (size, cvt->num_elements * 4, &size))
13318 goto bail2;
13319
13320 /* Now add the size of the tuple. */
13321 if (INT_ADD_WRAPV (size, sizeof *cvar->variation, &size))
13322 goto bail2;
13323 }
13324
13325 if (INT_ADD_WRAPV (sizeof *cvar, size, &size))
13326 goto bail2;
13327
13328 /* Reallocate cvar. */
13329 cvar = xrealloc (cvar, size);
13330 ntuples = cvar->tuple_count & 0x0fff;
13331 cvar->variation = (struct sfnt_tuple_variation *) (cvar + 1);
13332 coords = (sfnt_f2dot14 *) (cvar->variation + ntuples);
13333 tuple = buffer;
13334
13335 data_offset = ((ptrdiff_t) cvar->data_offset
13336 - (ptrdiff_t) min_size);
13337
13338 /* Start reading the tuples into cvar. */
13339 for (i = 0; i < ntuples; ++i)
13340 {
13341 data = buffer + data_offset;
13342
13343 /* Read the tuple. */
13344 if (tuple + 3 >= end)
13345 goto bail2;
13346
13347 memcpy (&data_size, tuple, sizeof data_size);
13348 tuple += sizeof data_size;
13349 memcpy (&index, tuple, sizeof index);
13350 tuple += sizeof index;
13351 sfnt_swap16 (&data_size);
13352 sfnt_swap16 (&index);
13353
13354 /* Increment the offset to the data by the data size specified
13355 here. */
13356 data_offset += data_size;
13357
13358 cvar->variation[i].intermediate_start = NULL;
13359 cvar->variation[i].intermediate_end = NULL;
13360
13361 if (index & 0x8000)
13362 {
13363 /* Embedded coordinates are present. Read each
13364 coordinate. */
13365 cvar->variation[i].coordinates = coords;
13366
13367 for (j = 0; j < fvar->axis_count; ++j)
13368 {
13369 if (tuple + 1 >= end)
13370 goto bail2;
13371
13372 memcpy (coords++, tuple, sizeof *coords);
13373 tuple += sizeof *coords;
13374 sfnt_swap16 (coords);
13375 }
13376 }
13377 else
13378 goto bail2;
13379
13380 /* Now read indeterminate tuples if required. */
13381 if (index & 0x4000)
13382 {
13383 cvar->variation[i].intermediate_start = coords;
13384
13385 for (j = 0; j < fvar->axis_count; ++j)
13386 {
13387 if (tuple + 1 >= end)
13388 goto bail2;
13389
13390 memcpy (coords++, tuple, sizeof *coords);
13391 tuple += sizeof *coords;
13392 sfnt_swap16 (coords);
13393 }
13394
13395 cvar->variation[i].intermediate_end = coords;
13396
13397 for (j = 0; j < fvar->axis_count; ++j)
13398 {
13399 if (tuple + 1 >= end)
13400 goto bail2;
13401
13402 memcpy (coords++, tuple, sizeof *coords);
13403 tuple += sizeof *coords;
13404 sfnt_swap16 (coords);
13405 }
13406 }
13407
13408 /* Finally, read private ``point'' numbers. If this flag is not
13409 set, use shared point numbers previously read.
13410
13411 Read at most CVT->num_elements points, as that is all the
13412 storage allocated. */
13413
13414 if (index & 0x2000)
13415 {
13416 local = sfnt_read_packed_points (data, &cvar->variation[i].num_points,
13417 end, &data);
13418 if (!local)
13419 goto bail2;
13420
13421 /* If points apply to all CVT indices, skip this part. */
13422
13423 if (cvar->variation[i].num_points != UINT16_MAX)
13424 {
13425 if (cvar->variation[i].num_points > cvt->num_elements)
13426 cvar->variation[i].num_points = cvt->num_elements;
13427
13428 cvar->variation[i].points = (uint16_t *) coords;
13429 for (j = 0; j < cvar->variation[i].num_points; ++j)
13430 *coords++ = local[j];
13431 xfree (local);
13432 }
13433 else
13434 cvar->variation[i].points = NULL;
13435 }
13436 else
13437 {
13438 /* Copy in the shared point numbers instead. */
13439 cvar->variation[i].num_points = npoints;
13440
13441 if (npoints != UINT16_MAX)
13442 {
13443 if (cvar->variation[i].num_points > cvt->num_elements)
13444 cvar->variation[i].num_points = cvt->num_elements;
13445
13446 cvar->variation[i].points = (uint16_t *) coords;
13447 for (j = 0; j < cvar->variation[i].num_points; ++j)
13448 *coords++ = points[j];
13449 }
13450 else
13451 cvar->variation[i].points = NULL;
13452 }
13453
13454 /* And read packed deltas. If cvar->variation[i].num_points is
13455 UINT16_MAX, then there is one delta for each CVT entry.
13456 Otherwise, there are that many deltas. */
13457
13458 if (cvar->variation[i].num_points == UINT16_MAX)
13459 {
13460 deltas = sfnt_read_packed_deltas (data, end, cvt->num_elements,
13461 &data);
13462
13463 if (!deltas)
13464 goto bail2;
13465
13466 cvar->variation[i].deltas = coords;
13467
13468 for (j = 0; j < cvt->num_elements; ++j)
13469 *coords++ = deltas[j];
13470 xfree (deltas);
13471 }
13472 else
13473 {
13474 deltas = sfnt_read_packed_deltas (data, end,
13475 cvar->variation[i].num_points,
13476 &data);
13477 if (!deltas)
13478 goto bail2;
13479
13480 cvar->variation[i].deltas = coords;
13481
13482 for (j = 0; j < cvar->variation[i].num_points; ++j)
13483 *coords++ = deltas[j];
13484 xfree (deltas);
13485 }
13486 }
13487
13488 /* Free data and return the read cvar table. */
13489 if (points != (void *) -1)
13490 xfree (points);
13491 xfree (buffer);
13492 return cvar;
13493
13494 bail2:
13495 if (points != (void *) -1)
13496 xfree (points);
13497 bail1:
13498 xfree (buffer);
13499 bail:
13500 xfree (cvar);
13501 return NULL;
13502}
13503
13504
13505
13506/* Initialize the specified BLEND with the given FVAR and GVAR tables.
13507 If non-NULL, adjust normalized coordinates using the axis variation
13508 table AVAR; similarly, adjust interpreter CVT values using CVAR, if
13509 specified. */
13510
13511TEST_STATIC void
13512sfnt_init_blend (struct sfnt_blend *blend, struct sfnt_fvar_table *fvar,
13513 struct sfnt_gvar_table *gvar, struct sfnt_avar_table *avar,
13514 struct sfnt_cvar_table *cvar)
13515{
13516 size_t size;
13517
13518 blend->fvar = fvar;
13519 blend->gvar = gvar;
13520 blend->avar = avar;
13521 blend->cvar = cvar;
13522
13523 /* Allocate a single array to hold both coords and norm_coords. */
13524 size = (fvar->axis_count * sizeof *blend->coords * 2);
13525 blend->coords = xmalloc (size);
13526 blend->norm_coords = blend->coords + fvar->axis_count;
13527}
13528
13529/* Free what was initialized in the specified BLEND. */
13530
13531TEST_STATIC void
13532sfnt_free_blend (struct sfnt_blend *blend)
13533{
13534 xfree (blend->coords);
13535}
13536
13537/* Normalize BLEND->fvar->axis_count coordinates in BLEND->coords and
13538 place the result in BLEND->norm_coords. */
13539
13540TEST_STATIC void
13541sfnt_normalize_blend (struct sfnt_blend *blend)
13542{
13543 struct sfnt_variation_axis *axis;
13544 int i, j;
13545 sfnt_fixed from, coord, j0, j1, j2;
13546 sfnt_fixed from_last, coord_last;
13547 struct sfnt_short_frac_segment *segment;
13548
13549 /* For each axis... */
13550 for (i = 0; i < blend->fvar->axis_count; ++i)
13551 {
13552 /* Normalize based on [min, default, max], into [-1, 0, 1]. */
13553 axis = &blend->fvar->axis[i];
13554
13555 /* Load the current design coordinate. */
13556 coord = blend->coords[i];
13557
13558 /* Keep it within bounds. */
13559
13560 if (coord > axis->max_value)
13561 coord = axis->max_value;
13562 else if (coord < axis->min_value)
13563 coord = axis->min_value;
13564
13565 if (coord > axis->default_value)
13566 {
13567 /* Avoid division by 0. */
13568 if (axis->max_value != axis->default_value)
13569 blend->norm_coords[i]
13570 = sfnt_div_fixed (sfnt_sub (coord, axis->default_value),
13571 sfnt_sub (axis->max_value,
13572 axis->default_value));
13573 else
13574 blend->norm_coords[i] = 0;
13575 }
13576 else if (coord < axis->default_value)
13577 {
13578 if (axis->default_value != axis->min_value)
13579 blend->norm_coords[i]
13580 = sfnt_div_fixed (sfnt_sub (coord, axis->default_value),
13581 sfnt_sub (axis->default_value,
13582 axis->min_value));
13583 else
13584 blend->norm_coords[i] = 0;
13585 }
13586 else
13587 blend->norm_coords[i] = 0;
13588 }
13589
13590 /* Now, apply axis variations, but only if the avar table has the
13591 right number of axes. */
13592
13593 if (blend->fvar->axis_count == blend->avar->axis_count)
13594 {
13595 for (i = 0; i < blend->fvar->axis_count; ++i)
13596 {
13597 segment = &blend->avar->segments[i];
13598
13599 /* Search for a correspondence record above the normalized
13600 coordinate of this axis. */
13601
13602 for (j = 1; j < segment->pair_count; ++j)
13603 {
13604 from = segment->correspondence[j].from_coord * 4;
13605 coord = segment->correspondence[j].to_coord * 4;
13606
13607 if (blend->norm_coords[i] < from)
13608 {
13609 from_last
13610 = segment->correspondence[j - 1].from_coord * 4;
13611 coord_last
13612 = segment->correspondence[j - 1].to_coord * 4;
13613
13614 j0 = blend->norm_coords[i] - from_last;
13615 j1 = coord - coord_last;
13616 j2 = from - from_last;
13617
13618 blend->norm_coords[i]
13619 = (sfnt_multiply_divide_signed (j0, j1, j2) + coord_last);
13620 break;
13621 }
13622 }
13623 }
13624 }
13625}
13626
13627
13628
13629struct sfnt_gvar_glyph_header
13630{
13631 /* A packed field. The high 4 bits are flags and the low 12 bits are
13632 the number of tuples for this glyph. The number of tuples can be
13633 any number between 1 and 4095. */
13634 uint16_t tuple_count;
13635
13636 /* Offset from the start of the GlyphVariationData table to the
13637 serialized data. */
13638 uint16_t data_offset;
13639};
13640
13285/* Given a BLEND containing normalized coordinates, an array of 13641/* Given a BLEND containing normalized coordinates, an array of
13286 BLEND->gvar->axis_count tuple coordinates, and, if INTERMEDIATE_P, 13642 BLEND->gvar->axis_count tuple coordinates, and, if INTERMEDIATE_P,
13287 a range of tuple coordinates from INTERMEDIATE_START to 13643 a range of tuple coordinates from INTERMEDIATE_START to
@@ -13758,13 +14114,15 @@ sfnt_infer_deltas (struct sfnt_glyph *glyph, bool *touched,
13758 - contains two elements for each axis, and its axis has a value 14114 - contains two elements for each axis, and its axis has a value
13759 between the first element and the second. 14115 between the first element and the second.
13760 14116
13761 After the deltas are applied, any points without deltas must be 14117 Return the deltas that would normally be applied to the two phantom
13762 interpolated similar to an IUP instruction. In addition, deltas 14118 points describing horizontal bounds in *DISTORTION. Do not
13763 may also be applied to phantom points within a glyph. */ 14119 transform the outline to reflect adjustments to the origin
14120 point. */
13764 14121
13765static int 14122TEST_STATIC int
13766sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id, 14123sfnt_vary_simple_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13767 struct sfnt_glyph *glyph) 14124 struct sfnt_glyph *glyph,
14125 struct sfnt_metrics_distortion *distortion)
13768{ 14126{
13769 uint32_t offset; 14127 uint32_t offset;
13770 struct sfnt_gvar_glyph_header header; 14128 struct sfnt_gvar_glyph_header header;
@@ -13775,7 +14133,7 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13775 sfnt_f2dot14 *restrict coords; 14133 sfnt_f2dot14 *restrict coords;
13776 sfnt_f2dot14 *restrict intermediate_start; 14134 sfnt_f2dot14 *restrict intermediate_start;
13777 sfnt_f2dot14 *restrict intermediate_end; 14135 sfnt_f2dot14 *restrict intermediate_end;
13778 sfnt_fword *dx, *dy, fword; 14136 sfnt_fword *restrict dx, *restrict dy, fword;
13779 struct sfnt_gvar_table *gvar; 14137 struct sfnt_gvar_table *gvar;
13780 uint16_t *local_points, n_local_points; 14138 uint16_t *local_points, n_local_points;
13781 sfnt_fixed scale; 14139 sfnt_fixed scale;
@@ -13806,6 +14164,10 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13806 if (offset + sizeof header > gvar->data_size) 14164 if (offset + sizeof header > gvar->data_size)
13807 return 1; 14165 return 1;
13808 14166
14167 /* Clear the distortion. */
14168 distortion->origin = 0;
14169 distortion->advance = 0;
14170
13809 memcpy (&header, gvar->glyph_variation_data + offset, 14171 memcpy (&header, gvar->glyph_variation_data + offset,
13810 sizeof header); 14172 sizeof header);
13811 14173
@@ -13846,7 +14208,11 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13846 /* Start reading each tuple. */ 14208 /* Start reading each tuple. */
13847 tuple = gvar->glyph_variation_data + offset + sizeof header; 14209 tuple = gvar->glyph_variation_data + offset + sizeof header;
13848 14210
13849 coords = xmalloc (gvar->axis_count * sizeof *coords * 3); 14211 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14212 coords = xmalloc (gvar->axis_count * sizeof *coords * 3);
14213 else
14214 coords = alloca (gvar->axis_count * sizeof *coords * 3);
14215
13850 intermediate_start = coords + gvar->axis_count; 14216 intermediate_start = coords + gvar->axis_count;
13851 intermediate_end = coords + gvar->axis_count; 14217 intermediate_end = coords + gvar->axis_count;
13852 14218
@@ -13856,7 +14222,7 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13856 original_x = NULL; 14222 original_x = NULL;
13857 original_y = NULL; 14223 original_y = NULL;
13858 14224
13859 for (i = 0; i < ntuples; ++i) 14225 while (ntuples--)
13860 { 14226 {
13861 data = gvar->glyph_variation_data + offset + data_offset; 14227 data = gvar->glyph_variation_data + offset + data_offset;
13862 14228
@@ -13899,7 +14265,7 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13899 gvar->axis_count * sizeof *coords); 14265 gvar->axis_count * sizeof *coords);
13900 14266
13901 /* Now read indeterminate tuples if required. */ 14267 /* Now read indeterminate tuples if required. */
13902 if (index & 0x1000) 14268 if (index & 0x4000)
13903 { 14269 {
13904 for (j = 0; j < gvar->axis_count; ++j) 14270 for (j = 0; j < gvar->axis_count; ++j)
13905 { 14271 {
@@ -13969,9 +14335,6 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13969 /* Deltas are provided for all points in the glyph. 14335 /* Deltas are provided for all points in the glyph.
13970 No glyph should have more than 65535 points. */ 14336 No glyph should have more than 65535 points. */
13971 14337
13972 if (glyph->simple->number_of_points > 65535)
13973 abort ();
13974
13975 /* Add 4 phantom points to each end. */ 14338 /* Add 4 phantom points to each end. */
13976 dx = sfnt_read_packed_deltas (data, end, 14339 dx = sfnt_read_packed_deltas (data, end,
13977 glyph->simple->number_of_points + 4, 14340 glyph->simple->number_of_points + 4,
@@ -13993,7 +14356,9 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
13993 glyph->simple->y_coordinates[i] += fword; 14356 glyph->simple->y_coordinates[i] += fword;
13994 } 14357 }
13995 14358
13996 /* TODO: apply metrics variations. */ 14359 /* Apply the deltas for the two phantom points. */
14360 distortion->origin += sfnt_mul_fixed (dx[i++], scale);
14361 distortion->advance += sfnt_mul_fixed (dx[i], scale);
13997 break; 14362 break;
13998 14363
13999 default: 14364 default:
@@ -14007,10 +14372,22 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14007 14372
14008 if (!original_x) 14373 if (!original_x)
14009 { 14374 {
14010 touched = xmalloc (sizeof *touched 14375 if ((glyph->simple->number_of_points
14011 * glyph->simple->number_of_points); 14376 * sizeof *touched) >= 1024 * 16)
14012 original_x = xmalloc (sizeof *original_x * 2 14377 touched = xmalloc (sizeof *touched
14013 * glyph->simple->number_of_points); 14378 * glyph->simple->number_of_points);
14379 else
14380 touched = alloca (sizeof *touched
14381 * glyph->simple->number_of_points);
14382
14383 if ((sizeof *original_x * 2
14384 * glyph->simple->number_of_points) >= 1024 * 16)
14385 original_x = xmalloc (sizeof *original_x * 2
14386 * glyph->simple->number_of_points);
14387 else
14388 original_x = alloca (sizeof *original_x * 2
14389 * glyph->simple->number_of_points);
14390
14014 original_y = original_x + glyph->simple->number_of_points; 14391 original_y = original_x + glyph->simple->number_of_points;
14015 memcpy (original_x, glyph->simple->x_coordinates, 14392 memcpy (original_x, glyph->simple->x_coordinates,
14016 (sizeof *original_x 14393 (sizeof *original_x
@@ -14025,6 +14402,20 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14025 14402
14026 for (i = 0; i < point_count; ++i) 14403 for (i = 0; i < point_count; ++i)
14027 { 14404 {
14405 /* Apply deltas to phantom points. */
14406
14407 if (glyph_points[i] == glyph->simple->number_of_points)
14408 {
14409 distortion->origin += sfnt_mul_fixed (dx[i], scale);
14410 continue;
14411 }
14412
14413 if (glyph_points[i] == glyph->simple->number_of_points + 1)
14414 {
14415 distortion->advance += sfnt_mul_fixed (dx[i], scale);
14416 continue;
14417 }
14418
14028 /* Make sure the point doesn't end up out of bounds. */ 14419 /* Make sure the point doesn't end up out of bounds. */
14029 if (glyph_points[i] >= glyph->simple->number_of_points) 14420 if (glyph_points[i] >= glyph->simple->number_of_points)
14030 continue; 14421 continue;
@@ -14038,8 +14429,422 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14038 14429
14039 sfnt_infer_deltas (glyph, touched, original_x, 14430 sfnt_infer_deltas (glyph, touched, original_x,
14040 original_y); 14431 original_y);
14432 break;
14433 }
14434
14435 xfree (dx);
14436 xfree (dy);
14437
14438 if (local_points != (uint16_t *) -1)
14439 xfree (local_points);
14440 }
14441
14442 /* Return success. */
14443
14444 if ((glyph->simple->number_of_points
14445 * sizeof *touched) >= 1024 * 16)
14446 xfree (touched);
14447
14448 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14449 xfree (coords);
14450
14451 if ((sizeof *original_x * 2
14452 * glyph->simple->number_of_points) >= 1024 * 16)
14453 xfree (original_x);
14454
14455 if (points != (uint16_t *) -1)
14456 xfree (points);
14457
14458 /* Set the glyph metrics distortion as well. */
14459 glyph->advance_distortion = distortion->advance;
14460 glyph->origin_distortion = distortion->origin;
14461
14462 return 0;
14463
14464 fail3:
14465 xfree (dx);
14466 xfree (dy);
14467 xfree (local_points);
14468 fail1:
14469
14470 if ((glyph->simple->number_of_points
14471 * sizeof *touched) >= 1024 * 16)
14472 xfree (touched);
14473
14474 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14475 xfree (coords);
14476
14477 if ((sizeof *original_x * 2
14478 * glyph->simple->number_of_points) >= 1024 * 16)
14479 xfree (original_x);
14480
14481 if (points != (uint16_t *) -1)
14482 xfree (points);
14483
14484 return 1;
14485}
14486
14487/* Read the glyph variation data for the specified glyph ID from
14488 BLEND's gvar table. Apply the deltas specified within to each
14489 component with offsets in the specified compound GLYPH, based on
14490 the specified BLEND. Return distortions to phantom points in
14491 *DISTORTION.
14492
14493 Value is 0 upon success, 1 otherwise. */
14494
14495TEST_STATIC int
14496sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14497 struct sfnt_glyph *glyph,
14498 struct sfnt_metrics_distortion *distortion)
14499{
14500 uint32_t offset;
14501 struct sfnt_gvar_glyph_header header;
14502 uint16_t *points, npoints;
14503 int i, ntuples, j, point_count;
14504 unsigned char *tuple, *end, *data;
14505 uint16_t data_size, index, *glyph_points;
14506 sfnt_f2dot14 *restrict coords;
14507 sfnt_f2dot14 *restrict intermediate_start;
14508 sfnt_f2dot14 *restrict intermediate_end;
14509 sfnt_fword *restrict dx, *restrict dy, fword, word;
14510 struct sfnt_gvar_table *gvar;
14511 uint16_t *local_points, n_local_points;
14512 sfnt_fixed scale;
14513 ptrdiff_t data_offset;
14514 bool *touched;
14515 sfnt_fword *restrict original_x, *restrict original_y;
14516 struct sfnt_compound_glyph_component *component;
14517
14518 gvar = blend->gvar;
14519
14520 if (gvar->axis_count != blend->fvar->axis_count)
14521 return 1;
14522
14523 if (gvar->glyph_count <= id)
14524 return 1;
14525
14526 if (gvar->flags & 1)
14527 offset = gvar->u.offset_long[id];
14528 else
14529 offset = gvar->u.offset_word[id] * 2u;
14530
14531 if (offset >= gvar->data_size)
14532 return 1;
14533
14534 end = gvar->glyph_variation_data + gvar->data_size;
14535
14536 /* Start reading the header. */
14537
14538 if (offset + sizeof header > gvar->data_size)
14539 return 1;
14540
14541 /* Clear the distortion. */
14542 distortion->origin = 0;
14543 distortion->advance = 0;
14544
14545 memcpy (&header, gvar->glyph_variation_data + offset,
14546 sizeof header);
14547
14548 /* Swap the header. */
14549 sfnt_swap16 (&header.tuple_count);
14550 sfnt_swap16 (&header.data_offset);
14551
14552 /* Prepare to read each tuple. */
14553 ntuples = header.tuple_count & 0x0fff;
14554
14555 /* Initialize the data offset. This is incremented with each tuple
14556 read. */
14557 data_offset = header.data_offset;
14558
14559 /* If gvar->flags & tuples_share_point_numbers, read the shared
14560 point numbers. */
14561
14562 npoints = 0;
14563
14564 if (header.tuple_count & 0x8000)
14565 {
14566 data = gvar->glyph_variation_data + offset + data_offset;
14567 points = sfnt_read_packed_points (data, &npoints, end,
14568 &tuple);
14569
14570 if (!points)
14571 return 1;
14572
14573 /* Shared point numbers are part of the data after the tuple
14574 array. Thus, increment data_offset by tuple - data. `tuple'
14575 here holds no relation to a pointer to the current part of
14576 the tuple array that is being read later on. */
14577 data_offset += tuple - data;
14578 }
14579 else
14580 points = NULL;
14581
14582 /* Start reading each tuple. */
14583 tuple = gvar->glyph_variation_data + offset + sizeof header;
14584
14585 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14586 coords = xmalloc (gvar->axis_count * sizeof *coords * 3);
14587 else
14588 coords = alloca (gvar->axis_count * sizeof *coords * 3);
14589
14590 intermediate_start = coords + gvar->axis_count;
14591 intermediate_end = coords + gvar->axis_count;
14592
14593 /* Allocate arrays of booleans and fwords to keep track of which
14594 points have been touched. */
14595 touched = NULL;
14596 original_x = NULL;
14597 original_y = NULL;
14598
14599 while (ntuples--)
14600 {
14601 data = gvar->glyph_variation_data + offset + data_offset;
14602
14603 if (tuple + 3 >= end)
14604 goto fail1;
14605
14606 memcpy (&data_size, tuple, sizeof data_size);
14607 tuple += sizeof data_size;
14608 memcpy (&index, tuple, sizeof index);
14609 tuple += sizeof index;
14610 sfnt_swap16 (&data_size);
14611 sfnt_swap16 (&index);
14612
14613 /* Increment the offset to the data by the data size specified
14614 here. */
14615 data_offset += data_size;
14616
14617 if (index & 0x8000)
14618 {
14619 /* Embedded coordinates are present. Read each
14620 coordinate and add it to the tuple. */
14621 for (j = 0; j < gvar->axis_count; ++j)
14622 {
14623 if (tuple + 1 >= end)
14624 goto fail1;
14625
14626 memcpy (&coords[j], tuple, sizeof *coords);
14627 tuple += sizeof *coords;
14628 sfnt_swap16 (&coords[j]);
14629 }
14630 }
14631 else if ((index & 0xfff) > gvar->shared_coord_count)
14632 /* index exceeds the number of shared tuples present. */
14633 goto fail1;
14634 else
14635 /* index points into gvar->axis_count coordinates making up
14636 the tuple. */
14637 memcpy (coords, (gvar->global_coords
14638 + ((index & 0xfff) * gvar->axis_count)),
14639 gvar->axis_count * sizeof *coords);
14640
14641 /* Now read indeterminate tuples if required. */
14642 if (index & 0x4000)
14643 {
14644 for (j = 0; j < gvar->axis_count; ++j)
14645 {
14646 if (tuple + 1 >= end)
14647 goto fail1;
14648
14649 memcpy (&intermediate_start[j], tuple,
14650 sizeof *intermediate_start);
14651 tuple += sizeof *intermediate_start;
14652 sfnt_swap16 (&intermediate_start[j]);
14653 }
14654
14655 for (j = 0; j < gvar->axis_count; ++j)
14656 {
14657 if (tuple + 1 >= end)
14658 goto fail1;
14659
14660 memcpy (&intermediate_end[j], tuple,
14661 sizeof *intermediate_end);
14662 tuple += sizeof *intermediate_end;
14663 sfnt_swap16 (&intermediate_end[j]);
14664 }
14665 }
14666
14667 /* See whether or not the tuple applies to the current variation
14668 configuration, and how much to scale them by. */
14669
14670 scale = sfnt_compute_tuple_scale (blend, index & 0x1000,
14671 coords, intermediate_start,
14672 intermediate_end);
14673
14674 if (!scale)
14675 continue;
14676
14677 local_points = NULL;
14678
14679 /* Finally, read private point numbers.
14680 Set local_points to those numbers; it will be freed
14681 once the loop ends. */
14682
14683 if (index & 0x2000)
14684 {
14685 local_points = sfnt_read_packed_points (data, &n_local_points,
14686 end, &data);
14687 if (!local_points)
14688 goto fail1;
14689
14690 point_count = n_local_points;
14691 glyph_points = local_points;
14692 }
14693 else
14694 {
14695 /* If there are no private point numbers, use global
14696 points. */
14697 point_count = npoints;
14698 glyph_points = points;
14699 }
14700
14701 /* Now, read packed deltas. */
14702
14703 dx = NULL;
14704 dy = NULL;
14705
14706 switch (point_count)
14707 {
14708 case UINT16_MAX:
14709 /* Deltas are provided for all components in the glyph. */
14710
14711 /* Add 4 phantom points to each end. */
14712 dx = sfnt_read_packed_deltas (data, end,
14713 glyph->compound->num_components + 4,
14714 &data);
14715 dy = sfnt_read_packed_deltas (data, end,
14716 glyph->compound->num_components + 4,
14717 &data);
14718
14719 if (!dx || !dy)
14720 goto fail3;
14721
14722 /* Apply each delta to the compound glyph. */
14723
14724 for (i = 0; i < glyph->compound->num_components; ++i)
14725 {
14726 component = &glyph->compound->components[i];
14727
14728 /* Check if the component uses deltas at all. */
14729 if (!(component->flags & 02))
14730 continue;
14731
14732 /* Vary the X offset. */
14733
14734 if (!(component->flags & 01))
14735 word = component->argument1.b;
14736 else
14737 word = component->argument1.d;
14738
14739 fword = sfnt_mul_fixed (dx[i], scale);
14740 component->flags |= 01;
14741 component->argument1.d = word + fword;
14742
14743 /* Vary the Y offset. */
14744
14745 if (!(component->flags & 01))
14746 word = component->argument2.b;
14747 else
14748 word = component->argument2.d;
14749
14750 fword = sfnt_mul_fixed (dy[i], scale);
14751 component->flags |= 01;
14752 component->argument2.d = word + fword;
14753 }
14754
14755 /* Apply the deltas for the two phantom points. */
14756 distortion->origin += sfnt_mul_fixed (dx[i++], scale);
14757 distortion->advance += sfnt_mul_fixed (dx[i], scale);
14758 break;
14759
14760 default:
14761 dx = sfnt_read_packed_deltas (data, end, point_count, &data);
14762 dy = sfnt_read_packed_deltas (data, end, point_count, &data);
14763
14764 if (!dx || !dy)
14765 goto fail3;
14766
14767 /* Deltas are only applied for each point number read. */
14768
14769 if (!original_x)
14770 {
14771 if ((glyph->compound->num_components
14772 * sizeof *touched) >= 1024 * 16)
14773 touched = xmalloc (sizeof *touched
14774 * glyph->compound->num_components);
14775 else
14776 touched = alloca (sizeof *touched
14777 * glyph->compound->num_components);
14778
14779 if ((sizeof *original_x * 2
14780 * glyph->compound->num_components) >= 1024 * 16)
14781 original_x = xmalloc (sizeof *original_x * 2
14782 * glyph->compound->num_components);
14783 else
14784 original_x = alloca (sizeof *original_x * 2
14785 * glyph->compound->num_components);
14786
14787 original_y = original_x + glyph->compound->num_components;
14788 memcpy (original_x, glyph->simple->x_coordinates,
14789 (sizeof *original_x
14790 * glyph->compound->num_components));
14791 memcpy (original_y, glyph->simple->y_coordinates,
14792 (sizeof *original_y
14793 * glyph->compound->num_components));
14794 }
14795
14796 memset (touched, 0, (sizeof *touched
14797 * glyph->compound->num_components));
14798
14799 for (i = 0; i < point_count; ++i)
14800 {
14801 /* Apply deltas to phantom points. */
14802
14803 if (glyph_points[i] == glyph->compound->num_components)
14804 {
14805 distortion->origin += sfnt_mul_fixed (dx[i], scale);
14806 continue;
14807 }
14808
14809 if (glyph_points[i] == glyph->compound->num_components + 1)
14810 {
14811 distortion->advance += sfnt_mul_fixed (dx[i], scale);
14812 continue;
14813 }
14814
14815 /* Make sure the point doesn't end up out of bounds. */
14816 if (glyph_points[i] >= glyph->compound->num_components)
14817 continue;
14818
14819 component = &glyph->compound->components[glyph_points[i]];
14820
14821 /* Check if the component uses deltas at all. */
14822 if (!(component->flags & 02))
14823 continue;
14824
14825 /* Vary the X offset. */
14826
14827 if (!(component->flags & 01))
14828 word = component->argument1.b;
14829 else
14830 word = component->argument1.d;
14831
14832 fword = sfnt_mul_fixed (dx[i], scale);
14833 component->flags |= 01;
14834 component->argument1.d = word + fword;
14835
14836 /* Vary the Y offset. */
14837
14838 if (!(component->flags & 01))
14839 word = component->argument2.b;
14840 else
14841 word = component->argument2.d;
14842
14843 fword = sfnt_mul_fixed (dy[i], scale);
14844 component->flags |= 01;
14845 component->argument2.d = word + fword;
14846 }
14041 14847
14042 /* TODO: apply metrics variations. */
14043 break; 14848 break;
14044 } 14849 }
14045 14850
@@ -14052,13 +14857,24 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14052 14857
14053 /* Return success. */ 14858 /* Return success. */
14054 14859
14055 xfree (touched); 14860 if ((glyph->compound->num_components
14056 xfree (coords); 14861 * sizeof *touched) >= 1024 * 16)
14057 xfree (original_x); 14862 xfree (touched);
14863
14864 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14865 xfree (coords);
14866
14867 if ((sizeof *original_x * 2
14868 * glyph->compound->num_components) >= 1024 * 16)
14869 xfree (original_x);
14058 14870
14059 if (points != (uint16_t *) -1) 14871 if (points != (uint16_t *) -1)
14060 xfree (points); 14872 xfree (points);
14061 14873
14874 /* Set the glyph metrics distortion as well. */
14875 glyph->advance_distortion = distortion->advance;
14876 glyph->origin_distortion = distortion->origin;
14877
14062 return 0; 14878 return 0;
14063 14879
14064 fail3: 14880 fail3:
@@ -14066,9 +14882,17 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14066 xfree (dy); 14882 xfree (dy);
14067 xfree (local_points); 14883 xfree (local_points);
14068 fail1: 14884 fail1:
14069 xfree (touched); 14885
14070 xfree (coords); 14886 if ((glyph->compound->num_components
14071 xfree (original_x); 14887 * sizeof *touched) >= 1024 * 16)
14888 xfree (touched);
14889
14890 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14891 xfree (coords);
14892
14893 if ((sizeof *original_x * 2
14894 * glyph->compound->num_components) >= 1024 * 16)
14895 xfree (original_x);
14072 14896
14073 if (points != (uint16_t *) -1) 14897 if (points != (uint16_t *) -1)
14074 xfree (points); 14898 xfree (points);
@@ -14076,7 +14900,66 @@ sfnt_vary_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14076 return 1; 14900 return 1;
14077} 14901}
14078 14902
14079#endif /* TEST */ 14903/* Vary the specified INTERPRETER's control value table using the
14904 variations in BLEND's CVT variations table.
14905
14906 The CVT table used to create INTERPRETER must be the same used
14907 to read BLEND->cvar. If not, behavior is undefined. */
14908
14909TEST_STATIC void
14910sfnt_vary_interpreter (struct sfnt_interpreter *interpreter,
14911 struct sfnt_blend *blend)
14912{
14913 sfnt_fixed scale;
14914 int i;
14915 struct sfnt_tuple_variation *variation;
14916 size_t ndeltas, j, index;
14917 sfnt_f26dot6 delta;
14918
14919 /* Return if there's no cvar table. */
14920 if (!blend->cvar)
14921 return;
14922
14923 /* For each tuple in the cvar table... */
14924 for (i = 0; i < (blend->cvar->tuple_count & 0x0fff); ++i)
14925 {
14926 /* See if the tuple applies. */
14927 variation = &blend->cvar->variation[i];
14928 scale = sfnt_compute_tuple_scale (blend,
14929 variation->intermediate_start != NULL,
14930 variation->coordinates,
14931 variation->intermediate_start,
14932 variation->intermediate_end);
14933 if (!scale)
14934 continue;
14935
14936 /* Figure out how many deltas there are. If variation->points,
14937 there are num_points deltas. Otherwise, there are
14938 interpreter->cvt->num_elements deltas. */
14939
14940 ndeltas = (variation->points
14941 ? variation->num_points
14942 : interpreter->cvt_size);
14943
14944 for (j = 0; j < ndeltas; ++j)
14945 {
14946 /* Figure out which CVT entry this applies to. */
14947 index = variation->points ? variation->points[j] : j;
14948
14949 if (index > interpreter->cvt_size)
14950 continue;
14951
14952 /* Multiply the delta by the interpreter scale factor and
14953 then the tuple scale factor. */
14954 delta = sfnt_mul_f26dot6_fixed (variation->deltas[j] * 64,
14955 interpreter->scale);
14956 delta = sfnt_mul_fixed (delta, scale);
14957
14958 /* Apply the delta to the control value table. */
14959 interpreter->cvt[i] += delta;
14960 }
14961 }
14962}
14080 14963
14081 14964
14082 14965
@@ -14088,6 +14971,7 @@ struct sfnt_test_dcontext
14088 struct sfnt_glyf_table *glyf; 14971 struct sfnt_glyf_table *glyf;
14089 struct sfnt_loca_table_short *loca_short; 14972 struct sfnt_loca_table_short *loca_short;
14090 struct sfnt_loca_table_long *loca_long; 14973 struct sfnt_loca_table_long *loca_long;
14974 struct sfnt_blend *blend;
14091}; 14975};
14092 14976
14093/* Global context for test functions. Height of glyph. */ 14977/* Global context for test functions. Height of glyph. */
@@ -14120,17 +15004,31 @@ sfnt_test_curve_to (struct sfnt_point control,
14120} 15004}
14121 15005
14122static struct sfnt_glyph * 15006static struct sfnt_glyph *
14123sfnt_test_get_glyph (sfnt_glyph glyph, void *dcontext, 15007sfnt_test_get_glyph (sfnt_glyph id, void *dcontext,
14124 bool *need_free) 15008 bool *need_free)
14125{ 15009{
14126 struct sfnt_test_dcontext *tables; 15010 struct sfnt_test_dcontext *tables;
15011 struct sfnt_glyph *glyph;
15012 struct sfnt_metrics_distortion distortion;
14127 15013
14128 tables = dcontext; 15014 tables = dcontext;
14129 *need_free = true; 15015 *need_free = true;
14130 15016
14131 return sfnt_read_glyph (glyph, tables->glyf, 15017 glyph = sfnt_read_glyph (id, tables->glyf,
14132 tables->loca_short, 15018 tables->loca_short,
14133 tables->loca_long); 15019 tables->loca_long);
15020
15021 if (tables->blend && glyph)
15022 {
15023 if (glyph->simple)
15024 sfnt_vary_simple_glyph (tables->blend, id, glyph,
15025 &distortion);
15026 else
15027 sfnt_vary_compound_glyph (tables->blend, id, glyph,
15028 &distortion);
15029 }
15030
15031 return glyph;
14134} 15032}
14135 15033
14136static void 15034static void
@@ -17881,7 +18779,7 @@ main (int argc, char **argv)
17881 struct sfnt_cmap_encoding_subtable *subtables; 18779 struct sfnt_cmap_encoding_subtable *subtables;
17882 struct sfnt_cmap_encoding_subtable_data **data; 18780 struct sfnt_cmap_encoding_subtable_data **data;
17883 struct sfnt_cmap_table *table; 18781 struct sfnt_cmap_table *table;
17884 int fd, i; 18782 int fd, i, j;
17885 sfnt_char character; 18783 sfnt_char character;
17886 struct sfnt_head_table *head; 18784 struct sfnt_head_table *head;
17887 struct sfnt_hhea_table *hhea; 18785 struct sfnt_hhea_table *hhea;
@@ -17911,6 +18809,8 @@ main (int argc, char **argv)
17911 struct sfnt_instructed_outline *value; 18809 struct sfnt_instructed_outline *value;
17912 struct sfnt_fvar_table *fvar; 18810 struct sfnt_fvar_table *fvar;
17913 struct sfnt_gvar_table *gvar; 18811 struct sfnt_gvar_table *gvar;
18812 struct sfnt_avar_table *avar;
18813 struct sfnt_cvar_table *cvar;
17914 sfnt_fixed scale; 18814 sfnt_fixed scale;
17915 char *fancy; 18815 char *fancy;
17916 int *advances; 18816 int *advances;
@@ -17919,6 +18819,7 @@ main (int argc, char **argv)
17919 char *axis_name; 18819 char *axis_name;
17920 struct sfnt_instance *instance; 18820 struct sfnt_instance *instance;
17921 struct sfnt_blend blend; 18821 struct sfnt_blend blend;
18822 struct sfnt_metrics_distortion distortion;
17922 18823
17923 if (argc < 2) 18824 if (argc < 2)
17924 return 1; 18825 return 1;
@@ -18029,8 +18930,8 @@ main (int argc, char **argv)
18029 return 1; 18930 return 1;
18030 } 18931 }
18031 18932
18032#define FANCY_PPEM 12 18933#define FANCY_PPEM 15
18033#define EASY_PPEM 12 18934#define EASY_PPEM 15
18034 18935
18035 interpreter = NULL; 18936 interpreter = NULL;
18036 head = sfnt_read_head_table (fd, font); 18937 head = sfnt_read_head_table (fd, font);
@@ -18044,16 +18945,123 @@ main (int argc, char **argv)
18044 prep = sfnt_read_prep_table (fd, font); 18945 prep = sfnt_read_prep_table (fd, font);
18045 fvar = sfnt_read_fvar_table (fd, font); 18946 fvar = sfnt_read_fvar_table (fd, font);
18046 gvar = sfnt_read_gvar_table (fd, font); 18947 gvar = sfnt_read_gvar_table (fd, font);
18948 avar = sfnt_read_avar_table (fd, font);
18949 cvar = NULL;
18047 hmtx = NULL; 18950 hmtx = NULL;
18048 18951
18952 if (fvar && cvt)
18953 cvar = sfnt_read_cvar_table (fd, font, fvar, cvt);
18954
18955 if (cvar)
18956 fprintf (stderr, "cvar table found\n");
18957
18049 exec_prep = prep; 18958 exec_prep = prep;
18050 exec_fpgm = fpgm; 18959 exec_fpgm = fpgm;
18051 fancy = getenv ("SFNT_FANCY_TEST"); 18960 fancy = getenv ("SFNT_FANCY_TEST");
18052 18961
18962 loca_long = NULL;
18963 loca_short = NULL;
18964
18965 if (fvar)
18966 {
18967 fprintf (stderr, "FVAR table found!\n"
18968 "version: %"PRIu16".%"PRIu16"\n"
18969 "axis_count: %"PRIu16"\n"
18970 "axis_size: %"PRIu16"\n"
18971 "instance_count: %"PRIu16"\n"
18972 "instance_size: %"PRIu16"\n",
18973 fvar->major_version,
18974 fvar->minor_version,
18975 fvar->axis_count,
18976 fvar->axis_size,
18977 fvar->instance_count,
18978 fvar->instance_size);
18979
18980 for (i = 0; i < fvar->axis_count; ++i)
18981 {
18982 if (name)
18983 {
18984 axis_name
18985 = (char *) sfnt_find_name (name, fvar->axis[i].name_id,
18986 &record);
18987
18988 if (axis_name)
18989 fprintf (stderr, "axis no: %d; name: %.*s\n",
18990 i, record.length, axis_name);
18991 }
18992
18993 fprintf (stderr, " axis: %"PRIx32" %g %g %g\n",
18994 fvar->axis[i].axis_tag,
18995 sfnt_coerce_fixed (fvar->axis[i].min_value),
18996 sfnt_coerce_fixed (fvar->axis[i].default_value),
18997 sfnt_coerce_fixed (fvar->axis[i].max_value));
18998 }
18999
19000 for (i = 0; i < fvar->instance_count; ++i)
19001 {
19002 if (name)
19003 {
19004 axis_name
19005 = (char *) sfnt_find_name (name, fvar->instance[i].name_id,
19006 &record);
19007
19008 if (axis_name)
19009 fprintf (stderr, "instance no: %d; name: %.*s\n",
19010 i, record.length, axis_name);
19011 }
19012 }
19013
19014 if (fvar->instance_count > 1)
19015 {
19016 printf ("instance? ");
19017
19018 if (scanf ("%d", &i) == EOF)
19019 goto free_lab;
19020
19021 if (i >= fvar->instance_count)
19022 goto free_lab;
19023
19024 if (i >= 0)
19025 instance = &fvar->instance[i];
19026 }
19027 }
19028
19029 if (gvar)
19030 fprintf (stderr, "gvar table found\n");
19031
19032 if (avar)
19033 {
19034 fprintf (stderr, "avar table found\n");
19035
19036 for (i = 0; i < avar->axis_count; ++i)
19037 {
19038 fprintf (stderr, "axis: %d, %"PRIu16" pairs\n",
19039 i, avar->segments[i].pair_count);
19040
19041 for (j = 0; j < avar->segments[i].pair_count; ++j)
19042 fprintf (stderr, "pair: %g, %g\n",
19043 (avar->segments[i].correspondence[j].from_coord
19044 / 16384.0),
19045 (avar->segments[i].correspondence[j].to_coord
19046 / 16384.0));
19047 }
19048 }
19049
19050 memset (&blend, 0, sizeof blend);
19051
19052 if (instance && gvar)
19053 {
19054 sfnt_init_blend (&blend, fvar, gvar, avar,
19055 cvar);
19056
19057 for (i = 0; i < fvar->axis_count; ++i)
19058 blend.coords[i] = instance->coords[i];
19059
19060 sfnt_normalize_blend (&blend);
19061 }
19062
18053 if (fancy) 19063 if (fancy)
18054 { 19064 {
18055 loca_long = NULL;
18056 loca_short = NULL;
18057 length = strlen (fancy); 19065 length = strlen (fancy);
18058 scale = sfnt_div_fixed (FANCY_PPEM, head->units_per_em); 19066 scale = sfnt_div_fixed (FANCY_PPEM, head->units_per_em);
18059 19067
@@ -18085,6 +19093,8 @@ main (int argc, char **argv)
18085 19093
18086 interpreter = sfnt_make_interpreter (maxp, cvt, head, 19094 interpreter = sfnt_make_interpreter (maxp, cvt, head,
18087 FANCY_PPEM, FANCY_PPEM); 19095 FANCY_PPEM, FANCY_PPEM);
19096 if (instance && gvar)
19097 sfnt_vary_interpreter (interpreter, &blend);
18088 19098
18089 if (!interpreter) 19099 if (!interpreter)
18090 exit (1); 19100 exit (1);
@@ -18128,6 +19138,10 @@ main (int argc, char **argv)
18128 if (!glyph || !glyph->simple) 19138 if (!glyph || !glyph->simple)
18129 exit (3); 19139 exit (3);
18130 19140
19141 if (instance && gvar)
19142 sfnt_vary_simple_glyph (&blend, code, glyph,
19143 &distortion);
19144
18131 if (sfnt_lookup_glyph_metrics (code, -1, 19145 if (sfnt_lookup_glyph_metrics (code, -1,
18132 &metrics, 19146 &metrics,
18133 hmtx, hhea, 19147 hmtx, hhea,
@@ -18159,58 +19173,14 @@ main (int argc, char **argv)
18159 xfree (outline); 19173 xfree (outline);
18160 19174
18161 rasters[i] = raster; 19175 rasters[i] = raster;
18162 advances[i] = sfnt_mul_fixed (metrics.advance, scale); 19176 advances[i] = (sfnt_mul_fixed (metrics.advance, scale)
19177 + sfnt_mul_fixed (distortion.advance, scale));
18163 } 19178 }
18164 19179
18165 sfnt_x_raster (rasters, advances, length, hhea, scale); 19180 sfnt_x_raster (rasters, advances, length, hhea, scale);
18166 exit (0); 19181 exit (0);
18167 } 19182 }
18168 19183
18169 if (head && maxp && maxp->version >= 0x00010000)
18170 {
18171 fprintf (stderr, "creating interpreter\n"
18172 "the size of the stack is %"PRIu16"\n"
18173 "the size of the twilight zone is %"PRIu16"\n"
18174 "the size of the storage area is %"PRIu16"\n"
18175 "there are at most %"PRIu16" idefs\n"
18176 "there are at most %"PRIu16" fdefs\n"
18177 "the cvt is %zu fwords in length\n",
18178 maxp->max_stack_elements,
18179 maxp->max_twilight_points,
18180 maxp->max_storage,
18181 maxp->max_instruction_defs,
18182 maxp->max_function_defs,
18183 cvt ? cvt->num_elements : 0ul);
18184
18185 interpreter = sfnt_make_interpreter (maxp, cvt, head,
18186 FANCY_PPEM,
18187 FANCY_PPEM);
18188 state = interpreter->state;
18189
18190 if (fpgm)
18191 {
18192 fprintf (stderr, "interpreting the font program, with"
18193 " %zu instructions\n", fpgm->num_instructions);
18194
18195 trap = sfnt_interpret_font_program (interpreter, fpgm);
18196
18197 if (trap)
18198 fprintf (stderr, "**TRAP**: %s\n", trap);
18199 }
18200
18201 if (prep)
18202 {
18203 fprintf (stderr, "interpreting the control value program, with"
18204 " %zu instructions\n", prep->num_instructions);
18205
18206 trap = sfnt_interpret_control_value_program (interpreter, prep,
18207 &state);
18208
18209 if (trap)
18210 fprintf (stderr, "**TRAP**: %s\n", trap);
18211 }
18212 }
18213
18214 if (hhea && maxp) 19184 if (hhea && maxp)
18215 hmtx = sfnt_read_hmtx_table (fd, font, hhea, maxp); 19185 hmtx = sfnt_read_hmtx_table (fd, font, hhea, maxp);
18216 19186
@@ -18315,82 +19285,54 @@ main (int argc, char **argv)
18315 (int) hhea->caret_slope_rise, 19285 (int) hhea->caret_slope_rise,
18316 (int) hhea->caret_slope_run); 19286 (int) hhea->caret_slope_run);
18317 19287
18318 if (fvar) 19288 if (head && maxp && maxp->version >= 0x00010000)
18319 { 19289 {
18320 fprintf (stderr, "FVAR table found!\n" 19290 fprintf (stderr, "creating interpreter\n"
18321 "version: %"PRIu16".%"PRIu16"\n" 19291 "the size of the stack is %"PRIu16"\n"
18322 "axis_count: %"PRIu16"\n" 19292 "the size of the twilight zone is %"PRIu16"\n"
18323 "axis_size: %"PRIu16"\n" 19293 "the size of the storage area is %"PRIu16"\n"
18324 "instance_count: %"PRIu16"\n" 19294 "there are at most %"PRIu16" idefs\n"
18325 "instance_size: %"PRIu16"\n", 19295 "there are at most %"PRIu16" fdefs\n"
18326 fvar->major_version, 19296 "the cvt is %zu fwords in length\n",
18327 fvar->minor_version, 19297 maxp->max_stack_elements,
18328 fvar->axis_count, 19298 maxp->max_twilight_points,
18329 fvar->axis_size, 19299 maxp->max_storage,
18330 fvar->instance_count, 19300 maxp->max_instruction_defs,
18331 fvar->instance_size); 19301 maxp->max_function_defs,
19302 cvt ? cvt->num_elements : 0ul);
18332 19303
18333 for (i = 0; i < fvar->axis_count; ++i) 19304 interpreter = sfnt_make_interpreter (maxp, cvt, head,
18334 { 19305 FANCY_PPEM,
18335 if (name) 19306 FANCY_PPEM);
18336 { 19307 state = interpreter->state;
18337 axis_name
18338 = (char *) sfnt_find_name (name, fvar->axis[i].name_id,
18339 &record);
18340 19308
18341 if (axis_name) 19309 if (instance && gvar)
18342 fprintf (stderr, "axis no: %d; name: %.*s\n", 19310 sfnt_vary_interpreter (interpreter, &blend);
18343 i, record.length, axis_name);
18344 }
18345 19311
18346 fprintf (stderr, " axis: %"PRIx32" %g %g %g\n", 19312 if (fpgm)
18347 fvar->axis[i].axis_tag,
18348 sfnt_coerce_fixed (fvar->axis[i].min_value),
18349 sfnt_coerce_fixed (fvar->axis[i].default_value),
18350 sfnt_coerce_fixed (fvar->axis[i].max_value));
18351 }
18352
18353 for (i = 0; i < fvar->instance_count; ++i)
18354 { 19313 {
18355 if (name) 19314 fprintf (stderr, "interpreting the font program, with"
18356 { 19315 " %zu instructions\n", fpgm->num_instructions);
18357 axis_name
18358 = (char *) sfnt_find_name (name, fvar->instance[i].name_id,
18359 &record);
18360 19316
18361 if (axis_name) 19317 trap = sfnt_interpret_font_program (interpreter, fpgm);
18362 fprintf (stderr, "instance no: %d; name: %.*s\n", 19318
18363 i, record.length, axis_name); 19319 if (trap)
18364 } 19320 fprintf (stderr, "**TRAP**: %s\n", trap);
18365 } 19321 }
18366 19322
18367 if (fvar->instance_count > 1) 19323 if (prep)
18368 { 19324 {
18369 printf ("instance? "); 19325 fprintf (stderr, "interpreting the control value program, with"
18370 19326 " %zu instructions\n", prep->num_instructions);
18371 if (scanf ("%d", &i) == EOF)
18372 goto free_lab;
18373 19327
18374 if (i < 0 || i >= fvar->instance_count) 19328 trap = sfnt_interpret_control_value_program (interpreter, prep,
18375 goto free_lab; 19329 &state);
18376 19330
18377 instance = &fvar->instance[i]; 19331 if (trap)
19332 fprintf (stderr, "**TRAP**: %s\n", trap);
18378 } 19333 }
18379 } 19334 }
18380 19335
18381 if (gvar)
18382 fprintf (stderr, "gvar table found\n");
18383
18384 if (instance && gvar)
18385 {
18386 sfnt_init_blend (&blend, fvar, gvar);
18387
18388 for (i = 0; i < fvar->axis_count; ++i)
18389 blend.coords[i] = instance->coords[i];
18390
18391 sfnt_normalize_blend (&blend);
18392 }
18393
18394 while (true) 19336 while (true)
18395 { 19337 {
18396 printf ("table, character? "); 19338 printf ("table, character? ");
@@ -18428,11 +19370,33 @@ main (int argc, char **argv)
18428 dcontext.loca_short = loca_short; 19370 dcontext.loca_short = loca_short;
18429 dcontext.loca_long = loca_long; 19371 dcontext.loca_long = loca_long;
18430 19372
19373 if (instance && gvar)
19374 dcontext.blend = &blend;
19375 else
19376 dcontext.blend = NULL;
19377
18431 if (glyph->simple && instance && gvar) 19378 if (glyph->simple && instance && gvar)
18432 { 19379 {
18433 printf ("applying variations to simple glyph...\n"); 19380 printf ("applying variations to simple glyph...\n");
18434 19381
18435 if (sfnt_vary_glyph (&blend, code, glyph)) 19382 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
19383 if (sfnt_vary_simple_glyph (&blend, code, glyph,
19384 &distortion))
19385 printf ("variation failed!\n");
19386 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
19387 sub = timespec_sub (end, start);
19388
19389 printf ("time spent varying: %lld sec %ld nsec\n",
19390 (long long) sub.tv_sec, sub.tv_nsec);
19391 printf ("distortions: %"PRIi16", %"PRIi16"\n",
19392 distortion.origin, distortion.advance);
19393 }
19394 else if (instance && gvar)
19395 {
19396 printf ("applying variations to compound glyph...\n");
19397
19398 if (sfnt_vary_compound_glyph (&blend, code, glyph,
19399 &distortion))
18436 printf ("variation failed!\n"); 19400 printf ("variation failed!\n");
18437 } 19401 }
18438 19402
@@ -18444,10 +19408,20 @@ main (int argc, char **argv)
18444 &dcontext)) 19408 &dcontext))
18445 printf ("decomposition failure\n"); 19409 printf ("decomposition failure\n");
18446 19410
19411 if (sfnt_lookup_glyph_metrics (code, EASY_PPEM,
19412 &metrics,
19413 hmtx, hhea,
19414 head, maxp))
19415 {
19416 printf ("metrics lookup failure");
19417 memset (&metrics, 0, sizeof metrics);
19418 }
19419
18447 /* Time this important bit. */ 19420 /* Time this important bit. */
18448 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); 19421 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
18449 outline = sfnt_build_glyph_outline (glyph, head, 19422 outline = sfnt_build_glyph_outline (glyph, head,
18450 EASY_PPEM, 19423 EASY_PPEM,
19424 &metrics,
18451 sfnt_test_get_glyph, 19425 sfnt_test_get_glyph,
18452 sfnt_test_free_glyph, 19426 sfnt_test_free_glyph,
18453 &dcontext); 19427 &dcontext);
@@ -18618,6 +19592,9 @@ main (int argc, char **argv)
18618 for (i = 0; i < table->num_subtables; ++i) 19592 for (i = 0; i < table->num_subtables; ++i)
18619 xfree (data[i]); 19593 xfree (data[i]);
18620 19594
19595 if (instance && gvar)
19596 sfnt_free_blend (&blend);
19597
18621 xfree (table); 19598 xfree (table);
18622 xfree (data); 19599 xfree (data);
18623 xfree (subtables); 19600 xfree (subtables);
@@ -18637,9 +19614,8 @@ main (int argc, char **argv)
18637 xfree (prep); 19614 xfree (prep);
18638 xfree (fvar); 19615 xfree (fvar);
18639 xfree (gvar); 19616 xfree (gvar);
18640 19617 xfree (avar);
18641 if (instance && gvar) 19618 xfree (cvar);
18642 sfnt_free_blend (&blend);
18643 19619
18644 return 0; 19620 return 0;
18645} 19621}
diff --git a/src/sfnt.h b/src/sfnt.h
index 82fa343f51d..84e51ff6766 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -27,10 +27,6 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29 29
30#if defined emacs || defined TEST
31#define SFNT_ENABLE_HINTING
32#endif
33
34 30
35 31
36/* Container structure and enumerator definitions. */ 32/* Container structure and enumerator definitions. */
@@ -56,6 +52,7 @@ enum sfnt_table
56 SFNT_TABLE_FVAR, 52 SFNT_TABLE_FVAR,
57 SFNT_TABLE_GVAR, 53 SFNT_TABLE_GVAR,
58 SFNT_TABLE_CVAR, 54 SFNT_TABLE_CVAR,
55 SFNT_TABLE_AVAR,
59 }; 56 };
60 57
61#define SFNT_ENDOF(type, field, type1) \ 58#define SFNT_ENDOF(type, field, type1) \
@@ -664,6 +661,12 @@ struct sfnt_glyph
664 /* Coordinate bounds. */ 661 /* Coordinate bounds. */
665 sfnt_fword xmin, ymin, xmax, ymax; 662 sfnt_fword xmin, ymin, xmax, ymax;
666 663
664 /* Distortion applied to the right side phantom point. */
665 sfnt_fword advance_distortion;
666
667 /* Distortion applied to the origin point. */
668 sfnt_fword origin_distortion;
669
667 /* Either a simple glyph or a compound glyph, depending on which is 670 /* Either a simple glyph or a compound glyph, depending on which is
668 set. */ 671 set. */
669 struct sfnt_simple_glyph *simple; 672 struct sfnt_simple_glyph *simple;
@@ -718,6 +721,10 @@ struct sfnt_glyph_outline
718 and maximum X and Y positions. */ 721 and maximum X and Y positions. */
719 sfnt_fixed xmin, ymin, xmax, ymax; 722 sfnt_fixed xmin, ymin, xmax, ymax;
720 723
724 /* The origin point of the outline on the X axis. Value defaults to
725 0. */
726 sfnt_fixed origin;
727
721 /* Reference count. Initially zero. */ 728 /* Reference count. Initially zero. */
722 short refcount; 729 short refcount;
723}; 730};
@@ -739,7 +746,8 @@ struct sfnt_raster
739 /* Basic dimensions of the raster. */ 746 /* Basic dimensions of the raster. */
740 unsigned short width, height; 747 unsigned short width, height;
741 748
742 /* Integer offset to apply to positions in the raster. */ 749 /* Integer offset to apply to positions in the raster so that they
750 start from the origin point of the glyph. */
743 short offx, offy; 751 short offx, offy;
744 752
745 /* The raster stride. */ 753 /* The raster stride. */
@@ -966,6 +974,357 @@ enum sfnt_ttc_tag
966 974
967 975
968 976
977/* Unicode Variation Sequence (UVS) support. */
978
979struct sfnt_default_uvs_table
980{
981 /* Number of ranges that follow. */
982 uint32_t num_unicode_value_ranges;
983
984 /* Variable length data. */
985 struct sfnt_unicode_value_range *ranges;
986};
987
988struct sfnt_unicode_value_range
989{
990 /* First value in this range. */
991 unsigned int start_unicode_value;
992
993 /* Number of additional values in this range. */
994 unsigned char additional_count;
995};
996
997struct sfnt_nondefault_uvs_table
998{
999 /* Number of UVS mappings which follow. */
1000 uint32_t num_uvs_mappings;
1001
1002 /* Variable length data. */
1003 struct sfnt_uvs_mapping *mappings;
1004};
1005
1006struct sfnt_uvs_mapping
1007{
1008 /* Base character value. */
1009 unsigned int unicode_value;
1010
1011 /* Glyph ID of the base character value. */
1012 uint16_t base_character_value;
1013};
1014
1015struct sfnt_mapped_variation_selector_record
1016{
1017 /* The variation selector. */
1018 unsigned int selector;
1019
1020 /* Its default UVS table. */
1021 struct sfnt_default_uvs_table *default_uvs;
1022
1023 /* Its nondefault UVS table. */
1024 struct sfnt_nondefault_uvs_table *nondefault_uvs;
1025};
1026
1027/* Structure describing a single offset to load into a variation
1028 selection context. */
1029
1030struct sfnt_table_offset_rec
1031{
1032 /* The offset from the start of the font file. */
1033 off_t offset;
1034
1035 /* Whether or not the offset points to a non-default UVS table. */
1036 bool is_nondefault_table;
1037
1038 /* Pointer to the UVS table. */
1039 void *table;
1040};
1041
1042struct sfnt_uvs_context
1043{
1044 /* Number of records and tables. */
1045 size_t num_records, nmemb;
1046
1047 /* Array of UVS tables. */
1048 struct sfnt_table_offset_rec *tables;
1049
1050 /* Array of variation selector records mapped to
1051 their corresponding tables. */
1052 struct sfnt_mapped_variation_selector_record *records;
1053};
1054
1055
1056
1057#if defined HAVE_MMAP && !defined TEST
1058
1059/* Memory mapping support. */
1060
1061struct sfnt_mapped_table
1062{
1063 /* Pointer to table data. */
1064 void *data;
1065
1066 /* Pointer to table mapping. */
1067 void *mapping;
1068
1069 /* Size of mapped data and size of mapping. */
1070 size_t length, size;
1071};
1072
1073#endif /* HAVE_MMAP && !TEST */
1074
1075
1076
1077/* Glyph variation support. */
1078
1079/* 2.14 fixed point type used to represent versors of unit
1080 vectors. */
1081typedef int16_t sfnt_f2dot14;
1082
1083/* Forward declaration used only for the distortable font stuff. */
1084struct sfnt_cvt_table;
1085
1086struct sfnt_variation_axis
1087{
1088 /* The axis tag. */
1089 uint32_t axis_tag;
1090
1091 /* The minimum style coordinate for the axis. */
1092 sfnt_fixed min_value;
1093
1094 /* The default style coordinate for the axis. */
1095 sfnt_fixed default_value;
1096
1097 /* The maximum style coordinate for the axis. */
1098 sfnt_fixed max_value;
1099
1100 /* Set to zero. */
1101 uint16_t flags;
1102
1103 /* Identifier under which this axis's name will be found in the
1104 `name' table. */
1105 uint16_t name_id;
1106};
1107
1108struct sfnt_instance
1109{
1110 /* The instance name ID. */
1111 uint16_t name_id;
1112
1113 /* Flags. */
1114 uint16_t flags;
1115
1116 /* Optional PostScript name. */
1117 uint16_t ps_name_id;
1118
1119 /* Coordinates of each defined instance. */
1120 sfnt_fixed *coords;
1121};
1122
1123struct sfnt_fvar_table
1124{
1125 /* Major version; should be 1. */
1126 uint16_t major_version;
1127
1128 /* Minor version; should be 0. */
1129 uint16_t minor_version;
1130
1131 /* Offset in bytes from the beginning of the table to the beginning
1132 of the first axis data. */
1133 uint16_t offset_to_data;
1134
1135 /* Reserved field; always 2. */
1136 uint16_t count_size_pairs;
1137
1138 /* Number of style axes in this font. */
1139 uint16_t axis_count;
1140
1141 /* The number of bytes in each variation axis record. Currently 20
1142 bytes. */
1143 uint16_t axis_size;
1144
1145 /* The number of named instances for the font found in the
1146 instance array. */
1147 uint16_t instance_count;
1148
1149 /* The size of each instance record. */
1150 uint16_t instance_size;
1151
1152 /* Variable length data. */
1153 struct sfnt_variation_axis *axis;
1154 struct sfnt_instance *instance;
1155};
1156
1157struct sfnt_short_frac_correspondence
1158{
1159 /* Value in normalized user space. */
1160 sfnt_f2dot14 from_coord;
1161
1162 /* Value in normalized axis space. */
1163 sfnt_f2dot14 to_coord;
1164};
1165
1166struct sfnt_short_frac_segment
1167{
1168 /* The number of pairs for this axis. */
1169 uint16_t pair_count;
1170
1171 /* Variable length data. */
1172 struct sfnt_short_frac_correspondence *correspondence;
1173};
1174
1175struct sfnt_avar_table
1176{
1177 /* The version of the table. Should be 1.0. */
1178 sfnt_fixed version;
1179
1180 /* Number of variation axes defined in this table.
1181 XXX: why is this signed? */
1182 int32_t axis_count;
1183
1184 /* Variable length data. */
1185 struct sfnt_short_frac_segment *segments;
1186};
1187
1188struct sfnt_tuple_variation
1189{
1190 /* Tuple point numbers. */
1191 uint16_t *points;
1192
1193 /* Deltas. */
1194 sfnt_fword *deltas;
1195
1196 /* Tuple coordinates. One for each axis specified in the [gaf]var
1197 tables. */
1198 sfnt_f2dot14 *coordinates;
1199
1200 /* Intermediate start and end coordinates. */
1201 sfnt_f2dot14 *restrict intermediate_start;
1202
1203 /* Intermediate start and end coordinates. */
1204 sfnt_f2dot14 *restrict intermediate_end;
1205
1206 /* The number of points and deltas present.
1207
1208 UINT16_MAX and POINTS set to NULL means there are deltas for each
1209 CVT entry. */
1210 uint16_t num_points;
1211};
1212
1213struct sfnt_cvar_table
1214{
1215 /* The version of this CVT variations table. */
1216 sfnt_fixed version;
1217
1218 /* Flags. */
1219 uint16_t tuple_count;
1220
1221 /* Offset from the beginning of the table to the tuple data. */
1222 uint16_t data_offset;
1223
1224 /* Variable length data. */
1225 struct sfnt_tuple_variation *variation;
1226};
1227
1228struct sfnt_gvar_table
1229{
1230 /* Version of the glyph variations table. */
1231 uint16_t version;
1232
1233 /* Reserved, currently 0. */
1234 uint16_t reserved;
1235
1236 /* The number of style axes for this font. This must be the same
1237 number as axisCount in the 'fvar' table. */
1238 uint16_t axis_count;
1239
1240 /* The number of shared coordinates. */
1241 uint16_t shared_coord_count;
1242
1243 /* Byte offset from the beginning of this table to the list of
1244 shared style coordinates. */
1245 uint32_t offset_to_coord;
1246
1247 /* The number of glyphs in this font; this should match the number
1248 of the glyphs store elsewhere in the font. */
1249 uint16_t glyph_count;
1250
1251 /* Bit-field that gives the format of the offset array that
1252 follows. If the flag is 0, the type is uint16. If the flag is 1,
1253 the type is unit 32. */
1254 uint16_t flags;
1255
1256 /* Byte offset from the beginning of this table to the first glyph
1257 glyphVariationData. */
1258 uint32_t offset_to_data;
1259
1260 /* Number of bytes in the glyph variation data. */
1261 size_t data_size;
1262
1263 /* Byte offsets from the beginning of the glyphVariationData array
1264 to the glyphVariationData for each glyph in the font. The format
1265 of this field is set by the flags field. */
1266 union {
1267 uint16_t *offset_word;
1268 uint32_t *offset_long;
1269 } u;
1270
1271 /* Other variable length data. */
1272 sfnt_f2dot14 *global_coords;
1273 unsigned char *glyph_variation_data;
1274};
1275
1276/* Structure repesenting a set of axis coordinates and their
1277 normalized equivalents.
1278
1279 To use this structure, call
1280
1281 sfnt_init_blend (&blend, fvar, gvar)
1282
1283 on a `struct sfnt_blend *', with an appropriate fvar and gvar
1284 table.
1285
1286 Then, fill in blend.coords with the un-normalized coordinates,
1287 and call
1288
1289 sfnt_normalize_blend (&blend)
1290
1291 finally, call sfnt_vary_simple_glyph and related functions. */
1292
1293struct sfnt_blend
1294{
1295 /* The fvar table. This determines the number of elements in each
1296 of the arrays below. */
1297 struct sfnt_fvar_table *fvar;
1298
1299 /* The gvar table. This provides the glyph variation data. */
1300 struct sfnt_gvar_table *gvar;
1301
1302 /* The avar table. This provides adjustments to normalized axis
1303 values, and may be NULL. */
1304 struct sfnt_avar_table *avar;
1305
1306 /* The cvar table. This provides adjustments to CVT values, and may
1307 be NULL. */
1308 struct sfnt_cvar_table *cvar;
1309
1310 /* Un-normalized coordinates. */
1311 sfnt_fixed *coords;
1312
1313 /* Normalized coordinates. */
1314 sfnt_fixed *norm_coords;
1315};
1316
1317struct sfnt_metrics_distortion
1318{
1319 /* Distortion applied to the origin point. */
1320 sfnt_fword origin;
1321
1322 /* Distortion applied to the advance point. */
1323 sfnt_fword advance;
1324};
1325
1326
1327
969#define SFNT_CEIL_FIXED(fixed) \ 1328#define SFNT_CEIL_FIXED(fixed) \
970 (!((fixed) & 0177777) ? (fixed) \ 1329 (!((fixed) & 0177777) ? (fixed) \
971 : ((fixed) + 0200000) & 037777600000) 1330 : ((fixed) + 0200000) & 037777600000)
@@ -1012,7 +1371,9 @@ extern void sfnt_free_glyph (struct sfnt_glyph *);
1012#define PROTOTYPE \ 1371#define PROTOTYPE \
1013 struct sfnt_glyph *, \ 1372 struct sfnt_glyph *, \
1014 struct sfnt_head_table *, \ 1373 struct sfnt_head_table *, \
1015 int, sfnt_get_glyph_proc, \ 1374 int, \
1375 struct sfnt_glyph_metrics *, \
1376 sfnt_get_glyph_proc, \
1016 sfnt_free_glyph_proc, \ 1377 sfnt_free_glyph_proc, \
1017 void * 1378 void *
1018extern struct sfnt_glyph_outline *sfnt_build_glyph_outline (PROTOTYPE); 1379extern struct sfnt_glyph_outline *sfnt_build_glyph_outline (PROTOTYPE);
@@ -1042,6 +1403,8 @@ extern int sfnt_lookup_glyph_metrics (sfnt_glyph, int,
1042 1403
1043extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *, 1404extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *,
1044 sfnt_fixed); 1405 sfnt_fixed);
1406extern void sfnt_scale_metrics_to_pixel_size (struct sfnt_glyph_metrics *,
1407 int, struct sfnt_head_table *);
1045 1408
1046#define PROTOTYPE int, struct sfnt_offset_subtable * 1409#define PROTOTYPE int, struct sfnt_offset_subtable *
1047extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE); 1410extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE);
@@ -1061,14 +1424,82 @@ extern char *sfnt_find_metadata (struct sfnt_meta_table *,
1061 1424
1062extern struct sfnt_ttc_header *sfnt_read_ttc_header (int); 1425extern struct sfnt_ttc_header *sfnt_read_ttc_header (int);
1063 1426
1427
1428
1429#define PROTOTYPE struct sfnt_cmap_format_14 *, int
1430
1431extern struct sfnt_uvs_context *sfnt_create_uvs_context (PROTOTYPE);
1432
1433#undef PROTOTYPE
1434
1435extern void sfnt_free_uvs_context (struct sfnt_uvs_context *);
1436
1437#define PROTOTYPE struct sfnt_nondefault_uvs_table *, sfnt_char
1438
1439extern sfnt_glyph sfnt_variation_glyph_for_char (PROTOTYPE);
1440
1441#undef PROTOTYPE
1442
1443
1444
1445#ifdef HAVE_MMAP
1446
1447extern int sfnt_map_table (int, struct sfnt_offset_subtable *,
1448 uint32_t, struct sfnt_mapped_table *);
1449extern int sfnt_unmap_table (struct sfnt_mapped_table *);
1450
1451#endif /* HAVE_MMAP */
1452
1453
1454
1455extern void *sfnt_read_table (int, struct sfnt_offset_subtable *,
1456 uint32_t, size_t *);
1457
1458
1459
1460#define PROTOTYPE int, struct sfnt_offset_subtable *
1461
1462extern struct sfnt_fvar_table *sfnt_read_fvar_table (PROTOTYPE);
1463extern struct sfnt_gvar_table *sfnt_read_gvar_table (PROTOTYPE);
1464extern struct sfnt_avar_table *sfnt_read_avar_table (PROTOTYPE);
1465
1466#undef PROTOTYPE
1467
1468#define PROTOTYPE \
1469 int, \
1470 struct sfnt_offset_subtable *, \
1471 struct sfnt_fvar_table *, \
1472 struct sfnt_cvt_table *
1473
1474extern struct sfnt_cvar_table *sfnt_read_cvar_table (PROTOTYPE);
1475
1476#undef PROTOTYPE
1477
1478
1479
1480extern void sfnt_init_blend (struct sfnt_blend *,
1481 struct sfnt_fvar_table *,
1482 struct sfnt_gvar_table *,
1483 struct sfnt_avar_table *,
1484 struct sfnt_cvar_table *);
1485extern void sfnt_free_blend (struct sfnt_blend *);
1486extern void sfnt_normalize_blend (struct sfnt_blend *);
1487
1488
1489
1490extern int sfnt_vary_simple_glyph (struct sfnt_blend *, sfnt_glyph,
1491 struct sfnt_glyph *,
1492 struct sfnt_metrics_distortion *);
1493extern int sfnt_vary_compound_glyph (struct sfnt_blend *, sfnt_glyph,
1494 struct sfnt_glyph *,
1495 struct sfnt_metrics_distortion *);
1496
1064#endif /* TEST */ 1497#endif /* TEST */
1065 1498
1066 1499
1067 1500
1068/* TrueType hinting support. */ 1501/* TrueType hinting support. */
1069 1502
1070#ifdef SFNT_ENABLE_HINTING
1071
1072/* Structure definitions for tables used by the TrueType 1503/* Structure definitions for tables used by the TrueType
1073 interpreter. */ 1504 interpreter. */
1074 1505
@@ -1107,10 +1538,6 @@ struct sfnt_prep_table
1107/* 26.6 fixed point type used within the interpreter. */ 1538/* 26.6 fixed point type used within the interpreter. */
1108typedef int32_t sfnt_f26dot6; 1539typedef int32_t sfnt_f26dot6;
1109 1540
1110/* 2.14 fixed point type used to represent versors of unit
1111 vectors. */
1112typedef int16_t sfnt_f2dot14;
1113
1114/* 18.14 fixed point type used to calculate rounding details. */ 1541/* 18.14 fixed point type used to calculate rounding details. */
1115typedef int32_t sfnt_f18dot14; 1542typedef int32_t sfnt_f18dot14;
1116 1543
@@ -1479,106 +1906,6 @@ struct sfnt_instructed_outline
1479 1906
1480 1907
1481 1908
1482/* Unicode Variation Sequence (UVS) support. */
1483
1484struct sfnt_default_uvs_table
1485{
1486 /* Number of ranges that follow. */
1487 uint32_t num_unicode_value_ranges;
1488
1489 /* Variable length data. */
1490 struct sfnt_unicode_value_range *ranges;
1491};
1492
1493struct sfnt_unicode_value_range
1494{
1495 /* First value in this range. */
1496 unsigned int start_unicode_value;
1497
1498 /* Number of additional values in this range. */
1499 unsigned char additional_count;
1500};
1501
1502struct sfnt_nondefault_uvs_table
1503{
1504 /* Number of UVS mappings which follow. */
1505 uint32_t num_uvs_mappings;
1506
1507 /* Variable length data. */
1508 struct sfnt_uvs_mapping *mappings;
1509};
1510
1511struct sfnt_uvs_mapping
1512{
1513 /* Base character value. */
1514 unsigned int unicode_value;
1515
1516 /* Glyph ID of the base character value. */
1517 uint16_t base_character_value;
1518};
1519
1520struct sfnt_mapped_variation_selector_record
1521{
1522 /* The variation selector. */
1523 unsigned int selector;
1524
1525 /* Its default UVS table. */
1526 struct sfnt_default_uvs_table *default_uvs;
1527
1528 /* Its nondefault UVS table. */
1529 struct sfnt_nondefault_uvs_table *nondefault_uvs;
1530};
1531
1532/* Structure describing a single offset to load into a variation
1533 selection context. */
1534
1535struct sfnt_table_offset_rec
1536{
1537 /* The offset from the start of the font file. */
1538 off_t offset;
1539
1540 /* Whether or not the offset points to a non-default UVS table. */
1541 bool is_nondefault_table;
1542
1543 /* Pointer to the UVS table. */
1544 void *table;
1545};
1546
1547struct sfnt_uvs_context
1548{
1549 /* Number of records and tables. */
1550 size_t num_records, nmemb;
1551
1552 /* Array of UVS tables. */
1553 struct sfnt_table_offset_rec *tables;
1554
1555 /* Array of variation selector records mapped to
1556 their corresponding tables. */
1557 struct sfnt_mapped_variation_selector_record *records;
1558};
1559
1560
1561
1562#if defined HAVE_MMAP && !defined TEST
1563
1564/* Memory mapping support. */
1565
1566struct sfnt_mapped_table
1567{
1568 /* Pointer to table data. */
1569 void *data;
1570
1571 /* Pointer to table mapping. */
1572 void *mapping;
1573
1574 /* Size of mapped data and size of mapping. */
1575 size_t length, size;
1576};
1577
1578#endif /* HAVE_MMAP && !TEST */
1579
1580
1581
1582/* Functions used to read tables used by the TrueType interpreter. */ 1909/* Functions used to read tables used by the TrueType interpreter. */
1583 1910
1584#ifndef TEST 1911#ifndef TEST
@@ -1653,39 +1980,11 @@ extern const char *sfnt_interpret_compound_glyph (PROTOTYPE);
1653 1980
1654 1981
1655 1982
1656#define PROTOTYPE struct sfnt_cmap_format_14 *, int 1983extern void sfnt_vary_interpreter (struct sfnt_interpreter *,
1657 1984 struct sfnt_blend *);
1658extern struct sfnt_uvs_context *sfnt_create_uvs_context (PROTOTYPE);
1659
1660#undef PROTOTYPE
1661
1662extern void sfnt_free_uvs_context (struct sfnt_uvs_context *);
1663
1664#define PROTOTYPE struct sfnt_nondefault_uvs_table *, sfnt_char
1665
1666extern sfnt_glyph sfnt_variation_glyph_for_char (PROTOTYPE);
1667
1668#undef PROTOTYPE
1669
1670
1671
1672#ifdef HAVE_MMAP
1673
1674extern int sfnt_map_table (int, struct sfnt_offset_subtable *,
1675 uint32_t, struct sfnt_mapped_table *);
1676extern int sfnt_unmap_table (struct sfnt_mapped_table *);
1677
1678#endif /* HAVE_MMAP */
1679
1680
1681
1682extern void *sfnt_read_table (int, struct sfnt_offset_subtable *,
1683 uint32_t, size_t *);
1684 1985
1685#endif /* TEST */ 1986#endif /* TEST */
1686 1987
1687 1988
1688 1989
1689#endif /* SFNT_ENABLE_HINTING */
1690
1691#endif /* _SFNT_H_ */ 1990#endif /* _SFNT_H_ */
diff --git a/src/sfntfont.c b/src/sfntfont.c
index 500256d6fb4..e4579d62154 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -1688,6 +1688,8 @@ sfntfont_dereference_outline (struct sfnt_glyph_outline *outline)
1688 1688
1689 If INTERPRETER is non-NULL, then possibly use the unscaled glyph 1689 If INTERPRETER is non-NULL, then possibly use the unscaled glyph
1690 metrics in METRICS and the interpreter STATE to instruct the glyph. 1690 metrics in METRICS and the interpreter STATE to instruct the glyph.
1691 Otherwise, METRICS must contain scaled glyph metrics used to
1692 compute the origin point of the outline.
1691 1693
1692 Return the outline with an incremented reference count and enter 1694 Return the outline with an incremented reference count and enter
1693 the generated outline into CACHE upon success, possibly discarding 1695 the generated outline into CACHE upon success, possibly discarding
@@ -1714,6 +1716,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
1714 struct sfntfont_get_glyph_outline_dcontext dcontext; 1716 struct sfntfont_get_glyph_outline_dcontext dcontext;
1715 struct sfnt_instructed_outline *value; 1717 struct sfnt_instructed_outline *value;
1716 const char *error; 1718 const char *error;
1719 struct sfnt_glyph_metrics temp;
1717 1720
1718 start = cache->next; 1721 start = cache->next;
1719 1722
@@ -1784,10 +1787,31 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
1784 } 1787 }
1785 1788
1786 if (!outline) 1789 if (!outline)
1787 outline = sfnt_build_glyph_outline (glyph, head, pixel_size, 1790 {
1788 sfntfont_get_glyph, 1791 /* If INTERPRETER is NULL, METRICS contains scaled metrics. */
1789 sfntfont_free_glyph, 1792
1790 &dcontext); 1793 if (!interpreter)
1794 outline = sfnt_build_glyph_outline (glyph, head, pixel_size,
1795 metrics,
1796 sfntfont_get_glyph,
1797 sfntfont_free_glyph,
1798 &dcontext);
1799 else
1800 {
1801 /* But otherwise, they are unscaled, and must be scaled
1802 before being used. */
1803
1804 temp = *metrics;
1805 sfnt_scale_metrics_to_pixel_size (&temp, pixel_size,
1806 head);
1807 outline = sfnt_build_glyph_outline (glyph, head, pixel_size,
1808 &temp,
1809 sfntfont_get_glyph,
1810 sfntfont_free_glyph,
1811 &dcontext);
1812 }
1813 }
1814
1791 xfree (glyph); 1815 xfree (glyph);
1792 1816
1793 if (!outline) 1817 if (!outline)
@@ -2689,8 +2713,8 @@ sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph,
2689 font->hmtx, font->hhea, 2713 font->hmtx, font->hhea,
2690 font->maxp, 2714 font->maxp,
2691 font->loca_short, 2715 font->loca_short,
2692 font->loca_long, NULL, NULL, 2716 font->loca_long, NULL,
2693 NULL); 2717 &metrics, NULL);
2694 2718
2695 if (!outline) 2719 if (!outline)
2696 return 1; 2720 return 1;