diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-09-03 17:21:08 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-09-03 17:21:08 +0000 |
commit | 64d2d7074fa59a4f1d261a866b564eb46ed45007 (patch) | |
tree | 670fbed94aa5c28a66a30de1c4cb4742111eb0a6 | |
parent | 44fea33c5d927cca8c48a40f14ed4f43d9ff5ff4 (diff) | |
parent | 062a15310aefd7feac19a5b7d2c3257d317dfff9 (diff) | |
download | gtk+-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.c | 11 | ||||
-rw-r--r-- | demos/gtk-demo/fontrendering.ui | 9 | ||||
-rw-r--r-- | gsk/gskrendernode.h | 13 | ||||
-rw-r--r-- | gsk/gskrendernodeimpl.c | 159 | ||||
-rw-r--r-- | gsk/ngl/gsknglglyphlibrary.c | 8 | ||||
-rw-r--r-- | gsk/ngl/gsknglglyphlibraryprivate.h | 5 | ||||
-rw-r--r-- | gsk/ngl/gsknglrenderjob.c | 7 | ||||
-rw-r--r-- | gtk/gskpango.c | 5 | ||||
-rw-r--r-- | gtk/gskpango.h | 2 | ||||
-rw-r--r-- | gtk/gtksnapshot.c | 22 | ||||
-rw-r--r-- | gtk/gtksnapshotprivate.h | 13 |
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); |