[pango/pango2-color-palette: 34/71] Implement all the line styles




commit 509d24d0359bc7c30028a7408b781d803c665959
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jun 22 23:22:32 2022 -0400

    Implement all the line styles

 pango/pango-renderer.c    | 127 +++++++++++++++++++++++--------
 pango/pango-renderer.h    |  27 +++++--
 pango/pangocairo-render.c | 188 ++++++++++++++++++++++------------------------
 pango/pangocairo-render.h |  21 ++----
 4 files changed, 211 insertions(+), 152 deletions(-)
---
diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c
index 03e24bb66..3bd2b7ea1 100644
--- a/pango/pango-renderer.c
+++ b/pango/pango-renderer.c
@@ -96,7 +96,9 @@ static void pango_renderer_default_draw_rectangle       (PangoRenderer    *rende
                                                          int               y,
                                                          int               width,
                                                          int               height);
-static void pango_renderer_default_draw_error_underline (PangoRenderer    *renderer,
+static void pango_renderer_default_draw_styled_line     (PangoRenderer    *renderer,
+                                                         PangoRenderPart   part,
+                                                         PangoLineStyle    style,
                                                          int               x,
                                                          int               y,
                                                          int               width,
@@ -136,7 +138,7 @@ pango_renderer_class_init (PangoRendererClass *klass)
   klass->draw_glyphs = pango_renderer_default_draw_glyphs;
   klass->draw_run = pango_renderer_default_draw_run;
   klass->draw_rectangle = pango_renderer_default_draw_rectangle;
-  klass->draw_error_underline = pango_renderer_default_draw_error_underline;
+  klass->draw_styled_line = pango_renderer_default_draw_styled_line;
   klass->prepare_run = pango_renderer_default_prepare_run;
 
   gobject_class->finalize = pango_renderer_finalize;
@@ -200,8 +202,6 @@ draw_underline (PangoRenderer *renderer,
                                      rect->height);
       G_GNUC_FALLTHROUGH;
     case PANGO_LINE_STYLE_SOLID:
-    case PANGO_LINE_STYLE_DOTTED:
-    case PANGO_LINE_STYLE_DASHED:
       pango_renderer_draw_rectangle (renderer,
                                      PANGO_RENDER_PART_UNDERLINE,
                                      rect->x,
@@ -209,12 +209,24 @@ draw_underline (PangoRenderer *renderer,
                                      rect->width,
                                      rect->height);
       break;
+    case PANGO_LINE_STYLE_DOTTED:
+    case PANGO_LINE_STYLE_DASHED:
+      pango_renderer_draw_styled_line (renderer,
+                                       PANGO_RENDER_PART_UNDERLINE,
+                                       underline,
+                                       rect->x,
+                                       rect->y,
+                                       rect->width,
+                                       rect->height);
+      break;
     case PANGO_LINE_STYLE_WAVY:
-      pango_renderer_draw_error_underline (renderer,
-                                           rect->x,
-                                           rect->y,
-                                           rect->width,
-                                           3 * rect->height);
+      pango_renderer_draw_styled_line (renderer,
+                                       PANGO_RENDER_PART_UNDERLINE,
+                                       underline,
+                                       rect->x,
+                                       rect->y,
+                                       rect->width,
+                                       3 * rect->height);
       break;
     default:
       break;
@@ -243,9 +255,6 @@ draw_overline (PangoRenderer *renderer,
                                      rect->height);
       G_GNUC_FALLTHROUGH;
     case PANGO_LINE_STYLE_SOLID:
-    case PANGO_LINE_STYLE_DOTTED:
-    case PANGO_LINE_STYLE_DASHED:
-    case PANGO_LINE_STYLE_WAVY:
       pango_renderer_draw_rectangle (renderer,
                                      PANGO_RENDER_PART_OVERLINE,
                                      rect->x,
@@ -253,6 +262,25 @@ draw_overline (PangoRenderer *renderer,
                                      rect->width,
                                      rect->height);
       break;
+    case PANGO_LINE_STYLE_DOTTED:
+    case PANGO_LINE_STYLE_DASHED:
+      pango_renderer_draw_styled_line (renderer,
+                                       PANGO_RENDER_PART_OVERLINE,
+                                       overline,
+                                       rect->x,
+                                       rect->y,
+                                       rect->width,
+                                       rect->height);
+      break;
+    case PANGO_LINE_STYLE_WAVY:
+      pango_renderer_draw_styled_line (renderer,
+                                       PANGO_RENDER_PART_OVERLINE,
+                                       overline,
+                                       rect->x,
+                                       rect->y,
+                                       rect->width,
+                                       3 * rect->height);
+      break;
     default:
       break;
     }
@@ -283,9 +311,6 @@ draw_strikethrough (PangoRenderer *renderer,
           rect->y += rect->height;
           G_GNUC_FALLTHROUGH;
         case PANGO_LINE_STYLE_SOLID:
-        case PANGO_LINE_STYLE_DOTTED:
-        case PANGO_LINE_STYLE_DASHED:
-        case PANGO_LINE_STYLE_WAVY:
           pango_renderer_draw_rectangle (renderer,
                                          PANGO_RENDER_PART_STRIKETHROUGH,
                                          rect->x,
@@ -293,6 +318,25 @@ draw_strikethrough (PangoRenderer *renderer,
                                          rect->width,
                                          rect->height);
           break;
+        case PANGO_LINE_STYLE_DOTTED:
+        case PANGO_LINE_STYLE_DASHED:
+          pango_renderer_draw_styled_line (renderer,
+                                           PANGO_RENDER_PART_STRIKETHROUGH,
+                                           state->strikethrough,
+                                           rect->x,
+                                           rect->y,
+                                           rect->width,
+                                           rect->height);
+          break;
+        case PANGO_LINE_STYLE_WAVY:
+          pango_renderer_draw_styled_line (renderer,
+                                           PANGO_RENDER_PART_STRIKETHROUGH,
+                                           state->strikethrough,
+                                           rect->x,
+                                           rect->y,
+                                           rect->width,
+                                           3 * rect->height);
+          break;
         default:
           break;
         }
@@ -1090,15 +1134,20 @@ pango_renderer_default_draw_rectangle (PangoRenderer  *renderer,
 }
 
 /**
- * pango_renderer_draw_error_underline:
+ * pango_renderer_draw_styled_line:
  * @renderer: a `PangoRenderer`
- * @x: X coordinate of underline, in Pango units in user coordinate system
- * @y: Y coordinate of underline, in Pango units in user coordinate system
- * @width: width of underline, in Pango units in user coordinate system
- * @height: height of underline, in Pango units in user coordinate system
+ * @part: type of object this rectangle is part of
+ * @style: the line style
+ * @x: X coordinate of line, in Pango units in user coordinate system
+ * @y: Y coordinate of line, in Pango units in user coordinate system
+ * @width: width of line, in Pango units in user coordinate system
+ * @height: height of line, in Pango units in user coordinate system
+ *
+ * Draw a line in the given style.
  *
- * Draw a squiggly line that approximately covers the given rectangle
- * in the style of an underline used to indicate a spelling error.
+ * For `PANGO_LINE_STYLE_WAVY`, this should draw a squiggly line that
+ * approximately covers the given rectangle in the style of an underline
+ * used to indicate a spelling error.
  *
  * The width of the underline is rounded to an integer number
  * of up/down segments and the resulting rectangle is centered
@@ -1108,18 +1157,21 @@ pango_renderer_default_draw_rectangle (PangoRenderer  *renderer,
  * Use [method@Pango.Renderer.activate] to activate a renderer.
  */
 void
-pango_renderer_draw_error_underline (PangoRenderer *renderer,
-                                     int            x,
-                                     int            y,
-                                     int            width,
-                                     int            height)
+pango_renderer_draw_styled_line (PangoRenderer   *renderer,
+                                 PangoRenderPart  part,
+                                 PangoLineStyle   style,
+                                 int              x,
+                                 int              y,
+                                 int              width,
+                                 int              height)
 {
   PangoRendererPrivate *priv = pango_renderer_get_instance_private (renderer);
 
   g_return_if_fail (PANGO_IS_RENDERER (renderer));
+  g_return_if_fail (IS_VALID_PART (part));
   g_return_if_fail (priv->active_count > 0);
 
-  PANGO_RENDERER_GET_CLASS (renderer)->draw_error_underline (renderer, x, y, width, height);
+  PANGO_RENDERER_GET_CLASS (renderer)->draw_styled_line (renderer, part, style, x, y, width, height);
 }
 
 /* We are drawing an error underline that looks like one of:
@@ -1189,11 +1241,13 @@ get_total_matrix (PangoMatrix       *total,
 }
 
 static void
-pango_renderer_default_draw_error_underline (PangoRenderer *renderer,
-                                             int            x,
-                                             int            y,
-                                             int            width,
-                                             int            height)
+pango_renderer_default_draw_styled_line (PangoRenderer   *renderer,
+                                         PangoRenderPart  part,
+                                         PangoLineStyle   style,
+                                         int              x,
+                                         int              y,
+                                         int              width,
+                                         int              height)
 {
   PangoRendererPrivate *priv = pango_renderer_get_instance_private (renderer);
   int square;
@@ -1208,6 +1262,13 @@ pango_renderer_default_draw_error_underline (PangoRenderer *renderer,
   if (width <= 0 || height <= 0)
     return;
 
+  if (style != PANGO_LINE_STYLE_WAVY)
+    {
+      /* subclasses can do better */
+      pango_renderer_draw_rectangle (renderer, part, x, y, width, height);
+      return;
+    }
+
   square = height / HEIGHT_SQUARES;
   unit_width = (HEIGHT_SQUARES - 1) * square;
   width_units = (width + unit_width / 2) / unit_width;
diff --git a/pango/pango-renderer.h b/pango/pango-renderer.h
index dfde01671..d75c6db19 100644
--- a/pango/pango-renderer.h
+++ b/pango/pango-renderer.h
@@ -75,13 +75,12 @@ struct _PangoRenderer
  * PangoRendererClass:
  * @draw_glyphs: draws a `PangoGlyphString`
  * @draw_rectangle: draws a rectangle
- * @draw_error_underline: draws a squiggly line that approximately
- * covers the given rectangle in the style of an underline used to
- * indicate a spelling error.
+ * @draw_line: draws a line in the given style that approximately
+ *   covers the given rectangle
  * @draw_trapezoid: draws a trapezoidal filled area
  * @draw_glyph: draws a single glyph
  * @part_changed: do renderer specific processing when rendering
- *  attributes change
+ *   attributes change
  * @begin: Do renderer-specific initialization before drawing
  * @end: Do renderer-specific cleanup after drawing
  * @prepare_run: updates the renderer for a new run
@@ -93,7 +92,7 @@ struct _PangoRenderer
  * and have default implementations:
  * - draw_glyphs
  * - draw_rectangle
- * - draw_error_underline
+ * - draw_styled_line
  * - draw_shape
  * - draw_glyph_item
  *
@@ -122,7 +121,15 @@ struct _PangoRendererClass
                                 int               y,
                                 int               width,
                                 int               height);
-  void (*draw_error_underline) (PangoRenderer    *renderer,
+  void (*draw_styled_line)     (PangoRenderer    *renderer,
+                                PangoRenderPart   part,
+                                PangoLineStyle    style,
+                                int               x,
+                                int               y,
+                                int               width,
+                                int               height);
+  void (*draw_line)            (PangoRenderer    *renderer,
+                                PangoLineStyle    style,
                                 int               x,
                                 int               y,
                                 int               width,
@@ -202,6 +209,14 @@ void pango_renderer_draw_rectangle       (PangoRenderer    *renderer,
                                           int               width,
                                           int               height);
 PANGO_AVAILABLE_IN_ALL
+void pango_renderer_draw_styled_line     (PangoRenderer    *renderer,
+                                          PangoRenderPart   part,
+                                          PangoLineStyle    style,
+                                          int               x,
+                                          int               y,
+                                          int               width,
+                                          int               height);
+PANGO_AVAILABLE_IN_ALL
 void pango_renderer_draw_error_underline (PangoRenderer    *renderer,
                                           int               x,
                                           int               y,
diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c
index 2a76a1619..533cf6386 100644
--- a/pango/pangocairo-render.c
+++ b/pango/pangocairo-render.c
@@ -689,11 +689,11 @@ pango_cairo_renderer_draw_trapezoid (PangoRenderer     *renderer,
 #define HEIGHT_SQUARES 2.5
 
 static void
-draw_error_underline (cairo_t *cr,
-                      double   x,
-                      double   y,
-                      double   width,
-                      double   height)
+draw_wavy_line (cairo_t *cr,
+                double   x,
+                double   y,
+                double   width,
+                double   height)
 {
   double square = height / HEIGHT_SQUARES;
   double unit_width = (HEIGHT_SQUARES - 1) * square;
@@ -742,11 +742,13 @@ draw_error_underline (cairo_t *cr,
 }
 
 static void
-pango_cairo_renderer_draw_error_underline (PangoRenderer *renderer,
-                                           int            x,
-                                           int            y,
-                                           int            width,
-                                           int            height)
+pango_cairo_renderer_draw_styled_line (PangoRenderer   *renderer,
+                                       PangoRenderPart  part,
+                                       PangoLineStyle   style,
+                                       int              x,
+                                       int              y,
+                                       int              width,
+                                       int              height)
 {
   PangoCairoRenderer *crenderer = (PangoCairoRenderer *) (renderer);
   cairo_t *cr = crenderer->cr;
@@ -755,15 +757,68 @@ pango_cairo_renderer_draw_error_underline (PangoRenderer *renderer,
     {
       cairo_save (cr);
 
-      set_color (crenderer, PANGO_RENDER_PART_UNDERLINE);
+      set_color (crenderer, part);
 
       cairo_new_path (cr);
     }
 
-  draw_error_underline (cr,
-                        crenderer->x_offset + (double)x / PANGO_SCALE,
-                        crenderer->y_offset + (double)y / PANGO_SCALE,
-                        (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+  switch (style)
+    {
+    case PANGO_LINE_STYLE_NONE:
+      break;
+
+    case PANGO_LINE_STYLE_DOTTED:
+    case PANGO_LINE_STYLE_DASHED:
+      cairo_save (cr);
+      cairo_set_line_width (cr, (double)height / PANGO_SCALE);
+      if (style == PANGO_LINE_STYLE_DOTTED)
+        {
+          cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+          cairo_set_dash (cr, (const double []){0., (double)(2 * height) / PANGO_SCALE}, 2, 0.);
+        }
+      else
+        {
+          cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+          cairo_set_dash (cr, (const double []){(double)(3 * height) / PANGO_SCALE, (double)(3 * height) / 
PANGO_SCALE}, 2, 0.);
+        }
+      cairo_move_to (cr,
+                     crenderer->x_offset + (double)x / PANGO_SCALE + (double)height / (2 * PANGO_SCALE),
+                     crenderer->y_offset + (double)y / PANGO_SCALE + (double)height / (2 * PANGO_SCALE));
+      cairo_line_to (cr,
+                     crenderer->x_offset + (double)x / PANGO_SCALE + (double)width / PANGO_SCALE - 
(double)height / PANGO_SCALE,
+                     crenderer->y_offset + (double)y / PANGO_SCALE + (double)height / (2 * PANGO_SCALE));
+      cairo_stroke (cr);
+      cairo_restore (cr);
+      break;
+
+    case PANGO_LINE_STYLE_SOLID:
+      cairo_rectangle (cr,
+                       crenderer->x_offset + (double)x / PANGO_SCALE,
+                       crenderer->y_offset + (double)y / PANGO_SCALE,
+                       (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+      break;
+
+    case PANGO_LINE_STYLE_DOUBLE:
+      cairo_rectangle (cr,
+                       crenderer->x_offset + (double)x / PANGO_SCALE,
+                       crenderer->y_offset + (double)y / PANGO_SCALE,
+                       (double)width / PANGO_SCALE, (double)height / (3 * PANGO_SCALE));
+      cairo_rectangle (cr,
+                       crenderer->x_offset + (double)x / PANGO_SCALE,
+                       crenderer->y_offset + (double)y / PANGO_SCALE + (double)(2 * height) / (3 * 
PANGO_SCALE),
+                       (double)width / PANGO_SCALE, (double)height / (3 * PANGO_SCALE));
+      break;
+
+
+    case PANGO_LINE_STYLE_WAVY:
+      draw_wavy_line (cr,
+                      crenderer->x_offset + (double)x / PANGO_SCALE,
+                      crenderer->y_offset + (double)y / PANGO_SCALE,
+                      (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+      break;
+    default:
+      g_assert_not_reached ();
+    }
 
   if (!crenderer->do_path)
     {
@@ -786,8 +841,8 @@ pango_cairo_renderer_class_init (PangoCairoRendererClass *klass)
   renderer_class->draw_glyphs = pango_cairo_renderer_draw_glyphs;
   renderer_class->draw_run = pango_cairo_renderer_draw_run;
   renderer_class->draw_rectangle = pango_cairo_renderer_draw_rectangle;
+  renderer_class->draw_styled_line = pango_cairo_renderer_draw_styled_line;
   renderer_class->draw_trapezoid = pango_cairo_renderer_draw_trapezoid;
-  renderer_class->draw_error_underline = pango_cairo_renderer_draw_error_underline;
 }
 
 static PangoCairoRenderer *cached_renderer = NULL; /* MT-safe */
@@ -992,30 +1047,6 @@ _pango_cairo_do_layout (cairo_t     *cr,
   release_renderer (crenderer);
 }
 
-static void
-_pango_cairo_do_error_underline (cairo_t *cr,
-                                 double   x,
-                                 double   y,
-                                 double   width,
-                                 double   height,
-                                 gboolean do_path)
-{
-  /* We don't use a renderer here, for a simple reason:
-   * the only renderer we can get is the default renderer, that
-   * is all implemented here, so we shortcircuit and make our
-   * life way easier.
-   */
-
-  if (!do_path)
-    cairo_new_path (cr);
-
-  draw_error_underline (cr, x, y, width, height);
-
-  if (!do_path)
-    cairo_fill (cr);
-}
-
-
 /* public wrapper of above to show or append path */
 
 
@@ -1131,35 +1162,6 @@ pango_cairo_show_layout (cairo_t     *cr,
   _pango_cairo_do_layout (cr, layout, FALSE);
 }
 
-/**
- * pango_cairo_show_error_underline:
- * @cr: a Cairo context
- * @x: The X coordinate of one corner of the rectangle
- * @y: The Y coordinate of one corner of the rectangle
- * @width: Non-negative width of the rectangle
- * @height: Non-negative height of the rectangle
- *
- * Draw a squiggly line in the specified cairo context that approximately
- * covers the given rectangle in the style of an underline used to indicate a
- * spelling error.
- *
- * The width of the underline is rounded to an integer
- * number of up/down segments and the resulting rectangle is centered in the
- * original rectangle.
- */
-void
-pango_cairo_show_error_underline (cairo_t *cr,
-                                  double  x,
-                                  double  y,
-                                  double  width,
-                                  double  height)
-{
-  g_return_if_fail (cr != NULL);
-  g_return_if_fail ((width >= 0) && (height >= 0));
-
-  _pango_cairo_do_error_underline (cr, x, y, width, height, FALSE);
-}
-
 /**
  * pango_cairo_glyph_string_path:
  * @cr: a Cairo context
@@ -1183,6 +1185,26 @@ pango_cairo_glyph_string_path (cairo_t          *cr,
   _pango_cairo_do_glyph_string (cr, font, glyphs, TRUE);
 }
 
+/**
+ * pango_cairo_run_path:
+ * @cr: a Cairo context
+ * @text: the UTF-8 text that @run refers to
+ * @run: a `PangoRun`
+ *
+ * Adds the text in `PangoRun` to the current path in the
+ * specified cairo context.
+ *
+ * The origin of the glyphs (the left edge of the line) will be
+ * at the current point of the cairo context.
+ */
+void
+pango_cairo_run_path (cairo_t    *cr,
+                      const char *text,
+                      PangoRun   *run)
+{
+  _pango_cairo_do_run (cr, text, run, TRUE);
+}
+
 /**
  * pango_cairo_line_path:
  * @cr: a Cairo context
@@ -1244,31 +1266,3 @@ pango_cairo_lines_path (cairo_t    *cr,
 
   _pango_cairo_do_lines (cr, lines, TRUE);
 }
-
-/**
- * pango_cairo_error_underline_path:
- * @cr: a Cairo context
- * @x: The X coordinate of one corner of the rectangle
- * @y: The Y coordinate of one corner of the rectangle
- * @width: Non-negative width of the rectangle
- * @height: Non-negative height of the rectangle
- *
- * Add a squiggly line to the current path in the specified cairo context that
- * approximately covers the given rectangle in the style of an underline used
- * to indicate a spelling error.
- *
- * The width of the underline is rounded to an integer number of up/down
- * segments and the resulting rectangle is centered in the original rectangle.
- */
-void
-pango_cairo_error_underline_path (cairo_t *cr,
-                                  double   x,
-                                  double   y,
-                                  double   width,
-                                  double   height)
-{
-  g_return_if_fail (cr != NULL);
-  g_return_if_fail ((width >= 0) && (height >= 0));
-
-  _pango_cairo_do_error_underline (cr, x, y, width, height, TRUE);
-}
diff --git a/pango/pangocairo-render.h b/pango/pangocairo-render.h
index 45ca44ae7..b93861426 100644
--- a/pango/pangocairo-render.h
+++ b/pango/pangocairo-render.h
@@ -42,33 +42,22 @@ void    pango_cairo_show_lines                  (cairo_t          *cr,
 PANGO_AVAILABLE_IN_ALL
 void    pango_cairo_show_layout                 (cairo_t          *cr,
                                                  PangoLayout      *layout);
-
-PANGO_AVAILABLE_IN_ALL
-void    pango_cairo_show_error_underline        (cairo_t          *cr,
-                                                 double            x,
-                                                 double            y,
-                                                 double            width,
-                                                 double            height);
-
 PANGO_AVAILABLE_IN_ALL
 void    pango_cairo_glyph_string_path           (cairo_t          *cr,
                                                  PangoFont        *font,
                                                  PangoGlyphString *glyphs);
 PANGO_AVAILABLE_IN_ALL
-void    pango_cairo_layout_path                 (cairo_t          *cr,
-                                                 PangoLayout      *layout);
+void    pango_cairo_run_path                    (cairo_t          *cr,
+                                                 const char       *text,
+                                                 PangoRun         *run);
 PANGO_AVAILABLE_IN_ALL
 void    pango_cairo_line_path                   (cairo_t          *cr,
                                                  PangoLine        *line);
 PANGO_AVAILABLE_IN_ALL
 void    pango_cairo_lines_path                  (cairo_t          *cr,
                                                  PangoLines       *lines);
-
 PANGO_AVAILABLE_IN_ALL
-void    pango_cairo_error_underline_path        (cairo_t          *cr,
-                                                 double            x,
-                                                 double            y,
-                                                 double            width,
-                                                 double            height);
+void    pango_cairo_layout_path                 (cairo_t          *cr,
+                                                 PangoLayout      *layout);
 
 G_END_DECLS


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