Skip to content

Commit 9823bad

Browse files
authored
Merge pull request #985 from ychin/fix-recurse-draw
Fix potential CoreText font rendering infinite recursion
2 parents 67aa513 + 61c8fa4 commit 9823bad

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

src/MacVim/MMCoreTextView.m

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ - (void)batchDrawData:(NSData *)data
17101710

17111711
static CTFontRef
17121712
lookupFont(NSMutableArray *fontCache, const unichar *chars, UniCharCount count,
1713-
CTFontRef currFontRef)
1713+
CTFontRef currFontRef, CGGlyph *glyphsOut)
17141714
{
17151715
CGGlyph glyphs[count];
17161716

@@ -1720,7 +1720,10 @@ - (void)batchDrawData:(NSData *)data
17201720
NSFont *font = [fontCache objectAtIndex:i];
17211721

17221722
if (CTFontGetGlyphsForCharacters((CTFontRef)font, chars, glyphs, count))
1723+
{
1724+
memcpy(glyphsOut, glyphs, count * sizeof(CGGlyph));
17231725
return (CTFontRef)[font retain];
1726+
}
17241727
}
17251728

17261729
// Ask Core Text for a font (can be *very* slow, which is why we cache
@@ -1737,6 +1740,7 @@ - (void)batchDrawData:(NSData *)data
17371740
if (newFontRef)
17381741
[fontCache addObject:(NSFont *)newFontRef];
17391742

1743+
memcpy(glyphsOut, glyphs, count * sizeof(CGGlyph));
17401744
return newFontRef;
17411745
}
17421746

@@ -1840,6 +1844,8 @@ - (void)batchDrawData:(NSData *)data
18401844
UniCharCount length, CGContextRef context, CTFontRef fontRef,
18411845
NSMutableArray *fontCache, BOOL isComposing, BOOL useLigatures)
18421846
{
1847+
// Note: This function is misnamed. It does not actually use recursion and
1848+
// will be renamed in future.
18431849
if (CTFontGetGlyphsForCharacters(fontRef, chars, glyphs, length)) {
18441850
// All chars were mapped to glyphs, so draw all at once and return.
18451851
length = isComposing || useLigatures
@@ -1897,17 +1903,21 @@ - (void)batchDrawData:(NSData *)data
18971903
CTFontRef fallback = nil;
18981904
while (fallback == nil && attemptedCount > 0) {
18991905
fallback = lookupFont(fontCache, chars, attemptedCount,
1900-
fontRef);
1906+
fontRef, glyphs);
19011907
if (!fallback)
19021908
attemptedCount /= 2;
19031909
}
19041910

19051911
if (!fallback)
19061912
return;
19071913

1908-
recurseDraw(chars, glyphs, positions, attemptedCount, context,
1909-
fallback, fontCache, isComposing, useLigatures);
1914+
UniCharCount actualAttemptLength = isComposing || useLigatures
1915+
? composeGlyphsForChars(chars, glyphs, positions, attemptedCount,
1916+
fallback, isComposing, useLigatures)
1917+
: gatherGlyphs(glyphs, attemptedCount);
1918+
CTFontDrawGlyphs(fallback, glyphs, positions, actualAttemptLength, context);
19101919

1920+
// TODO: This doesn't take into account surrogate pairs for 'p'. Clean this up.
19111921
// If only a portion of the invalid range was rendered above,
19121922
// the remaining range needs to be attempted by subsequent
19131923
// iterations of the draw loop.

0 commit comments

Comments
 (0)