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);
/* 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);
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)
{
}
/* 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,
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. */
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;
struct sfnt_instance *instance;
struct sfnt_blend blend;
struct sfnt_metrics_distortion distortion;
+ sfnt_fixed advance;
if (argc < 2)
return 1;
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);
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,
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);
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);
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++)
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
const char *error;
struct sfnt_glyph_metrics temp;
struct sfnt_metrics_distortion distortion;
+ sfnt_fixed advance;
start = cache->next;
distortion.advance = 0;
if (!error)
{
- outline = sfnt_build_instructed_outline (value);
+ /* Now record the advance with that measured from the
+ phantom points within the instructed glyph outline, and
+ subsequently replace it once metrics are scaled. */
+
+ outline = sfnt_build_instructed_outline (value,
+ &advance);
xfree (value);
+
+ if (outline)
+ {
+ /* Save the new advance width. */
+ temp.advance = advance;
+
+ /* Finally, adjust the left side bearing of the glyph
+ metrics by the origin point of the outline, should a
+ transformation have been applied by either
+ instruction code or glyph variation. The left side
+ bearing is the distance from the origin point to the
+ left most point on the X axis. */
+ temp.lbearing = outline->xmin - outline->origin;
+ }
}
}
if (!outline)
- outline = sfnt_build_glyph_outline (glyph, scale,
- &temp,
- sfntfont_get_glyph,
- sfntfont_free_glyph,
- sfntfont_get_metrics,
- &dcontext);
-
- /* At this point, the glyph metrics are unscaled. Scale them up.
- If INTERPRETER is set, use the scale placed within. */
-
- sfnt_scale_metrics (&temp, scale);
+ {
+ outline = sfnt_build_glyph_outline (glyph, scale,
+ &temp,
+ sfntfont_get_glyph,
+ sfntfont_free_glyph,
+ sfntfont_get_metrics,
+ &dcontext);
+
+ /* At this point, the glyph metrics are unscaled. Scale them
+ up. If INTERPRETER is set, use the scale placed within. */
+ sfnt_scale_metrics (&temp, scale);
+
+ /* Finally, adjust the left side bearing of the glyph metrics by
+ the origin point of the outline, should a transformation have
+ been applied by either instruction code or glyph variation.
+ The left side bearing is the distance from the origin point
+ to the left most point on the X axis. */
+
+ if (index != -1)
+ temp.lbearing = outline->xmin - outline->origin;
+ }
fail:
if (!outline)
return NULL;
- if (index != -1)
- /* Finally, adjust the left side bearing of the glyph metrics by
- the origin point of the outline, should a distortion have been
- applied. The left side bearing is the distance from the origin
- point to the left most point on the X axis. */
- temp.lbearing = outline->xmin - outline->origin;
-
start = xmalloc (sizeof *start);
start->glyph = glyph_code;
start->outline = outline;
return glyph;
}
+static int sfntfont_measure_pcm (struct sfnt_font_info *, sfnt_glyph,
+ struct font_metrics *);
+
/* Probe and set FONT_INFO->font.average_width,
FONT_INFO->font.space_width, and FONT_INFO->font.min_width
- according to the tables contained therein. */
+ according to the tables contained therein.
+
+ As this function generates outlines for all glyphs, outlines for
+ all ASCII characters will be entered into the outline cache as
+ well. */
static void
sfntfont_probe_widths (struct sfnt_font_info *font_info)
{
int i, num_characters, total_width;
sfnt_glyph glyph;
- struct sfnt_glyph_metrics metrics;
+ struct font_metrics pcm;
num_characters = 0;
total_width = 0;
if (!glyph)
continue;
- /* Now look up the metrics of this glyph. */
- if (sfnt_lookup_glyph_metrics (glyph, font_info->font.pixel_size,
- &metrics, font_info->hmtx,
- font_info->hhea, font_info->head,
- font_info->maxp))
+ /* Now look up the metrics of this glyph. Data from the metrics
+ table doesn't fit the bill, since variations and instruction
+ code is not applied to it. */
+ if (sfntfont_measure_pcm (font_info, glyph, &pcm))
continue;
/* Increase the number of characters. */
num_characters++;
/* Add the advance to total_width. */
- total_width += SFNT_CEIL_FIXED (metrics.advance) / 65536;
+ total_width += pcm.width;
/* Update min_width if it hasn't been set yet or is wider. */
if (font_info->font.min_width == 1
- || font_info->font.min_width > metrics.advance / 65536)
- font_info->font.min_width = metrics.advance / 65536;
+ || font_info->font.min_width > pcm.width)
+ font_info->font.min_width = pcm.width;
/* If i is the space character, set the space width. Make sure
to round this up. */
if (i == 32)
- font_info->font.space_width
- = SFNT_CEIL_FIXED (metrics.advance) / 65536;
+ font_info->font.space_width = pcm.width;
}
/* Now, if characters were found, set average_width. */
ASET (font_object, FONT_ADSTYLE_INDEX, Qnil);
- /* Find out the minimum, maximum and average widths. */
- sfntfont_probe_widths (font_info);
-
/* Clear various offsets. */
font_info->font.baseline_offset = 0;
font_info->font.relative_compose = 0;
}
cancel_blend:
+
+ /* Find out the minimum, maximum and average widths. */
+ sfntfont_probe_widths (font_info);
+
/* Calculate the xfld name. */
font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil, Qt);
if (!outline)
return 1;
- /* Round the left side bearing downwards. */
+ /* Round the left side bearing down. */
pcm->lbearing = SFNT_FLOOR_FIXED (metrics.lbearing) / 65536;
pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) / 65536;