mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 04:08:13 +02:00
Improve the subpixel positioning machinery
Extract the resolution of the subpixel grid. This is in preparation for allowing a finer subpixel grid. No functional change.
This commit is contained in:
parent
c4f291bc3a
commit
3625b20901
6 changed files with 66 additions and 30 deletions
|
|
@ -2449,10 +2449,11 @@ _cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font,
|
|||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, face->glyph);
|
||||
|
||||
if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
unsigned int bits = _cairo_subpixel_bits (scaled_font->base.options.subpixel_positions);
|
||||
FT_Pos xshift, yshift;
|
||||
|
||||
xshift = _cairo_scaled_glyph_xphase (scaled_glyph) << 4;
|
||||
yshift = _cairo_scaled_glyph_yphase (scaled_glyph) << 4;
|
||||
xshift = _cairo_scaled_glyph_xphase (scaled_glyph) << (6 - bits);
|
||||
yshift = _cairo_scaled_glyph_yphase (scaled_glyph) << (6 - bits);
|
||||
|
||||
FT_Outline_Translate (&face->glyph->outline, xshift, -yshift);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -845,9 +845,6 @@ _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,
|
||||
|
|
@ -891,12 +888,11 @@ composite_glyphs (void *_dst,
|
|||
const void *glyph;
|
||||
|
||||
if (info->font->options.subpixel_positions != CAIRO_SUBPIXEL_POSITIONS_OFF) {
|
||||
int res = _cairo_subpixel_resolution (info->font->options.subpixel_positions);
|
||||
unsigned long xphase, yphase;
|
||||
|
||||
xphase = PHASE(info->glyphs[i].x);
|
||||
yphase = PHASE(info->glyphs[i].y);
|
||||
|
||||
index = index | (xphase << 24) | (yphase << 26);
|
||||
xphase = _cairo_subpixel_phase (info->glyphs[i].x, res);
|
||||
yphase = _cairo_subpixel_phase (info->glyphs[i].y, res);
|
||||
index = index | (xphase << XSHIFT) | (yphase << YSHIFT);
|
||||
}
|
||||
|
||||
glyph = pixman_glyph_cache_lookup (glyph_cache, info->font, (void *)(uintptr_t)index);
|
||||
|
|
@ -929,8 +925,9 @@ composite_glyphs (void *_dst,
|
|||
}
|
||||
|
||||
if (info->font->options.subpixel_positions != CAIRO_SUBPIXEL_POSITIONS_OFF) {
|
||||
pg->x = POSITION (info->glyphs[i].x);
|
||||
pg->y = POSITION (info->glyphs[i].y);
|
||||
int res = _cairo_subpixel_resolution (info->font->options.subpixel_positions);
|
||||
pg->x = _cairo_subpixel_position (info->glyphs[i].x, res);
|
||||
pg->y = _cairo_subpixel_position (info->glyphs[i].y, res);
|
||||
}
|
||||
else {
|
||||
pg->x = _cairo_lround (info->glyphs[i].x);
|
||||
|
|
|
|||
|
|
@ -208,8 +208,9 @@ _cairo_user_scaled_glyph_init_record_glyph (cairo_user_scaled_font_t *scaled_fon
|
|||
cairo_surface_destroy (recording_surface);
|
||||
recording_surface = _cairo_user_scaled_font_create_recording_surface (scaled_font, FALSE, foreground_color);
|
||||
if (scaled_font->base.options.subpixel_positions != CAIRO_SUBPIXEL_POSITIONS_OFF) {
|
||||
recording_surface->device_transform.x0 = .25 * _cairo_scaled_glyph_xphase (scaled_glyph);
|
||||
recording_surface->device_transform.y0 = .25 * _cairo_scaled_glyph_yphase (scaled_glyph);
|
||||
double res = _cairo_subpixel_resolution (scaled_font->base.options.subpixel_positions);
|
||||
recording_surface->device_transform.x0 = _cairo_scaled_glyph_xphase (scaled_glyph) / res;
|
||||
recording_surface->device_transform.y0 = _cairo_scaled_glyph_yphase (scaled_glyph) / res;
|
||||
}
|
||||
|
||||
cr = _cairo_user_scaled_font_create_recording_context (scaled_font, recording_surface, FALSE);
|
||||
|
|
|
|||
|
|
@ -1570,9 +1570,6 @@ check_composite_glyphs (const cairo_composite_rectangles_t *extents,
|
|||
* enough room for padding */
|
||||
#define _cairo_sz_xGlyphElt (sz_xGlyphElt + 4)
|
||||
|
||||
#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 *surface,
|
||||
cairo_operator_t op,
|
||||
|
|
@ -1612,12 +1609,18 @@ composite_glyphs (void *surface,
|
|||
int old_width;
|
||||
|
||||
if (info->font->options.subpixel_positions != CAIRO_SUBPIXEL_POSITIONS_OFF) {
|
||||
int res = _cairo_subpixel_resolution (info->font->options.subpixel_positions);
|
||||
unsigned long xphase, yphase;
|
||||
xphase = _cairo_subpixel_phase (glyphs[i].d.x, res);
|
||||
yphase = _cairo_subpixel_phase (glyphs[i].d.y, res);
|
||||
glyphs[i].index |= (xphase << XSHIFT) | (yphase << YSHIFT);
|
||||
|
||||
xphase = PHASE(glyphs[i].d.x);
|
||||
yphase = PHASE(glyphs[i].d.y);
|
||||
|
||||
glyphs[i].index |= (xphase << 24) | (yphase << 26);
|
||||
this_x = _cairo_subpixel_position (glyphs[i].d.x, res);
|
||||
this_y = _cairo_subpixel_position (glyphs[i].d.y, res);
|
||||
}
|
||||
else {
|
||||
this_x = _cairo_lround (glyphs[i].d.x);
|
||||
this_y = _cairo_lround (glyphs[i].d.y);
|
||||
}
|
||||
|
||||
status = _cairo_scaled_glyph_lookup (info->font,
|
||||
|
|
@ -1628,9 +1631,6 @@ composite_glyphs (void *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
this_x = POSITION (glyphs[i].d.x);
|
||||
this_y = POSITION (glyphs[i].d.y);
|
||||
|
||||
/* Send unsent glyphs to the server */
|
||||
if (glyph->dev_private_key != display) {
|
||||
status = _cairo_xlib_surface_add_glyph (display, info->font, &glyph);
|
||||
|
|
|
|||
|
|
@ -400,10 +400,46 @@ cairo_private uintptr_t
|
|||
_cairo_hash_uintptr (uintptr_t hash,
|
||||
uintptr_t u);
|
||||
|
||||
/* We use bits 24-27 to store phases for subpixel positions */
|
||||
#define _cairo_scaled_glyph_index(g) ((unsigned long)((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)
|
||||
/* We use the upper 8 bits to store phases for 64x64 subpixel positions */
|
||||
|
||||
static inline int _cairo_subpixel_bits (cairo_subpixel_positions_t subpixel_positions)
|
||||
{
|
||||
int bits[] = {
|
||||
[CAIRO_SUBPIXEL_POSITIONS_DEFAULT] = 2,
|
||||
[CAIRO_SUBPIXEL_POSITIONS_OFF] = 0,
|
||||
[CAIRO_SUBPIXEL_POSITIONS_ON] = 2,
|
||||
};
|
||||
|
||||
return bits[subpixel_positions];
|
||||
}
|
||||
|
||||
static inline int _cairo_subpixel_resolution (cairo_subpixel_positions_t subpixel_positions)
|
||||
{
|
||||
return 1 << _cairo_subpixel_bits (subpixel_positions);
|
||||
}
|
||||
|
||||
static inline int _cairo_subpixel_phase (double pos, int res)
|
||||
{
|
||||
double shifted_pos = pos + 1.0 / (2 * res);
|
||||
return (int) (floor (res * shifted_pos) - res * floor (shifted_pos));
|
||||
}
|
||||
|
||||
static inline double _cairo_subpixel_position (double pos, int res)
|
||||
{
|
||||
return floor (pos + 1.0 / (2 * res));
|
||||
}
|
||||
|
||||
#define MAX_PHASE_BITS 4
|
||||
|
||||
#define XSHIFT (32 - 2 * MAX_PHASE_BITS)
|
||||
#define YSHIFT (32 - MAX_PHASE_BITS)
|
||||
|
||||
#define PHASE_MASK ((1 << MAX_PHASE_BITS) - 1)
|
||||
#define INDEX_MASK ((1 << XSHIFT) - 1)
|
||||
|
||||
#define _cairo_scaled_glyph_index(g) ((unsigned long)((g)->hash_entry.hash & INDEX_MASK))
|
||||
#define _cairo_scaled_glyph_xphase(g) (unsigned int)(((g)->hash_entry.hash >> XSHIFT) & PHASE_MASK)
|
||||
#define _cairo_scaled_glyph_yphase(g) ((unsigned int)(((g)->hash_entry.hash >> YSHIFT) & PHASE_MASK))
|
||||
#define _cairo_scaled_glyph_set_index(g, i) ((g)->hash_entry.hash = (i))
|
||||
|
||||
#include "cairo-scaled-font-private.h"
|
||||
|
|
|
|||
|
|
@ -1112,8 +1112,9 @@ _cairo_dwrite_scaled_font_init_glyph_color_surface(cairo_dwrite_scaled_font_t *s
|
|||
double x = -x1;
|
||||
double y = -y1;
|
||||
if (scaled_font->base.options.subpixel_positions != CAIRO_SUBPIXEL_POSITIONS_OFF) {
|
||||
x += .25 * _cairo_scaled_glyph_xphase (scaled_glyph);
|
||||
y += .25 * _cairo_scaled_glyph_yphase (scaled_glyph);
|
||||
double res = _cairo_subpixel_resolution (scaled_font->base.options.subpixel_positions);
|
||||
x += _cairo_scaled_glyph_xphase (scaled_glyph) / res;
|
||||
y += _cairo_scaled_glyph_yphase (scaled_glyph) / res;
|
||||
}
|
||||
DWRITE_MATRIX matrix;
|
||||
D2D1_POINT_2F origin = {0, 0};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue