1 diff --git a/modules/basic/.libs/basic-coretext.o b/modules/basic/.libs/basic-coretext.o
2 index 13cce67..80c3268 100644
3 Binary files a/modules/basic/.libs/basic-coretext.o and b/modules/basic/.libs/basic-coretext.o differ
4 diff --git a/modules/basic/.libs/pango-basic-coretext.so b/modules/basic/.libs/pango-basic-coretext.so
5 index 70bb117..d0940c4 100755
6 Binary files a/modules/basic/.libs/pango-basic-coretext.so and b/modules/basic/.libs/pango-basic-coretext.so differ
7 diff --git a/modules/basic/basic-coretext.c b/modules/basic/basic-coretext.c
8 index c34460a..46d83ff 100644
9 --- a/modules/basic/basic-coretext.c
10 +++ b/modules/basic/basic-coretext.c
11 @@ -92,6 +92,7 @@ struct RunIterator
13 CFIndex *current_indices;
14 const CGGlyph *current_cgglyphs;
15 + CGGlyph *current_cgglyphs_buffer;
16 CTRunStatus current_run_status;
19 @@ -101,6 +102,9 @@ run_iterator_free_current_run (struct RunIterator *iter)
20 iter->current_run_number = -1;
21 iter->current_run = NULL;
22 iter->current_cgglyphs = NULL;
23 + if (iter->current_cgglyphs_buffer)
24 + free (iter->current_cgglyphs_buffer);
25 + iter->current_cgglyphs_buffer = NULL;
26 if (iter->current_indices)
27 free (iter->current_indices);
28 iter->current_indices = NULL;
29 @@ -116,10 +120,18 @@ run_iterator_set_current_run (struct RunIterator *iter,
31 iter->current_run_number = run_number;
32 iter->current_run = CFArrayGetValueAtIndex (iter->runs, run_number);
33 + ct_glyph_count = CTRunGetGlyphCount (iter->current_run);
35 iter->current_run_status = CTRunGetStatus (iter->current_run);
36 iter->current_cgglyphs = CTRunGetGlyphsPtr (iter->current_run);
37 + if (!iter->current_cgglyphs)
39 + iter->current_cgglyphs_buffer = (CGGlyph *)malloc (sizeof (CGGlyph) * ct_glyph_count);
40 + CTRunGetGlyphs (iter->current_run, CFRangeMake (0, ct_glyph_count),
41 + iter->current_cgglyphs_buffer);
42 + iter->current_cgglyphs = iter->current_cgglyphs_buffer;
45 - ct_glyph_count = CTRunGetGlyphCount (iter->current_run);
46 iter->current_indices = malloc (sizeof (CFIndex *) * ct_glyph_count);
47 CTRunGetStringIndices (iter->current_run, CFRangeMake (0, ct_glyph_count),
48 iter->current_indices);
49 @@ -237,6 +249,7 @@ run_iterator_create (struct RunIterator *iter,
50 iter->current_run = NULL;
51 iter->current_indices = NULL;
52 iter->current_cgglyphs = NULL;
53 + iter->current_cgglyphs_buffer = NULL;
56 attributes = CFDictionaryCreate (kCFAllocatorDefault,
57 diff --git a/modules/basic/basic-coretext.c.orig b/modules/basic/basic-coretext.c.orig
58 index 0a2c27f..c34460a 100644
59 --- a/modules/basic/basic-coretext.c.orig
60 +++ b/modules/basic/basic-coretext.c.orig
61 @@ -166,7 +166,42 @@ run_iterator_run_is_non_monotonic (struct RunIterator *iter)
63 run_iterator_get_character (struct RunIterator *iter)
65 - return CFStringGetCharacterAtIndex (iter->cstr, iter->current_indices[iter->ct_i]);
68 + lower = iter->current_indices[iter->ct_i];
69 + if (iter->ct_i + 1 < CTRunGetGlyphCount (iter->current_run))
70 + upper = iter->current_indices[iter->ct_i + 1];
73 + CFRange range = CTRunGetStringRange (iter->current_run);
74 + upper = range.location + range.length;
77 + if (upper - lower == 1)
78 + return CFStringGetCharacterAtIndex (iter->cstr, lower);
79 + if (upper - lower == 2)
81 + /* Character is encoded in two UTF16 code points. */
86 + orig[0] = CFStringGetCharacterAtIndex (iter->cstr, lower);
87 + orig[1] = CFStringGetCharacterAtIndex (iter->cstr, lower + 1);
89 + ch = g_utf16_to_ucs4 (orig, 2, NULL, NULL, NULL);
96 + /* This should not be reached, because other cases cannot occur. Instead
97 + * of crashing, return the first character which will likely be displayed
101 + return CFStringGetCharacterAtIndex (iter->cstr, lower);
105 @@ -175,12 +210,6 @@ run_iterator_get_cgglyph (struct RunIterator *iter)
106 return iter->current_cgglyphs[iter->ct_i];
110 -run_iterator_get_index (struct RunIterator *iter)
112 - return iter->current_indices[iter->ct_i];
116 run_iterator_create (struct RunIterator *iter,
118 @@ -190,13 +219,17 @@ run_iterator_create (struct RunIterator *iter,
120 CFDictionaryRef attributes;
121 CFAttributedStringRef attstr;
123 + CFNumberRef number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &val);
126 - (CFTypeRef) kCTFontAttributeName
127 + (CFTypeRef) kCTFontAttributeName,
128 + kCTLigatureAttributeName
131 CFTypeRef values[] = {
137 /* Initialize RunIterator structure */
138 @@ -209,7 +242,7 @@ run_iterator_create (struct RunIterator *iter,
139 attributes = CFDictionaryCreate (kCFAllocatorDefault,
141 (const void **)values,
143 + sizeof (keys) / sizeof (keys[0]),
144 &kCFCopyStringDictionaryKeyCallBacks,
145 &kCFTypeDictionaryValueCallBacks);
147 @@ -233,6 +266,7 @@ run_iterator_create (struct RunIterator *iter,
148 iter->line = CTLineCreateWithAttributedString (attstr);
149 iter->runs = CTLineGetGlyphRuns (iter->line);
151 + CFRelease (number);
153 CFRelease (attributes);
155 @@ -336,7 +370,7 @@ create_core_text_glyph_list (const char *text,
156 struct GlyphInfo *gi;
158 gi = g_slice_new (struct GlyphInfo);
159 - gi->index = run_iterator_get_index (&riter);
160 + gi->index = riter.total_ct_i;
161 gi->cgglyph = run_iterator_get_cgglyph (&riter);
162 gi->wc = run_iterator_get_character (&riter);
164 @@ -378,9 +412,8 @@ basic_engine_shape (PangoEngineShape *engine,
165 * glyph sequence generated by the CoreText typesetter:
166 * # E.g. zero-width spaces do not end up in the CoreText glyph sequence. We have
167 * to manually account for the gap in the character indices.
168 - * # Sometimes, CoreText generates two glyph for the same character index. We
169 - * currently handle this "properly" as in we do not crash or corrupt memory,
170 - * but that's about it.
171 + * # Sometimes, CoreText generates two glyph for the same character index. These
172 + * are properly composed into a single 32-bit gunichar.
173 * # Due to mismatches in size, the CoreText glyph sequence can either be longer or
174 * shorter than the PangoGlyphString. Note that the size of the PangoGlyphString
175 * should match the number of characters in "text".
176 @@ -392,11 +425,6 @@ basic_engine_shape (PangoEngineShape *engine,
177 * increasing/decreasing.
179 * FIXME items for future fixing:
180 - * # CoreText strings are UTF16, and the indices *often* refer to characters,
181 - * but not *always*. Notable exception is when a character is encoded using
182 - * two UTF16 code points. This are two characters in a CFString. At this point
183 - * advancing a single character in the CFString and advancing a single character
184 - * using g_utf8_next_char in the const char string goes out of sync.
185 * # We currently don't bother about LTR, Pango core appears to fix this up for us.
186 * (Even when we cared warnings were generated that strings were in the wrong
187 * order, this should be investigated).