glyphpaintable: Improve palette handling

Parse the custom colors when they are set,
not every time we snapshot.
This commit is contained in:
Matthias Clasen
2023-01-23 22:31:21 -05:00
parent 1869909a7d
commit ce23f588d0

View File

@@ -15,6 +15,8 @@ struct _GtkGlyphPaintable
hb_codepoint_t glyph;
unsigned int palette_index;
char *variations;
GdkRGBA *custom_palette;
unsigned int num_palette_entries;
char *custom_colors;
GdkRGBA color;
unsigned int uses_foreground : 1;
@@ -50,7 +52,7 @@ gtk_glyph_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable,
GskRenderNode *node;
GdkRGBA foreground_color;
unsigned int num_colors = 0;
GdkRGBA *_colors = NULL;
GdkRGBA *custom_palette = NULL;
if (self->face == NULL)
return;
@@ -60,41 +62,23 @@ gtk_glyph_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable,
else
foreground_color = self->color;
if (self->custom_colors)
if (self->custom_palette && colors)
{
char **entries = g_strsplit (self->custom_colors, ",", -1);
num_colors = self->num_palette_entries;
custom_palette = g_newa (GdkRGBA, num_colors);
num_colors = g_strv_length (entries);
if (n_colors > 1)
num_colors = MAX (n_colors - 1, num_colors);
_colors = g_new0 (GdkRGBA, num_colors);
for (int i = 0; entries[i]; i++)
{
unsigned int r, g, b, a;
if (sscanf (entries[i], "%2x%2x%2x%2x", &r, &g, &b, &a) == 4)
{
_colors[i].red = r / 255.;
_colors[i].green = g / 255.;
_colors[i].blue = b / 255.;
_colors[i].alpha = a / 255.;
}
}
g_strfreev (entries);
memcpy (custom_palette, self->custom_palette, sizeof (GdkRGBA) * num_colors);
memcpy (custom_palette, &colors[1], sizeof (GdkRGBA) * MIN (n_colors - 1, num_colors));
}
if (n_colors > 1 && !colors)
colors = g_new0 (GdkRGBA, n_colors - 1);
for (int i = 0; i + 1 < MIN (4, n_colors); i++)
else if (self->custom_palette)
{
_colors[i].red = colors[i + 1].red;
_colors[i].green = colors[i + 1].green;
_colors[i].blue = colors[i + 1].blue;
_colors[i].alpha = colors[i + 1].alpha;
num_colors = self->num_palette_entries;
custom_palette = self->custom_palette;
}
else
{
num_colors = n_colors;
custom_palette = (GdkRGBA *)colors;
}
node = gsk_glyph_node_new (&GRAPHENE_RECT_INIT (0, 0, width, height),
@@ -103,7 +87,7 @@ gtk_glyph_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable,
self->palette_index,
&foreground_color,
num_colors,
_colors);
custom_palette);
gtk_snapshot_append_node (snapshot, node);
@@ -185,6 +169,7 @@ gtk_glyph_paintable_dispose (GObject *object)
g_clear_pointer (&self->font, hb_font_destroy);
g_free (self->variations);
g_free (self->custom_colors);
g_free (self->custom_palette);
G_OBJECT_CLASS (gtk_glyph_paintable_parent_class)->dispose (object);
}
@@ -558,6 +543,55 @@ gtk_glyph_paintable_get_glyph (GtkGlyphPaintable *self)
return self->glyph;
}
static void
update_custom_palette (GtkGlyphPaintable *self)
{
unsigned int len;
hb_color_t *colors;
char **entries;
if (self->custom_colors == NULL)
{
g_clear_pointer (&self->custom_palette, g_free);
self->num_palette_entries = 0;
return;
}
len = hb_ot_color_palette_get_colors (self->face, self->palette_index, 0, NULL, NULL);
if (self->num_palette_entries != len)
{
self->custom_palette = g_realloc (self->custom_palette, sizeof (GdkRGBA) * len);
self->num_palette_entries = len;
}
colors = g_newa (hb_color_t, len);
hb_ot_color_palette_get_colors (self->face, self->palette_index, 0, &len, colors);
for (unsigned int i = 0; i < len; i++)
{
self->custom_palette[i].red = hb_color_get_red (colors[i]) / 255.;
self->custom_palette[i].green = hb_color_get_green (colors[i]) / 255.;
self->custom_palette[i].blue = hb_color_get_blue (colors[i]) / 255.;
self->custom_palette[i].alpha = hb_color_get_alpha (colors[i]) / 255.;
}
entries = g_strsplit (self->custom_colors, ",", -1);
for (int i = 0; entries[i] && i < len; i++)
{
unsigned int r, g, b, a;
if (sscanf (entries[i], "%2x%2x%2x%2x", &r, &g, &b, &a) == 4)
{
self->custom_palette[i].red = r / 255.;
self->custom_palette[i].green = g / 255.;
self->custom_palette[i].blue = b / 255.;
self->custom_palette[i].alpha = a / 255.;
}
}
g_strfreev (entries);
}
void
gtk_glyph_paintable_set_palette_index (GtkGlyphPaintable *self,
unsigned int palette_index)
@@ -566,6 +600,8 @@ gtk_glyph_paintable_set_palette_index (GtkGlyphPaintable *self,
self->palette_index = palette_index;
update_custom_palette (self);
if (self->uses_palette)
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE_INDEX]);
@@ -612,6 +648,8 @@ gtk_glyph_paintable_set_custom_colors (GtkGlyphPaintable *self,
g_free (self->custom_colors);
self->custom_colors = g_strdup (custom_colors);
update_custom_palette (self);
if (self->uses_palette)
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CUSTOM_COLORS]);