Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1047)

Unified Diff: src/ports/SkFontHost_mac.cpp

Issue 43463005: onCharsToGlyphs to handle non-bmp on Mac. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/FontHostTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ports/SkFontHost_mac.cpp
===================================================================
--- src/ports/SkFontHost_mac.cpp (revision 11960)
+++ src/ports/SkFontHost_mac.cpp (working copy)
@@ -946,19 +946,16 @@
uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) {
CGGlyph cgGlyph[2];
- UniChar theChar[2];
+ UniChar theChar[2]; // UniChar is a UTF-16 16-bit code unit.
// Get the glyph
size_t numUniChar = SkUTF16_FromUnichar(uni, theChar);
SkASSERT(sizeof(CGGlyph) <= sizeof(uint16_t));
- // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points.
- // When a surragate pair is detected, the glyph index used is the index of the first
- // UniChar of the pair (the lower location).
- if (!CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar)) {
- cgGlyph[0] = 0;
- }
-
+ // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points:
+ // When a surrogate pair is detected, the glyph index used is the index of the high surrogate.
+ // It is documented that if a mapping is unavailable, the glyph will be set to 0.
+ CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar);
return cgGlyph[0];
}
@@ -1920,53 +1917,89 @@
}
int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
- uint16_t glyphs[], int glyphCount) const {
- // UniChar is utf16
+ uint16_t glyphs[], int glyphCount) const
+{
+ // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points:
+ // When a surrogate pair is detected, the glyph index used is the index of the high surrogate.
+ // It is documented that if a mapping is unavailable, the glyph will be set to 0.
+
SkAutoSTMalloc<1024, UniChar> charStorage;
- const UniChar* src;
+ const UniChar* src; // UniChar is a UTF-16 16-bit code unit.
+ int srcCount;
switch (encoding) {
case kUTF8_Encoding: {
- const char* u8 = (const char*)chars;
- const UniChar* u16 = src = charStorage.reset(2 * glyphCount);
+ const char* utf8 = reinterpret_cast<const char*>(chars);
+ UniChar* utf16 = charStorage.reset(2 * glyphCount);
+ src = utf16;
for (int i = 0; i < glyphCount; ++i) {
- SkUnichar uni = SkUTF8_NextUnichar(&u8);
- int n = SkUTF16_FromUnichar(uni, (uint16_t*)u16);
- u16 += n;
+ SkUnichar uni = SkUTF8_NextUnichar(&utf8);
+ utf16 += SkUTF16_FromUnichar(uni, utf16);
}
+ srcCount = utf16 - src;
break;
}
- case kUTF16_Encoding:
- src = (const UniChar*)chars;
+ case kUTF16_Encoding: {
+ src = reinterpret_cast<const UniChar*>(chars);
+ int extra = 0;
+ for (int i = 0; i < glyphCount; ++i) {
+ if (SkUTF16_IsHighSurrogate(src[i + extra])) {
+ ++extra;
+ }
+ }
+ srcCount = glyphCount + extra;
break;
+ }
case kUTF32_Encoding: {
- const SkUnichar* u32 = (const SkUnichar*)chars;
- const UniChar* u16 = src = charStorage.reset(2 * glyphCount);
+ const SkUnichar* utf32 = reinterpret_cast<const SkUnichar*>(chars);
+ UniChar* utf16 = charStorage.reset(2 * glyphCount);
+ src = utf16;
for (int i = 0; i < glyphCount; ++i) {
- int n = SkUTF16_FromUnichar(u32[i], (uint16_t*)u16);
- u16 += n;
+ utf16 += SkUTF16_FromUnichar(utf32[i], utf16);
}
+ srcCount = utf16 - src;
break;
}
}
- // Our caller may not want glyphs for output, but we need to give that
- // storage to CT, so we can walk it looking for the first non-zero.
+ // If glyphs is NULL, CT still needs glyph storage for finding the first failure.
+ // Also, if there are any non-bmp code points, the provided 'glyphs' storage will be inadequate.
SkAutoSTMalloc<1024, uint16_t> glyphStorage;
uint16_t* macGlyphs = glyphs;
- if (NULL == macGlyphs) {
- macGlyphs = glyphStorage.reset(glyphCount);
+ if (NULL == macGlyphs || srcCount > glyphCount) {
+ macGlyphs = glyphStorage.reset(srcCount);
}
- if (CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, glyphCount)) {
+ bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, srcCount);
+
+ // If there were any non-bmp, then copy and compact.
+ // If 'glyphs' is NULL, then compact glyphStorage in-place.
+ // If all are bmp and 'glyphs' is non-NULL, 'glyphs' already contains the compact glyphs.
+ // If some are non-bmp and 'glyphs' is non-NULL, copy and compact into 'glyphs'.
+ uint16_t* compactedGlyphs = glyphs;
+ if (NULL == compactedGlyphs) {
+ compactedGlyphs = macGlyphs;
+ }
+ if (srcCount > glyphCount) {
+ int extra = 0;
+ for (int i = 0; i < glyphCount; ++i) {
+ if (SkUTF16_IsHighSurrogate(src[i + extra])) {
+ ++extra;
+ }
+ compactedGlyphs[i] = macGlyphs[i + extra];
+ }
+ }
+
+ if (allEncoded) {
return glyphCount;
}
- // If we got false, then we need to manually look for first failure
+
+ // If we got false, then we need to manually look for first failure.
for (int i = 0; i < glyphCount; ++i) {
- if (0 == macGlyphs[i]) {
+ if (0 == compactedGlyphs[i]) {
return i;
}
}
- // odd to get here, as we expected CT to have returned true up front.
+ // Odd to get here, as we expected CT to have returned true up front.
return glyphCount;
}
« no previous file with comments | « no previous file | tests/FontHostTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698