summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-09-03 17:21:08 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-09-03 17:21:08 +0000
commit64d2d7074fa59a4f1d261a866b564eb46ed45007 (patch)
tree670fbed94aa5c28a66a30de1c4cb4742111eb0a6
parent44fea33c5d927cca8c48a40f14ed4f43d9ff5ff4 (diff)
parent062a15310aefd7feac19a5b7d2c3257d317dfff9 (diff)
downloadgtk+-64d2d7074fa59a4f1d261a866b564eb46ed45007.tar.gz
Merge branch 'small-text-fixes' into 'master'
gsk: Pass font options down See merge request GNOME/gtk!3908
-rw-r--r--demos/gtk-demo/fontrendering.c11
-rw-r--r--demos/gtk-demo/fontrendering.ui9
-rw-r--r--gsk/gskrendernode.h13
-rw-r--r--gsk/gskrendernodeimpl.c159
-rw-r--r--gsk/ngl/gsknglglyphlibrary.c8
-rw-r--r--gsk/ngl/gsknglglyphlibraryprivate.h5
-rw-r--r--gsk/ngl/gsknglrenderjob.c7
-rw-r--r--gtk/gskpango.c5
-rw-r--r--gtk/gskpango.h2
-rw-r--r--gtk/gtksnapshot.c22
-rw-r--r--gtk/gtksnapshotprivate.h13
11 files changed, 217 insertions, 37 deletions
diff --git a/demos/gtk-demo/fontrendering.c b/demos/gtk-demo/fontrendering.c
index 005f3637c6..e95a78f7e7 100644
--- a/demos/gtk-demo/fontrendering.c
+++ b/demos/gtk-demo/fontrendering.c
@@ -10,6 +10,7 @@ static GtkWidget *font_button = NULL;
static GtkWidget *entry = NULL;
static GtkWidget *image = NULL;
static GtkWidget *hinting = NULL;
+static GtkWidget *anti_alias = NULL;
static GtkWidget *hint_metrics = NULL;
static GtkWidget *up_button = NULL;
static GtkWidget *down_button = NULL;
@@ -37,6 +38,7 @@ update_image (void)
cairo_font_options_t *fopt;
cairo_hint_style_t hintstyle;
cairo_hint_metrics_t hintmetrics;
+ cairo_antialias_t antialias;
if (!context)
context = gtk_widget_create_pango_context (image);
@@ -65,6 +67,13 @@ update_image (void)
hintmetrics = CAIRO_HINT_METRICS_OFF;
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (anti_alias)))
+ antialias = CAIRO_ANTIALIAS_GRAY;
+ else
+ antialias = CAIRO_ANTIALIAS_NONE;
+ cairo_font_options_set_antialias (fopt, antialias);
+
+ pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
@@ -252,6 +261,7 @@ do_fontrendering (GtkWidget *do_widget)
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
+ anti_alias = GTK_WIDGET (gtk_builder_get_object (builder, "antialias"));
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
@@ -262,6 +272,7 @@ do_fontrendering (GtkWidget *do_widget)
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
+ g_signal_connect (anti_alias, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
diff --git a/demos/gtk-demo/fontrendering.ui b/demos/gtk-demo/fontrendering.ui
index 363f6f5e3d..fc7a9fed4a 100644
--- a/demos/gtk-demo/fontrendering.ui
+++ b/demos/gtk-demo/fontrendering.ui
@@ -99,6 +99,15 @@
</object>
</child>
<child>
+ <object class="GtkCheckButton" id="antialias">
+ <property name="label">Antialias</property>
+ <layout>
+ <property name="column">3</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index c420633a91..c362ddb70c 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -492,6 +492,19 @@ GskRenderNode * gsk_text_node_new (PangoFont
PangoGlyphString *glyphs,
const GdkRGBA *color,
const graphene_point_t *offset);
+GDK_AVAILABLE_IN_4_6
+GskRenderNode * gsk_text_node_new_with_font_options (const cairo_font_options_t *options,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ const graphene_point_t *offset);
+
+GDK_AVAILABLE_IN_4_6
+gboolean gsk_text_node_get_hint_metrics (const GskRenderNode *node) G_GNUC_PURE;
+GDK_AVAILABLE_IN_4_6
+gboolean gsk_text_node_get_antialias (const GskRenderNode *node) G_GNUC_PURE;
+GDK_AVAILABLE_IN_4_6
+cairo_hint_style_t gsk_text_node_get_hint_style (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
PangoFont * gsk_text_node_get_font (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 30ef0ff38b..8a4c003a5a 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -4336,7 +4336,10 @@ struct _GskTextNode
GskRenderNode render_node;
PangoFont *font;
- gboolean has_color_glyphs;
+ guint has_color_glyphs : 1;
+ guint hint_metrics : 1;
+ guint antialias : 1;
+ guint hint_style : 3;
GdkRGBA color;
graphene_point_t offset;
@@ -4363,6 +4366,7 @@ gsk_text_node_draw (GskRenderNode *node,
{
GskTextNode *self = (GskTextNode *) node;
PangoGlyphString glyphs;
+ cairo_font_options_t *options;
glyphs.num_glyphs = self->num_glyphs;
glyphs.glyphs = self->glyphs;
@@ -4370,6 +4374,13 @@ gsk_text_node_draw (GskRenderNode *node,
cairo_save (cr);
+ options = cairo_font_options_create ();
+ cairo_font_options_set_hint_metrics (options, self->hint_metrics ? CAIRO_HINT_METRICS_ON : CAIRO_HINT_METRICS_OFF);
+ cairo_font_options_set_antialias (options, self->antialias ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE);
+ cairo_font_options_set_hint_style (options, self->hint_style);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
gdk_cairo_set_source_rgba (cr, &self->color);
cairo_translate (cr, self->offset.x, self->offset.y);
pango_cairo_show_glyph_string (cr, self->font, &glyphs);
@@ -4424,25 +4435,12 @@ gsk_text_node_diff (GskRenderNode *node1,
gsk_render_node_diff_impossible (node1, node2, region);
}
-/**
- * gsk_text_node_new:
- * @font: the `PangoFont` containing the glyphs
- * @glyphs: the `PangoGlyphString` to render
- * @color: the foreground color to render with
- * @offset: offset of the baseline
- *
- * Creates a render node that renders the given glyphs.
- *
- * Note that @color may not be used if the font contains
- * color glyphs.
- *
- * Returns: (nullable) (transfer full) (type GskTextNode): a new `GskRenderNode`
- */
-GskRenderNode *
-gsk_text_node_new (PangoFont *font,
- PangoGlyphString *glyphs,
- const GdkRGBA *color,
- const graphene_point_t *offset)
+static GskRenderNode *
+gsk_text_node_new_internal (const cairo_font_options_t *options,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ const graphene_point_t *offset)
{
GskTextNode *self;
GskRenderNode *node;
@@ -4464,6 +4462,16 @@ gsk_text_node_new (PangoFont *font,
self->color = *color;
self->offset = *offset;
self->has_color_glyphs = FALSE;
+ self->antialias = TRUE;
+ self->hint_style = CAIRO_HINT_STYLE_NONE;
+ self->hint_metrics = FALSE;
+
+ if (options)
+ {
+ self->antialias = cairo_font_options_get_antialias (options) != CAIRO_ANTIALIAS_NONE;
+ self->hint_metrics = cairo_font_options_get_hint_metrics (options) == CAIRO_HINT_METRICS_ON;
+ self->hint_style = cairo_font_options_get_hint_style (options);
+ }
glyph_infos = g_malloc_n (glyphs->num_glyphs, sizeof (PangoGlyphInfo));
@@ -4495,6 +4503,117 @@ gsk_text_node_new (PangoFont *font,
}
/**
+ * gsk_text_node_new_with_font_options:
+ * @options: `cairo_font_options_t` to render with
+ * @font: the `PangoFont` containing the glyphs
+ * @glyphs: the `PangoGlyphString` to render
+ * @color: the foreground color to render with
+ * @offset: offset of the baseline
+ *
+ * Creates a render node that renders the given glyphs.
+ *
+ * Note that @color may not be used if the font contains
+ * color glyphs.
+ *
+ * Returns: (nullable) (transfer full) (type GskTextNode): a new `GskRenderNode`
+ *
+ * Since: 4.6
+ */
+GskRenderNode *
+gsk_text_node_new_with_font_options (const cairo_font_options_t *options,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ const graphene_point_t *offset)
+{
+ return gsk_text_node_new_internal (options, font, glyphs, color, offset);
+}
+
+/**
+ * gsk_text_node_new:
+ * @font: the `PangoFont` containing the glyphs
+ * @glyphs: the `PangoGlyphString` to render
+ * @color: the foreground color to render with
+ * @offset: offset of the baseline
+ *
+ * Creates a render node that renders the given glyphs.
+ *
+ * Note that @color may not be used if the font contains
+ * color glyphs.
+ *
+ * Returns: (nullable) (transfer full) (type GskTextNode): a new `GskRenderNode`
+ */
+GskRenderNode *
+gsk_text_node_new (PangoFont *font,
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ const graphene_point_t *offset)
+{
+ return gsk_text_node_new_internal (NULL, font, glyphs, color, offset);
+}
+
+/**
+ * gsk_text_node_get_hint_metrics:
+ * @node: (type GskTextNode): a text `GskRenderNode`
+ *
+ * Retrieves whether metrics hinting is enabled for rendering.
+ *
+ * See the cairo [documentation](https://www.cairographics.org/manual/cairo-cairo-font-options-t.html#cairo-hint-metrics-t).
+ *
+ * Returns: whether metrics hinting is enabled
+ *
+ * Since: 4.6
+ */
+gboolean
+gsk_text_node_get_hint_metrics (const GskRenderNode *node)
+{
+ const GskTextNode *self = (const GskTextNode *) node;
+
+ return self->hint_metrics;
+}
+
+/**
+ * gsk_text_node_get_antialias:
+ * @node: (type GskTextNode): a text `GskRenderNode`
+ *
+ * Retrieves whether antialiasing is enabled for rendering.
+ *
+ * See the cairo [documentation](https://www.cairographics.org/manual/cairo-cairo-t.html#cairo-antialias-t).
+ * Note that GSK only supports grayscale antialiasing.
+ *
+ * Returns: whether antialiasing is enabled
+ *
+ * Since: 4.6
+ */
+gboolean
+gsk_text_node_get_antialias (const GskRenderNode *node)
+{
+ const GskTextNode *self = (const GskTextNode *) node;
+
+ return self->antialias;
+}
+
+/**
+ * gsk_text_node_get_hint_style:
+ * @node: (type GskTextNode): a text `GskRenderNode`
+ *
+ * Retrieves what style of font hinting is used for rendering.
+ *
+ * See the cairo [documentation](https://www.cairographics.org/manual/cairo-cairo-font-options-t.html#cairo-hint-style-t).
+ *
+ * Returns: what style of hinting is used
+ *
+ * Since: 4.6
+ */
+cairo_hint_style_t
+gsk_text_node_get_hint_style (const GskRenderNode *node)
+{
+ const GskTextNode *self = (const GskTextNode *) node;
+
+ return self->hint_style;
+}
+
+/**
* gsk_text_node_get_color:
* @node: (type GskTextNode): a text `GskRenderNode`
*
diff --git a/gsk/ngl/gsknglglyphlibrary.c b/gsk/ngl/gsknglglyphlibrary.c
index 9f269d8643..fdfa1abe30 100644
--- a/gsk/ngl/gsknglglyphlibrary.c
+++ b/gsk/ngl/gsknglglyphlibrary.c
@@ -166,11 +166,19 @@ render_glyph (cairo_surface_t *surface,
{
cairo_t *cr;
cairo_glyph_t glyph;
+ cairo_font_options_t *options;
g_assert (surface != NULL);
g_assert (scaled_font != NULL);
cr = cairo_create (surface);
+ options = cairo_font_options_create ();
+ cairo_font_options_set_hint_metrics (options, key->hint_metrics ? CAIRO_HINT_METRICS_ON : CAIRO_HINT_METRICS_OFF);
+ cairo_font_options_set_antialias (options, key->antialias ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE);
+ cairo_font_options_set_hint_style (options, key->hint_style);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
cairo_set_scaled_font (cr, scaled_font);
cairo_set_source_rgba (cr, 1, 1, 1, 1);
diff --git a/gsk/ngl/gsknglglyphlibraryprivate.h b/gsk/ngl/gsknglglyphlibraryprivate.h
index a9f099c0b5..6d9e81060e 100644
--- a/gsk/ngl/gsknglglyphlibraryprivate.h
+++ b/gsk/ngl/gsknglglyphlibraryprivate.h
@@ -35,7 +35,10 @@ typedef struct _GskNglGlyphKey
PangoGlyph glyph;
guint xshift : 2;
guint yshift : 2;
- guint scale : 28; /* times 1024 */
+ guint hint_metrics : 1;
+ guint antialias : 1;
+ guint hint_style : 3;
+ guint scale : 23; /* times 1024 */
} GskNglGlyphKey;
typedef struct _GskNglGlyphValue
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 4b04310e66..719b9da0dc 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -2875,9 +2875,16 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob *job,
rgba_to_half (color, cc);
+ /* We have 23 bits in the key for the scale */
+ g_assert (text_scale * 1024 < (1 << 24));
+
lookup.font = (PangoFont *)font;
lookup.scale = (guint) (text_scale * 1024);
+ lookup.hint_metrics = gsk_text_node_get_hint_metrics (node);
+ lookup.antialias = gsk_text_node_get_antialias (node);
+ lookup.hint_style = gsk_text_node_get_hint_style (node);
+
yshift = compute_phase_and_pos (y, &ypos);
gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, coloring));
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index e96c84a2fc..93aba75f60 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -100,6 +100,7 @@ gsk_pango_renderer_draw_glyph_item (PangoRenderer *renderer,
get_color (crenderer, PANGO_RENDER_PART_FOREGROUND, &color);
gtk_snapshot_append_text (crenderer->snapshot,
+ crenderer->options,
glyph_item->item->analysis.font,
glyph_item->glyphs,
&color,
@@ -467,14 +468,18 @@ gtk_snapshot_append_layout (GtkSnapshot *snapshot,
const GdkRGBA *color)
{
GskPangoRenderer *crenderer;
+ PangoContext *context;
g_return_if_fail (snapshot != NULL);
g_return_if_fail (PANGO_IS_LAYOUT (layout));
crenderer = gsk_pango_renderer_acquire ();
+ context = pango_layout_get_context (layout);
+
crenderer->snapshot = snapshot;
crenderer->fg_color = color;
+ crenderer->options = pango_cairo_context_get_font_options (context);
pango_renderer_draw_layout (PANGO_RENDERER (crenderer), layout, 0, 0);
diff --git a/gtk/gskpango.h b/gtk/gskpango.h
index 672128d1c1..05fa2254a0 100644
--- a/gtk/gskpango.h
+++ b/gtk/gskpango.h
@@ -63,6 +63,8 @@ struct _GskPangoRenderer
/* Error underline color for this widget */
GdkRGBA *error_color;
+ const cairo_font_options_t *options;
+
GskPangoRendererState state;
guint is_cached_renderer : 1;
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 5ebb37f14f..b8d0968c8f 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -2121,22 +2121,24 @@ gtk_snapshot_render_layout (GtkSnapshot *snapshot,
}
void
-gtk_snapshot_append_text (GtkSnapshot *snapshot,
- PangoFont *font,
- PangoGlyphString *glyphs,
- const GdkRGBA *color,
- float x,
- float y)
+gtk_snapshot_append_text (GtkSnapshot *snapshot,
+ const cairo_font_options_t *options,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ float x,
+ float y)
{
GskRenderNode *node;
float dx, dy;
gtk_snapshot_ensure_translate (snapshot, &dx, &dy);
- node = gsk_text_node_new (font,
- glyphs,
- color,
- &GRAPHENE_POINT_INIT (x + dx, y + dy));
+ node = gsk_text_node_new_with_font_options (options,
+ font,
+ glyphs,
+ color,
+ &GRAPHENE_POINT_INIT (x + dx, y + dy));
if (node == NULL)
return;
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index 99714c5a99..ca32df1a52 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -24,12 +24,13 @@
G_BEGIN_DECLS
-void gtk_snapshot_append_text (GtkSnapshot *snapshot,
- PangoFont *font,
- PangoGlyphString *glyphs,
- const GdkRGBA *color,
- float x,
- float y);
+void gtk_snapshot_append_text (GtkSnapshot *snapshot,
+ const cairo_font_options_t *options,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ float x,
+ float y);
void gtk_snapshot_push_collect (GtkSnapshot *snapshot);
GskRenderNode * gtk_snapshot_pop_collect (GtkSnapshot *snapshot);