101 { |
101 { |
102 CTFontGetGlyphsForCharacters((CTFontRef)font->fFont, unicodes, glyphs, count); |
102 CTFontGetGlyphsForCharacters((CTFontRef)font->fFont, unicodes, glyphs, count); |
103 |
103 |
104 size_t i; |
104 size_t i; |
105 for (i = 0; i < count; i++) { |
105 for (i = 0; i < count; i++) { |
|
106 UniChar unicode = unicodes[i]; |
|
107 UniChar nextUnicode = (i+1) < count ? unicodes[i+1] : 0; |
|
108 bool surrogatePair = unicode >= HI_SURROGATE_START && unicode <= HI_SURROGATE_END |
|
109 && nextUnicode >= LO_SURROGATE_START && nextUnicode <= LO_SURROGATE_END; |
|
110 |
106 CGGlyph glyph = glyphs[i]; |
111 CGGlyph glyph = glyphs[i]; |
107 if (glyph > 0) { |
112 if (glyph > 0) { |
108 glyphsAsInts[i] = glyph; |
113 glyphsAsInts[i] = glyph; |
|
114 if (surrogatePair) i++; |
109 continue; |
115 continue; |
110 } |
116 } |
111 |
117 |
112 UniChar unicode = unicodes[i]; |
118 const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, &unicodes[i], |
113 const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, &unicode, 1); |
119 surrogatePair ? 2 : 1); |
114 if (fallback) { |
120 if (fallback) { |
115 CTFontGetGlyphsForCharacters(fallback, &unicode, &glyph, 1); |
121 CTFontGetGlyphsForCharacters(fallback, &unicodes[i], &glyphs[i], surrogatePair ? 2 : 1); |
|
122 glyph = glyphs[i]; |
116 CFRelease(fallback); |
123 CFRelease(fallback); |
117 } |
124 } |
118 |
125 |
119 if (glyph > 0) { |
126 if (glyph > 0) { |
120 glyphsAsInts[i] = -unicode; // set the glyph code to the negative unicode value |
127 int codePoint = surrogatePair ? (((int)(unicode - HI_SURROGATE_START)) << 10) |
|
128 + nextUnicode - LO_SURROGATE_START + 0x10000 : unicode; |
|
129 glyphsAsInts[i] = -codePoint; // set the glyph code to the negative unicode value |
121 } else { |
130 } else { |
122 glyphsAsInts[i] = 0; // CoreText couldn't find a glyph for this character either |
131 glyphsAsInts[i] = 0; // CoreText couldn't find a glyph for this character either |
123 } |
132 } |
|
133 if (surrogatePair) i++; |
124 } |
134 } |
125 } |
135 } |
126 |
136 |
127 /* |
137 /* |
128 * Translates a Unicode into a CGGlyph/CTFontRef pair |
138 * Translates a Unicode into a CGGlyph/CTFontRef pair |
156 *glyphRef = glyphCode; |
166 *glyphRef = glyphCode; |
157 CFRetain(font->fFont); |
167 CFRetain(font->fFont); |
158 return (CTFontRef)font->fFont; |
168 return (CTFontRef)font->fFont; |
159 } |
169 } |
160 |
170 |
161 UTF16Char character = -glyphCode; |
171 int codePoint = -glyphCode; |
162 return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1); |
172 if (codePoint >= 0x10000) { |
|
173 UTF16Char chars[2]; |
|
174 CGGlyph glyphs[2]; |
|
175 CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, chars); |
|
176 CTFontRef result = CTS_CopyCTFallbackFontAndGlyphForUnicode(font, chars, glyphs, 2); |
|
177 *glyphRef = glyphs[0]; |
|
178 return result; |
|
179 } else { |
|
180 UTF16Char character = codePoint; |
|
181 return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1); |
|
182 } |
163 } |
183 } |
164 |
184 |
165 // Breakup a 32 bit unicode value into the component surrogate pairs |
185 // Breakup a 32 bit unicode value into the component surrogate pairs |
166 void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) { |
186 void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) { |
167 int value = uniChar - 0x10000; |
187 int value = uniChar - 0x10000; |