[pango/pango2: 28/118] Split off an underline position attribute




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

    Split off an 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-item-private.h |  2 +-
 pango/pango-item.c         | 10 ++++++----
 pango/pango-markup.c       |  9 ++++++++-
 pango/pango-renderer.c     | 21 +++++++++++++++++----
 pango/pango-renderer.h     |  1 +
 pango/pango-run.c          | 22 +++++++++++++---------
 pango/serializer.c         | 14 ++++++++++++++
 tests/testattributes.c     |  4 ++--
 11 files changed, 81 insertions(+), 28 deletions(-)
---
diff --git a/pango/pango-attr-list.c b/pango/pango-attr-list.c
index 873b0d280..30de21784 100644
--- a/pango/pango-attr-list.c
+++ b/pango/pango-attr-list.c
@@ -1144,6 +1144,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 5a514053f..213d48e55 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 57d961257..805e1e2c4 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -91,6 +91,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),
@@ -151,12 +152,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
@@ -173,7 +168,6 @@ typedef enum {
   PANGO_UNDERLINE_NONE,
   PANGO_UNDERLINE_SINGLE,
   PANGO_UNDERLINE_DOUBLE,
-  PANGO_UNDERLINE_LOW,
   PANGO_UNDERLINE_ERROR
 } PangoUnderline;
 
@@ -181,6 +175,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_ALL
+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-item-private.h b/pango/pango-item-private.h
index 6705e19c8..5310c4d63 100644
--- a/pango/pango-item-private.h
+++ b/pango/pango-item-private.h
@@ -59,8 +59,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;
diff --git a/pango/pango-item.c b/pango/pango-item.c
index b977d4c5e..120f1b2fe 100644
--- a/pango/pango-item.c
+++ b/pango/pango-item.c
@@ -378,8 +378,8 @@ pango_item_get_properties (PangoItem      *item,
 
   properties->uline_single = FALSE;
   properties->uline_double = FALSE;
-  properties->uline_low = FALSE;
   properties->uline_error = FALSE;
+  properties->uline_position = PANGO_UNDERLINE_POSITION_NORMAL;
   properties->oline_single = FALSE;
   properties->strikethrough = FALSE;
   properties->showing_space = FALSE;
@@ -406,9 +406,6 @@ pango_item_get_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;
@@ -417,6 +414,11 @@ pango_item_get_properties (PangoItem      *item,
               break;
             }
           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 b84a0cade..3f55a17b6 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 2234807f9..90c0dee4b 100644
--- a/pango/pango-renderer.c
+++ b/pango/pango-renderer.c
@@ -44,6 +44,7 @@ struct _Point
 struct _LineState
 {
   PangoUnderline underline;
+  PangoUnderlinePosition underline_position;
   PangoRectangle underline_rect;
 
   gboolean strikethrough;
@@ -173,6 +174,7 @@ draw_underline (PangoRenderer *renderer,
   PangoUnderline underline = state->underline;
 
   state->underline = PANGO_UNDERLINE_NONE;
+  state->underline_position = PANGO_UNDERLINE_POSITION_NORMAL;
 
   switch (underline)
     {
@@ -187,7 +189,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,
@@ -272,6 +273,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;
     }
@@ -324,10 +326,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;
@@ -344,6 +349,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)
     {
@@ -355,6 +361,7 @@ add_underline (PangoRenderer    *renderer,
 
       *current_rect = new_rect;
       state->underline = renderer->underline;
+      state->underline_position = renderer->underline_position;
     }
 }
 
@@ -484,6 +491,7 @@ pango_renderer_draw_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;
 
@@ -1400,6 +1408,7 @@ pango_renderer_default_prepare_run (PangoRenderer  *renderer,
   glyph_item = pango_run_get_glyph_item (run);
 
   renderer->underline = PANGO_UNDERLINE_NONE;
+  renderer->underline_position = PANGO_UNDERLINE_POSITION_NORMAL;
   renderer->priv->overline = PANGO_OVERLINE_NONE;
   renderer->strikethrough = FALSE;
 
@@ -1413,6 +1422,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 ede8d4f3b..82e2dd88e 100644
--- a/pango/pango-renderer.h
+++ b/pango/pango-renderer.h
@@ -83,6 +83,7 @@ struct _PangoRenderer
   GObject parent_instance;
 
   PangoUnderline underline;
+  PangoUnderlinePosition underline_position;
   gboolean strikethrough;
   int active_count;
 
diff --git a/pango/pango-run.c b/pango/pango-run.c
index 7fba066c1..a1ba537ab 100644
--- a/pango/pango-run.c
+++ b/pango/pango-run.c
@@ -79,8 +79,9 @@ pango_run_get_extents (PangoRun         *run,
 
   pango_item_get_properties (glyph_item->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 (!logical_rect && (glyph_item->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE))
@@ -135,17 +136,20 @@ pango_run_get_extents (PangoRun         *run,
           ink_rect->height += underline_thickness;
         }
 
-      if (properties.uline_low)
-        ink_rect->height += 2 * underline_thickness;
       if (properties.uline_single)
-        ink_rect->height = MAX (ink_rect->height,
-                               underline_thickness - underline_position - ink_rect->y);
-      if (properties.uline_double)
+        {
+          if (properties.uline_position == PANGO_UNDERLINE_POSITION_UNDER)
+            ink_rect->height += 2 * underline_thickness;
+          else
+            ink_rect->height = MAX (ink_rect->height,
+                                    underline_thickness - underline_position - ink_rect->y);
+        }
+      else if (properties.uline_double)
         ink_rect->height = MAX (ink_rect->height,
                                  3 * underline_thickness - underline_position - ink_rect->y);
-      if (properties.uline_error)
+      else if (properties.uline_error)
         ink_rect->height = MAX (ink_rect->height,
-                               3 * underline_thickness - underline_position - ink_rect->y);
+                                3 * underline_thickness - underline_position - ink_rect->y);
     }
 
   y_offset = glyph_item->y_offset;
diff --git a/pango/serializer.c b/pango/serializer.c
index 62700344a..b2ad60919 100644
--- a/pango/serializer.c
+++ b/pango/serializer.c
@@ -82,6 +82,12 @@ static const char *underline_names[] = {
   NULL
 };
 
+static const char *underline_position_names[] = {
+  "normal",
+  "under",
+  NULL
+};
+
 static const char *overline_names[] = {
   "none",
   "single",
@@ -317,6 +323,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;
@@ -995,6 +1005,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 ec1a8a5a8..40fee748c 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]