]> git.eshelyaron.com Git - emacs.git/commitdiff
Update Android port
authorPo Lu <luangruo@yahoo.com>
Sun, 20 Aug 2023 04:44:38 +0000 (12:44 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 20 Aug 2023 04:48:03 +0000 (12:48 +0800)
* 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
src/sfnt.h
src/sfntfont.c

index 5cea2613ddbd5ada273cf426adcfa6bdb0f561ea..14e353013cd2631c341014e2f3bdf819dfe665e9 100644 (file)
@@ -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);
index 6f93393c1d38c71b3b1e3e06e1c75d0b3b1963e6..0fb67e918a66b4be07282a9028cc768839a28093 100644 (file)
@@ -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 *);
 
 \f
 
@@ -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
index 531622f84df4111d8d3420160d5b075ee45e8895..c48339b6b66ace6c33a7167ecf75c1728d283a93 100644 (file)
@@ -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);
     }