[pango/pango2: 68/115] Make strikethrough styled




commit 301d9b2c8ef7e75a96d8ff4c94c350f2735efcc9
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Feb 7 01:17:08 2022 -0500

    Make strikethrough styled
    
    Support single and double styles for strikethrough.

 pango/pango-attr-list.c  |  3 ++-
 pango/pango-attributes.c |  6 ++---
 pango/pango-attributes.h |  7 ++---
 pango/pango-markup.c     | 26 ++++++++++++++-----
 pango/pango-renderer.c   | 66 +++++++++++++++++++++++++++++++++---------------
 pango/pango-renderer.h   |  2 +-
 pango/serializer.c       |  3 ++-
 7 files changed, 77 insertions(+), 36 deletions(-)
---
diff --git a/pango/pango-attr-list.c b/pango/pango-attr-list.c
index 6f85eeec..5a639b35 100644
--- a/pango/pango-attr-list.c
+++ b/pango/pango-attr-list.c
@@ -772,6 +772,7 @@ get_attr_value_type (PangoAttrType type)
     case PANGO_ATTR_GRAVITY: return PANGO_TYPE_GRAVITY;
     case PANGO_ATTR_GRAVITY_HINT: return PANGO_TYPE_GRAVITY_HINT;
     case PANGO_ATTR_UNDERLINE: return PANGO_TYPE_LINE_STYLE;
+    case PANGO_ATTR_STRIKETHROUGH: return PANGO_TYPE_LINE_STYLE;
     case PANGO_ATTR_OVERLINE: return PANGO_TYPE_OVERLINE;
     case PANGO_ATTR_BASELINE_SHIFT: return PANGO_TYPE_BASELINE_SHIFT;
     case PANGO_ATTR_FONT_SCALE: return PANGO_TYPE_FONT_SCALE;
@@ -1149,7 +1150,7 @@ pango_attr_list_from_string (const char *text)
           break;
 
         case PANGO_ATTR_STRIKETHROUGH:
-          BOOLEAN_ATTR(strikethrough, gboolean);
+          ENUM_ATTR(strikethrough, PangoLineStyle, PANGO_LINE_STYLE_NONE, PANGO_LINE_STYLE_DOTTED);
           break;
 
         case PANGO_ATTR_RISE:
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index e4ba9149..06131565 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -367,7 +367,7 @@ pango_attr_underline_position_new (PangoUnderlinePosition position)
 }
 /**
  * pango_attr_strikethrough_new:
- * @strikethrough: %TRUE if the text should be struck-through
+ * @style: the line style
  *
  * Create a new strike-through attribute.
  *
@@ -376,9 +376,9 @@ pango_attr_underline_position_new (PangoUnderlinePosition position)
  *   [method@Pango.Attribute.destroy]
  */
 PangoAttribute *
-pango_attr_strikethrough_new (gboolean strikethrough)
+pango_attr_strikethrough_new (PangoLineStyle style)
 {
-  return pango_attr_boolean_new (PANGO_ATTR_STRIKETHROUGH, (int)strikethrough);
+  return pango_attr_int_new (PANGO_ATTR_STRIKETHROUGH, (int)style);
 }
 
 /**
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index cbc05ab2..19f1a608 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -42,7 +42,8 @@ G_BEGIN_DECLS
  * @PANGO_ATTR_FONT_DESC: font description
  * @PANGO_ATTR_FOREGROUND: foreground color
  * @PANGO_ATTR_BACKGROUND: background color
- * @PANGO_ATTR_UNDERLINE: whether the text has an underline
+ * @PANGO_ATTR_UNDERLINE: underline style
+ * @PANGO_ATTR_UNDERLINE_POSITION: underline position
  * @PANGO_ATTR_STRIKETHROUGH: whether the text is struck-through
  * @PANGO_ATTR_RISE: baseline displacement
  * @PANGO_ATTR_SCALE: font size scale factor
@@ -92,7 +93,7 @@ typedef enum
   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_STRIKETHROUGH        = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
   PANGO_ATTR_RISE                 = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
   PANGO_ATTR_SCALE                = PANGO_ATTR_TYPE (FLOAT, ITEMIZATION, OVERRIDES),
   PANGO_ATTR_FALLBACK             = PANGO_ATTR_TYPE (BOOLEAN, ITEMIZATION, OVERRIDES),
@@ -179,7 +180,7 @@ PANGO_AVAILABLE_IN_ALL
 PangoAttribute *        pango_attr_underline_position_new       (PangoUnderlinePosition      position);
 
 PANGO_AVAILABLE_IN_ALL
-PangoAttribute *        pango_attr_strikethrough_new            (gboolean                    strikethrough);
+PangoAttribute *        pango_attr_strikethrough_new            (PangoLineStyle              style);
 PANGO_AVAILABLE_IN_1_8
 PangoAttribute *        pango_attr_strikethrough_color_new      (PangoColor                 *color);
 PANGO_AVAILABLE_IN_ALL
diff --git a/pango/pango-markup.c b/pango/pango-markup.c
index ec79aaa8..7233e4f4 100644
--- a/pango/pango-markup.c
+++ b/pango/pango-markup.c
@@ -1218,6 +1218,7 @@ span_parse_func     (MarkupData            *md G_GNUC_UNUSED,
   const char *foreground = NULL;
   const char *background = NULL;
   const char *underline = NULL;
+  const char *underline_position = NULL;
   const char *underline_color = NULL;
   const char *overline = NULL;
   const char *overline_color = NULL;
@@ -1332,6 +1333,7 @@ span_parse_func     (MarkupData            *md G_GNUC_UNUSED,
        break;
       case 'u':
        CHECK_ATTRIBUTE (underline);
+       CHECK_ATTRIBUTE (underline_position);
        CHECK_ATTRIBUTE (underline_color);
        break;
       case 'r':
@@ -1546,12 +1548,22 @@ span_parse_func     (MarkupData            *md G_GNUC_UNUSED,
 
   if (G_UNLIKELY (underline))
     {
-      PangoLineStyle ul = PANGO_LINE_STYLE_NONE;
+      PangoLineStyle style = PANGO_LINE_STYLE_NONE;
 
-      if (!span_parse_enum ("underline", underline, PANGO_TYPE_LINE_STYLE, (int*)(void*)&ul, line_number, 
error))
+      if (!span_parse_enum ("underline", underline, PANGO_TYPE_LINE_STYLE, (int*)(void*)&style, line_number, 
error))
        goto error;
 
-      add_attribute (tag, pango_attr_underline_new (ul));
+      add_attribute (tag, pango_attr_underline_new (style));
+    }
+
+  if (G_UNLIKELY (underline_position))
+    {
+      PangoUnderlinePosition pos = PANGO_UNDERLINE_POSITION_NORMAL;
+
+      if (!span_parse_enum ("underline_position", underline_position, PANGO_TYPE_UNDERLINE_POSITION, 
(int*)(void*)&pos, line_number, error))
+       goto error;
+
+      add_attribute (tag, pango_attr_underline_position_new (pos));
     }
 
   if (G_UNLIKELY (underline_color))
@@ -1619,12 +1631,12 @@ span_parse_func     (MarkupData            *md G_GNUC_UNUSED,
 
   if (G_UNLIKELY (strikethrough))
     {
-      gboolean b = FALSE;
+      PangoLineStyle style = PANGO_LINE_STYLE_NONE;
 
-      if (!span_parse_boolean ("strikethrough", strikethrough, &b, line_number, error))
-       goto error;
+      if (!span_parse_enum ("strikethrough", strikethrough, PANGO_TYPE_LINE_STYLE, (int*)(void*)&style, 
line_number, error))
+        goto error;
 
-      add_attribute (tag, pango_attr_strikethrough_new (b));
+      add_attribute (tag, pango_attr_strikethrough_new (style));
     }
 
   if (G_UNLIKELY (strikethrough_color))
diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c
index 737ad508..42d460e3 100644
--- a/pango/pango-renderer.c
+++ b/pango/pango-renderer.c
@@ -47,7 +47,7 @@ struct _LineState
   PangoUnderlinePosition underline_position;
   PangoRectangle underline_rect;
 
-  gboolean strikethrough;
+  PangoLineStyle strikethrough;
   PangoRectangle strikethrough_rect;
   int strikethrough_glyphs;
 
@@ -239,17 +239,40 @@ draw_strikethrough (PangoRenderer *renderer,
                     LineState     *state)
 {
   PangoRectangle *rect = &state->strikethrough_rect;
-  int num_glyphs = state->strikethrough_glyphs;
 
-  if (state->strikethrough && num_glyphs > 0)
-    pango_renderer_draw_rectangle (renderer,
-                                   PANGO_RENDER_PART_STRIKETHROUGH,
-                                   rect->x,
-                                   rect->y / num_glyphs,
-                                   rect->width,
-                                   rect->height / num_glyphs);
+  if (state->strikethrough_glyphs > 0)
+    {
+      rect->y /= state->strikethrough_glyphs;
+      rect->height /= state->strikethrough_glyphs;
+
+      switch (state->strikethrough)
+        {
+        case PANGO_LINE_STYLE_NONE:
+          break;
+        case PANGO_LINE_STYLE_DOUBLE:
+          pango_renderer_draw_rectangle (renderer,
+                                         PANGO_RENDER_PART_STRIKETHROUGH,
+                                         rect->x,
+                                         rect->y - rect->height,
+                                         rect->width,
+                                         rect->height);
+          rect->y += rect->height;
+          G_GNUC_FALLTHROUGH;
+        case PANGO_LINE_STYLE_SINGLE:
+        case PANGO_LINE_STYLE_DOTTED:
+          pango_renderer_draw_rectangle (renderer,
+                                         PANGO_RENDER_PART_STRIKETHROUGH,
+                                         rect->x,
+                                         rect->y,
+                                         rect->width,
+                                         rect->height);
+          break;
+        default:
+          break;
+        }
+    }
 
-  state->strikethrough = FALSE;
+  state->strikethrough = PANGO_LINE_STYLE_NONE;
   state->strikethrough_glyphs = 0;
   rect->x += rect->width;
   rect->width = 0;
@@ -291,7 +314,7 @@ handle_line_state_change (PangoRenderer  *renderer,
     }
 
   if (part == PANGO_RENDER_PART_STRIKETHROUGH &&
-      state->strikethrough)
+      state->strikethrough != PANGO_LINE_STYLE_NONE)
     {
       PangoRectangle *rect = &state->strikethrough_rect;
 
@@ -327,7 +350,7 @@ add_underline (PangoRenderer    *renderer,
       g_assert_not_reached ();
       break;
     case PANGO_LINE_STYLE_SINGLE:
-      if (state->underline_position == PANGO_UNDERLINE_POSITION_UNDER)
+      if (renderer->underline_position == PANGO_UNDERLINE_POSITION_UNDER)
         {
           new_rect.y += ink_rect->y + ink_rect->height + underline_thickness;
           break;
@@ -439,7 +462,7 @@ add_strikethrough (PangoRenderer    *renderer,
   new_rect.y = (base_y - strikethrough_position) * num_glyphs;
   new_rect.height = strikethrough_thickness * num_glyphs;
 
-  if (state->strikethrough)
+  if (state->strikethrough == renderer->strikethrough)
     {
       current_rect->width = new_rect.x + new_rect.width - current_rect->x;
       current_rect->y += new_rect.y;
@@ -448,8 +471,10 @@ add_strikethrough (PangoRenderer    *renderer,
     }
   else
     {
+      draw_strikethrough (renderer, state);
+
       *current_rect = new_rect;
-      state->strikethrough = TRUE;
+      state->strikethrough = renderer->strikethrough;
       state->strikethrough_glyphs = num_glyphs;
     }
 }
@@ -493,7 +518,7 @@ pango_renderer_draw_line (PangoRenderer   *renderer,
   state.underline = PANGO_LINE_STYLE_NONE;
   state.underline_position = PANGO_UNDERLINE_POSITION_NORMAL;
   state.overline = PANGO_OVERLINE_NONE;
-  state.strikethrough = FALSE;
+  state.strikethrough = PANGO_LINE_STYLE_NONE;
 
   pango_renderer_draw_runs (renderer, line->runs, line->data->text, x, y);
 
@@ -584,7 +609,7 @@ pango_renderer_draw_runs (PangoRenderer *renderer,
 
       if (renderer->underline != PANGO_LINE_STYLE_NONE ||
           renderer->priv->overline != PANGO_OVERLINE_NONE ||
-          renderer->strikethrough)
+          renderer->strikethrough != PANGO_LINE_STYLE_NONE)
         {
           ink = &ink_rect;
           logical = &logical_rect;
@@ -634,7 +659,7 @@ pango_renderer_draw_runs (PangoRenderer *renderer,
 
       if (renderer->underline != PANGO_LINE_STYLE_NONE ||
           renderer->priv->overline != PANGO_OVERLINE_NONE ||
-          renderer->strikethrough)
+          renderer->strikethrough != PANGO_LINE_STYLE_NONE)
         {
           metrics = pango_font_get_metrics (item->analysis.font,
                                             item->analysis.language);
@@ -649,7 +674,7 @@ pango_renderer_draw_runs (PangoRenderer *renderer,
                            x + x_off, y - y_off,
                            ink, logical);
 
-          if (renderer->strikethrough)
+          if (renderer->strikethrough != PANGO_LINE_STYLE_NONE)
             add_strikethrough (renderer, renderer->priv->line_state, metrics,
                                x + x_off, y - y_off,
                                ink, logical, glyphs->num_glyphs);
@@ -665,7 +690,8 @@ pango_renderer_draw_runs (PangoRenderer *renderer,
           renderer->priv->line_state->overline != PANGO_OVERLINE_NONE)
         draw_overline (renderer, renderer->priv->line_state);
 
-      if (!renderer->strikethrough && renderer->priv->line_state->strikethrough)
+      if (renderer->strikethrough == PANGO_LINE_STYLE_NONE &&
+          renderer->priv->line_state->strikethrough != PANGO_LINE_STYLE_NONE)
         draw_strikethrough (renderer, renderer->priv->line_state);
 
       x_off += glyph_string_width;
@@ -1410,7 +1436,7 @@ pango_renderer_default_prepare_run (PangoRenderer  *renderer,
   renderer->underline = PANGO_LINE_STYLE_NONE;
   renderer->underline_position = PANGO_UNDERLINE_POSITION_NORMAL;
   renderer->priv->overline = PANGO_OVERLINE_NONE;
-  renderer->strikethrough = FALSE;
+  renderer->strikethrough = PANGO_LINE_STYLE_NONE;
 
   for (l = glyph_item->item->analysis.extra_attrs; l; l = l->next)
     {
diff --git a/pango/pango-renderer.h b/pango/pango-renderer.h
index ea5816f5..403d3128 100644
--- a/pango/pango-renderer.h
+++ b/pango/pango-renderer.h
@@ -84,7 +84,7 @@ struct _PangoRenderer
 
   PangoLineStyle underline;
   PangoUnderlinePosition underline_position;
-  gboolean strikethrough;
+  PangoLineStyle strikethrough;
   int active_count;
 
   /*< public >*/
diff --git a/pango/serializer.c b/pango/serializer.c
index 3801ba67..fcf26ea8 100644
--- a/pango/serializer.c
+++ b/pango/serializer.c
@@ -319,6 +319,7 @@ add_attribute (GtkJsonPrinter *printer,
           break;
 
         case PANGO_ATTR_UNDERLINE:
+        case PANGO_ATTR_STRIKETHROUGH:
           gtk_json_printer_add_string (printer, "value", line_style_names[attr->int_value]);
           break;
 
@@ -1009,7 +1010,7 @@ attr_for_type (GtkJsonParser *parser,
       break;
 
     case PANGO_ATTR_STRIKETHROUGH:
-      attr = pango_attr_strikethrough_new (gtk_json_parser_get_boolean (parser));
+      attr = pango_attr_strikethrough_new ((PangoLineStyle) parser_select_string (parser, line_style_names));
       break;
 
     case PANGO_ATTR_RISE:


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