summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-08-28 09:29:53 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-08-29 22:49:02 -0400
commitea2c84eb7357031af60d37cb5378a254abe37ccc (patch)
treeb6cb57e84959021280b3088ff7a26d142b022392
parentb5d3ad90e39a58967aa75aa08acd623c440aa97b (diff)
downloadpango-ea2c84eb7357031af60d37cb5378a254abe37ccc.tar.gz
Add pango_glyph_string_index_to_x_full
This variant of pango_glyph_string_index_to_x takes log attrs so it does not have to compute them when it needs them to determine grapheme boundaries.
-rw-r--r--pango/glyphstring.c85
-rw-r--r--pango/pango-glyph.h11
2 files changed, 72 insertions, 24 deletions
diff --git a/pango/glyphstring.c b/pango/glyphstring.c
index 11eeffbf..282de61d 100644
--- a/pango/glyphstring.c
+++ b/pango/glyphstring.c
@@ -378,7 +378,6 @@ pango_glyph_string_get_logical_widths (PangoGlyphString *glyphs,
* <source srcset="glyphstring-positions-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Glyph positions" src="glyphstring-positions-light.png">
* </picture>
-
*/
void
pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
@@ -389,6 +388,46 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
gboolean trailing,
int *x_pos)
{
+ pango_glyph_string_index_to_x_full (glyphs,
+ text, length,
+ analysis,
+ NULL,
+ index, trailing,
+ x_pos);
+}
+
+/**
+ * pango_glyph_string_index_to_x_full:
+ * @glyphs: the glyphs return from [func@shape]
+ * @text: the text for the run
+ * @length: the number of bytes (not characters) in @text.
+ * @analysis: the analysis information return from [func@itemize]
+ * @attrs: (nullable): `PangoLogAttr` array for @text
+ * @index_: the byte index within @text
+ * @trailing: whether we should compute the result for the beginning (%FALSE)
+ * or end (%TRUE) of the character.
+ * @x_pos: (out): location to store result
+ *
+ * Converts from character position to x position.
+ *
+ * This variant of [method@Pango.GlyphString.index_to_x] additionally
+ * accepts a `PangoLogAttr` array. The grapheme boundary information
+ * in it can be used to disambiguate positioning inside some complex
+ * clusters. [method@Pango.GlyphString.index_to_x] will compute this
+ * information if it needs it.
+ *
+ * Since: 1.50
+ */
+void
+pango_glyph_string_index_to_x_full (PangoGlyphString *glyphs,
+ const char *text,
+ int length,
+ PangoAnalysis *analysis,
+ PangoLogAttr *attrs,
+ int index,
+ gboolean trailing,
+ int *x_pos)
+{
int i;
int start_xpos = 0;
int end_xpos = 0;
@@ -404,9 +443,6 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
const char *p;
- int attrs_len;
- PangoLogAttr *attrs = NULL;
-
g_return_if_fail (glyphs != NULL);
g_return_if_fail (length >= 0);
g_return_if_fail (length == 0 || text != NULL);
@@ -496,12 +532,15 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
end_xpos = (analysis->level % 2) ? 0 : width;
}
- /* Calculate offset of character within cluster */
-
- if (g_utf8_next_char (text + start_index) != text + end_index)
+ /* Calculate offset of character within cluster.
+ * To come up with accurate answers here, we need to know grapheme
+ * boundaries.
+ */
+ if (attrs == NULL &&
+ g_utf8_next_char (text + start_index) != text + end_index)
{
- /* FIXME: should allow log attrs to be passed in */
- attrs_len = g_utf8_strlen (text, length) + 1;
+ int attrs_len = g_utf8_strlen (text, length) + 1;
+
attrs = g_new0 (PangoLogAttr, attrs_len + 1);
pango_default_break (text, length, analysis, attrs, attrs_len);
}
@@ -510,10 +549,13 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
p < text + end_index;
p = g_utf8_next_char (p), i++)
{
- if (!attrs[i].is_cursor_position)
+ if (attrs && !attrs[i].is_cursor_position)
continue;
+
if (p < text + index)
- cluster_offset++;
+ {
+ cluster_offset++;
+ }
cluster_chars++;
}
@@ -521,17 +563,14 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
cluster_offset += 1;
if (G_UNLIKELY (!cluster_chars)) /* pedantic */
- {
+ {
*x_pos = start_xpos;
return;
}
- /* Try to get a ligature caret position for the glyph
- * from the font.
- *
- * If start_glyph_pos != end_glyph_pos, we are dealing
- * with an m-n situation, where LigatureCaretList is
- * not going to help. Just give up and do the simple thing.
+ /* Try to get a ligature caret position for the glyph from the font.
+ * This only makes sense if the cluster contains a single spacing
+ * glyph, so we need to check that all but one of them are marks.
*/
if (cluster_offset > 0 && cluster_offset < cluster_chars)
{
@@ -558,7 +597,7 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
{
if (glyph_pos != -1)
{
- g_print ("multiple non-mark glyphs in cluster, giving up\n");
+ /* multiple non-mark glyphs in cluster, giving up */
goto fallback;
}
glyph_pos = i;
@@ -566,7 +605,7 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
}
if (glyph_pos == -1)
{
- g_print ("no non-mark glyph in a multi-glyph cluster, giving up\n");
+ /* no non-mark glyph in a multi-glyph cluster, giving up */
goto fallback;
}
}
@@ -575,14 +614,12 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
(analysis->level % 2) ? HB_DIRECTION_RTL : HB_DIRECTION_LTR,
glyphs->glyphs[glyph_pos].glyph,
cluster_offset - 1, &caret_count, &caret);
- if (caret_count == 0)
+ if (caret_count == 0 || num_carets == 0)
{
- g_print ("no ligature caret information found for glyph %d, caret %d / %d. font has %d ligature carets\n", glyphs->glyphs[glyph_pos].glyph, cluster_offset - 1, cluster_chars, num_carets);
+ /* no ligature caret information found for this glyph */
goto fallback;
}
- g_print ("using ligature caret information for glyph %d, caret %d / %d. font has %d ligature carets\n", glyphs->glyphs[glyph_pos].glyph, cluster_offset - 1, cluster_chars, num_carets);
-
if (analysis->level % 2) /* Right to left */
*x_pos = end_xpos + caret;
else
diff --git a/pango/pango-glyph.h b/pango/pango-glyph.h
index 2094fa53..cd29b77a 100644
--- a/pango/pango-glyph.h
+++ b/pango/pango-glyph.h
@@ -24,6 +24,7 @@
#include <pango/pango-types.h>
#include <pango/pango-item.h>
+#include <pango/pango-break.h>
G_BEGIN_DECLS
@@ -198,6 +199,16 @@ void pango_glyph_string_x_to_index (PangoGlyphStrin
int *index_,
int *trailing);
+PANGO_AVAILABLE_IN_1_50
+void pango_glyph_string_index_to_x_full (PangoGlyphString *glyphs,
+ const char *text,
+ int length,
+ PangoAnalysis *analysis,
+ PangoLogAttr *attrs,
+ int index_,
+ gboolean trailing,
+ int *x_pos);
+
/* Shaping */
/**