[pango/redo-attrs: 12/16] Split off and underline position attribute




commit ae40e5e71b5f2825c2dbfb34ab6e9fc0ca335b88
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Feb 7 00:38:47 2022 -0500

    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));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]