[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 103f36cced3 1/2: Enable the new font scaler
From: |
Po Lu |
Subject: |
master 103f36cced3 1/2: Enable the new font scaler |
Date: |
Sun, 17 Dec 2023 22:11:46 -0500 (EST) |
branch: master
commit 103f36cced37eed1bb51cd704b0a64b42f7b8144
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Enable the new font scaler
* src/sfnt.c (sfnt_curve_is_flat): Tighten threshold for flat
curves.
(sfnt_insert_raster_step): Rewrite loop for clarity.
(sfnt_poly_set_steps): New function; fill small spans with a
plain unexceptional loop rather than memset.
(sfnt_poly_steps): Call that function.
(sfnt_verbose, main): Adjust tests such that the scaler can be
selected at runtime.
* src/sfnt.h: Update prototypes.
* src/sfntfont.c (sfntfont_get_glyph_raster)
(syms_of_sfntfont) <sfnt_raster_glyphs_exactly>: New variable.
---
src/sfnt.c | 96 ++++++++++++++++++++++++++++++++++++++++------------------
src/sfnt.h | 1 +
src/sfntfont.c | 13 +++++++-
3 files changed, 80 insertions(+), 30 deletions(-)
diff --git a/src/sfnt.c b/src/sfnt.c
index 208d0139022..7d43f06b748 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -3905,11 +3905,11 @@ sfnt_curve_is_flat (struct sfnt_point control0,
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
@@ -4621,8 +4621,6 @@ sfnt_raster_glyph_outline (struct sfnt_glyph_outline
*outline)
-#ifdef SFNT_EXACT_SCALING
-
/* Exact coverage scaler.
The foregoing routines calculate partial coverage for each pixel by
@@ -4910,13 +4908,8 @@ sfnt_insert_raster_step (struct sfnt_step_raster *raster,
p_next = &raster->steps[scanline];
- while (true)
+ while ((step = *p_next))
{
- step = *p_next;
-
- if (!step)
- break;
-
if (step->x > x)
break;
@@ -4926,7 +4919,8 @@ sfnt_insert_raster_step (struct sfnt_step_raster *raster,
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. */
@@ -4989,7 +4983,7 @@ sfnt_fedge_sort (struct sfnt_fedge *edges, size_t size)
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)
@@ -5409,6 +5403,45 @@ sfnt_compute_fill (float value)
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. */
@@ -5438,7 +5471,7 @@ sfnt_poly_steps (struct sfnt_step_raster *steps,
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);
@@ -5446,7 +5479,7 @@ sfnt_poly_steps (struct sfnt_step_raster *steps,
}
if (x < raster->width)
- memset (data + x, fill, raster->width - x);
+ sfnt_poly_set_steps (data + x, fill, raster->width - x);
}
}
@@ -5499,8 +5532,6 @@ sfnt_raster_glyph_outline_exact (struct
sfnt_glyph_outline *outline)
return data;
}
-#endif /* SFNT_EXACT_SCALING */
-
/* Glyph metrics computation. */
@@ -16464,10 +16495,6 @@ sfnt_read_post_table (int fd, struct
sfnt_offset_subtable *subtable)
#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. */
@@ -20124,6 +20151,11 @@ sfnt_identify_instruction (struct sfnt_interpreter
*interpreter)
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)
{
@@ -20157,7 +20189,7 @@ 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);
@@ -20380,6 +20412,11 @@ main (int argc, char **argv)
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)
@@ -20471,8 +20508,8 @@ main (int argc, char **argv)
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);
@@ -20723,7 +20760,7 @@ main (int argc, char **argv)
xfree (value);
- raster = sfnt_raster_glyph_outline (outline);
+ raster = (*test_raster_glyph_outline) (outline);
if (!raster)
exit (7);
@@ -21028,10 +21065,10 @@ main (int argc, char **argv)
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);
@@ -21116,7 +21153,8 @@ main (int argc, char **argv)
if (outline)
{
- raster = sfnt_raster_glyph_outline (outline);
+ raster
+ = (*test_raster_glyph_outline) (outline);
if (raster)
{
@@ -21142,7 +21180,7 @@ main (int argc, char **argv)
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);
}
diff --git a/src/sfnt.h b/src/sfnt.h
index a875c1a722d..2ae47ad30ce 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -1512,6 +1512,7 @@ extern void sfnt_prepare_raster (struct sfnt_raster *,
#define PROTOTYPE struct sfnt_glyph_outline *
extern struct sfnt_raster *sfnt_raster_glyph_outline (PROTOTYPE);
+extern struct sfnt_raster *sfnt_raster_glyph_outline_exact (PROTOTYPE);
#undef PROTOTYPE
#define PROTOTYPE \
diff --git a/src/sfntfont.c b/src/sfntfont.c
index f002712dc10..0a8797bfb3b 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -2444,7 +2444,11 @@ sfntfont_get_glyph_raster (sfnt_glyph glyph_code,
}
/* Not already cached. Raster the outline. */
- raster = sfnt_raster_glyph_outline (outline);
+
+ if (!sfnt_raster_glyphs_exactly)
+ raster = sfnt_raster_glyph_outline (outline);
+ else
+ raster = sfnt_raster_glyph_outline_exact (outline);
if (!raster)
return NULL;
@@ -4116,6 +4120,13 @@ eliminating artifacts and chance effects consequent upon
the direct
upscaling of glyph outline data. Instruction code is occasionally
incompatible with Emacs and must be disregarded. */);
Vsfnt_uninstructable_family_regexp = Qnil;
+
+ DEFVAR_BOOL ("sfnt-raster-glyphs-exactly", sfnt_raster_glyphs_exactly,
+ doc: /* How font glyph outlines should be converted to graphics.
+If non-nil, glyphs will be displayed in a more precise manner, at the
+cost of performance on devices where floating-point math operations
+are slow. */);
+ sfnt_raster_glyphs_exactly = true;
}
void
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 103f36cced3 1/2: Enable the new font scaler,
Po Lu <=