diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-07-28 12:25:47 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2019-07-18 14:38:47 -0700 |
commit | ea9329215d3431ded51a71b724baf0edc25ad633 (patch) | |
tree | 2d805ecfe9f443941bf8831d70adba7a77e5b940 | |
parent | bab53d91a8543e2ddb15f9dce98ebb3f9bcd5d22 (diff) |
image compositor: Support subpixel positioning
Support subpixel positioning with a 4x4 subpixel grid.
When compositing glyphs in the image compositor,
we store the subpixel phases in the high bits of the
glyph index. The _cairo_scaled_glyph_index() macro
has been updated to discard these bits. By storing
the phases in the glyph index, the glyph cache just
keeps working. When loading a glyph, the Freetype
font backend shifts the outline according to the
phases.
-rw-r--r-- | src/cairo-ft-font.c | 10 | ||||
-rw-r--r-- | src/cairo-image-compositor.c | 13 | ||||
-rw-r--r-- | src/cairoint.h | 5 |
3 files changed, 25 insertions, 3 deletions
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 6b2af3713..7db16e8bd 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2455,6 +2455,16 @@ _cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font, if (vertical_layout) _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, face->glyph); + + if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { + FT_Pos xshift, yshift; + + xshift = _cairo_scaled_glyph_xphase (scaled_glyph) << 4; + yshift = _cairo_scaled_glyph_yphase (scaled_glyph) << 4; + + FT_Outline_Translate (&face->glyph->outline, xshift, yshift); + } + return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index 434f67e59..6fccb79f1 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -847,6 +847,9 @@ _cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex); } +#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125))) +#define POSITION(x) ((int) floor (x + 0.125)) + static cairo_int_status_t composite_glyphs (void *_dst, cairo_operator_t op, @@ -888,6 +891,12 @@ composite_glyphs (void *_dst, for (i = 0; i < info->num_glyphs; i++) { unsigned long index = info->glyphs[i].index; const void *glyph; + int xphase, yphase; + + xphase = PHASE(info->glyphs[i].x); + yphase = PHASE(info->glyphs[i].y); + + index = index | (xphase << 24) | (yphase << 26); glyph = pixman_glyph_cache_lookup (glyph_cache, info->font, (void *)index); if (!glyph) { @@ -917,8 +926,8 @@ composite_glyphs (void *_dst, } } - pg->x = _cairo_lround (info->glyphs[i].x); - pg->y = _cairo_lround (info->glyphs[i].y); + pg->x = POSITION (info->glyphs[i].x); + pg->y = POSITION (info->glyphs[i].y); pg->glyph = glyph; pg++; } diff --git a/src/cairoint.h b/src/cairoint.h index 29b844d3a..7c1000556 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -428,7 +428,10 @@ _cairo_hash_bytes (unsigned long hash, const void *bytes, unsigned int length); -#define _cairo_scaled_glyph_index(g) ((g)->hash_entry.hash) +/* We use bits 24-27 to store phases for subpixel positions */ +#define _cairo_scaled_glyph_index(g) ((g)->hash_entry.hash & 0xffffff) +#define _cairo_scaled_glyph_xphase(g) (int)(((g)->hash_entry.hash >> 24) & 3) +#define _cairo_scaled_glyph_yphase(g) (int)(((g)->hash_entry.hash >> 26) & 3) #define _cairo_scaled_glyph_set_index(g, i) ((g)->hash_entry.hash = (i)) #include "cairo-scaled-font-private.h" |