[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 15e498047f8 1/2: Update Android port
From: |
Po Lu |
Subject: |
master 15e498047f8 1/2: Update Android port |
Date: |
Sun, 20 Aug 2023 00:48:21 -0400 (EDT) |
branch: master
commit 15e498047f8d37526e0c361e369e5f06c4712db3
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Update Android port
* src/sfnt.c (sfnt_decompose_compound_glyph): New argument
GET_METRICS. Call this function to retrieve glyph metrics used
to compute phantom points when a component glyph's anchor point
is one.
(sfnt_decompose_glyph, sfnt_build_glyph_outline): Plumb
GET_METRICS these two functions.
(sfnt_interpret_shc): Don't shift the provided reference point.
(sfnt_transform_f26dot6): Eschew looping through X and Y if no
offsets are provided.
(sfnt_interpret_compound_glyph_2): Discontinue initializing
phantom points here.
(sfnt_interpret_compound_glyph_1): Do not incorporate phantom
points into the ultimately produced glyph outline. Correctly
provide for phantom childanchor points.
(sfnt_test_get_metrics, main): Update tests.
* src/sfnt.h: Update prototypes.
* src/sfntfont.c (struct sfntfont_get_glyph_outline_dcontext):
New fields `hmtx', `hhea' and `maxp'.
(sfntfont_get_metrics): New function.
(sfntfont_get_glyph_outline): Provide new tables and the new
callback function.
---
src/sfnt.c | 328 ++++++++++++++++++++++++++++++++++++++++++---------------
src/sfnt.h | 7 ++
src/sfntfont.c | 27 +++++
3 files changed, 279 insertions(+), 83 deletions(-)
diff --git a/src/sfnt.c b/src/sfnt.c
index 5cea2613ddb..14e353013cd 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -2629,8 +2629,9 @@ sfnt_round_fixed (int32_t number)
contours.
CONTEXT should be zeroed and put on the stack. RECURSION_COUNT
- should be initialized to 0. GET_GLYPH and FREE_GLYPH, along with
- DCONTEXT, mean the same as in sfnt_decompose_glyph.
+ should be initialized to 0. GET_GLYPH, FREE_GLYPH, and
+ GET_METRICS, along with DCONTEXT, mean the same as in
+ sfnt_decompose_glyph.
Value is 1 upon failure, else 0. */
@@ -2639,6 +2640,7 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
struct sfnt_compound_glyph_context *context,
sfnt_get_glyph_proc get_glyph,
sfnt_free_glyph_proc free_glyph,
+ sfnt_get_metrics_proc get_metrics,
int recursion_count,
void *dcontext)
{
@@ -2654,6 +2656,8 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
unsigned char *flags_base;
size_t base_index, contour_start;
bool defer_offsets;
+ struct sfnt_glyph_metrics sub_metrics;
+ sfnt_fixed f1, f2;
/* Set up the base index. This is the index from where on point
renumbering starts.
@@ -2756,6 +2760,42 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
{
if (point2 >= subglyph->simple->number_of_points)
{
+ if (point2 < subglyph->simple->number_of_points + 2)
+ {
+ /* POINT2 is one of SUBGLYPH's phantom points.
+ Retrieve the glyph's metrics. */
+
+ if ((*get_metrics) (component->glyph_index, &sub_metrics,
+ dcontext))
+ {
+ if (need_free)
+ free_glyph (subglyph, dcontext);
+
+ return 1;
+ }
+
+ /* Derive the phantom points from those metrics. */
+ f1 = glyph->xmin - sub_metrics.lbearing;
+ f2 = f1 + sub_metrics.advance;
+
+ /* Apply the metrics distortion. */
+ f1 += glyph->origin_distortion;
+ f2 += glyph->advance_distortion;
+
+ /* Get the points and use them to compute the offsets. */
+
+ if (!(point2 - subglyph->simple->number_of_points))
+ x = f1 * 65536;
+ else
+ x = f2 * 65536;
+
+ x = context->x_coordinates[point] - x;
+ y = context->y_coordinates[point];
+
+ /* X and Y offsets have been ascertained. */
+ goto skip_computation;
+ }
+
if (need_free)
free_glyph (subglyph, dcontext);
@@ -2767,6 +2807,9 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
ytemp = context->y_coordinates[point];
x = (xtemp - subglyph->simple->x_coordinates[point2] * 65536);
y = (ytemp - subglyph->simple->y_coordinates[point2] * 65536);
+
+ skip_computation:
+ ;
}
else
{
@@ -2842,6 +2885,7 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
context,
get_glyph,
free_glyph,
+ get_metrics,
recursion_count + 1,
dcontext);
@@ -2879,6 +2923,38 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
if (point2 >= context->num_points)
{
+ /* POINT2 might fall within the phantom points of
+ that glyph. */
+
+ if (point2 - context->num_points < 2)
+ {
+ if ((*get_metrics) (component->glyph_index, &sub_metrics,
+ dcontext))
+ goto error_in_defer_offsets;
+
+ /* Derive the phantom points from those metrics. */
+ f1 = glyph->xmin - sub_metrics.lbearing;
+ f2 = f1 + sub_metrics.advance;
+
+ /* Apply the metrics distortion. */
+ f1 += glyph->origin_distortion;
+ f2 += glyph->advance_distortion;
+
+ /* Get the points and use them to compute the offsets. */
+
+ if (!(point2 - context->num_points))
+ x = f1 * 65536;
+ else
+ x = f2 * 65536;
+
+ x = context->x_coordinates[point] - x;
+ y = context->y_coordinates[point];
+
+ /* X and Y offsets have been ascertained. */
+ goto skip_computation_from_defer_offsets;
+ }
+
+ error_in_defer_offsets:
if (need_free)
free_glyph (subglyph, dcontext);
@@ -2892,12 +2968,15 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
ytemp = context->y_coordinates[point];
x = (xtemp - context->x_coordinates[point2]);
y = (ytemp - context->y_coordinates[point2]);
+
+ skip_computation_from_defer_offsets:
+ ;
}
sfnt_transform_coordinates (component,
context->x_coordinates + contour_start,
context->y_coordinates + contour_start,
- contour_start - context->num_points,
+ context->num_points - contour_start,
x, y);
}
@@ -3204,7 +3283,10 @@ sfnt_decompose_glyph_2 (size_t here, size_t last,
If GLYPH is compound, use GET_GLYPH to obtain subglyphs. PROC must
return whether or not FREE_GLYPH will be called with the glyph
- after sfnt_decompose_glyph is done with it.
+ after sfnt_decompose_glyph is done with it. If GLYPH moreover
+ incorporates components whose anchor points are phantom points, use
+ GET_METRICS to obtain glyph metrics prerequisite for establishing
+ their coordinates.
All functions will be called with DCONTEXT as an argument.
@@ -3222,6 +3304,7 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
sfnt_curve_to_proc curve_to,
sfnt_get_glyph_proc get_glyph,
sfnt_free_glyph_proc free_glyph,
+ sfnt_get_metrics_proc get_metrics,
void *dcontext)
{
size_t here, last, n;
@@ -3269,7 +3352,8 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
if (sfnt_decompose_compound_glyph (glyph, &context,
get_glyph, free_glyph,
- 0, dcontext))
+ get_metrics, 0,
+ dcontext))
{
xfree (context.x_coordinates);
xfree (context.y_coordinates);
@@ -3833,7 +3917,8 @@ sfnt_curve_to_and_build (struct sfnt_point control,
outline.
Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain
- glyphs for compound glyph subcomponents. */
+ glyphs for compound glyph subcomponents, and GET_METRICS with the
+ provided DCONTEXT for unscaled glyph metrics. */
TEST_STATIC struct sfnt_glyph_outline *
sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
@@ -3841,6 +3926,7 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
struct sfnt_glyph_metrics *metrics,
sfnt_get_glyph_proc get_glyph,
sfnt_free_glyph_proc free_glyph,
+ sfnt_get_metrics_proc get_metrics,
void *dcontext)
{
struct sfnt_glyph_outline *outline;
@@ -3875,7 +3961,8 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build,
sfnt_line_to_and_build,
sfnt_curve_to_and_build,
- get_glyph, free_glyph, dcontext);
+ get_glyph, free_glyph, get_metrics,
+ dcontext);
/* Synchronize the outline object with what might have changed
inside sfnt_decompose_glyph. */
@@ -9720,7 +9807,8 @@ sfnt_interpret_shc (struct sfnt_interpreter *interpreter,
{
sfnt_f26dot6 x, y, original_x, original_y;
sfnt_f26dot6 magnitude;
- size_t start, end, n;
+ uint16_t reference_point;
+ size_t start, end, start1, end1, n;
if (!interpreter->glyph_zone)
TRAP ("SHC without glyph zone");
@@ -9733,10 +9821,12 @@ sfnt_interpret_shc (struct sfnt_interpreter
*interpreter,
projection vector. */
if (opcode == 0x35)
- sfnt_address_zp0 (interpreter, interpreter->state.rp1,
+ sfnt_address_zp0 (interpreter,
+ (reference_point = interpreter->state.rp1),
&x, &y, &original_x, &original_y);
else
- sfnt_address_zp1 (interpreter, interpreter->state.rp2,
+ sfnt_address_zp1 (interpreter,
+ (reference_point = interpreter->state.rp2),
&x, &y, &original_x, &original_y);
magnitude = sfnt_project_vector (interpreter,
@@ -9747,7 +9837,7 @@ sfnt_interpret_shc (struct sfnt_interpreter *interpreter,
Verify that both are valid. */
if (contour)
- start = interpreter->glyph_zone->contour_end_points[contour - 1];
+ start = interpreter->glyph_zone->contour_end_points[contour - 1] + 1;
else
start = 0;
@@ -9756,6 +9846,31 @@ sfnt_interpret_shc (struct sfnt_interpreter *interpreter,
if (start > end || end >= interpreter->glyph_zone->num_points)
TRAP ("invalid contour data in glyph");
+ /* If the reference point falls between end and start, split the
+ range formed by end and start at the reference point and keep the
+ latter intact. */
+
+ if (start <= reference_point && reference_point <= end)
+ {
+ /* Do the points between start and rpN. */
+ start1 = start;
+ end1 = reference_point - 1;
+
+ if (start1 <= end1)
+ sfnt_move_glyph_zone (interpreter, start1,
+ end1 - start1 + 1, magnitude);
+
+ /* Now the points between rpN + 1 and end. */
+ start1 = reference_point + 1;
+ end1 = end;
+
+ if (start1 <= end1)
+ sfnt_move_glyph_zone (interpreter, start1,
+ end1 - start1 + 1, magnitude);
+
+ return;
+ }
+
/* Compute the number of points to move. */
n = end - start + 1;
@@ -11378,8 +11493,11 @@ sfnt_transform_f26dot6 (struct
sfnt_compound_glyph_component *component,
}
else /* No scale, just apply x_off and y_off. */
{
- for (i = 0; i < num_coordinates; ++i)
- x[i] += x_off, y[i] += y_off;
+ if (x_off || y_off)
+ {
+ for (i = 0; i < num_coordinates; ++i)
+ x[i] += x_off, y[i] += y_off;
+ }
return;
}
@@ -11421,6 +11539,8 @@ sfnt_transform_f26dot6 (struct
sfnt_compound_glyph_component *component,
CONTEXT contains the points and contours of this compound glyph,
numbered starting from BASE_INDEX and BASE_CONTOUR respectively.
+ In addition, CONTEXT also contains two additional ``phantom
+ points'' supplying the left and right side bearings of GLYPH.
Value is NULL upon success, or a description of the error upon
failure. */
@@ -11436,10 +11556,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph
*glyph,
size_t zone_size, temp;
struct sfnt_interpreter_zone *zone;
struct sfnt_interpreter_zone *volatile preserved_zone;
- sfnt_f26dot6 phantom_point_1_x;
- sfnt_f26dot6 phantom_point_1_y;
- sfnt_f26dot6 phantom_point_2_x;
- sfnt_f26dot6 phantom_point_2_y;
volatile bool zone_was_allocated;
int rc;
sfnt_f26dot6 *x_base, *y_base;
@@ -11487,7 +11603,7 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph
*glyph,
}
/* Now load the zone with data. */
- zone->num_points = num_points + 2;
+ zone->num_points = num_points;
zone->num_contours = num_contours;
zone->contour_end_points = (size_t *) (zone + 1);
zone->x_points = (sfnt_f26dot6 *) (zone->contour_end_points
@@ -11514,17 +11630,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph
*glyph,
zone->x_points[i] = context->x_coordinates[i + base_index];
}
- /* Compute phantom points. */
- sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
- &phantom_point_1_x, &phantom_point_1_y,
- &phantom_point_2_x, &phantom_point_2_y);
-
- /* Load phantom points. */
- zone->x_points[i] = phantom_point_1_x;
- zone->x_points[i + 1] = phantom_point_2_x;
- zone->x_current[i] = phantom_point_1_x;
- zone->x_current[i + 1] = phantom_point_2_x;
-
for (i = 0; i < num_points; ++i)
{
zone->y_current[i] = context->y_coordinates[i + base_index];
@@ -11535,16 +11640,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph
*glyph,
& ~SFNT_POINT_TOUCHED_BOTH);
}
- /* Load phantom points. */
- zone->y_points[i] = phantom_point_1_y;
- zone->y_points[i + 1] = phantom_point_2_y;
- zone->y_current[i] = phantom_point_1_x;
- zone->y_current[i + 1] = phantom_point_2_x;
-
- /* Load phantom point flags. */
- zone->flags[i] = SFNT_POINT_PHANTOM;
- zone->flags[i + 1] = SFNT_POINT_PHANTOM;
-
/* Load the compound glyph program. */
interpreter->IP = 0;
interpreter->SP = interpreter->stack;
@@ -11646,6 +11741,10 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
bool defer_offsets;
struct sfnt_instructed_outline *value;
struct sfnt_glyph_metrics sub_metrics;
+ sfnt_f26dot6 phantom_point_1_x;
+ sfnt_f26dot6 phantom_point_1_y;
+ sfnt_f26dot6 phantom_point_2_x;
+ sfnt_f26dot6 phantom_point_2_y;
error = NULL;
@@ -11758,36 +11857,22 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
if (!subglyph->compound)
{
- if (point2 >= subglyph->simple->number_of_points)
+ if (point2 >= subglyph->simple->number_of_points + 2)
{
+ /* If POINT2 is placed within a phantom point, use
+ that. */
+
if (need_free)
free_glyph (subglyph, dcontext);
return "Invalid component anchor point";
}
- /* Get the points and use them to compute the offsets. */
- xtemp = context->x_coordinates[point];
- ytemp = context->y_coordinates[point];
-
- /* Convert the unscaled coordinates within
- SIMPLE->x_coordinates to device space. */
- x = subglyph->simple->x_coordinates[point2];
- y = subglyph->simple->y_coordinates[point2];
- x = sfnt_mul_f26dot6_fixed (x * 64, interpreter->scale);
- y = sfnt_mul_f26dot6_fixed (y * 64, interpreter->scale);
-
- /* Derive the X and Y offsets from the difference
- between the reference point's position and the anchor
- point's. */
- x = xtemp - x;
- y = ytemp - y;
- }
- else
- {
/* First, set offsets to 0, because it is not yet
- possible to determine the position of the anchor
- point in the child. */
+ possible to ascertain the position of the anchor
+ point in the child. That position cannot be
+ established prior to the completion of
+ grid-fitting. */
x = 0;
y = 0;
@@ -11837,10 +11922,12 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
}
/* Figure out how many more points and contours are
- needed. Here, last_point is not the end of the
- glyph's contours, as two phantom points are
- included. */
- last_point = value->num_points;
+ needed. While phantom points are not included within
+ the outline ultimately produced, they are temporarily
+ appended to the outline here, so as to enable
+ defer_offsets below to refer to them. */
+ assert (value->num_points >= 2);
+ last_point = value->num_points - 2;
number_of_contours = value->num_contours;
/* Grow various arrays. */
@@ -11882,9 +11969,33 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
contour_base[i] = (contour_start
+ value->contour_end_points[i]);
+ /* Establish offsets for anchor points here. It is
+ possible for glyph anchors to be set to phantom
+ points, whose coordinates cannot be established until
+ grid fitting completes. */
+
+ if (defer_offsets)
+ {
+ x = 0;
+ y = 0;
+
+ /* Assert the child anchor is within the confines of
+ the zone. */
+ assert (point2 < value->num_points);
+
+ /* Get the points and use them to compute the
+ offsets. */
+
+ xtemp = context->x_coordinates[point];
+ ytemp = context->y_coordinates[point];
+ x = (xtemp - value->x_points[point2]);
+ y = (ytemp - value->y_points[point2]);
+ }
+
xfree (value);
- /* Apply the transform to the points. */
+ /* Apply the transform to the points, excluding phantom
+ points within. */
sfnt_transform_f26dot6 (component, x_base, y_base,
last_point, x, y);
}
@@ -11910,22 +12021,19 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
return error;
}
- /* When an anchor point is being used to translate the
- glyph, and the subglyph in question is actually a
- compound glyph, it is impossible to know which offset to
- use until the compound subglyph has actually been
- loaded.
+ /* Anchor points for glyphs with instructions must be
+ computed after grid fitting completes.
- As a result, the offset is calculated here, using the
- points in the loaded child compound glyph. But first, X
- and Y must be reset to 0, as otherwise the translation
- might be applied twice if defer_offsets is not set. */
-
- x = 0;
- y = 0;
+ As such, the offset is calculated here, using the points
+ in the loaded child compound glyph. At present, CONTEXT
+ incorporates the two phantom points after the end of the
+ last component within SUBGLYPH. */
if (defer_offsets)
{
+ x = 0;
+ y = 0;
+
/* Renumber the non renumbered point2 to point into the
decomposed component. */
point2 += contour_start;
@@ -11939,7 +12047,7 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
if (need_free)
free_glyph (subglyph, dcontext);
- return "Invalid point2";
+ return "Invalid anchor reference point";
}
/* Get the points and use them to compute the
@@ -11951,10 +12059,18 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
y = (ytemp - context->y_coordinates[point2]);
}
+ /* Subtract the two phantom points from context->num_points.
+ This behavior is correct, as only the subglyph's phantom
+ points may be provided as anchor points. */
+ assert (context->num_points - contour_start >= 2);
+ context->num_points -= 2;
+
sfnt_transform_f26dot6 (component,
context->x_coordinates + contour_start,
context->y_coordinates + contour_start,
- contour_start - context->num_points,
+ /* Exclude phantom points from
+ transformations. */
+ context->num_points - contour_start,
x, y);
}
@@ -11963,7 +12079,33 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph
*glyph,
free_glyph (subglyph, dcontext);
}
- /* Run the program for the entire compound glyph, if any. */
+ /* Run the program for the entire compound glyph, if any. CONTEXT
+ should not contain phantom points by this point, so append its
+ own. */
+
+ /* Compute phantom points. */
+ sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
+ &phantom_point_1_x, &phantom_point_1_y,
+ &phantom_point_2_x, &phantom_point_2_y);
+
+ /* Grow various arrays to include those points. */
+ rc = sfnt_expand_compound_glyph_context (context,
+ /* Number of new contours
+ required. */
+ 0,
+ /* Number of new points
+ required. */
+ 2,
+ &x_base, &y_base,
+ &flags_base, &contour_base);
+
+ /* Store the phantom points within the compound glyph. */
+ x_base[0] = phantom_point_1_x;
+ x_base[1] = phantom_point_2_x;
+ y_base[0] = phantom_point_1_y;
+ y_base[1] = phantom_point_2_y;
+ flags_base[0] = SFNT_POINT_PHANTOM;
+ flags_base[1] = SFNT_POINT_PHANTOM;
if (glyph->compound->instruction_length)
{
@@ -15115,6 +15257,9 @@ struct sfnt_test_dcontext
struct sfnt_glyf_table *glyf;
struct sfnt_loca_table_short *loca_short;
struct sfnt_loca_table_long *loca_long;
+ struct sfnt_hmtx_table *hmtx;
+ struct sfnt_hhea_table *hhea;
+ struct sfnt_maxp_table *maxp;
struct sfnt_blend *blend;
};
@@ -15181,6 +15326,18 @@ sfnt_test_free_glyph (struct sfnt_glyph *glyph, void
*dcontext)
sfnt_free_glyph (glyph);
}
+static int
+sfnt_test_get_metrics (sfnt_glyph glyph, struct sfnt_glyph_metrics *metrics,
+ void *dcontext)
+{
+ struct sfnt_test_dcontext *tables;
+
+ tables = dcontext;
+ return sfnt_lookup_glyph_metrics (glyph, -1, metrics,
+ tables->hmtx, tables->hhea,
+ NULL, tables->maxp);
+}
+
static void
sfnt_test_span (struct sfnt_edge *edge, sfnt_fixed y,
void *dcontext)
@@ -19074,8 +19231,8 @@ main (int argc, char **argv)
return 1;
}
-#define FANCY_PPEM 12
-#define EASY_PPEM 12
+#define FANCY_PPEM 18
+#define EASY_PPEM 18
interpreter = NULL;
head = sfnt_read_head_table (fd, font);
@@ -19513,6 +19670,9 @@ main (int argc, char **argv)
dcontext.glyf = glyf;
dcontext.loca_short = loca_short;
dcontext.loca_long = loca_long;
+ dcontext.hmtx = hmtx;
+ dcontext.hhea = hhea;
+ dcontext.maxp = maxp;
if (instance && gvar)
dcontext.blend = &blend;
@@ -19549,6 +19709,7 @@ main (int argc, char **argv)
sfnt_test_curve_to,
sfnt_test_get_glyph,
sfnt_test_free_glyph,
+ sfnt_test_get_metrics,
&dcontext))
printf ("decomposition failure\n");
@@ -19567,6 +19728,7 @@ main (int argc, char **argv)
&metrics,
sfnt_test_get_glyph,
sfnt_test_free_glyph,
+ sfnt_test_get_metrics,
&dcontext);
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
diff --git a/src/sfnt.h b/src/sfnt.h
index 6f93393c1d3..0fb67e918a6 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -688,9 +688,15 @@ typedef void (*sfnt_curve_to_proc) (struct sfnt_point,
struct sfnt_point,
void *);
+/* Forward declaration for use in sfnt_get_metrics_proc. */
+struct sfnt_glyph_metrics;
+
typedef struct sfnt_glyph *(*sfnt_get_glyph_proc) (sfnt_glyph, void *,
bool *);
typedef void (*sfnt_free_glyph_proc) (struct sfnt_glyph *, void *);
+typedef int (*sfnt_get_metrics_proc) (sfnt_glyph,
+ struct sfnt_glyph_metrics *,
+ void *);
@@ -1372,6 +1378,7 @@ extern void sfnt_free_glyph (struct sfnt_glyph *);
struct sfnt_glyph_metrics *, \
sfnt_get_glyph_proc, \
sfnt_free_glyph_proc, \
+ sfnt_get_metrics_proc, \
void *
extern struct sfnt_glyph_outline *sfnt_build_glyph_outline (PROTOTYPE);
#undef PROTOTYPE
diff --git a/src/sfntfont.c b/src/sfntfont.c
index 531622f84df..c48339b6b66 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -1943,6 +1943,11 @@ struct sfntfont_get_glyph_outline_dcontext
/* glyf table. */
struct sfnt_glyf_table *glyf;
+ /* hmtx, hhea and maxp tables utilized to acquire glyph metrics. */
+ struct sfnt_hmtx_table *hmtx;
+ struct sfnt_hhea_table *hhea;
+ struct sfnt_maxp_table *maxp;
+
/* Variation settings, or NULL. */
struct sfnt_blend *blend;
};
@@ -1987,6 +1992,23 @@ sfntfont_free_glyph (struct sfnt_glyph *glyph, void
*dcontext)
sfnt_free_glyph (glyph);
}
+/* Return unscaled glyph metrics for the glyph designated by the ID
+ GLYPH within *METRICS, utilizing tables within DCONTEXT.
+
+ Value is 1 upon failure, 0 otherwise. */
+
+static int
+sfntfont_get_metrics (sfnt_glyph glyph, struct sfnt_glyph_metrics *metrics,
+ void *dcontext)
+{
+ struct sfntfont_get_glyph_outline_dcontext *tables;
+
+ tables = dcontext;
+ return sfnt_lookup_glyph_metrics (glyph, -1, metrics,
+ tables->hmtx, tables->hhea,
+ NULL, tables->maxp);
+}
+
/* Dereference the outline OUTLINE. Free it once refcount reaches
0. */
@@ -2112,6 +2134,9 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
dcontext.loca_long = loca_long;
dcontext.loca_short = loca_short;
dcontext.glyf = glyf;
+ dcontext.hhea = hhea;
+ dcontext.hmtx = hmtx;
+ dcontext.maxp = maxp;
dcontext.blend = (index != -1 ? blend : NULL);
/* Now load the glyph's unscaled metrics into TEMP. */
@@ -2160,12 +2185,14 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
&temp,
sfntfont_get_glyph,
sfntfont_free_glyph,
+ sfntfont_get_metrics,
&dcontext);
else
outline = sfnt_build_glyph_outline (glyph, scale,
&temp,
sfntfont_get_glyph,
sfntfont_free_glyph,
+ sfntfont_get_metrics,
&dcontext);
}