diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-08-24 16:07:02 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-08-24 19:55:23 -0400 |
commit | 3f508127a873a2085aefe6e7ca18c1511147c053 (patch) | |
tree | 6fee64e3faea5f9e953611648e1fa6d9684725f7 /pango/pango-layout.c | |
parent | 4740e552b3c8ca005beea88001a82ea6bb266076 (diff) | |
download | pango-3f508127a873a2085aefe6e7ca18c1511147c053.tar.gz |
Add pango_layout_get_caret_pos
This is like pango_layout_get_cursor_pos, but returns
a rectangle that has caret font metrics applied to it.
Diffstat (limited to 'pango/pango-layout.c')
-rw-r--r-- | pango/pango-layout.c | 100 |
1 files changed, 95 insertions, 5 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c index b6e0c217..9912ccdc 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -83,6 +83,8 @@ #include <string.h> #include <math.h> +#include <hb-ot.h> + #include "pango-layout-private.h" #include "pango-attributes-private.h" @@ -2458,23 +2460,37 @@ pango_layout_index_to_pos (PangoLayout *layout, _pango_layout_iter_destroy (&iter); } -static int -pango_layout_line_get_char_level (PangoLayoutLine *layout_line, - int index) +static PangoLayoutRun * +pango_layout_line_get_run (PangoLayoutLine *line, + int index) { GSList *run_list; - run_list = layout_line->runs; + run_list = line->runs; while (run_list) { PangoLayoutRun *run = run_list->data; if (run->item->offset <= index && run->item->offset + run->item->length > index) - return run->item->analysis.level; + return run; run_list = run_list->next; } + return NULL; +} + +static int +pango_layout_line_get_char_level (PangoLayoutLine *line, + int index) +{ + PangoLayoutRun *run; + + run = pango_layout_line_get_run (line, index); + + if (run) + return run->item->analysis.level; + return 0; } @@ -2630,6 +2646,80 @@ pango_layout_get_cursor_pos (PangoLayout *layout, } } +/** + * pango_layout_get_caret_pos: + * @layout: a `PangoLayout` + * @index_: the byte index of the cursor + * @strong_pos: (out) (optional): location to store the strong cursor position + * @weak_pos: (out) (optional): location to store the weak cursor position + * + * Given an index within a layout, determines the positions that of the + * strong and weak cursors if the insertion point is at that index. + * + * This is a variant of [method@Pango.Layout.get_cursor_pos] that applies + * font metric information about caret slope and offset to the positions + * it returns. + * + * TOOD: Image here + * + * Since: 1.50 + */ +void +pango_layout_get_caret_pos (PangoLayout *layout, + int index, + PangoRectangle *strong_pos, + PangoRectangle *weak_pos) +{ + PangoLayoutLine *line; + PangoLayoutRun *run; + hb_font_t *hb_font; + hb_position_t caret_offset, caret_run, caret_rise, descender; + + pango_layout_get_cursor_pos (layout, index, strong_pos, weak_pos); + + /* FIXME: not very efficient to re-iterate here */ + line = pango_layout_index_to_line_and_extents (layout, index, NULL, NULL); + run = pango_layout_line_get_run (line, index); + if (!run) + run = pango_layout_line_get_run (line, index - 1); + + if (!run) + return; + + hb_font = pango_font_get_hb_font (run->item->analysis.font); + + if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE, &caret_rise) && + hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN, &caret_run) && + hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET, &caret_offset) && + hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &descender)) + { + double slope_inv; + + if (strong_pos) + strong_pos->x += caret_offset; + + if (weak_pos) + weak_pos->x += caret_offset; + + if (caret_rise == 0) + return; + + slope_inv = caret_run / (double) caret_rise; + + if (strong_pos) + { + strong_pos->x += descender * slope_inv; + strong_pos->width = strong_pos->height * slope_inv; + } + + if (weak_pos) + { + weak_pos->x += descender * slope_inv; + weak_pos->width = weak_pos->height * slope_inv; + } + } +} + static inline int direction_simple (PangoDirection d) { |