diff options
| -rw-r--r-- | src/sfnt.c | 300 | ||||
| -rw-r--r-- | src/sfnt.h | 3 | ||||
| -rw-r--r-- | src/sfntfont.c | 23 |
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 | ||
| 2709 | static int | 2724 | static int |
| 2710 | sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph, | 2725 | sfnt_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 | ||
| 3368 | static int | 3447 | static int |
| 3369 | sfnt_decompose_glyph (struct sfnt_glyph *glyph, | 3448 | sfnt_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 | ||
| 5608 | TEST_STATIC int | 5710 | TEST_STATIC int |
| 5609 | sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size, | 5711 | sfnt_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 | ||
| 16635 | static void | 16771 | static 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); | |||
| 1524 | extern struct sfnt_hmtx_table *sfnt_read_hmtx_table (PROTOTYPE); | 1524 | extern struct sfnt_hmtx_table *sfnt_read_hmtx_table (PROTOTYPE); |
| 1525 | #undef PROTOTYPE | 1525 | #undef PROTOTYPE |
| 1526 | 1526 | ||
| 1527 | extern int sfnt_lookup_glyph_metrics (sfnt_glyph, int, | 1527 | extern 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 | ||
| 1534 | extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *, | 1533 | extern 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: |