6bdd276d05
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
188 lines
7.5 KiB
Diff
188 lines
7.5 KiB
Diff
diff --git a/modules/basic/.libs/basic-coretext.o b/modules/basic/.libs/basic-coretext.o
|
|
index 13cce67..80c3268 100644
|
|
Binary files a/modules/basic/.libs/basic-coretext.o and b/modules/basic/.libs/basic-coretext.o differ
|
|
diff --git a/modules/basic/.libs/pango-basic-coretext.so b/modules/basic/.libs/pango-basic-coretext.so
|
|
index 70bb117..d0940c4 100755
|
|
Binary files a/modules/basic/.libs/pango-basic-coretext.so and b/modules/basic/.libs/pango-basic-coretext.so differ
|
|
diff --git a/modules/basic/basic-coretext.c b/modules/basic/basic-coretext.c
|
|
index c34460a..46d83ff 100644
|
|
--- a/modules/basic/basic-coretext.c
|
|
+++ b/modules/basic/basic-coretext.c
|
|
@@ -92,6 +92,7 @@ struct RunIterator
|
|
CTRunRef current_run;
|
|
CFIndex *current_indices;
|
|
const CGGlyph *current_cgglyphs;
|
|
+ CGGlyph *current_cgglyphs_buffer;
|
|
CTRunStatus current_run_status;
|
|
};
|
|
|
|
@@ -101,6 +102,9 @@ run_iterator_free_current_run (struct RunIterator *iter)
|
|
iter->current_run_number = -1;
|
|
iter->current_run = NULL;
|
|
iter->current_cgglyphs = NULL;
|
|
+ if (iter->current_cgglyphs_buffer)
|
|
+ free (iter->current_cgglyphs_buffer);
|
|
+ iter->current_cgglyphs_buffer = NULL;
|
|
if (iter->current_indices)
|
|
free (iter->current_indices);
|
|
iter->current_indices = NULL;
|
|
@@ -116,10 +120,18 @@ run_iterator_set_current_run (struct RunIterator *iter,
|
|
|
|
iter->current_run_number = run_number;
|
|
iter->current_run = CFArrayGetValueAtIndex (iter->runs, run_number);
|
|
+ ct_glyph_count = CTRunGetGlyphCount (iter->current_run);
|
|
+
|
|
iter->current_run_status = CTRunGetStatus (iter->current_run);
|
|
iter->current_cgglyphs = CTRunGetGlyphsPtr (iter->current_run);
|
|
+ if (!iter->current_cgglyphs)
|
|
+ {
|
|
+ iter->current_cgglyphs_buffer = (CGGlyph *)malloc (sizeof (CGGlyph) * ct_glyph_count);
|
|
+ CTRunGetGlyphs (iter->current_run, CFRangeMake (0, ct_glyph_count),
|
|
+ iter->current_cgglyphs_buffer);
|
|
+ iter->current_cgglyphs = iter->current_cgglyphs_buffer;
|
|
+ }
|
|
|
|
- ct_glyph_count = CTRunGetGlyphCount (iter->current_run);
|
|
iter->current_indices = malloc (sizeof (CFIndex *) * ct_glyph_count);
|
|
CTRunGetStringIndices (iter->current_run, CFRangeMake (0, ct_glyph_count),
|
|
iter->current_indices);
|
|
@@ -237,6 +249,7 @@ run_iterator_create (struct RunIterator *iter,
|
|
iter->current_run = NULL;
|
|
iter->current_indices = NULL;
|
|
iter->current_cgglyphs = NULL;
|
|
+ iter->current_cgglyphs_buffer = NULL;
|
|
|
|
/* Create CTLine */
|
|
attributes = CFDictionaryCreate (kCFAllocatorDefault,
|
|
diff --git a/modules/basic/basic-coretext.c.orig b/modules/basic/basic-coretext.c.orig
|
|
index 0a2c27f..c34460a 100644
|
|
--- a/modules/basic/basic-coretext.c.orig
|
|
+++ b/modules/basic/basic-coretext.c.orig
|
|
@@ -166,7 +166,42 @@ run_iterator_run_is_non_monotonic (struct RunIterator *iter)
|
|
static gunichar
|
|
run_iterator_get_character (struct RunIterator *iter)
|
|
{
|
|
- return CFStringGetCharacterAtIndex (iter->cstr, iter->current_indices[iter->ct_i]);
|
|
+ int lower, upper;
|
|
+
|
|
+ lower = iter->current_indices[iter->ct_i];
|
|
+ if (iter->ct_i + 1 < CTRunGetGlyphCount (iter->current_run))
|
|
+ upper = iter->current_indices[iter->ct_i + 1];
|
|
+ else
|
|
+ {
|
|
+ CFRange range = CTRunGetStringRange (iter->current_run);
|
|
+ upper = range.location + range.length;
|
|
+ }
|
|
+
|
|
+ if (upper - lower == 1)
|
|
+ return CFStringGetCharacterAtIndex (iter->cstr, lower);
|
|
+ if (upper - lower == 2)
|
|
+ {
|
|
+ /* Character is encoded in two UTF16 code points. */
|
|
+ gunichar *ch;
|
|
+ gunichar retval;
|
|
+ gunichar2 orig[2];
|
|
+
|
|
+ orig[0] = CFStringGetCharacterAtIndex (iter->cstr, lower);
|
|
+ orig[1] = CFStringGetCharacterAtIndex (iter->cstr, lower + 1);
|
|
+
|
|
+ ch = g_utf16_to_ucs4 (orig, 2, NULL, NULL, NULL);
|
|
+ retval = *ch;
|
|
+ g_free (ch);
|
|
+
|
|
+ return retval;
|
|
+ }
|
|
+
|
|
+ /* This should not be reached, because other cases cannot occur. Instead
|
|
+ * of crashing, return the first character which will likely be displayed
|
|
+ * as unknown glyph.
|
|
+ */
|
|
+
|
|
+ return CFStringGetCharacterAtIndex (iter->cstr, lower);
|
|
}
|
|
|
|
static CGGlyph
|
|
@@ -175,12 +210,6 @@ run_iterator_get_cgglyph (struct RunIterator *iter)
|
|
return iter->current_cgglyphs[iter->ct_i];
|
|
}
|
|
|
|
-static CFIndex
|
|
-run_iterator_get_index (struct RunIterator *iter)
|
|
-{
|
|
- return iter->current_indices[iter->ct_i];
|
|
-}
|
|
-
|
|
static gboolean
|
|
run_iterator_create (struct RunIterator *iter,
|
|
const char *text,
|
|
@@ -190,13 +219,17 @@ run_iterator_create (struct RunIterator *iter,
|
|
char *copy;
|
|
CFDictionaryRef attributes;
|
|
CFAttributedStringRef attstr;
|
|
+ int val = 0;
|
|
+ CFNumberRef number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &val);
|
|
|
|
CFTypeRef keys[] = {
|
|
- (CFTypeRef) kCTFontAttributeName
|
|
+ (CFTypeRef) kCTFontAttributeName,
|
|
+ kCTLigatureAttributeName
|
|
};
|
|
|
|
CFTypeRef values[] = {
|
|
- ctfont
|
|
+ ctfont,
|
|
+ number
|
|
};
|
|
|
|
/* Initialize RunIterator structure */
|
|
@@ -209,7 +242,7 @@ run_iterator_create (struct RunIterator *iter,
|
|
attributes = CFDictionaryCreate (kCFAllocatorDefault,
|
|
(const void **)keys,
|
|
(const void **)values,
|
|
- 1,
|
|
+ sizeof (keys) / sizeof (keys[0]),
|
|
&kCFCopyStringDictionaryKeyCallBacks,
|
|
&kCFTypeDictionaryValueCallBacks);
|
|
|
|
@@ -233,6 +266,7 @@ run_iterator_create (struct RunIterator *iter,
|
|
iter->line = CTLineCreateWithAttributedString (attstr);
|
|
iter->runs = CTLineGetGlyphRuns (iter->line);
|
|
|
|
+ CFRelease (number);
|
|
CFRelease (attstr);
|
|
CFRelease (attributes);
|
|
|
|
@@ -336,7 +370,7 @@ create_core_text_glyph_list (const char *text,
|
|
struct GlyphInfo *gi;
|
|
|
|
gi = g_slice_new (struct GlyphInfo);
|
|
- gi->index = run_iterator_get_index (&riter);
|
|
+ gi->index = riter.total_ct_i;
|
|
gi->cgglyph = run_iterator_get_cgglyph (&riter);
|
|
gi->wc = run_iterator_get_character (&riter);
|
|
|
|
@@ -378,9 +412,8 @@ basic_engine_shape (PangoEngineShape *engine,
|
|
* glyph sequence generated by the CoreText typesetter:
|
|
* # E.g. zero-width spaces do not end up in the CoreText glyph sequence. We have
|
|
* to manually account for the gap in the character indices.
|
|
- * # Sometimes, CoreText generates two glyph for the same character index. We
|
|
- * currently handle this "properly" as in we do not crash or corrupt memory,
|
|
- * but that's about it.
|
|
+ * # Sometimes, CoreText generates two glyph for the same character index. These
|
|
+ * are properly composed into a single 32-bit gunichar.
|
|
* # Due to mismatches in size, the CoreText glyph sequence can either be longer or
|
|
* shorter than the PangoGlyphString. Note that the size of the PangoGlyphString
|
|
* should match the number of characters in "text".
|
|
@@ -392,11 +425,6 @@ basic_engine_shape (PangoEngineShape *engine,
|
|
* increasing/decreasing.
|
|
*
|
|
* FIXME items for future fixing:
|
|
- * # CoreText strings are UTF16, and the indices *often* refer to characters,
|
|
- * but not *always*. Notable exception is when a character is encoded using
|
|
- * two UTF16 code points. This are two characters in a CFString. At this point
|
|
- * advancing a single character in the CFString and advancing a single character
|
|
- * using g_utf8_next_char in the const char string goes out of sync.
|
|
* # We currently don't bother about LTR, Pango core appears to fix this up for us.
|
|
* (Even when we cared warnings were generated that strings were in the wrong
|
|
* order, this should be investigated).
|