From 16b209a5e8abdc2dfed469f043498bf954efd7e0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 7 Feb 2022 00:38:47 -0500 Subject: Split off and underline position attribute Make the 'low' positioning a separate attribute. --- pango/pango-attr-list.c | 4 ++++ pango/pango-attributes.c | 5 +++++ pango/pango-attributes.h | 17 ++++++++++------- pango/pango-layout.c | 31 ++++++++++++++++++------------- pango/pango-markup.c | 9 ++++++++- pango/pango-renderer.c | 21 +++++++++++++++++---- pango/pango-renderer.h | 1 + pango/serializer.c | 14 ++++++++++++++ tests/testattributes.c | 4 ++-- 9 files changed, 79 insertions(+), 27 deletions(-) diff --git a/pango/pango-attr-list.c b/pango/pango-attr-list.c index 07e98b68..95e500dd 100644 --- a/pango/pango-attr-list.c +++ b/pango/pango-attr-list.c @@ -1138,6 +1138,10 @@ pango_attr_list_from_string (const char *text) ENUM_ATTR(underline, PangoUnderline, PANGO_UNDERLINE_NONE, PANGO_UNDERLINE_ERROR); break; + case PANGO_ATTR_UNDERLINE_POSITION: + ENUM_ATTR(underline_position, PangoUnderlinePosition, PANGO_UNDERLINE_POSITION_NORMAL, PANGO_UNDERLINE_POSITION_UNDER); + break; + case PANGO_ATTR_STRIKETHROUGH: BOOLEAN_ATTR(strikethrough, gboolean); break; diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 6568fbf1..019fa79a 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -360,6 +360,11 @@ pango_attr_underline_color_new (PangoColor *color) return pango_attr_color_new (PANGO_ATTR_UNDERLINE_COLOR, color); } +PangoAttribute * +pango_attr_underline_position_new (PangoUnderlinePosition position) +{ + return pango_attr_int_new (PANGO_ATTR_UNDERLINE_POSITION, (int)position); +} /** * pango_attr_strikethrough_new: * @strikethrough: %TRUE if the text should be struck-through diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 0a35bebb..dc276024 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -88,6 +88,7 @@ typedef enum PANGO_ATTR_FOREGROUND = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES), PANGO_ATTR_BACKGROUND = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES), PANGO_ATTR_UNDERLINE = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES), + PANGO_ATTR_UNDERLINE_POSITION = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES), PANGO_ATTR_STRIKETHROUGH = PANGO_ATTR_TYPE (BOOLEAN, RENDERING, OVERRIDES), PANGO_ATTR_RISE = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES), PANGO_ATTR_SCALE = PANGO_ATTR_TYPE (FLOAT, ITEMIZATION, OVERRIDES), @@ -146,12 +147,6 @@ PangoAttribute * pango_attr_font_desc_new (const PangoFont * @PANGO_UNDERLINE_NONE: no underline should be drawn * @PANGO_UNDERLINE_SINGLE: a single underline should be drawn * @PANGO_UNDERLINE_DOUBLE: a double underline should be drawn - * @PANGO_UNDERLINE_LOW: a single underline should be drawn at a - * position beneath the ink extents of the text being - * underlined. This should be used only for underlining - * single characters, such as for keyboard accelerators. - * %PANGO_UNDERLINE_SINGLE should be used for extended - * portions of text. * @PANGO_UNDERLINE_ERROR: an underline indicating an error should * be drawn below. The exact style of rendering is up to the * `PangoRenderer` in use, but typical styles include wavy @@ -168,7 +163,6 @@ typedef enum { PANGO_UNDERLINE_NONE, PANGO_UNDERLINE_SINGLE, PANGO_UNDERLINE_DOUBLE, - PANGO_UNDERLINE_LOW, PANGO_UNDERLINE_ERROR } PangoUnderline; @@ -176,6 +170,15 @@ PANGO_AVAILABLE_IN_ALL PangoAttribute * pango_attr_underline_new (PangoUnderline underline); PANGO_AVAILABLE_IN_1_8 PangoAttribute * pango_attr_underline_color_new (PangoColor *color); + +typedef enum { + PANGO_UNDERLINE_POSITION_NORMAL, + PANGO_UNDERLINE_POSITION_UNDER +} PangoUnderlinePosition; + +PANGO_AVAILABLE_IN_1_52 +PangoAttribute * pango_attr_underline_position_new (PangoUnderlinePosition position); + PANGO_AVAILABLE_IN_ALL PangoAttribute * pango_attr_strikethrough_new (gboolean strikethrough); PANGO_AVAILABLE_IN_1_8 diff --git a/pango/pango-layout.c b/pango/pango-layout.c index e09b6309..2e8e92e7 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -108,8 +108,8 @@ struct _ItemProperties { guint uline_single : 1; guint uline_double : 1; - guint uline_low : 1; guint uline_error : 1; + PangoUnderlinePosition uline_position; guint strikethrough : 1; guint oline_single : 1; guint showing_space : 1; @@ -5561,8 +5561,9 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run, pango_layout_get_item_properties (run->item, &properties); - has_underline = properties.uline_single || properties.uline_double || - properties.uline_low || properties.uline_error; + has_underline = properties.uline_single || + properties.uline_double || + properties.uline_error; has_overline = properties.oline_single; if (!run_logical && (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)) @@ -5620,15 +5621,18 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run, run_ink->height += underline_thickness; } - if (properties.uline_low) - run_ink->height += 2 * underline_thickness; if (properties.uline_single) - run_ink->height = MAX (run_ink->height, - underline_thickness - underline_position - run_ink->y); - if (properties.uline_double) + { + if (properties.uline_position == PANGO_UNDERLINE_POSITION_UNDER) + run_ink->height += 2 * underline_thickness; + else + run_ink->height = MAX (run_ink->height, + underline_thickness - underline_position - run_ink->y); + } + else if (properties.uline_double) run_ink->height = MAX (run_ink->height, 3 * underline_thickness - underline_position - run_ink->y); - if (properties.uline_error) + else if (properties.uline_error) run_ink->height = MAX (run_ink->height, 3 * underline_thickness - underline_position - run_ink->y); } @@ -6728,7 +6732,7 @@ pango_layout_get_item_properties (PangoItem *item, properties->uline_single = FALSE; properties->uline_double = FALSE; - properties->uline_low = FALSE; + properties->uline_position = PANGO_UNDERLINE_POSITION_NORMAL; properties->uline_error = FALSE; properties->oline_single = FALSE; properties->strikethrough = FALSE; @@ -6754,9 +6758,6 @@ pango_layout_get_item_properties (PangoItem *item, case PANGO_UNDERLINE_DOUBLE: properties->uline_double = TRUE; break; - case PANGO_UNDERLINE_LOW: - properties->uline_low = TRUE; - break; case PANGO_UNDERLINE_ERROR: properties->uline_error = TRUE; break; @@ -6766,6 +6767,10 @@ pango_layout_get_item_properties (PangoItem *item, } break; + case PANGO_ATTR_UNDERLINE_POSITION: + properties->uline_position = attr->int_value; + break; + case PANGO_ATTR_OVERLINE: switch (attr->int_value) { diff --git a/pango/pango-markup.c b/pango/pango-markup.c index 6f7a2a67..f8838d84 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -500,7 +500,7 @@ text_handler (GMarkupParseContext *context G_GNUC_UNUSED, /* Add the underline indicating the accelerator */ PangoAttribute *attr; - attr = pango_attr_underline_new (PANGO_UNDERLINE_LOW); + attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); uline_index = md->index; uline_len = g_utf8_next_char (p) - p; @@ -509,6 +509,13 @@ text_handler (GMarkupParseContext *context G_GNUC_UNUSED, attr->end_index = uline_index + uline_len; pango_attr_list_change (md->attr_list, attr); + + attr = pango_attr_underline_position_new (PANGO_UNDERLINE_POSITION_UNDER); + + attr->start_index = uline_index; + attr->end_index = uline_index + uline_len; + + pango_attr_list_change (md->attr_list, attr); } /* set next range_start to include this char */ diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c index 687e678c..c4c20a87 100644 --- a/pango/pango-renderer.c +++ b/pango/pango-renderer.c @@ -42,6 +42,7 @@ struct _Point struct _LineState { PangoUnderline underline; + PangoUnderlinePosition underline_position; PangoRectangle underline_rect; gboolean strikethrough; @@ -218,6 +219,7 @@ draw_underline (PangoRenderer *renderer, PangoUnderline underline = state->underline; state->underline = PANGO_UNDERLINE_NONE; + state->underline_position = PANGO_UNDERLINE_POSITION_NORMAL; switch (underline) { @@ -232,7 +234,6 @@ draw_underline (PangoRenderer *renderer, rect->height); G_GNUC_FALLTHROUGH; case PANGO_UNDERLINE_SINGLE: - case PANGO_UNDERLINE_LOW: pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_UNDERLINE, rect->x, @@ -317,6 +318,7 @@ handle_line_state_change (PangoRenderer *renderer, rect->width = state->logical_rect_end - rect->x; draw_underline (renderer, state); state->underline = renderer->underline; + state->underline_position = renderer->underline_position; rect->x = state->logical_rect_end; rect->width = 0; } @@ -369,10 +371,13 @@ add_underline (PangoRenderer *renderer, case PANGO_UNDERLINE_NONE: g_assert_not_reached (); break; - case PANGO_UNDERLINE_LOW: - new_rect.y += ink_rect->y + ink_rect->height + underline_thickness; - break; case PANGO_UNDERLINE_SINGLE: + if (state->underline_position == PANGO_UNDERLINE_POSITION_UNDER) + { + new_rect.y += ink_rect->y + ink_rect->height + underline_thickness; + break; + } + G_GNUC_FALLTHROUGH; case PANGO_UNDERLINE_DOUBLE: case PANGO_UNDERLINE_ERROR: new_rect.y -= underline_position; @@ -389,6 +394,7 @@ add_underline (PangoRenderer *renderer, } if (renderer->underline == state->underline && + renderer->underline_position == state->underline_position && new_rect.y == current_rect->y && new_rect.height == current_rect->height) { @@ -400,6 +406,7 @@ add_underline (PangoRenderer *renderer, *current_rect = new_rect; state->underline = renderer->underline; + state->underline_position = renderer->underline_position; } } @@ -541,6 +548,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, renderer->priv->line_state = &state; state.underline = PANGO_UNDERLINE_NONE; + state.underline_position = PANGO_UNDERLINE_POSITION_NORMAL; state.overline = PANGO_OVERLINE_NONE; state.strikethrough = FALSE; @@ -1396,6 +1404,7 @@ pango_renderer_default_prepare_run (PangoRenderer *renderer, GSList *l; renderer->underline = PANGO_UNDERLINE_NONE; + renderer->underline_position = PANGO_UNDERLINE_POSITION_NORMAL; renderer->priv->overline = PANGO_OVERLINE_NONE; renderer->strikethrough = FALSE; @@ -1409,6 +1418,10 @@ pango_renderer_default_prepare_run (PangoRenderer *renderer, renderer->underline = attr->int_value; break; + case PANGO_ATTR_UNDERLINE_POSITION: + renderer->underline_position = attr->int_value; + break; + case PANGO_ATTR_OVERLINE: renderer->priv->overline = attr->int_value; break; diff --git a/pango/pango-renderer.h b/pango/pango-renderer.h index 20bf59d9..fcad2b3d 100644 --- a/pango/pango-renderer.h +++ b/pango/pango-renderer.h @@ -80,6 +80,7 @@ struct _PangoRenderer GObject parent_instance; PangoUnderline underline; + PangoUnderlinePosition underline_position; gboolean strikethrough; int active_count; diff --git a/pango/serializer.c b/pango/serializer.c index 3b0e3dd5..9a1ee065 100644 --- a/pango/serializer.c +++ b/pango/serializer.c @@ -81,6 +81,12 @@ static const char *underline_names[] = { NULL }; +static const char *underline_position_names[] = { + "normal", + "under", + NULL +}; + static const char *overline_names[] = { "none", "single", @@ -322,6 +328,10 @@ add_attribute (GtkJsonPrinter *printer, gtk_json_printer_add_string (printer, "value", underline_names[attr->int_value]); break; + case PANGO_ATTR_UNDERLINE_POSITION: + gtk_json_printer_add_string (printer, "value", underline_position_names[attr->int_value]); + break; + case PANGO_ATTR_OVERLINE: gtk_json_printer_add_string (printer, "value", overline_names[attr->int_value]); break; @@ -1006,6 +1016,10 @@ attr_for_type (GtkJsonParser *parser, attr = pango_attr_underline_new ((PangoUnderline) parser_select_string (parser, underline_names)); break; + case PANGO_ATTR_UNDERLINE_POSITION: + attr = pango_attr_underline_position_new ((PangoUnderlinePosition) parser_select_string (parser, underline_position_names)); + break; + case PANGO_ATTR_STRIKETHROUGH: attr = pango_attr_strikethrough_new (gtk_json_parser_get_boolean (parser)); break; diff --git a/tests/testattributes.c b/tests/testattributes.c index a066422c..e07387f4 100644 --- a/tests/testattributes.c +++ b/tests/testattributes.c @@ -50,7 +50,7 @@ test_attributes_basic (void) desc = pango_font_description_from_string ("Computer Modern 12"); test_copy (pango_attr_font_desc_new (desc)); pango_font_description_free (desc); - test_copy (pango_attr_underline_new (PANGO_UNDERLINE_LOW)); + test_copy (pango_attr_underline_new (PANGO_UNDERLINE_SINGLE)); test_copy (pango_attr_underline_new (PANGO_UNDERLINE_ERROR)); test_copy (pango_attr_underline_color_new (&(PangoColor){100, 200, 300})); test_copy (pango_attr_overline_new (PANGO_OVERLINE_SINGLE)); @@ -230,7 +230,7 @@ test_binding_helpers (void) desc = pango_font_description_from_string ("Computer Modern 12"); test_binding (pango_attr_font_desc_new (desc)); pango_font_description_free (desc); - test_binding (pango_attr_underline_new (PANGO_UNDERLINE_LOW)); + test_binding (pango_attr_underline_new (PANGO_UNDERLINE_SINGLE)); test_binding (pango_attr_underline_new (PANGO_UNDERLINE_ERROR)); test_binding (pango_attr_underline_color_new (&(PangoColor){100, 200, 300})); test_binding (pango_attr_overline_new (PANGO_OVERLINE_SINGLE)); -- cgit v1.2.1