summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-08-23 17:39:04 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-08-25 06:53:53 -0400
commitf90e9b26f8d0b9de50fa1a8e86ed3e26706827c3 (patch)
treec2e54040d002145f0cdadaa0f5788da9b669685d
parentad71f454bd98a55539a0d470b780ea9862ccd78f (diff)
downloadgtk+-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.c111
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,