summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-07-28 12:25:47 +0000
committerBehdad Esfahbod <behdad@behdad.org>2019-07-18 14:38:47 -0700
commitea9329215d3431ded51a71b724baf0edc25ad633 (patch)
tree2d805ecfe9f443941bf8831d70adba7a77e5b940
parentbab53d91a8543e2ddb15f9dce98ebb3f9bcd5d22 (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.c10
-rw-r--r--src/cairo-image-compositor.c13
-rw-r--r--src/cairoint.h5
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"