aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-12-29 14:58:19 +0800
committerPo Lu2023-12-29 14:58:41 +0800
commitea3d211f3f7ecc5b59d5affc1aed812a2ded62b0 (patch)
treebd83822c8a517b4ed6aca9e84cfd3d2e7486d9c3
parent714942b1c3767ee6c70a5644d6a4460dedbe4422 (diff)
downloademacs-ea3d211f3f7ecc5b59d5affc1aed812a2ded62b0.tar.gz
emacs-ea3d211f3f7ecc5b59d5affc1aed812a2ded62b0.zip
Obey USE_MY_METRICS in compound glyphs
* src/sfnt.c (struct sfnt_compound_glyph_context): New fields holding the positions of both phantom points. (sfnt_decompose_compound_glyph): New argument METRICS_RETURN; return the metrics of components with USE_MY_METRICS within this field. (sfnt_decompose_glyph): New argument METRICS_RETURN, which serves the same purpose. (sfnt_build_glyph_outline): Apply glyph advance and origin distortion to METRICS, and return the metrics as altered by compound glyphs in there. (sfnt_lookup_glyph_metrics): Trim away two unused parameters, PIXEL_SIZE and HEAD, whose functionality has been superseeded by sfnt_scale_metrics and the implicit scaling the interpreter performs. (sfnt_interpret_compound_glyph_2): Save phantom points within fields provided to that end in CONTEXT. (sfnt_interpret_compound_glyph_1): Save and source phantom points for each glyph to and from the context. (sfnt_test_get_metrics, main): Adjust tests correspondingly. * src/sfnt.h: Update prototypes. * src/sfntfont.c (sfntfont_get_metrics): Remove obsolete parameters. (sfntfont_get_glyph_outline): Don't change temp by the metrics distortions, which is now the task of sfnt_decompose_glyph.
-rw-r--r--src/sfnt.c300
-rw-r--r--src/sfnt.h3
-rw-r--r--src/sfntfont.c23
3 files changed, 228 insertions, 98 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index b67377ad064..7625254d0bd 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -2600,6 +2600,16 @@ struct sfnt_compound_glyph_context
2600 2600
2601 /* Number of elements in and the size of that array. */ 2601 /* Number of elements in and the size of that array. */
2602 size_t num_end_points, end_points_size; 2602 size_t num_end_points, end_points_size;
2603
2604 /* The X positions of two phantom points marking this glyph's origin
2605 and advance position, only used while interpreting the glyph. */
2606 sfnt_f26dot6 phantom_point_1_x, phantom_point_2_x;
2607
2608 /* Y positions. */
2609 sfnt_f26dot6 phantom_point_1_y, phantom_point_2_y;
2610
2611 /* Unrounded X positions. */
2612 sfnt_f26dot6 phantom_point_1_s, phantom_point_2_s;
2603}; 2613};
2604 2614
2605/* Extend the arrays inside the compound glyph decomposition context 2615/* Extend the arrays inside the compound glyph decomposition context
@@ -2704,11 +2714,17 @@ sfnt_round_fixed (int32_t number)
2704 GET_METRICS, along with DCONTEXT, mean the same as in 2714 GET_METRICS, along with DCONTEXT, mean the same as in
2705 sfnt_decompose_glyph. 2715 sfnt_decompose_glyph.
2706 2716
2717 If it has been arranged that a component's metrics (or those of an
2718 innermore component also with the flag set) replace the metrics of
2719 GLYPH, set *METRICS_RETURN to those metrics. Mind that such
2720 metrics are not scaled in any manner.
2721
2707 Value is 1 upon failure, else 0. */ 2722 Value is 1 upon failure, else 0. */
2708 2723
2709static int 2724static int
2710sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph, 2725sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2711 struct sfnt_compound_glyph_context *context, 2726 struct sfnt_compound_glyph_context *context,
2727 struct sfnt_glyph_metrics *metrics_return,
2712 sfnt_get_glyph_proc get_glyph, 2728 sfnt_get_glyph_proc get_glyph,
2713 sfnt_free_glyph_proc free_glyph, 2729 sfnt_free_glyph_proc free_glyph,
2714 sfnt_get_metrics_proc get_metrics, 2730 sfnt_get_metrics_proc get_metrics,
@@ -2944,16 +2960,61 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2944 2960
2945 /* Copy over the contours. */ 2961 /* Copy over the contours. */
2946 for (i = 0; i < number_of_contours; ++i) 2962 for (i = 0; i < number_of_contours; ++i)
2947 contour_base[i] = (contour_start 2963 contour_base[i]
2948 + subglyph->simple->end_pts_of_contours[i]); 2964 = (contour_start
2965 + subglyph->simple->end_pts_of_contours[i]);
2966
2967 /* If USE_MY_METRICS is present within this component,
2968 save its metrics within *METRICS_RETURN. */
2969
2970 if (component->flags & 01000 /* USE_MY_METRICS */)
2971 {
2972 if ((*get_metrics) (component->glyph_index,
2973 metrics_return, dcontext))
2974 {
2975 if (need_free)
2976 free_glyph (subglyph, dcontext);
2977
2978 return 1;
2979 }
2980
2981 /* Refer to the comment above sfnt_decompose_glyph
2982 for reasons and manner in which these offsets are
2983 applied. */
2984 metrics_return->lbearing -= subglyph->origin_distortion;
2985 metrics_return->advance += subglyph->advance_distortion;
2986 }
2949 } 2987 }
2950 } 2988 }
2951 else 2989 else
2952 { 2990 {
2991 /* If USE_MY_METRICS, save this subglyph's metrics within
2992 sub_metrics; they might be overwritten by metrics for
2993 subglyphs of this compound subglyph in turn. */
2994
2995 if (component->flags & 01000 /* USE_MY_METRICS */)
2996 {
2997 if ((*get_metrics) (component->glyph_index,
2998 &sub_metrics, dcontext))
2999 {
3000 if (need_free)
3001 free_glyph (subglyph, dcontext);
3002
3003 return 1;
3004 }
3005
3006 /* Refer to the comment above sfnt_decompose_glyph for
3007 reasons and manner in which these offsets are
3008 applied. */
3009 sub_metrics.lbearing -= subglyph->origin_distortion;
3010 sub_metrics.advance += subglyph->advance_distortion;
3011 }
3012
2953 /* Compound subglyph. Decompose the glyph recursively, and 3013 /* Compound subglyph. Decompose the glyph recursively, and
2954 then apply the transform. */ 3014 then apply the transform. */
2955 rc = sfnt_decompose_compound_glyph (subglyph, 3015 rc = sfnt_decompose_compound_glyph (subglyph,
2956 context, 3016 context,
3017 &sub_metrics,
2957 get_glyph, 3018 get_glyph,
2958 free_glyph, 3019 free_glyph,
2959 get_metrics, 3020 get_metrics,
@@ -2968,6 +3029,11 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2968 return 1; 3029 return 1;
2969 } 3030 }
2970 3031
3032 if (component->flags & 01000 /* USE_MY_METRICS */)
3033 /* Save sub_metrics inside *metrics_return as stated
3034 above. */
3035 *metrics_return = sub_metrics;
3036
2971 /* When an anchor point is being used to translate the 3037 /* When an anchor point is being used to translate the
2972 glyph, and the subglyph in question is actually a 3038 glyph, and the subglyph in question is actually a
2973 compound glyph, it is impossible to know which offset to 3039 compound glyph, it is impossible to know which offset to
@@ -3356,6 +3422,19 @@ sfnt_decompose_glyph_2 (size_t here, size_t last,
3356 GET_METRICS to obtain glyph metrics prerequisite for establishing 3422 GET_METRICS to obtain glyph metrics prerequisite for establishing
3357 their coordinates. 3423 their coordinates.
3358 3424
3425 When glyphs originate from a GX font with an active set of
3426 transforms, the correct manner of applying such transforms is to
3427 apply them within GET_GLYPH, while returning unaltered metrics from
3428 GET_METRICS.
3429
3430 If there is a component glyph within GLYPH whose metrics have been
3431 indicated as replacing those of its parent glyph, the variable
3432 *METRICS_RETURN will be set to its metrics with GX-induced offsets
3433 applied.
3434
3435 *METRICS_RETURN must initially hold metrics with GX offsets
3436 applied, if any.
3437
3359 All functions will be called with DCONTEXT as an argument. 3438 All functions will be called with DCONTEXT as an argument.
3360 3439
3361 The winding rule used to fill the resulting lines is described in 3440 The winding rule used to fill the resulting lines is described in
@@ -3367,6 +3446,7 @@ sfnt_decompose_glyph_2 (size_t here, size_t last,
3367 3446
3368static int 3447static int
3369sfnt_decompose_glyph (struct sfnt_glyph *glyph, 3448sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3449 struct sfnt_glyph_metrics *metrics_return,
3370 sfnt_move_to_proc move_to, 3450 sfnt_move_to_proc move_to,
3371 sfnt_line_to_proc line_to, 3451 sfnt_line_to_proc line_to,
3372 sfnt_curve_to_proc curve_to, 3452 sfnt_curve_to_proc curve_to,
@@ -3377,6 +3457,7 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3377{ 3457{
3378 size_t here, last, n; 3458 size_t here, last, n;
3379 struct sfnt_compound_glyph_context context; 3459 struct sfnt_compound_glyph_context context;
3460 struct sfnt_glyph_metrics compound_metrics;
3380 3461
3381 if (glyph->simple) 3462 if (glyph->simple)
3382 { 3463 {
@@ -3418,7 +3499,15 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3418 /* Decompose the specified compound glyph. */ 3499 /* Decompose the specified compound glyph. */
3419 memset (&context, 0, sizeof context); 3500 memset (&context, 0, sizeof context);
3420 3501
3502 /* Rather than handing METRICS_RETURN over to
3503 sfnt_decompose_compound_glyph, save metrics within a temporary
3504 variable and postpone returning them until it is certain the
3505 decomposition has succeeded. */
3506
3507 compound_metrics = *metrics_return;
3508
3421 if (sfnt_decompose_compound_glyph (glyph, &context, 3509 if (sfnt_decompose_compound_glyph (glyph, &context,
3510 &compound_metrics,
3422 get_glyph, free_glyph, 3511 get_glyph, free_glyph,
3423 get_metrics, 0, 3512 get_metrics, 0,
3424 dcontext)) 3513 dcontext))
@@ -3431,6 +3520,8 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3431 return 1; 3520 return 1;
3432 } 3521 }
3433 3522
3523 *metrics_return = compound_metrics;
3524
3434 /* Now, generate the outlines. */ 3525 /* Now, generate the outlines. */
3435 3526
3436 if (!context.num_end_points) 3527 if (!context.num_end_points)
@@ -3988,7 +4079,14 @@ sfnt_curve_to_and_build (struct sfnt_point control,
3988 space. 4079 space.
3989 4080
3990 Use the unscaled glyph METRICS to determine the origin point of the 4081 Use the unscaled glyph METRICS to determine the origin point of the
3991 outline. 4082 outline, or those of compound glyph components within *GLYPH
4083 configured to replace their parents', which if existent are
4084 returned in *METRICS. METRICS should not be altered by GX-derived
4085 offsets, as they will be applied to *METRICS if present, following
4086 this formula:
4087
4088 LBEARING = LBEARING - GLYPH->origin_distortion
4089 ADVANCE = ADVANCE + GLYPH->advance_distortion
3992 4090
3993 Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain 4091 Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain
3994 glyphs for compound glyph subcomponents, and GET_METRICS with the 4092 glyphs for compound glyph subcomponents, and GET_METRICS with the
@@ -4031,8 +4129,15 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
4031 /* Set the scale factor. */ 4129 /* Set the scale factor. */
4032 build_outline_context.factor = scale; 4130 build_outline_context.factor = scale;
4033 4131
4132 /* Apply the glyph's advance and origin distortion to METRICS in
4133 advance of constructing the glyph outline, which might replace
4134 METRICS with the metrics of a compound subglyph. */
4135 metrics->lbearing -= glyph->origin_distortion;
4136 metrics->advance += glyph->advance_distortion;
4137
4034 /* Decompose the outline. */ 4138 /* Decompose the outline. */
4035 rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build, 4139 rc = sfnt_decompose_glyph (glyph, metrics,
4140 sfnt_move_to_and_build,
4036 sfnt_line_to_and_build, 4141 sfnt_line_to_and_build,
4037 sfnt_curve_to_and_build, 4142 sfnt_curve_to_and_build,
4038 get_glyph, free_glyph, get_metrics, 4143 get_glyph, free_glyph, get_metrics,
@@ -4052,7 +4157,7 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
4052 is first used to calculate the origin point, and the origin 4157 is first used to calculate the origin point, and the origin
4053 distortion is applied to it to get the distorted origin. */ 4158 distortion is applied to it to get the distorted origin. */
4054 4159
4055 origin = glyph->xmin - metrics->lbearing + glyph->origin_distortion; 4160 origin = glyph->xmin - metrics->lbearing;
4056 outline->origin = sfnt_mul_fixed (origin, scale); 4161 outline->origin = sfnt_mul_fixed (origin, scale);
4057 4162
4058 return outline; 4163 return outline;
@@ -5595,27 +5700,22 @@ sfnt_read_hmtx_table (int fd, struct sfnt_offset_subtable *subtable,
5595 return hmtx; 5700 return hmtx;
5596} 5701}
5597 5702
5598/* Obtain glyph metrics for the glyph indiced by GLYPH at the 5703/* Obtain unscaled glyph metrics for the glyph indexed by GLYPH.
5599 specified PIXEL_SIZE. Return 0 and the metrics in *METRICS if 5704 Return 0 and the metrics in *METRICS if metrics could be found,
5600 metrics could be found, else 1. 5705 else 1.
5601
5602 If PIXEL_SIZE is -1, do not perform any scaling on the glyph
5603 metrics; HEAD need not be specified in that case.
5604 5706
5605 HMTX, HHEA, HEAD and MAXP should be the hmtx, hhea, head, and maxp 5707 HMTX, HHEA and MAXP should be the hmtx, hhea, head, and maxp tables
5606 tables of the font respectively. */ 5708 of the font respectively. */
5607 5709
5608TEST_STATIC int 5710TEST_STATIC int
5609sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size, 5711sfnt_lookup_glyph_metrics (sfnt_glyph glyph,
5610 struct sfnt_glyph_metrics *metrics, 5712 struct sfnt_glyph_metrics *metrics,
5611 struct sfnt_hmtx_table *hmtx, 5713 struct sfnt_hmtx_table *hmtx,
5612 struct sfnt_hhea_table *hhea, 5714 struct sfnt_hhea_table *hhea,
5613 struct sfnt_head_table *head,
5614 struct sfnt_maxp_table *maxp) 5715 struct sfnt_maxp_table *maxp)
5615{ 5716{
5616 short lbearing; 5717 short lbearing;
5617 unsigned short advance; 5718 unsigned short advance;
5618 sfnt_fixed factor;
5619 5719
5620 if (glyph < hhea->num_of_long_hor_metrics) 5720 if (glyph < hhea->num_of_long_hor_metrics)
5621 { 5721 {
@@ -5637,22 +5737,9 @@ sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
5637 /* No entry corresponds to the glyph. */ 5737 /* No entry corresponds to the glyph. */
5638 return 1; 5738 return 1;
5639 5739
5640 if (pixel_size == -1) 5740 /* Return unscaled metrics. */
5641 { 5741 metrics->lbearing = lbearing;
5642 /* Return unscaled metrics in this case. */ 5742 metrics->advance = advance;
5643 metrics->lbearing = lbearing;
5644 metrics->advance = advance;
5645 return 0;
5646 }
5647
5648 /* Now scale lbearing and advance up to the pixel size. */
5649 factor = sfnt_div_fixed (pixel_size, head->units_per_em);
5650
5651 /* Save them. */
5652 metrics->lbearing = sfnt_mul_fixed (lbearing * 65536, factor);
5653 metrics->advance = sfnt_mul_fixed (advance * 65536, factor);
5654
5655 /* All done. */
5656 return 0; 5743 return 0;
5657} 5744}
5658 5745
@@ -12586,7 +12673,8 @@ sfnt_transform_f26dot6 (struct sfnt_compound_glyph_component *component,
12586/* Internal helper for sfnt_interpret_compound_glyph_3. 12673/* Internal helper for sfnt_interpret_compound_glyph_3.
12587 12674
12588 Instruct the compound glyph GLYPH using INTERPRETER after all of 12675 Instruct the compound glyph GLYPH using INTERPRETER after all of
12589 its components have been instructed. 12676 its components have been instructed. Save the resulting points
12677 within CONTEXT, and set its phantom point fields to match as well.
12590 12678
12591 Use the unscaled METRICS to compute the phantom points of this 12679 Use the unscaled METRICS to compute the phantom points of this
12592 glyph. 12680 glyph.
@@ -12746,6 +12834,12 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph *glyph,
12746 x_base[1] = zone->x_current[num_points - 1]; 12834 x_base[1] = zone->x_current[num_points - 1];
12747 y_base[0] = zone->y_current[num_points - 2]; 12835 y_base[0] = zone->y_current[num_points - 2];
12748 y_base[1] = zone->y_current[num_points - 1]; 12836 y_base[1] = zone->y_current[num_points - 1];
12837 context->phantom_point_1_x = x_base[0];
12838 context->phantom_point_1_y = y_base[0];
12839 context->phantom_point_1_s = x_base[0];
12840 context->phantom_point_2_x = x_base[1];
12841 context->phantom_point_2_y = y_base[1];
12842 context->phantom_point_2_s = x_base[1];
12749 12843
12750 /* Free the zone if needed. */ 12844 /* Free the zone if needed. */
12751 if (zone_was_allocated) 12845 if (zone_was_allocated)
@@ -12792,12 +12886,8 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
12792 bool defer_offsets; 12886 bool defer_offsets;
12793 struct sfnt_instructed_outline *value; 12887 struct sfnt_instructed_outline *value;
12794 struct sfnt_glyph_metrics sub_metrics; 12888 struct sfnt_glyph_metrics sub_metrics;
12795 sfnt_f26dot6 phantom_point_1_x; 12889 sfnt_f26dot6 pp1x, pp1y, pp1s;
12796 sfnt_f26dot6 phantom_point_1_y; 12890 sfnt_f26dot6 pp2x, pp2y, pp2s;
12797 sfnt_f26dot6 phantom_point_2_x;
12798 sfnt_f26dot6 phantom_point_2_y;
12799 sfnt_f26dot6 phantom_point_1_s;
12800 sfnt_f26dot6 phantom_point_2_s;
12801 12891
12802 error = NULL; 12892 error = NULL;
12803 12893
@@ -12820,6 +12910,17 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
12820 /* Pacify -Wmaybe-uninitialized. */ 12910 /* Pacify -Wmaybe-uninitialized. */
12821 point = point2 = 0; 12911 point = point2 = 0;
12822 12912
12913 /* Compute phantom points for this glyph here. They will be
12914 subsequently overridden if a component glyph's metrics must be
12915 used instead. */
12916 sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
12917 &context->phantom_point_1_x,
12918 &context->phantom_point_1_y,
12919 &context->phantom_point_2_x,
12920 &context->phantom_point_2_y,
12921 &context->phantom_point_1_s,
12922 &context->phantom_point_2_s);
12923
12823 for (j = 0; j < glyph->compound->num_components; ++j) 12924 for (j = 0; j < glyph->compound->num_components; ++j)
12824 { 12925 {
12825 /* Look up the associated subglyph. */ 12926 /* Look up the associated subglyph. */
@@ -12939,8 +13040,8 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
12939 decomposition. */ 13040 decomposition. */
12940 13041
12941 if (sfnt_lookup_glyph_metrics (component->glyph_index, 13042 if (sfnt_lookup_glyph_metrics (component->glyph_index,
12942 -1, &sub_metrics, 13043 &sub_metrics, hmtx, hhea,
12943 hmtx, hhea, NULL, maxp)) 13044 maxp))
12944 { 13045 {
12945 if (need_free) 13046 if (need_free)
12946 free_glyph (subglyph, dcontext); 13047 free_glyph (subglyph, dcontext);
@@ -13044,6 +13145,27 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
13044 y = (ytemp - value->y_points[point2]); 13145 y = (ytemp - value->y_points[point2]);
13045 } 13146 }
13046 13147
13148 /* If USE_MY_METRICS is present in this component, save
13149 the instructed phantom points inside CONTEXT.
13150
13151 N.B. such points replace even the unrounded points
13152 within the context, as this distinction is lost in
13153 phantom points sourced from instructed glyphs. */
13154
13155 if (component->flags & 01000) /* USE_MY_METRICS */
13156 {
13157 context->phantom_point_1_x
13158 = context->phantom_point_1_s
13159 = value->x_points[last_point];
13160 context->phantom_point_1_y
13161 = value->y_points[last_point];
13162 context->phantom_point_2_x
13163 = context->phantom_point_2_s
13164 = value->x_points[last_point + 1];
13165 context->phantom_point_2_y
13166 = value->y_points[last_point + 1];
13167 }
13168
13047 xfree (value); 13169 xfree (value);
13048 13170
13049 /* Apply the transform to the points, excluding phantom 13171 /* Apply the transform to the points, excluding phantom
@@ -13055,7 +13177,17 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
13055 else 13177 else
13056 { 13178 {
13057 /* Compound subglyph. Decompose and instruct the glyph 13179 /* Compound subglyph. Decompose and instruct the glyph
13058 recursively, and then apply the transform. */ 13180 recursively, and then apply the transform.
13181
13182 If USE_MY_METRICS is not set, save the phantom points
13183 presently in CONTEXT, then restore them afterwards. */
13184
13185 pp1x = context->phantom_point_1_x;
13186 pp1y = context->phantom_point_1_y;
13187 pp1s = context->phantom_point_1_s;
13188 pp2x = context->phantom_point_2_x;
13189 pp2y = context->phantom_point_2_y;
13190 pp2s = context->phantom_point_2_s;
13059 13191
13060 error = sfnt_interpret_compound_glyph_1 (subglyph, interpreter, 13192 error = sfnt_interpret_compound_glyph_1 (subglyph, interpreter,
13061 state, 13193 state,
@@ -13073,6 +13205,16 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
13073 return error; 13205 return error;
13074 } 13206 }
13075 13207
13208 if (!(component->flags & 01000)) /* USE_MY_METRICS */
13209 {
13210 context->phantom_point_1_x = pp1x;
13211 context->phantom_point_1_y = pp1y;
13212 context->phantom_point_1_s = pp1s;
13213 context->phantom_point_2_x = pp2x;
13214 context->phantom_point_2_y = pp2y;
13215 context->phantom_point_2_s = pp2s;
13216 }
13217
13076 /* Anchor points for glyphs with instructions must be 13218 /* Anchor points for glyphs with instructions must be
13077 computed after grid fitting completes. 13219 computed after grid fitting completes.
13078 13220
@@ -13135,12 +13277,6 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
13135 should not contain phantom points by this point, so append the 13277 should not contain phantom points by this point, so append the
13136 points for this glyph as a whole. */ 13278 points for this glyph as a whole. */
13137 13279
13138 /* Compute phantom points. */
13139 sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
13140 &phantom_point_1_x, &phantom_point_1_y,
13141 &phantom_point_2_x, &phantom_point_2_y,
13142 &phantom_point_1_s, &phantom_point_2_s);
13143
13144 /* Grow various arrays to include those points. */ 13280 /* Grow various arrays to include those points. */
13145 rc = sfnt_expand_compound_glyph_context (context, 13281 rc = sfnt_expand_compound_glyph_context (context,
13146 /* Number of new contours 13282 /* Number of new contours
@@ -13153,10 +13289,10 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
13153 &flags_base, &contour_base); 13289 &flags_base, &contour_base);
13154 13290
13155 /* Store the phantom points within the compound glyph. */ 13291 /* Store the phantom points within the compound glyph. */
13156 x_base[0] = phantom_point_1_x; 13292 x_base[0] = context->phantom_point_1_x;
13157 x_base[1] = phantom_point_2_x; 13293 x_base[1] = context->phantom_point_2_x;
13158 y_base[0] = phantom_point_1_y; 13294 y_base[0] = context->phantom_point_1_y;
13159 y_base[1] = phantom_point_2_y; 13295 y_base[1] = context->phantom_point_2_y;
13160 flags_base[0] = SFNT_POINT_PHANTOM; 13296 flags_base[0] = SFNT_POINT_PHANTOM;
13161 flags_base[1] = SFNT_POINT_PHANTOM; 13297 flags_base[1] = SFNT_POINT_PHANTOM;
13162 13298
@@ -13167,8 +13303,8 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
13167 context, base_index, 13303 context, base_index,
13168 base_contour, 13304 base_contour,
13169 metrics, 13305 metrics,
13170 phantom_point_1_s, 13306 context->phantom_point_1_s,
13171 phantom_point_2_s); 13307 context->phantom_point_2_s);
13172 } 13308 }
13173 13309
13174 return error; 13310 return error;
@@ -16627,9 +16763,9 @@ sfnt_test_get_metrics (sfnt_glyph glyph, struct sfnt_glyph_metrics *metrics,
16627 struct sfnt_test_dcontext *tables; 16763 struct sfnt_test_dcontext *tables;
16628 16764
16629 tables = dcontext; 16765 tables = dcontext;
16630 return sfnt_lookup_glyph_metrics (glyph, -1, metrics, 16766 return sfnt_lookup_glyph_metrics (glyph, metrics,
16631 tables->hmtx, tables->hhea, 16767 tables->hmtx, tables->hhea,
16632 NULL, tables->maxp); 16768 tables->maxp);
16633} 16769}
16634 16770
16635static void 16771static void
@@ -20560,8 +20696,8 @@ main (int argc, char **argv)
20560 return 1; 20696 return 1;
20561 } 20697 }
20562 20698
20563#define FANCY_PPEM 12 20699#define FANCY_PPEM 30
20564#define EASY_PPEM 12 20700#define EASY_PPEM 30
20565 20701
20566 interpreter = NULL; 20702 interpreter = NULL;
20567 head = sfnt_read_head_table (fd, font); 20703 head = sfnt_read_head_table (fd, font);
@@ -20791,10 +20927,8 @@ main (int argc, char **argv)
20791 else 20927 else
20792 memset (&distortion, 0, sizeof distortion); 20928 memset (&distortion, 0, sizeof distortion);
20793 20929
20794 if (sfnt_lookup_glyph_metrics (code, -1, 20930 if (sfnt_lookup_glyph_metrics (code, &metrics,
20795 &metrics, 20931 hmtx, hhea, maxp))
20796 hmtx, hhea,
20797 head, maxp))
20798 exit (4); 20932 exit (4);
20799 20933
20800 interpreter->state = state; 20934 interpreter->state = state;
@@ -21053,7 +21187,15 @@ main (int argc, char **argv)
21053 printf ("variation failed!\n"); 21187 printf ("variation failed!\n");
21054 } 21188 }
21055 21189
21056 if (sfnt_decompose_glyph (glyph, sfnt_test_move_to, 21190 if (sfnt_lookup_glyph_metrics (code, &metrics,
21191 hmtx, hhea, maxp))
21192 {
21193 printf ("metrics lookup failure");
21194 memset (&metrics, 0, sizeof metrics);
21195 }
21196
21197 if (sfnt_decompose_glyph (glyph, &metrics,
21198 sfnt_test_move_to,
21057 sfnt_test_line_to, 21199 sfnt_test_line_to,
21058 sfnt_test_curve_to, 21200 sfnt_test_curve_to,
21059 sfnt_test_get_glyph, 21201 sfnt_test_get_glyph,
@@ -21062,10 +21204,8 @@ main (int argc, char **argv)
21062 &dcontext)) 21204 &dcontext))
21063 printf ("decomposition failure\n"); 21205 printf ("decomposition failure\n");
21064 21206
21065 if (sfnt_lookup_glyph_metrics (code, -1, 21207 if (sfnt_lookup_glyph_metrics (code, &metrics,
21066 &metrics, 21208 hmtx, hhea, maxp))
21067 hmtx, hhea,
21068 head, maxp))
21069 { 21209 {
21070 printf ("metrics lookup failure"); 21210 printf ("metrics lookup failure");
21071 memset (&metrics, 0, sizeof metrics); 21211 memset (&metrics, 0, sizeof metrics);
@@ -21145,13 +21285,19 @@ main (int argc, char **argv)
21145 21285
21146 if (hmtx && head) 21286 if (hmtx && head)
21147 { 21287 {
21148 if (!sfnt_lookup_glyph_metrics (code, EASY_PPEM, 21288 sfnt_scale_metrics (&metrics, scale);
21149 &metrics, 21289 printf ("scaled lbearing, advance: %g, %g\n",
21150 hmtx, hhea, 21290 sfnt_coerce_fixed (metrics.lbearing),
21151 head, maxp)) 21291 sfnt_coerce_fixed (metrics.advance));
21152 printf ("lbearing, advance: %g, %g\n", 21292
21153 sfnt_coerce_fixed (metrics.lbearing), 21293 if (!sfnt_lookup_glyph_metrics (code, &metrics, hmtx,
21154 sfnt_coerce_fixed (metrics.advance)); 21294 hhea, maxp))
21295 {
21296 sfnt_scale_metrics (&metrics, scale);
21297 printf ("lbearing, advance: %g, %g\n",
21298 sfnt_coerce_fixed (metrics.lbearing),
21299 sfnt_coerce_fixed (metrics.advance));
21300 }
21155 21301
21156 if (interpreter) 21302 if (interpreter)
21157 { 21303 {
@@ -21164,10 +21310,8 @@ main (int argc, char **argv)
21164 interpreter->pop_hook = sfnt_pop_hook; 21310 interpreter->pop_hook = sfnt_pop_hook;
21165 } 21311 }
21166 21312
21167 if (!sfnt_lookup_glyph_metrics (code, -1, 21313 if (!sfnt_lookup_glyph_metrics (code, &metrics,
21168 &metrics, 21314 hmtx, hhea, maxp))
21169 hmtx, hhea,
21170 head, maxp))
21171 { 21315 {
21172 printf ("interpreting glyph\n"); 21316 printf ("interpreting glyph\n");
21173 interpreter->state = state; 21317 interpreter->state = state;
diff --git a/src/sfnt.h b/src/sfnt.h
index 576d287e8e6..8f6d6bf427b 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -1524,11 +1524,10 @@ extern struct sfnt_raster *sfnt_raster_glyph_outline_exact (PROTOTYPE);
1524extern struct sfnt_hmtx_table *sfnt_read_hmtx_table (PROTOTYPE); 1524extern struct sfnt_hmtx_table *sfnt_read_hmtx_table (PROTOTYPE);
1525#undef PROTOTYPE 1525#undef PROTOTYPE
1526 1526
1527extern int sfnt_lookup_glyph_metrics (sfnt_glyph, int, 1527extern int sfnt_lookup_glyph_metrics (sfnt_glyph,
1528 struct sfnt_glyph_metrics *, 1528 struct sfnt_glyph_metrics *,
1529 struct sfnt_hmtx_table *, 1529 struct sfnt_hmtx_table *,
1530 struct sfnt_hhea_table *, 1530 struct sfnt_hhea_table *,
1531 struct sfnt_head_table *,
1532 struct sfnt_maxp_table *); 1531 struct sfnt_maxp_table *);
1533 1532
1534extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *, 1533extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *,
diff --git a/src/sfntfont.c b/src/sfntfont.c
index b20a7c91115..04caf77e72a 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -2115,9 +2115,8 @@ sfntfont_get_metrics (sfnt_glyph glyph, struct sfnt_glyph_metrics *metrics,
2115 struct sfntfont_get_glyph_outline_dcontext *tables; 2115 struct sfntfont_get_glyph_outline_dcontext *tables;
2116 2116
2117 tables = dcontext; 2117 tables = dcontext;
2118 return sfnt_lookup_glyph_metrics (glyph, -1, metrics, 2118 return sfnt_lookup_glyph_metrics (glyph, metrics, tables->hmtx,
2119 tables->hmtx, tables->hhea, 2119 tables->hhea, tables->maxp);
2120 NULL, tables->maxp);
2121} 2120}
2122 2121
2123/* Dereference the outline OUTLINE. Free it once refcount reaches 2122/* Dereference the outline OUTLINE. Free it once refcount reaches
@@ -2253,8 +2252,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
2253 2252
2254 /* Now load the glyph's unscaled metrics into TEMP. */ 2253 /* Now load the glyph's unscaled metrics into TEMP. */
2255 2254
2256 if (sfnt_lookup_glyph_metrics (glyph_code, -1, &temp, hmtx, hhea, 2255 if (sfnt_lookup_glyph_metrics (glyph_code, &temp, hmtx, hhea, maxp))
2257 head, maxp))
2258 goto fail; 2256 goto fail;
2259 2257
2260 if (interpreter) 2258 if (interpreter)
@@ -2312,6 +2310,8 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
2312 2310
2313 if (!outline) 2311 if (!outline)
2314 { 2312 {
2313 /* Build the outline. This will apply GX offsets within *GLYPH
2314 to TEMP. */
2315 outline = sfnt_build_glyph_outline (glyph, scale, 2315 outline = sfnt_build_glyph_outline (glyph, scale,
2316 &temp, 2316 &temp,
2317 sfntfont_get_glyph, 2317 sfntfont_get_glyph,
@@ -2319,22 +2319,9 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
2319 sfntfont_get_metrics, 2319 sfntfont_get_metrics,
2320 &dcontext); 2320 &dcontext);
2321 2321
2322 /* Add the advance width distortion, which is not applied to
2323 glyph metrics in advance of their being instructed, and thus
2324 has to be applied before the metrics are. */
2325 temp.advance += distortion.advance;
2326
2327 /* At this point, the glyph metrics are unscaled. Scale them 2322 /* At this point, the glyph metrics are unscaled. Scale them
2328 up. If INTERPRETER is set, use the scale placed within. */ 2323 up. If INTERPRETER is set, use the scale placed within. */
2329 sfnt_scale_metrics (&temp, scale); 2324 sfnt_scale_metrics (&temp, scale);
2330
2331 /* Finally, adjust the left side bearing of the glyph metrics by
2332 the origin point of the outline, should a transformation have
2333 been applied by either instruction code or glyph variation.
2334 The left side bearing is the distance from the origin point
2335 to the left most point on the X axis. */
2336 if (index != -1)
2337 temp.lbearing = outline->xmin - outline->origin;
2338 } 2325 }
2339 2326
2340 fail: 2327 fail: