summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Rietveld <kris@lanedo.com>2011-11-26 17:27:43 +0100
committerKristian Rietveld <kris@lanedo.com>2012-01-19 17:20:23 +0100
commitdbf40154eb5804f4e8c582f12b30b8291c9c3532 (patch)
treedc072c5f950edc9801f177cdd9ec7745ce2683fa
parent92c58b4372833db6974da73b75d457177f402bb6 (diff)
downloadpango-dbf40154eb5804f4e8c582f12b30b8291c9c3532.tar.gz
Bug 664125 - Zero-width spaces cause missing characters
This is fixed by using the characters obtained from CoreText's mapping from glyphs back to the original string instead of blindly iterating over the original gchar string. Take notice that we have to convert these indices from the mapping back to a byte index in the original UTF8 string. Zero-width spaces are already removed from the list of CGGlyphs, so we were mismatching CGGlyphs and characters from the original string. Using CoreText's list of string indices instead eliminates the mismatches.
-rw-r--r--modules/basic/basic-coretext.c80
1 files changed, 37 insertions, 43 deletions
diff --git a/modules/basic/basic-coretext.c b/modules/basic/basic-coretext.c
index 8dc3dbab..991743e4 100644
--- a/modules/basic/basic-coretext.c
+++ b/modules/basic/basic-coretext.c
@@ -76,7 +76,6 @@ basic_engine_shape (PangoEngineShape *engine,
const PangoAnalysis *analysis,
PangoGlyphString *glyphs)
{
- const char *p;
char *copy;
CTLineRef line;
CFStringRef cstr;
@@ -88,6 +87,7 @@ basic_engine_shape (PangoEngineShape *engine,
CTRunRef run;
CTRunStatus run_status;
CFIndex i, glyph_count;
+ CFIndex *indices = NULL;
const CGGlyph *cgglyphs;
CFTypeRef keys[] = {
@@ -128,7 +128,9 @@ basic_engine_shape (PangoEngineShape *engine,
glyph_count = CTRunGetGlyphCount (run);
cgglyphs = CTRunGetGlyphsPtr (run);
- p = text;
+ indices = malloc (sizeof (CFIndex *) * glyph_count);
+ CTRunGetStringIndices (run, CFRangeMake (0, glyph_count), indices);
+
pango_glyph_string_set_size (glyphs, glyph_count);
coverage = pango_font_get_coverage (PANGO_FONT (cfont),
analysis->language);
@@ -138,12 +140,7 @@ basic_engine_shape (PangoEngineShape *engine,
CFIndex real_i, prev_i;
gunichar wc;
gunichar mirrored_ch;
-
- wc = g_utf8_get_char (p);
-
- if (analysis->level % 2)
- if (pango_get_mirror_char (wc, &mirrored_ch))
- wc = mirrored_ch;
+ PangoCoverageLevel result;
if (run_status & kCTRunStatusRightToLeft)
{
@@ -156,53 +153,50 @@ basic_engine_shape (PangoEngineShape *engine,
prev_i = real_i - 1;
}
+ wc = CFStringGetCharacterAtIndex (cstr, indices[real_i]);
+
+ if (analysis->level % 2)
+ if (pango_get_mirror_char (wc, &mirrored_ch))
+ wc = mirrored_ch;
+
if (wc == 0xa0) /* non-break-space */
wc = 0x20;
- if (pango_is_zero_width (wc))
- {
- set_glyph (font, glyphs, real_i, p - text, PANGO_GLYPH_EMPTY);
- }
- else
- {
- PangoCoverageLevel result;
+ result = pango_coverage_get (coverage, wc);
- result = pango_coverage_get (coverage, wc);
+ if (result != PANGO_COVERAGE_NONE)
+ {
+ set_glyph (font, glyphs, real_i,
+ g_utf8_offset_to_pointer (text, indices[real_i]) - text,
+ cgglyphs[real_i]);
- if (result != PANGO_COVERAGE_NONE)
+ if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
{
- set_glyph (font, glyphs, real_i, p - text, cgglyphs[real_i]);
-
- if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
+ if (i > 0)
{
- if (i > 0)
- {
- PangoRectangle logical_rect, ink_rect;
-
- glyphs->glyphs[real_i].geometry.width = MAX (glyphs->glyphs[prev_i].geometry.width,
- glyphs->glyphs[prev_i].geometry.width);
- glyphs->glyphs[prev_i].geometry.width = 0;
- glyphs->log_clusters[real_i] = glyphs->log_clusters[prev_i];
-
- /* Some heuristics to try to guess how overstrike glyphs are
- * done and compensate
- */
- pango_font_get_glyph_extents (font, glyphs->glyphs[real_i].glyph, &ink_rect, &logical_rect);
- if (logical_rect.width == 0 && ink_rect.x == 0)
- glyphs->glyphs[real_i].geometry.x_offset = (glyphs->glyphs[real_i].geometry.width - ink_rect.width) / 2;
- }
+ PangoRectangle logical_rect, ink_rect;
+
+ glyphs->glyphs[real_i].geometry.width = MAX (glyphs->glyphs[prev_i].geometry.width,
+ glyphs->glyphs[real_i].geometry.width);
+ glyphs->glyphs[prev_i].geometry.width = 0;
+ glyphs->log_clusters[real_i] = glyphs->log_clusters[prev_i];
+
+ /* Some heuristics to try to guess how overstrike glyphs are
+ * done and compensate
+ */
+ pango_font_get_glyph_extents (font, glyphs->glyphs[real_i].glyph, &ink_rect, &logical_rect);
+ if (logical_rect.width == 0 && ink_rect.x == 0)
+ glyphs->glyphs[real_i].geometry.x_offset = (glyphs->glyphs[real_i].geometry.width - ink_rect.width) / 2;
}
}
- else
- {
- set_glyph (font, glyphs, real_i, p - text,
- PANGO_GET_UNKNOWN_GLYPH (wc));
- }
}
-
- p = g_utf8_next_char (p);
+ else
+ set_glyph (font, glyphs, real_i,
+ g_utf8_offset_to_pointer (text, indices[real_i]) - text,
+ PANGO_GET_UNKNOWN_GLYPH (wc));
}
+ free (indices);
CFRelease (line);
CFRelease (attstr);
CFRelease (cstr);