mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
Merge branch 'subpixel-positioning' into 'master'
Subpixel positioning See merge request GNOME/gtk!1024
This commit is contained in:
commit
4a631787bd
@ -83,6 +83,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
|
||||
|
||||
return key1->font == key2->font &&
|
||||
key1->glyph == key2->glyph &&
|
||||
key1->xshift == key2->xshift &&
|
||||
key1->yshift == key2->yshift &&
|
||||
key1->scale == key2->scale;
|
||||
}
|
||||
|
||||
@ -91,7 +93,11 @@ glyph_cache_hash (gconstpointer v)
|
||||
{
|
||||
const GlyphCacheKey *key = v;
|
||||
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
|
||||
return GPOINTER_TO_UINT (key->font) ^
|
||||
key->glyph ^
|
||||
(key->xshift << 24) ^
|
||||
(key->yshift << 26) ^
|
||||
key->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -146,10 +152,10 @@ render_glyph (GlyphCacheKey *key,
|
||||
|
||||
cairo_glyph.index = key->glyph;
|
||||
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
cairo_glyph.x = 0;
|
||||
cairo_glyph.x = 0.25 * key->xshift;
|
||||
else
|
||||
cairo_glyph.x = - value->draw_x;
|
||||
cairo_glyph.y = - value->draw_y;
|
||||
cairo_glyph.x = 0.25 * key->xshift - value->draw_x;
|
||||
cairo_glyph.y = 0.25 * key->yshift - value->draw_y;
|
||||
|
||||
cairo_show_glyphs (cr, &cairo_glyph, 1);
|
||||
cairo_destroy (cr);
|
||||
@ -243,20 +249,28 @@ add_to_cache (GskGLGlyphCache *self,
|
||||
upload_glyph (key, value);
|
||||
}
|
||||
|
||||
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
|
||||
|
||||
gboolean
|
||||
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale,
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *cached_glyph_out)
|
||||
{
|
||||
GskGLCachedGlyph *value;
|
||||
guint xshift = PHASE (x);
|
||||
guint yshift = PHASE (y);
|
||||
|
||||
value = g_hash_table_lookup (cache->hash_table,
|
||||
&(GlyphCacheKey) {
|
||||
.font = font,
|
||||
.glyph = glyph,
|
||||
.xshift = xshift,
|
||||
.yshift = yshift,
|
||||
.scale = (guint)(scale * 1024)
|
||||
});
|
||||
|
||||
@ -288,6 +302,10 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
|
||||
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
|
||||
pango_extents_to_pixels (&ink_rect, NULL);
|
||||
if (xshift != 0)
|
||||
ink_rect.width += 1;
|
||||
if (yshift != 0)
|
||||
ink_rect.height += 1;
|
||||
|
||||
value = g_new0 (GskGLCachedGlyph, 1);
|
||||
|
||||
@ -302,6 +320,8 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->xshift = xshift;
|
||||
key->yshift = yshift;
|
||||
key->scale = key_scale;
|
||||
|
||||
if (key->scale > 0 &&
|
||||
|
@ -22,6 +22,8 @@ typedef struct
|
||||
{
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
guint scale; /* times 1024 */
|
||||
} GlyphCacheKey;
|
||||
|
||||
@ -55,6 +57,8 @@ void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache
|
||||
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale,
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *cached_glyph_out);
|
||||
|
@ -595,6 +595,8 @@ render_text_node (GskGLRenderer *self,
|
||||
gsk_gl_glyph_cache_lookup (self->glyph_cache,
|
||||
(PangoFont *)font,
|
||||
gi->glyph,
|
||||
x * PANGO_SCALE + x_position + gi->geometry.x_offset,
|
||||
+ y * PANGO_SCALE + gi->geometry.y_offset,
|
||||
text_scale,
|
||||
self->gl_driver,
|
||||
&glyph);
|
||||
@ -606,8 +608,8 @@ render_text_node (GskGLRenderer *self,
|
||||
if (glyph.texture_id == 0)
|
||||
goto next;
|
||||
|
||||
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
cy = gi->geometry.y_offset / PANGO_SCALE;
|
||||
|
||||
ops_set_texture (builder, glyph.texture_id);
|
||||
|
||||
|
@ -119,12 +119,17 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
|
||||
|
||||
if (gi->glyph != PANGO_GLYPH_EMPTY)
|
||||
{
|
||||
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = gi->geometry.y_offset / PANGO_SCALE;
|
||||
GskVulkanColorTextInstance *instance = &instances[count];
|
||||
GskVulkanCachedGlyph *glyph;
|
||||
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
|
||||
font,
|
||||
gi->glyph,
|
||||
x_position + gi->geometry.x_offset,
|
||||
gi->geometry.y_offset,
|
||||
scale);
|
||||
|
||||
instance->tex_rect[0] = glyph->tx;
|
||||
instance->tex_rect[1] = glyph->ty;
|
||||
|
@ -115,6 +115,8 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
|
||||
typedef struct {
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
guint scale; /* times 1024 */
|
||||
} GlyphCacheKey;
|
||||
|
||||
@ -126,6 +128,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
|
||||
|
||||
return key1->font == key2->font &&
|
||||
key1->glyph == key2->glyph &&
|
||||
key1->xshift == key2->xshift &&
|
||||
key1->yshift == key2->yshift &&
|
||||
key1->scale == key2->scale;
|
||||
}
|
||||
|
||||
@ -134,7 +138,7 @@ glyph_cache_hash (gconstpointer v)
|
||||
{
|
||||
const GlyphCacheKey *key = v;
|
||||
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ (key->xshift << 24) ^ (key->yshift << 26) ^ key->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -267,10 +271,10 @@ render_glyph (Atlas *atlas,
|
||||
gi.glyph = key->glyph;
|
||||
gi.geometry.width = value->draw_width * 1024;
|
||||
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
gi.geometry.x_offset = 0;
|
||||
gi.geometry.x_offset = key->xshift * 256;
|
||||
else
|
||||
gi.geometry.x_offset = - value->draw_x * 1024;
|
||||
gi.geometry.y_offset = - value->draw_y * 1024;
|
||||
gi.geometry.x_offset = key->xshift * 256 - value->draw_x * 1024;
|
||||
gi.geometry.y_offset = key->yshift * 256 - value->draw_y * 1024;
|
||||
|
||||
glyphs.num_glyphs = 1;
|
||||
glyphs.glyphs = &gi;
|
||||
@ -328,18 +332,29 @@ gsk_vulkan_glyph_cache_new (GskRenderer *renderer,
|
||||
return cache;
|
||||
}
|
||||
|
||||
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
|
||||
|
||||
GskVulkanCachedGlyph *
|
||||
gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
|
||||
gboolean create,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale)
|
||||
{
|
||||
GlyphCacheKey lookup_key;
|
||||
GskVulkanCachedGlyph *value;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
|
||||
xshift = PHASE (x);
|
||||
yshift = PHASE (y);
|
||||
|
||||
lookup_key.font = font;
|
||||
lookup_key.glyph = glyph;
|
||||
lookup_key.xshift = xshift;
|
||||
lookup_key.yshift = yshift;
|
||||
lookup_key.scale = (guint)(scale * 1024);
|
||||
|
||||
value = g_hash_table_lookup (cache->hash_table, &lookup_key);
|
||||
@ -374,6 +389,8 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
|
||||
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->xshift = xshift;
|
||||
key->yshift = yshift;
|
||||
key->scale = (guint)(scale * 1024);
|
||||
|
||||
if (ink_rect.width > 0 && ink_rect.height > 0)
|
||||
|
@ -22,6 +22,9 @@ GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache
|
||||
gboolean create,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
|
||||
float scale);
|
||||
|
||||
void gsk_vulkan_glyph_cache_begin_frame (GskVulkanGlyphCache *cache);
|
||||
|
@ -362,15 +362,6 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
return image;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, scale)->texture_index;
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
GskVulkanUploader *uploader,
|
||||
@ -379,13 +370,26 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
return g_object_ref (gsk_vulkan_glyph_cache_get_glyph_image (self->glyph_cache, uploader, index));
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, x, y, scale)->texture_index;
|
||||
}
|
||||
|
||||
GskVulkanCachedGlyph *
|
||||
gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, x, y, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,8 @@ typedef struct
|
||||
guint gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *renderer,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale);
|
||||
|
||||
GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
@ -39,6 +41,8 @@ GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *
|
||||
GskVulkanCachedGlyph * gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale);
|
||||
|
||||
|
||||
|
@ -370,6 +370,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
int i;
|
||||
guint count;
|
||||
guint texture_index;
|
||||
gint x_position;
|
||||
GskVulkanRenderer *renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
|
||||
|
||||
if (font_has_color_glyphs (font))
|
||||
@ -402,11 +403,17 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
op.text.texture_index = G_MAXUINT;
|
||||
op.text.scale = self->scale_factor;
|
||||
|
||||
x_position = 0;
|
||||
for (i = 0, count = 0; i < num_glyphs; i++)
|
||||
{
|
||||
const PangoGlyphInfo *gi = &glyphs[i];
|
||||
|
||||
texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph, op.text.scale);
|
||||
texture_index = gsk_vulkan_renderer_cache_glyph (renderer,
|
||||
(PangoFont *)font,
|
||||
gi->glyph,
|
||||
x_position + gi->geometry.x_offset,
|
||||
gi->geometry.y_offset,
|
||||
op.text.scale);
|
||||
if (op.text.texture_index == G_MAXUINT)
|
||||
op.text.texture_index = texture_index;
|
||||
if (texture_index != op.text.texture_index)
|
||||
@ -421,6 +428,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
}
|
||||
else
|
||||
count++;
|
||||
|
||||
x_position += gi->geometry.width;
|
||||
}
|
||||
|
||||
if (op.text.texture_index != G_MAXUINT && count != 0)
|
||||
|
@ -127,12 +127,17 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
|
||||
|
||||
if (gi->glyph != PANGO_GLYPH_EMPTY)
|
||||
{
|
||||
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = gi->geometry.y_offset / PANGO_SCALE;
|
||||
GskVulkanTextInstance *instance = &instances[count];
|
||||
GskVulkanCachedGlyph *glyph;
|
||||
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
|
||||
font,
|
||||
gi->glyph,
|
||||
x_position + gi->geometry.x_offset,
|
||||
gi->geometry.y_offset,
|
||||
scale);
|
||||
|
||||
instance->tex_rect[0] = glyph->tx;
|
||||
instance->tex_rect[1] = glyph->ty;
|
||||
|
@ -2062,7 +2062,7 @@ settings_update_font_options (GtkSettings *settings)
|
||||
|
||||
priv->font_options = cairo_font_options_create ();
|
||||
|
||||
cairo_font_options_set_hint_metrics (priv->font_options, CAIRO_HINT_METRICS_ON);
|
||||
cairo_font_options_set_hint_metrics (priv->font_options, CAIRO_HINT_METRICS_OFF);
|
||||
|
||||
hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
if (hinting == 0)
|
||||
|
@ -430,6 +430,10 @@ xfails = [
|
||||
'textview-border-windows.ui',
|
||||
'window-show-contents-on-map.ui',
|
||||
'toplevel-vs-popup.ui',
|
||||
# these depend on details of text layout
|
||||
'label-background.ui',
|
||||
'label-wrap-justify.ui',
|
||||
'quit-mnemonic.ui',
|
||||
]
|
||||
|
||||
foreach testname : testdata
|
||||
|
Loading…
Reference in New Issue
Block a user