forked from AuroraMiddleware/gtk
gsk: Scale glyphs in the glyph cache
Pass a scale factor when caching glyphs or looking them up in the cache. The glyphs in the cache are rendered with subpixel precision determined by the scale. Update all callers to pass a scale factor according to the window scale. This lets us render crisp glyphs on hidpi systems.
This commit is contained in:
parent
6560961c59
commit
a0bbd14325
@ -103,7 +103,8 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
|
||||
float x,
|
||||
float y,
|
||||
guint start_glyph,
|
||||
guint num_glyphs)
|
||||
guint num_glyphs,
|
||||
float scale)
|
||||
{
|
||||
GskVulkanColorTextInstance *instances = (GskVulkanColorTextInstance *) data;
|
||||
int i;
|
||||
@ -127,7 +128,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
|
||||
GskVulkanColorTextInstance *instance = &instances[count];
|
||||
GskVulkanCachedGlyph *glyph;
|
||||
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph);
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
|
||||
|
||||
instance->tex_rect[0] = glyph->tx;
|
||||
instance->tex_rect[1] = glyph->ty;
|
||||
|
@ -31,7 +31,8 @@ void gsk_vulkan_color_text_pipeline_collect_vertex_data (Gs
|
||||
float x,
|
||||
float y,
|
||||
guint start_glyph,
|
||||
guint num_glyphs);
|
||||
guint num_glyphs,
|
||||
float scale);
|
||||
gsize gsk_vulkan_color_text_pipeline_draw (GskVulkanColorTextPipeline *pipeline,
|
||||
VkCommandBuffer command_buffer,
|
||||
gsize offset,
|
||||
|
@ -116,6 +116,7 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
|
||||
typedef struct {
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
guint scale; /* times 1024 */
|
||||
} GlyphCacheKey;
|
||||
|
||||
static gboolean
|
||||
@ -125,7 +126,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
|
||||
const GlyphCacheKey *key2 = v2;
|
||||
|
||||
return key1->font == key2->font &&
|
||||
key1->glyph == key2->glyph;
|
||||
key1->glyph == key2->glyph &&
|
||||
key1->scale == key2->scale;
|
||||
}
|
||||
|
||||
static guint
|
||||
@ -133,7 +135,7 @@ glyph_cache_hash (gconstpointer v)
|
||||
{
|
||||
const GlyphCacheKey *key = v;
|
||||
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph;
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -175,6 +177,8 @@ add_to_cache (GskVulkanGlyphCache *cache,
|
||||
Atlas *atlas;
|
||||
int i;
|
||||
DirtyGlyph *dirty;
|
||||
int width = value->draw_width * key->scale / 1024;
|
||||
int height = value->draw_height * key->scale / 1024;
|
||||
|
||||
for (i = 0; i < cache->atlases->len; i++)
|
||||
{
|
||||
@ -185,14 +189,14 @@ add_to_cache (GskVulkanGlyphCache *cache,
|
||||
y = atlas->y;
|
||||
y0 = atlas->y0;
|
||||
|
||||
if (atlas->x + value->draw_width + 1 >= atlas->width)
|
||||
if (atlas->x + width + 1 >= atlas->width)
|
||||
{
|
||||
/* start a new row */
|
||||
y0 = y + 1;
|
||||
x = 1;
|
||||
}
|
||||
|
||||
if (y0 + value->draw_height + 1 >= atlas->height)
|
||||
if (y0 + height + 1 >= atlas->height)
|
||||
continue;
|
||||
|
||||
atlas->y0 = y0;
|
||||
@ -209,8 +213,8 @@ add_to_cache (GskVulkanGlyphCache *cache,
|
||||
|
||||
value->tx = (float)atlas->x / atlas->width;
|
||||
value->ty = (float)atlas->y0 / atlas->height;
|
||||
value->tw = (float)value->draw_width / atlas->width;
|
||||
value->th = (float)value->draw_height / atlas->height;
|
||||
value->tw = (float)width / atlas->width;
|
||||
value->th = (float)height / atlas->height;
|
||||
|
||||
value->texture_index = i;
|
||||
|
||||
@ -219,8 +223,8 @@ add_to_cache (GskVulkanGlyphCache *cache,
|
||||
dirty->value = value;
|
||||
atlas->dirty_glyphs = g_list_prepend (atlas->dirty_glyphs, dirty);
|
||||
|
||||
atlas->x = atlas->x + value->draw_width + 1;
|
||||
atlas->y = MAX (atlas->y, atlas->y0 + value->draw_height + 1);
|
||||
atlas->x = atlas->x + width + 1;
|
||||
atlas->y = MAX (atlas->y, atlas->y0 + height + 1);
|
||||
|
||||
atlas->num_glyphs++;
|
||||
|
||||
@ -254,8 +258,9 @@ render_glyph (Atlas *atlas,
|
||||
cairo_glyph_t cg;
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
value->draw_width,
|
||||
value->draw_height);
|
||||
value->draw_width * key->scale / 1024,
|
||||
value->draw_height * key->scale / 1024);
|
||||
cairo_surface_set_device_scale (surface, key->scale / 1024.0, key->scale / 1024.0);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
|
||||
@ -324,13 +329,15 @@ GskVulkanCachedGlyph *
|
||||
gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
|
||||
gboolean create,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph)
|
||||
PangoGlyph glyph,
|
||||
float scale)
|
||||
{
|
||||
GlyphCacheKey lookup_key;
|
||||
GskVulkanCachedGlyph *value;
|
||||
|
||||
lookup_key.font = font;
|
||||
lookup_key.glyph = glyph;
|
||||
lookup_key.scale = (guint)(scale * 1024);
|
||||
|
||||
value = g_hash_table_lookup (cache->hash_table, &lookup_key);
|
||||
|
||||
@ -364,6 +371,7 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
|
||||
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->scale = (guint)(scale * 1024);
|
||||
|
||||
if (ink_rect.width > 0 && ink_rect.height > 0)
|
||||
add_to_cache (cache, key, value);
|
||||
|
@ -20,7 +20,8 @@ GskVulkanImage * gsk_vulkan_glyph_cache_get_glyph_image (GskVulkanGlyphCache
|
||||
GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
|
||||
gboolean create,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph);
|
||||
PangoGlyph glyph,
|
||||
float scale);
|
||||
|
||||
void gsk_vulkan_glyph_cache_begin_frame (GskVulkanGlyphCache *cache);
|
||||
|
||||
|
@ -350,9 +350,10 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
guint
|
||||
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph)
|
||||
PangoGlyph glyph,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph)->texture_index;
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, scale)->texture_index;
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
@ -366,7 +367,8 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
GskVulkanCachedGlyph *
|
||||
gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph)
|
||||
PangoGlyph glyph,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph);
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ typedef struct
|
||||
|
||||
guint gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *renderer,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph);
|
||||
PangoGlyph glyph,
|
||||
float scale);
|
||||
|
||||
GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
GskVulkanUploader *uploader,
|
||||
@ -52,7 +53,8 @@ GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *
|
||||
|
||||
GskVulkanCachedGlyph * gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph);
|
||||
PangoGlyph glyph,
|
||||
float scale);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -90,6 +90,7 @@ struct _GskVulkanOpText
|
||||
guint texture_index; /* index of the texture in the glyph cache */
|
||||
guint start_glyph; /* the first glyph in nodes glyphstring that we render */
|
||||
guint num_glyphs; /* number of *non-empty* glyphs (== instances) we render */
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct _GskVulkanOpPushConstants
|
||||
@ -406,6 +407,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
|
||||
op.text.start_glyph = 0;
|
||||
op.text.texture_index = G_MAXUINT;
|
||||
op.text.scale = gdk_window_get_scale_factor (gsk_renderer_get_window (GSK_RENDERER (renderer)));
|
||||
|
||||
for (i = 0, count = 0; i < num_glyphs; i++)
|
||||
{
|
||||
@ -413,7 +415,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
|
||||
if (gi->glyph != PANGO_GLYPH_EMPTY && !(gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
|
||||
{
|
||||
texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph);
|
||||
texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph, op.text.scale);
|
||||
if (op.text.texture_index == G_MAXUINT)
|
||||
op.text.texture_index = texture_index;
|
||||
if (texture_index != op.text.texture_index)
|
||||
@ -1232,7 +1234,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
gsk_text_node_get_x (op->text.node),
|
||||
gsk_text_node_get_y (op->text.node),
|
||||
op->text.start_glyph,
|
||||
op->text.num_glyphs);
|
||||
op->text.num_glyphs,
|
||||
op->text.scale);
|
||||
n_bytes += op->text.vertex_count;
|
||||
}
|
||||
break;
|
||||
@ -1250,7 +1253,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
gsk_text_node_get_x (op->text.node),
|
||||
gsk_text_node_get_y (op->text.node),
|
||||
op->text.start_glyph,
|
||||
op->text.num_glyphs);
|
||||
op->text.num_glyphs,
|
||||
op->text.scale);
|
||||
n_bytes += op->text.vertex_count;
|
||||
}
|
||||
break;
|
||||
|
@ -111,7 +111,8 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
|
||||
float x,
|
||||
float y,
|
||||
guint start_glyph,
|
||||
guint num_glyphs)
|
||||
guint num_glyphs,
|
||||
float scale)
|
||||
{
|
||||
GskVulkanTextInstance *instances = (GskVulkanTextInstance *) data;
|
||||
int i;
|
||||
@ -135,7 +136,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
|
||||
GskVulkanTextInstance *instance = &instances[count];
|
||||
GskVulkanCachedGlyph *glyph;
|
||||
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph);
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
|
||||
|
||||
instance->tex_rect[0] = glyph->tx;
|
||||
instance->tex_rect[1] = glyph->ty;
|
||||
|
@ -32,7 +32,8 @@ void gsk_vulkan_text_pipeline_collect_vertex_data (GskVulka
|
||||
float x,
|
||||
float y,
|
||||
guint start_glyph,
|
||||
guint num_glyphs);
|
||||
guint num_glyphs,
|
||||
float scale);
|
||||
gsize gsk_vulkan_text_pipeline_draw (GskVulkanTextPipeline *pipeline,
|
||||
VkCommandBuffer command_buffer,
|
||||
gsize offset,
|
||||
|
Loading…
Reference in New Issue
Block a user