forked from AuroraMiddleware/gtk
Add gtk_css_style_snapshot_caret
This commit is contained in:
parent
484cff2182
commit
0522dade9f
@ -24,6 +24,7 @@
|
|||||||
#include "gtkpangoprivate.h"
|
#include "gtkpangoprivate.h"
|
||||||
#include "gtksnapshot.h"
|
#include "gtksnapshot.h"
|
||||||
#include "gtktypebuiltins.h"
|
#include "gtktypebuiltins.h"
|
||||||
|
#include "gtksettings.h"
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -60,3 +61,250 @@ gtk_css_style_snapshot_layout (GtkCssBoxes *boxes,
|
|||||||
gtk_snapshot_pop (snapshot);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -27,11 +27,20 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
void gtk_css_style_snapshot_layout (GtkCssBoxes *boxes,
|
void gtk_css_style_snapshot_layout (GtkCssBoxes *boxes,
|
||||||
GtkSnapshot *snapshot,
|
GtkSnapshot *snapshot,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
PangoLayout *layout);
|
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
|
G_END_DECLS
|
||||||
|
Loading…
Reference in New Issue
Block a user