[gtk/sloped-caret: 1/2] Implement sloped caret drawing




commit 1687349cb4e802e3e307887042343c3de3c5bb6f
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Aug 23 17:39:04 2021 -0400

    Implement sloped caret drawing
    
    Prepare for Pango to return slope information for carets.
    
    While we are at it, improve the shape of our carets a bit.

 gtk/gtkstylecontext.c | 111 +++++++++++++++++++++++++-------------------------
 1 file changed, 56 insertions(+), 55 deletions(-)
---
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 4ded60230c..2642106bf0 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -972,6 +972,7 @@ draw_insertion_cursor (GtkStyleContext *context,
                        cairo_t         *cr,
                        double           x,
                        double           y,
+                       double           width,
                        double           height,
                        double           aspect_ratio,
                        gboolean         is_primary,
@@ -981,7 +982,8 @@ draw_insertion_cursor (GtkStyleContext *context,
   GdkRGBA primary_color;
   GdkRGBA secondary_color;
   int stem_width;
-  int offset;
+  double angle;
+  double dx, dy;
 
   cairo_save (cr);
   cairo_new_path (cr);
@@ -990,107 +992,104 @@ draw_insertion_cursor (GtkStyleContext *context,
   gdk_cairo_set_source_rgba (cr, is_primary ? &primary_color : &secondary_color);
 
   stem_width = height * aspect_ratio + 1;
+  if (width < 0)
+    stem_width = - stem_width;
 
-  /* put (stem_width % 2) on the proper side of the cursor */
-  if (direction == PANGO_DIRECTION_LTR)
-    offset = stem_width / 2;
-  else
-    offset = stem_width - stem_width / 2;
+  angle = atan (height / width);
 
-  cairo_rectangle (cr, x - offset, y, stem_width, height);
-  cairo_fill (cr);
+  dx = (stem_width/2.0) * cos (M_PI/2 - angle);
+  dy = (stem_width/2.0) * sin (M_PI/2 - angle);
 
   if (draw_arrow)
     {
-      int arrow_width;
-      int ax, ay;
-
-      arrow_width = stem_width + 1;
-
       if (direction == PANGO_DIRECTION_RTL)
         {
-          ax = x - offset - 1;
-          ay = y + height - arrow_width * 2 - arrow_width + 1;
+          double x0, y0, x1, y1, x2, y2;
 
-          cairo_move_to (cr, ax, ay + 1);
-          cairo_line_to (cr, ax - arrow_width, ay + arrow_width);
-          cairo_line_to (cr, ax, ay + 2 * arrow_width);
-          cairo_fill (cr);
+          x0 = x - dx + 2 * dy;
+          y0 = y + height - dy - 2 * dx;
+
+          x1 = x0 + 4 * dy;
+          y1 = y0 - 4 * dx;
+          x2 = x0 + 2 * dy - 3 * dx;
+          y2 = y0 - 2 * dx - 3 * dy;
+
+          cairo_move_to (cr, x + width + dx, y + dy);
+          cairo_line_to (cr, x + dx, y + height + dy);
+          cairo_line_to (cr, x2, y2);
+          cairo_line_to (cr, x1, y1);
+          cairo_line_to (cr, x + width - dx, y - dy);
         }
       else if (direction == PANGO_DIRECTION_LTR)
         {
-          ax = x + stem_width - offset;
-          ay = y + height - arrow_width * 2 - arrow_width + 1;
+          double x0, y0, x1, y1, x2, y2;
+
+          x0 = x + dx + 2 * dy;
+          y0 = y + height + dy - 2 * dx;
 
-          cairo_move_to (cr, ax, ay + 1);
-          cairo_line_to (cr, ax + arrow_width, ay + arrow_width);
-          cairo_line_to (cr, ax, ay + 2 * arrow_width);
-          cairo_fill (cr);
+          x1 = x0 + 4 * dy;
+          y1 = y0 - 4 * dx;
+          x2 = x0 + 2 * dy + 3 * dx;
+          y2 = y0 - 2 * dx + 3 * dy;
+
+          cairo_move_to (cr, x + width - dx, y - dy);
+          cairo_line_to (cr, x - dx, y + height - dy);
+          cairo_line_to (cr, x2, y2);
+          cairo_line_to (cr, x1, y1);
+          cairo_line_to (cr, x + width + dx, y + dy);
         }
       else
         g_assert_not_reached();
     }
+  else
+    {
+      cairo_move_to (cr, x + width + dx, y + dy);
+      cairo_line_to (cr, x + dx, y + height + dy);
+      cairo_line_to (cr, x - dx, y + height - dy);
+      cairo_line_to (cr, x + width - dx, y - dy);
+    }
+
+  cairo_fill (cr);
 
   cairo_restore (cr);
 }
 
 static void
-get_insertion_cursor_bounds (double           height,
+get_insertion_cursor_bounds (double           width,
+                             double           height,
                              double           aspect_ratio,
                              PangoDirection   direction,
                              gboolean         draw_arrow,
                              graphene_rect_t *bounds)
 {
   int stem_width;
-  int offset;
 
   stem_width = height * aspect_ratio + 1;
-  if (direction == PANGO_DIRECTION_LTR)
-    offset = stem_width / 2;
-  else
-    offset = stem_width - stem_width / 2;
 
-  if (draw_arrow)
-    {
-      if (direction == PANGO_DIRECTION_LTR)
-        {
-          graphene_rect_init (bounds,
-                              - offset, 0,
-                              2 * stem_width + 1, height);
-        }
-      else
-        {
-          graphene_rect_init (bounds,
-                              - offset - stem_width - 2, 0,
-                              2 * stem_width + 2, height);
-        }
-    }
-  else
-    {
-      graphene_rect_init (bounds,
-                          - offset, 0,
-                          stem_width, height);
-    }
+  graphene_rect_init (bounds,
+                      - 2 * stem_width, - stem_width,
+                      width + 4 * stem_width, height + 2 * stem_width);
 }
 
 static void
 snapshot_insertion_cursor (GtkSnapshot     *snapshot,
                            GtkStyleContext *context,
+                           double           width,
                            double           height,
                            double           aspect_ratio,
                            gboolean         is_primary,
                            PangoDirection   direction,
                            gboolean         draw_arrow)
 {
-  if (draw_arrow)
+  if (width != 0 || draw_arrow)
     {
       cairo_t *cr;
       graphene_rect_t bounds;
 
-      get_insertion_cursor_bounds (height, aspect_ratio, direction, draw_arrow, &bounds);
+      get_insertion_cursor_bounds (width, height, aspect_ratio, direction, draw_arrow, &bounds);
       cr = gtk_snapshot_append_cairo (snapshot, &bounds);
 
-      draw_insertion_cursor (context, cr, 0, 0, height, aspect_ratio, is_primary, direction, draw_arrow);
+      draw_insertion_cursor (context, cr, 0, 0, width, height, aspect_ratio, is_primary, direction, 
draw_arrow);
 
       cairo_destroy (cr);
     }
@@ -1193,6 +1192,7 @@ gtk_snapshot_render_insertion_cursor (GtkSnapshot     *snapshot,
   gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x + PANGO_PIXELS (cursor1->x), y + PANGO_PIXELS 
(cursor1->y)));
   snapshot_insertion_cursor (snapshot,
                              context,
+                             PANGO_PIXELS (cursor1->width),
                              PANGO_PIXELS (cursor1->height),
                              aspect_ratio,
                              TRUE,
@@ -1206,6 +1206,7 @@ gtk_snapshot_render_insertion_cursor (GtkSnapshot     *snapshot,
       gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x + PANGO_PIXELS (cursor2->x), y + 
PANGO_PIXELS (cursor2->y)));
       snapshot_insertion_cursor (snapshot,
                                  context,
+                                 PANGO_PIXELS (cursor2->width),
                                  PANGO_PIXELS (cursor2->height),
                                  aspect_ratio,
                                  FALSE,


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