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

Side by Side 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, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/FontHostTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include <vector> 9 #include <vector>
10 #ifdef SK_BUILD_FOR_MAC 10 #ifdef SK_BUILD_FOR_MAC
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 939
940 return true; 940 return true;
941 } 941 }
942 942
943 unsigned SkScalerContext_Mac::generateGlyphCount(void) { 943 unsigned SkScalerContext_Mac::generateGlyphCount(void) {
944 return fGlyphCount; 944 return fGlyphCount;
945 } 945 }
946 946
947 uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) { 947 uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) {
948 CGGlyph cgGlyph[2]; 948 CGGlyph cgGlyph[2];
949 UniChar theChar[2]; 949 UniChar theChar[2]; // UniChar is a UTF-16 16-bit code unit.
950 950
951 // Get the glyph 951 // Get the glyph
952 size_t numUniChar = SkUTF16_FromUnichar(uni, theChar); 952 size_t numUniChar = SkUTF16_FromUnichar(uni, theChar);
953 SkASSERT(sizeof(CGGlyph) <= sizeof(uint16_t)); 953 SkASSERT(sizeof(CGGlyph) <= sizeof(uint16_t));
954 954
955 // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code p oints. 955 // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code p oints:
956 // When a surragate pair is detected, the glyph index used is the index of t he first 956 // When a surrogate pair is detected, the glyph index used is the index of t he high surrogate.
957 // UniChar of the pair (the lower location). 957 // It is documented that if a mapping is unavailable, the glyph will be set to 0.
958 if (!CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar)) { 958 CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar);
959 cgGlyph[0] = 0;
960 }
961
962 return cgGlyph[0]; 959 return cgGlyph[0];
963 } 960 }
964 961
965 void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) { 962 void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) {
966 this->generateMetrics(glyph); 963 this->generateMetrics(glyph);
967 } 964 }
968 965
969 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { 966 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) {
970 const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(fBaseGlyphCount); 967 const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(fBaseGlyphCount);
971 glyph->zeroMetrics(); 968 glyph->zeroMetrics();
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
1913 SkString tmpStr; 1910 SkString tmpStr;
1914 1911
1915 desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr)); 1912 desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
1916 desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr)); 1913 desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
1917 desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr) ); 1914 desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr) );
1918 // TODO: need to add support for local-streams (here and openStream) 1915 // TODO: need to add support for local-streams (here and openStream)
1919 *isLocalStream = false; 1916 *isLocalStream = false;
1920 } 1917 }
1921 1918
1922 int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding, 1919 int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
1923 uint16_t glyphs[], int glyphCount) const { 1920 uint16_t glyphs[], int glyphCount) const
1924 // UniChar is utf16 1921 {
1922 // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code p oints:
1923 // When a surrogate pair is detected, the glyph index used is the index of t he high surrogate.
1924 // It is documented that if a mapping is unavailable, the glyph will be set to 0.
1925
1925 SkAutoSTMalloc<1024, UniChar> charStorage; 1926 SkAutoSTMalloc<1024, UniChar> charStorage;
1926 const UniChar* src; 1927 const UniChar* src; // UniChar is a UTF-16 16-bit code unit.
1928 int srcCount;
1927 switch (encoding) { 1929 switch (encoding) {
1928 case kUTF8_Encoding: { 1930 case kUTF8_Encoding: {
1929 const char* u8 = (const char*)chars; 1931 const char* utf8 = reinterpret_cast<const char*>(chars);
1930 const UniChar* u16 = src = charStorage.reset(2 * glyphCount); 1932 UniChar* utf16 = charStorage.reset(2 * glyphCount);
1933 src = utf16;
1931 for (int i = 0; i < glyphCount; ++i) { 1934 for (int i = 0; i < glyphCount; ++i) {
1932 SkUnichar uni = SkUTF8_NextUnichar(&u8); 1935 SkUnichar uni = SkUTF8_NextUnichar(&utf8);
1933 int n = SkUTF16_FromUnichar(uni, (uint16_t*)u16); 1936 utf16 += SkUTF16_FromUnichar(uni, utf16);
1934 u16 += n;
1935 } 1937 }
1938 srcCount = utf16 - src;
1936 break; 1939 break;
1937 } 1940 }
1938 case kUTF16_Encoding: 1941 case kUTF16_Encoding: {
1939 src = (const UniChar*)chars; 1942 src = reinterpret_cast<const UniChar*>(chars);
1943 int extra = 0;
1944 for (int i = 0; i < glyphCount; ++i) {
1945 if (SkUTF16_IsHighSurrogate(src[i + extra])) {
1946 ++extra;
1947 }
1948 }
1949 srcCount = glyphCount + extra;
1940 break; 1950 break;
1951 }
1941 case kUTF32_Encoding: { 1952 case kUTF32_Encoding: {
1942 const SkUnichar* u32 = (const SkUnichar*)chars; 1953 const SkUnichar* utf32 = reinterpret_cast<const SkUnichar*>(chars);
1943 const UniChar* u16 = src = charStorage.reset(2 * glyphCount); 1954 UniChar* utf16 = charStorage.reset(2 * glyphCount);
1955 src = utf16;
1944 for (int i = 0; i < glyphCount; ++i) { 1956 for (int i = 0; i < glyphCount; ++i) {
1945 int n = SkUTF16_FromUnichar(u32[i], (uint16_t*)u16); 1957 utf16 += SkUTF16_FromUnichar(utf32[i], utf16);
1946 u16 += n;
1947 } 1958 }
1959 srcCount = utf16 - src;
1948 break; 1960 break;
1949 } 1961 }
1950 } 1962 }
1951 1963
1952 // Our caller may not want glyphs for output, but we need to give that 1964 // If glyphs is NULL, CT still needs glyph storage for finding the first fai lure.
1953 // storage to CT, so we can walk it looking for the first non-zero. 1965 // Also, if there are any non-bmp code points, the provided 'glyphs' storage will be inadequate.
1954 SkAutoSTMalloc<1024, uint16_t> glyphStorage; 1966 SkAutoSTMalloc<1024, uint16_t> glyphStorage;
1955 uint16_t* macGlyphs = glyphs; 1967 uint16_t* macGlyphs = glyphs;
1956 if (NULL == macGlyphs) { 1968 if (NULL == macGlyphs || srcCount > glyphCount) {
1957 macGlyphs = glyphStorage.reset(glyphCount); 1969 macGlyphs = glyphStorage.reset(srcCount);
1958 } 1970 }
1959 1971
1960 if (CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, glyphCount)) { 1972 bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, src Count);
1973
1974 // If there were any non-bmp, then copy and compact.
1975 // If 'glyphs' is NULL, then compact glyphStorage in-place.
1976 // If all are bmp and 'glyphs' is non-NULL, 'glyphs' already contains the co mpact glyphs.
1977 // If some are non-bmp and 'glyphs' is non-NULL, copy and compact into 'glyp hs'.
1978 uint16_t* compactedGlyphs = glyphs;
1979 if (NULL == compactedGlyphs) {
1980 compactedGlyphs = macGlyphs;
1981 }
1982 if (srcCount > glyphCount) {
1983 int extra = 0;
1984 for (int i = 0; i < glyphCount; ++i) {
1985 if (SkUTF16_IsHighSurrogate(src[i + extra])) {
1986 ++extra;
1987 }
1988 compactedGlyphs[i] = macGlyphs[i + extra];
1989 }
1990 }
1991
1992 if (allEncoded) {
1961 return glyphCount; 1993 return glyphCount;
1962 } 1994 }
1963 // If we got false, then we need to manually look for first failure 1995
1996 // If we got false, then we need to manually look for first failure.
1964 for (int i = 0; i < glyphCount; ++i) { 1997 for (int i = 0; i < glyphCount; ++i) {
1965 if (0 == macGlyphs[i]) { 1998 if (0 == compactedGlyphs[i]) {
1966 return i; 1999 return i;
1967 } 2000 }
1968 } 2001 }
1969 // odd to get here, as we expected CT to have returned true up front. 2002 // Odd to get here, as we expected CT to have returned true up front.
1970 return glyphCount; 2003 return glyphCount;
1971 } 2004 }
1972 2005
1973 int SkTypeface_Mac::onCountGlyphs() const { 2006 int SkTypeface_Mac::onCountGlyphs() const {
1974 return CTFontGetGlyphCount(fFontRef); 2007 return CTFontGetGlyphCount(fFontRef);
1975 } 2008 }
1976 2009
1977 /////////////////////////////////////////////////////////////////////////////// 2010 ///////////////////////////////////////////////////////////////////////////////
1978 /////////////////////////////////////////////////////////////////////////////// 2011 ///////////////////////////////////////////////////////////////////////////////
1979 #if 1 2012 #if 1
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2305 } 2338 }
2306 return create_from_dataProvider(provider); 2339 return create_from_dataProvider(provider);
2307 } 2340 }
2308 2341
2309 #endif 2342 #endif
2310 2343
2311 SkFontMgr* SkFontMgr::Factory() { 2344 SkFontMgr* SkFontMgr::Factory() {
2312 return SkNEW(SkFontMgr_Mac); 2345 return SkNEW(SkFontMgr_Mac);
2313 } 2346 }
2314 #endif 2347 #endif
OLDNEW
« 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