diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-08-23 17:39:04 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-08-25 06:53:53 -0400 |
commit | f90e9b26f8d0b9de50fa1a8e86ed3e26706827c3 (patch) | |
tree | c2e54040d002145f0cdadaa0f5788da9b669685d | |
parent | ad71f454bd98a55539a0d470b780ea9862ccd78f (diff) | |
download | gtk+-f90e9b26f8d0b9de50fa1a8e86ed3e26706827c3.tar.gz |
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.
-rw-r--r-- | gtk/gtkstylecontext.c | 111 |
1 files 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, |