[gtk/deprecate-render: 30/48] Add gtk_css_style_snapshot_caret
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/deprecate-render: 30/48] Add gtk_css_style_snapshot_caret
- Date: Tue, 11 Oct 2022 21:20:00 +0000 (UTC)
commit 65ce3ead364af849a784e230fb077100360f8f41
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Oct 8 16:32:13 2022 -0400
Add gtk_css_style_snapshot_caret
gtk/gtkrenderlayout.c | 248 +++++++++++++++++++++++++++++++++++++++++++
gtk/gtkrenderlayoutprivate.h | 19 +++-
2 files changed, 262 insertions(+), 5 deletions(-)
---
diff --git a/gtk/gtkrenderlayout.c b/gtk/gtkrenderlayout.c
index 1d38ff097b..454ca2fc78 100644
--- a/gtk/gtkrenderlayout.c
+++ b/gtk/gtkrenderlayout.c
@@ -24,6 +24,7 @@
#include "gtkpangoprivate.h"
#include "gtksnapshot.h"
#include "gtktypebuiltins.h"
+#include "gtksettings.h"
void
@@ -60,3 +61,250 @@ gtk_css_style_snapshot_layout (GtkCssBoxes *boxes,
gtk_snapshot_pop (snapshot);
}
+static void
+draw_insertion_cursor (cairo_t *cr,
+ double x,
+ double y,
+ double width,
+ double height,
+ double aspect_ratio,
+ const GdkRGBA *color,
+ PangoDirection direction,
+ gboolean draw_arrow)
+{
+ int stem_width;
+ double angle;
+ double dx, dy;
+ double xx1, yy1, xx2, yy2;
+
+ cairo_save (cr);
+ cairo_new_path (cr);
+
+ gdk_cairo_set_source_rgba (cr, color);
+
+ stem_width = height * aspect_ratio + 1;
+
+ yy1 = y;
+ yy2 = y + height;
+
+ if (width < 0)
+ {
+ xx1 = x;
+ xx2 = x - width;
+ }
+ else
+ {
+ xx1 = x + width;
+ xx2 = x;
+ }
+
+ angle = atan2 (height, width);
+
+ dx = (stem_width/2.0) * cos (M_PI/2 - angle);
+ dy = (stem_width/2.0) * sin (M_PI/2 - angle);
+
+ if (draw_arrow)
+ {
+ if (direction == PANGO_DIRECTION_RTL)
+ {
+ double x0, y0, x1, y1, x2, y2;
+
+ x0 = xx2 - dx + 2 * dy;
+ y0 = yy2 - 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, xx1 + dx, yy1 + dy);
+ cairo_line_to (cr, xx2 + dx, yy2 + dy);
+ cairo_line_to (cr, x2, y2);
+ cairo_line_to (cr, x1, y1);
+ cairo_line_to (cr, xx1 - dx, yy1 - dy);
+ }
+ else if (direction == PANGO_DIRECTION_LTR)
+ {
+ double x0, y0, x1, y1, x2, y2;
+
+ x0 = xx2 + dx + 2 * dy;
+ y0 = yy2 + 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, xx1 - dx, yy1 - dy);
+ cairo_line_to (cr, xx2 - dx, yy2 - dy);
+ cairo_line_to (cr, x2, y2);
+ cairo_line_to (cr, x1, y1);
+ cairo_line_to (cr, xx1 + dx, yy1 + dy);
+ }
+ else
+ g_assert_not_reached();
+ }
+ else
+ {
+ cairo_move_to (cr, xx1 + dx, yy1 + dy);
+ cairo_line_to (cr, xx2 + dx, yy2 + dy);
+ cairo_line_to (cr, xx2 - dx, yy2 - dy);
+ cairo_line_to (cr, xx1 - dx, yy1 - dy);
+ }
+
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+get_insertion_cursor_bounds (double width,
+ double height,
+ double aspect_ratio,
+ PangoDirection direction,
+ gboolean draw_arrow,
+ graphene_rect_t *bounds)
+{
+ int stem_width;
+
+ if (width < 0)
+ width = - width;
+
+ stem_width = height * aspect_ratio + 1;
+
+ graphene_rect_init (bounds,
+ - 2 * stem_width, - stem_width,
+ width + 4 * stem_width, height + 2 * stem_width);
+}
+
+static void
+snapshot_insertion_cursor (GtkSnapshot *snapshot,
+ GtkCssStyle *style,
+ double width,
+ double height,
+ double aspect_ratio,
+ gboolean is_primary,
+ PangoDirection direction,
+ gboolean draw_arrow)
+{
+ GdkRGBA color;
+
+ if (is_primary)
+ color = *gtk_css_color_value_get_rgba (style->font->caret_color ? style->font->caret_color :
style->core->color);
+ else
+ color = *gtk_css_color_value_get_rgba (style->font->secondary_caret_color ?
style->font->secondary_caret_color : style->core->color);
+
+ if (width != 0 || draw_arrow)
+ {
+ cairo_t *cr;
+ graphene_rect_t bounds;
+
+ get_insertion_cursor_bounds (width, height, aspect_ratio, direction, draw_arrow, &bounds);
+ cr = gtk_snapshot_append_cairo (snapshot, &bounds);
+
+ draw_insertion_cursor (cr, 0, 0, width, height, aspect_ratio, &color, direction, draw_arrow);
+
+ cairo_destroy (cr);
+ }
+ else
+ {
+ int stem_width;
+ int offset;
+
+ stem_width = height * aspect_ratio + 1;
+
+ /* 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;
+
+ gtk_snapshot_append_color (snapshot,
+ &color,
+ &GRAPHENE_RECT_INIT (- offset, 0, stem_width, height));
+ }
+}
+
+void
+gtk_css_style_snapshot_caret (GtkCssBoxes *boxes,
+ GdkDisplay *display,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ PangoLayout *layout,
+ int index,
+ PangoDirection direction)
+{
+ gboolean split_cursor;
+ double aspect_ratio;
+ PangoRectangle strong_pos, weak_pos;
+ PangoRectangle *cursor1, *cursor2;
+ GdkSeat *seat;
+ PangoDirection keyboard_direction;
+ PangoDirection direction2;
+
+ g_object_get (gtk_settings_get_for_display (display),
+ "gtk-split-cursor", &split_cursor,
+ "gtk-cursor-aspect-ratio", &aspect_ratio,
+ NULL);
+
+ keyboard_direction = PANGO_DIRECTION_LTR;
+ seat = gdk_display_get_default_seat (display);
+ if (seat)
+ {
+ GdkDevice *keyboard = gdk_seat_get_keyboard (seat);
+
+ if (keyboard)
+ keyboard_direction = gdk_device_get_direction (keyboard);
+ }
+
+ pango_layout_get_caret_pos (layout, index, &strong_pos, &weak_pos);
+
+ direction2 = PANGO_DIRECTION_NEUTRAL;
+
+ if (split_cursor)
+ {
+ cursor1 = &strong_pos;
+
+ if (strong_pos.x != weak_pos.x || strong_pos.y != weak_pos.y)
+ {
+ direction2 = (direction == PANGO_DIRECTION_LTR) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
+ cursor2 = &weak_pos;
+ }
+ }
+ else
+ {
+ if (keyboard_direction == direction)
+ cursor1 = &strong_pos;
+ else
+ cursor1 = &weak_pos;
+ }
+
+ gtk_snapshot_save (snapshot);
+ gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x + PANGO_PIXELS (MIN (cursor1->x, cursor1->x +
cursor1->width)), y + PANGO_PIXELS (cursor1->y)));
+ snapshot_insertion_cursor (snapshot,
+ boxes->style,
+ PANGO_PIXELS (cursor1->width),
+ PANGO_PIXELS (cursor1->height),
+ aspect_ratio,
+ TRUE,
+ direction,
+ direction2 != PANGO_DIRECTION_NEUTRAL);
+ gtk_snapshot_restore (snapshot);
+
+ if (direction2 != PANGO_DIRECTION_NEUTRAL)
+ {
+ gtk_snapshot_save (snapshot);
+ gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x + PANGO_PIXELS (MIN (cursor2->x, cursor2->x
+ cursor2->width)), y + PANGO_PIXELS (cursor2->y)));
+ snapshot_insertion_cursor (snapshot,
+ boxes->style,
+ PANGO_PIXELS (cursor2->width),
+ PANGO_PIXELS (cursor2->height),
+ aspect_ratio,
+ FALSE,
+ direction2,
+ TRUE);
+ gtk_snapshot_restore (snapshot);
+ }
+}
+
diff --git a/gtk/gtkrenderlayoutprivate.h b/gtk/gtkrenderlayoutprivate.h
index ec4d13b816..e14b5c0b78 100644
--- a/gtk/gtkrenderlayoutprivate.h
+++ b/gtk/gtkrenderlayoutprivate.h
@@ -27,11 +27,20 @@
G_BEGIN_DECLS
-void gtk_css_style_snapshot_layout (GtkCssBoxes *boxes,
- GtkSnapshot *snapshot,
- int x,
- int y,
- PangoLayout *layout);
+void gtk_css_style_snapshot_layout (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ PangoLayout *layout);
+
+void gtk_css_style_snapshot_caret (GtkCssBoxes *boxes,
+ GdkDisplay *display,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ PangoLayout *layout,
+ int index,
+ PangoDirection direction);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]