summaryrefslogtreecommitdiff
path: root/src/sfnt.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-12-23 11:22:21 +0800
committerPo Lu <luangruo@yahoo.com>2023-12-23 11:22:21 +0800
commit9aea075f5fd6e1d6b7f6d7fe35de8f3da752c3e7 (patch)
tree92c0862ae15042ef5f21d3d1b60de9e3b405b83f /src/sfnt.c
parente84493eae91f9d94902844ef6e8fb296bde72ca7 (diff)
downloademacs-9aea075f5fd6e1d6b7f6d7fe35de8f3da752c3e7.tar.gz
Respect glyph metrics modified by instruction code
* src/sfnt.c (sfnt_read_glyph): Clear advance and origin distortion returning an empty glyph. (sfnt_build_instructed_outline): New parameter *ADVANCE_WIDTH, in which the glyph's advance width is saved. (sfnt_interpret_compound_glyph_1): Refine commentary. (sfnt_verbose, main): Adjust tests. * src/sfnt.h: Update prototypes correspondingly. * src/sfntfont.c (sfntfont_get_glyph_outline): If an instructed outline is available, derive the advance and lbearing from the measurements within. (sfntfont_probe_widths): Call sfntfont_measure_pcm to establish average widths. (sfntfont_open): Do so after instruction code initialization completes. (sfntfont_measure_pcm): Revise commentary.
Diffstat (limited to 'src/sfnt.c')
-rw-r--r--src/sfnt.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index 1397e341aa8..6698c9c27df 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -2421,6 +2421,8 @@ sfnt_read_glyph (sfnt_glyph glyph_code,
glyph.ymin = 0;
glyph.xmax = 0;
glyph.ymax = 0;
+ glyph.advance_distortion = 0;
+ glyph.origin_distortion = 0;
glyph.simple = xmalloc (sizeof *glyph.simple);
glyph.compound = NULL;
memset (glyph.simple, 0, sizeof *glyph.simple);
@@ -12202,15 +12204,18 @@ sfnt_decompose_instructed_outline (struct sfnt_instructed_outline *outline,
/* Decompose and build an outline for the specified instructed outline
INSTRUCTED. Return the outline data with a refcount of 0 upon
- success, or NULL upon failure.
+ success, and the advance width of the instructed glyph in
+ *ADVANCE_WIDTH, or NULL upon failure.
This function is not reentrant. */
TEST_STATIC struct sfnt_glyph_outline *
-sfnt_build_instructed_outline (struct sfnt_instructed_outline *instructed)
+sfnt_build_instructed_outline (struct sfnt_instructed_outline *instructed,
+ sfnt_fixed *advance_width)
{
struct sfnt_glyph_outline *outline;
int rc;
+ sfnt_f26dot6 x1, x2;
memset (&build_outline_context, 0, sizeof build_outline_context);
@@ -12247,10 +12252,23 @@ sfnt_build_instructed_outline (struct sfnt_instructed_outline *instructed)
instructed. */
if (instructed->num_points > 1)
- outline->origin
- = instructed->x_points[instructed->num_points - 2];
+ {
+ x1 = instructed->x_points[instructed->num_points - 2];
+ x2 = instructed->x_points[instructed->num_points - 1];
+
+ /* Convert the origin point to a 16.16 fixed point number. */
+ outline->origin = x1 * 1024;
+
+ /* Do the same for the advance width. */
+ *advance_width = (x2 - x1) * 1024;
+ }
else
- outline->origin = 0;
+ {
+ /* Phantom points are absent from this outline, which is
+ impossible. */
+ *advance_width = 0;
+ outline->origin = 0;
+ }
if (rc)
{
@@ -13133,8 +13151,8 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
}
/* Run the program for the entire compound glyph, if any. CONTEXT
- should not contain phantom points by this point, so append its
- own. */
+ should not contain phantom points by this point, so append the
+ points for this glyph as a whole. */
/* Compute phantom points. */
sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
@@ -20216,6 +20234,7 @@ sfnt_verbose (struct sfnt_interpreter *interpreter)
unsigned char opcode;
const char *name;
static unsigned int instructions;
+ sfnt_fixed advance;
/* Build a temporary outline containing the values of the
interpreter's glyph zone. */
@@ -20229,7 +20248,7 @@ sfnt_verbose (struct sfnt_interpreter *interpreter)
temp.y_points = interpreter->glyph_zone->y_current;
temp.flags = interpreter->glyph_zone->flags;
- outline = sfnt_build_instructed_outline (&temp);
+ outline = sfnt_build_instructed_outline (&temp, &advance);
if (!outline)
return;
@@ -20444,6 +20463,7 @@ main (int argc, char **argv)
struct sfnt_instance *instance;
struct sfnt_blend blend;
struct sfnt_metrics_distortion distortion;
+ sfnt_fixed advance;
if (argc < 2)
return 1;
@@ -20559,8 +20579,8 @@ main (int argc, char **argv)
return 1;
}
-#define FANCY_PPEM 14
-#define EASY_PPEM 14
+#define FANCY_PPEM 12
+#define EASY_PPEM 12
interpreter = NULL;
head = sfnt_read_head_table (fd, font);
@@ -20787,6 +20807,8 @@ main (int argc, char **argv)
if (instance && gvar)
sfnt_vary_simple_glyph (&blend, code, glyph,
&distortion);
+ else
+ memset (&distortion, 0, sizeof distortion);
if (sfnt_lookup_glyph_metrics (code, -1,
&metrics,
@@ -20804,7 +20826,10 @@ main (int argc, char **argv)
exit (5);
}
- outline = sfnt_build_instructed_outline (value);
+ outline = sfnt_build_instructed_outline (value, &advance);
+ advances[i] = (advance / 65536);
+
+ fprintf (stderr, "advance: %d\n", advances[i]);
if (!outline)
exit (6);
@@ -20819,8 +20844,6 @@ main (int argc, char **argv)
xfree (outline);
rasters[i] = raster;
- advances[i] = (sfnt_mul_fixed (metrics.advance, scale)
- + sfnt_mul_fixed (distortion.advance, scale));
}
sfnt_x_raster (rasters, advances, length, hhea, scale);
@@ -21085,7 +21108,7 @@ main (int argc, char **argv)
fprintf (stderr, "outline origin, rbearing: %"
PRIi32" %"PRIi32"\n",
outline->origin,
- outline->ymax - outline->origin);
+ outline->xmax - outline->origin);
sfnt_test_max = outline->ymax - outline->ymin;
for (i = 0; i < outline->outline_used; i++)
@@ -21199,9 +21222,20 @@ main (int argc, char **argv)
printf ("rasterizing instructed outline\n");
if (outline)
xfree (outline);
- outline = sfnt_build_instructed_outline (value);
+ outline
+ = sfnt_build_instructed_outline (value,
+ &advance);
xfree (value);
+#define LB outline->xmin - outline->origin
+#define RB outline->xmax - outline->origin
+ printf ("instructed advance, lb, rb: %g %g %g\n",
+ sfnt_coerce_fixed (advance),
+ sfnt_coerce_fixed (LB),
+ sfnt_coerce_fixed (RB));
+#undef LB
+#undef RB
+
if (outline)
{
raster