--- old/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m 2016-10-26 11:10:16.591477004 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m 2016-10-26 11:10:16.495477002 +0300 @@ -591,7 +591,7 @@ static inline GlyphInfo * CGGI_CreateImageForUnicode (CGGI_GlyphCanvas *canvas, const AWTStrike *strike, - const CGGI_RenderingMode *mode, const UniChar uniChar) + const CGGI_RenderingMode *mode, const UnicodeScalarValue uniChar) { // save the state of the world CGContextSaveGState(canvas->context); @@ -668,7 +668,7 @@ const AWTStrike *strike, const CGGI_RenderingMode *mode, jlong glyphInfos[], - const UniChar uniChars[], + const UnicodeScalarValue uniChars[], const CGGlyph glyphs[], const CFIndex len) { @@ -720,7 +720,7 @@ static inline void CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike, const CGGI_RenderingMode *mode, - const UniChar uniChars[], const CGGlyph glyphs[], + const UnicodeScalarValue uniChars[], const CGGlyph glyphs[], const size_t maxWidth, const size_t maxHeight, const CFIndex len) { @@ -767,7 +767,7 @@ static inline void CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike, const CGGI_RenderingMode *mode, - const UniChar uniChars[], const CGGlyph glyphs[], + const UnicodeScalarValue uniChars[], const CGGlyph glyphs[], CGSize advances[], CGRect bboxes[], const CFIndex len) { AWTFont *font = strike->fAWTFont; @@ -817,7 +817,7 @@ const AWTStrike *strike, const CGGI_RenderingMode *mode, jint rawGlyphCodes[], - UniChar uniChars[], CGGlyph glyphs[], + UnicodeScalarValue uniChars[], CGGlyph glyphs[], CGSize advances[], CGRect bboxes[], const CFIndex len) { @@ -860,7 +860,7 @@ CGRect bboxes[len]; CGSize advances[len]; CGGlyph glyphs[len]; - UniChar uniChars[len]; + UnicodeScalarValue uniChars[len]; CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode, rawGlyphCodes, uniChars, glyphs, @@ -871,7 +871,7 @@ // just do one malloc, and carve it up for all the buffers void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) * - sizeof(CGGlyph) * sizeof(UniChar) * len); + sizeof(CGGlyph) * sizeof(UnicodeScalarValue) * len); if (buffer == NULL) { [[NSException exceptionWithName:NSMallocException reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise]; @@ -880,7 +880,7 @@ CGRect *bboxes = (CGRect *)(buffer); CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len); CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len); - UniChar *uniChars = (UniChar *)(glyphs + sizeof(UniChar) * len); + UnicodeScalarValue *uniChars = (UnicodeScalarValue *)(glyphs + sizeof(UnicodeScalarValue) * len); CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode, rawGlyphCodes, uniChars, glyphs, --- old/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h 2016-10-26 11:10:16.867477008 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h 2016-10-26 11:10:16.779477006 +0300 @@ -32,7 +32,9 @@ #pragma mark --- CoreText Support --- #define HI_SURROGATE_START 0xD800 +#define HI_SURROGATE_END 0xDBFF #define LO_SURROGATE_START 0xDC00 +#define LO_SURROGATE_END 0xDFFF /* * Transform Unicode characters into glyphs. --- old/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m 2016-10-26 11:10:17.135477012 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m 2016-10-26 11:10:17.043477011 +0300 @@ -103,24 +103,34 @@ size_t i; for (i = 0; i < count; i++) { + UniChar unicode = unicodes[i]; + UniChar nextUnicode = (i+1) < count ? unicodes[i+1] : 0; + bool surrogatePair = unicode >= HI_SURROGATE_START && unicode <= HI_SURROGATE_END + && nextUnicode >= LO_SURROGATE_START && nextUnicode <= LO_SURROGATE_END; + CGGlyph glyph = glyphs[i]; if (glyph > 0) { glyphsAsInts[i] = glyph; + if (surrogatePair) i++; continue; } - UniChar unicode = unicodes[i]; - const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, &unicode, 1); + const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, &unicodes[i], + surrogatePair ? 2 : 1); if (fallback) { - CTFontGetGlyphsForCharacters(fallback, &unicode, &glyph, 1); + CTFontGetGlyphsForCharacters(fallback, &unicodes[i], &glyphs[i], surrogatePair ? 2 : 1); + glyph = glyphs[i]; CFRelease(fallback); } if (glyph > 0) { - glyphsAsInts[i] = -unicode; // set the glyph code to the negative unicode value + int codePoint = surrogatePair ? (((int)(unicode - HI_SURROGATE_START)) << 10) + + nextUnicode - LO_SURROGATE_START + 0x10000 : unicode; + glyphsAsInts[i] = -codePoint; // set the glyph code to the negative unicode value } else { glyphsAsInts[i] = 0; // CoreText couldn't find a glyph for this character either } + if (surrogatePair) i++; } } @@ -158,8 +168,18 @@ return (CTFontRef)font->fFont; } - UTF16Char character = -glyphCode; - return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1); + int codePoint = -glyphCode; + if (codePoint >= 0x10000) { + UTF16Char chars[2]; + CGGlyph glyphs[2]; + CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, chars); + CTFontRef result = CTS_CopyCTFallbackFontAndGlyphForUnicode(font, chars, glyphs, 2); + *glyphRef = glyphs[0]; + return result; + } else { + UTF16Char character = codePoint; + return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1); + } } // Breakup a 32 bit unicode value into the component surrogate pairs