linux-packaging-mono/external/bockbuild/packages/patches/pango-coretext-fix-yosemite-crasher.patch
Xamarin Public Jenkins (auto-signing) 6bdd276d05 Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
2017-04-10 11:41:01 +00:00

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).