h.x = endpoint.x - control0.x;
h.y = endpoint.y - control0.y;
- /* 2.0 is a constant describing the area covered at which point the
- curve is considered "flat". */
+ /* 1.0 is a constant representing the area covered at which point
+ the curve is considered "flat". */
return (abs (sfnt_mul_fixed (g.x, h.y)
- sfnt_mul_fixed (g.y, h.x))
- <= 0400000);
+ <= 0200000);
}
/* Recursively split the splines in the bezier curve formed from
\f
-#ifdef SFNT_EXACT_SCALING
-
/* Exact coverage scaler.
The foregoing routines calculate partial coverage for each pixel by
p_next = &raster->steps[scanline];
- while (true)
+ while ((step = *p_next))
{
- step = *p_next;
-
- if (!step)
- break;
-
if (step->x > x)
break;
p_next = &step->next;
}
- if (!raster->chunks || raster->chunks->nused == SFNT_BLOCK_STEPS)
+ if (!raster->chunks
+ || raster->chunks->nused == SFNT_BLOCK_STEPS)
{
/* All chunks have been consumed, and consequently a new chunk
must be allocated. */
guarantee that no steps generated extend past WIDTH, steps starting
after width might be omitted, and as such it must be accurate. */
-static void
+TEST_STATIC void
sfnt_poly_edges_exact (struct sfnt_fedge *edges, size_t nedges,
size_t height, size_t width,
sfnt_step_raster_proc proc, void *dcontext)
return MIN (value * 255, 255);
}
+/* Set N pixels at DATA to the value VALUE. If N is large, call
+ memset; otherwise set this by hand. */
+
+static void
+sfnt_poly_set_steps (unsigned char *data, int value, int n)
+{
+ unsigned char *p;
+
+ p = data;
+ switch (n)
+ {
+ case 7:
+ *p++ = value;
+ FALLTHROUGH;
+ case 6:
+ *p++ = value;
+ FALLTHROUGH;
+ case 5:
+ *p++ = value;
+ FALLTHROUGH;
+ case 4:
+ *p++ = value;
+ FALLTHROUGH;
+ case 3:
+ *p++ = value;
+ FALLTHROUGH;
+ case 2:
+ *p++ = value;
+ FALLTHROUGH;
+ case 1:
+ *p++ = value;
+ FALLTHROUGH;
+ case 0:
+ break;
+ default:
+ memset (data, value, n);
+ }
+}
+
/* Transfer steps generated by sfnt_poly_edges_exact from STEPS to the
provided raster RASTER. */
xend = MIN (step->x, raster->width);
if (fill)
- memset (data + x, fill, xend - x);
+ sfnt_poly_set_steps (data + x, fill, xend - x);
total += step->coverage;
fill = sfnt_compute_fill (total);
}
if (x < raster->width)
- memset (data + x, fill, raster->width - x);
+ sfnt_poly_set_steps (data + x, fill, raster->width - x);
}
}
return data;
}
-#endif /* SFNT_EXACT_SCALING */
-
\f
/* Glyph metrics computation. */
#ifdef TEST
-#ifdef SFNT_EXACT_SCALING
-#define sfnt_raster_glyph_outline sfnt_raster_glyph_outline_exact
-#endif /* SFNT_EXACT_SCALING */
-
struct sfnt_test_dcontext
{
/* Context for sfnt_test_get_glyph. */
return buffer;
}
+/* Function called to rasterize a glyph outline. */
+#define TYPE struct sfnt_glyph_outline *
+static struct sfnt_raster *(*test_raster_glyph_outline) (TYPE);
+#undef TYPE
+
static void
sfnt_verbose (struct sfnt_interpreter *interpreter)
{
sfnt_coerce_fixed (outline->xmax),
sfnt_coerce_fixed (outline->ymax));
- raster = sfnt_raster_glyph_outline (outline);
+ raster = (*test_raster_glyph_outline) (outline);
if (raster)
sfnt_test_raster (raster, NULL, 0);
exit (0);
}
+ if (getenv ("SFNT_EXACT_SCALING"))
+ test_raster_glyph_outline = sfnt_raster_glyph_outline_exact;
+ else
+ test_raster_glyph_outline = sfnt_raster_glyph_outline;
+
fd = open (argv[1], O_RDONLY);
if (fd < 0)
return 1;
}
-#define FANCY_PPEM 12
-#define EASY_PPEM 12
+#define FANCY_PPEM 30
+#define EASY_PPEM 30
interpreter = NULL;
head = sfnt_read_head_table (fd, font);
xfree (value);
- raster = sfnt_raster_glyph_outline (outline);
+ raster = (*test_raster_glyph_outline) (outline);
if (!raster)
exit (7);
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
- for (i = 0; i < 120; ++i)
+ for (i = 0; i < 800; ++i)
{
xfree (raster);
- raster = sfnt_raster_glyph_outline (outline);
+ raster = (*test_raster_glyph_outline) (outline);
}
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
if (outline)
{
- raster = sfnt_raster_glyph_outline (outline);
+ raster
+ = (*test_raster_glyph_outline) (outline);
if (raster)
{
printf ("time spent building edges: %lld sec %ld nsec\n",
(long long) sub1.tv_sec, sub1.tv_nsec);
printf ("time spent rasterizing: %lld sec %ld nsec\n",
- (long long) sub2.tv_sec / 120, sub2.tv_nsec / 120);
+ (long long) sub2.tv_sec / 800, sub2.tv_nsec / 800);
xfree (outline);
}