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

Side by Side Diff: src/ports/SkFontHost_win.cpp

Issue 22859070: Implement charToGlyph on remaining ports. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Tabs and line length. 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 unified diff | Download patch | Annotate | Revision Log
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 "SkAdvancedTypefaceMetrics.h" 9 #include "SkAdvancedTypefaceMetrics.h"
10 #include "SkBase64.h" 10 #include "SkBase64.h"
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 260 }
261 261
262 protected: 262 protected:
263 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; 263 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
264 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK _OVERRIDE; 264 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK _OVERRIDE;
265 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; 265 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
266 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( 266 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
267 SkAdvancedTypefaceMetrics::PerGlyphInfo, 267 SkAdvancedTypefaceMetrics::PerGlyphInfo,
268 const uint32_t*, uint32_t) const SK_OVERRIDE; 268 const uint32_t*, uint32_t) const SK_OVERRIDE;
269 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ; 269 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ;
270 virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
271 uint16_t glyphs[], int glyphCount) const SK_OVER RIDE;
270 virtual int onCountGlyphs() const SK_OVERRIDE; 272 virtual int onCountGlyphs() const SK_OVERRIDE;
271 virtual int onGetUPEM() const SK_OVERRIDE; 273 virtual int onGetUPEM() const SK_OVERRIDE;
272 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_ OVERRIDE; 274 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_ OVERRIDE;
273 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; 275 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
274 virtual size_t onGetTableData(SkFontTableTag, size_t offset, 276 virtual size_t onGetTableData(SkFontTableTag, size_t offset,
275 size_t length, void* data) const SK_OVERRIDE; 277 size_t length, void* data) const SK_OVERRIDE;
276 virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE; 278 virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE;
277 }; 279 };
278 280
279 class FontMemResourceTypeface : public LogFontTypeface { 281 class FontMemResourceTypeface : public LogFontTypeface {
(...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after
2072 } 2074 }
2073 } 2075 }
2074 2076
2075 SelectObject(hdc, savefont); 2077 SelectObject(hdc, savefont);
2076 DeleteObject(font); 2078 DeleteObject(font);
2077 DeleteDC(hdc); 2079 DeleteDC(hdc);
2078 2080
2079 return stream; 2081 return stream;
2080 } 2082 }
2081 2083
2084 static void bmpCharsToGlyphs(HDC hdc, const WCHAR* bmpChars, int count, uint16_t * glyphs,
2085 bool Ox1FHack)
2086 {
2087 DWORD result = GetGlyphIndicesW(hdc, bmpChars, count, glyphs, GGI_MARK_NONEX ISTING_GLYPHS);
2088 if (GDI_ERROR == result) {
2089 for (int i = 0; i < count; ++i) {
2090 glyphs[i] = 0;
2091 }
2092 return;
2093 }
2094
2095 if (Ox1FHack) {
2096 for (int i = 0; i < count; ++i) {
2097 if (0xFFFF == glyphs[i] || 0x1F == glyphs[i]) {
2098 glyphs[i] = 0;
2099 }
2100 }
2101 } else {
2102 for (int i = 0; i < count; ++i) {
2103 if (0xFFFF == glyphs[i]){
2104 glyphs[i] = 0;
2105 }
2106 }
2107 }
2108 }
2109
2110 static uint16_t nonBmpCharToGlyph(HDC hdc, SCRIPT_CACHE* scriptCache, const WCHA R utf16[2]) {
2111 uint16_t index = 0;
2112 // Use uniscribe to detemine glyph index for non-BMP characters.
2113 static const int numWCHAR = 2;
2114 static const int maxItems = 2;
2115 // MSDN states that this can be NULL, but some things don't work then.
2116 SCRIPT_CONTROL scriptControl = { 0 };
2117 // Add extra item to SCRIPT_ITEM to work around a bug (now documented).
2118 // https://bugzilla.mozilla.org/show_bug.cgi?id=366643
2119 SCRIPT_ITEM si[maxItems + 1];
2120 int numItems;
2121 HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &scriptControl, NULL, si, &num Items),
2122 "Could not itemize character.");
2123
2124 // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2 spa ce glyphs.
2125 static const int maxGlyphs = 2;
2126 SCRIPT_VISATTR vsa[maxGlyphs];
2127 WORD outGlyphs[maxGlyphs];
2128 WORD logClust[numWCHAR];
2129 int numGlyphs;
2130 HRZM(ScriptShape(hdc, scriptCache, utf16, numWCHAR, maxGlyphs, &si[0].a,
2131 outGlyphs, logClust, vsa, &numGlyphs),
2132 "Could not shape character.");
2133 if (1 == numGlyphs) {
2134 index = outGlyphs[0];
2135 }
2136 return index;
2137 }
2138
2139 class SkAutoHDC {
2140 public:
2141 SkAutoHDC(const LOGFONT& lf)
2142 : fHdc(::CreateCompatibleDC(NULL))
2143 , fFont(::CreateFontIndirect(&lf))
2144 , fSavefont((HFONT)SelectObject(fHdc, fFont))
2145 { }
2146 ~SkAutoHDC() {
2147 SelectObject(fHdc, fSavefont);
2148 DeleteObject(fFont);
2149 DeleteDC(fHdc);
2150 }
2151 operator HDC() { return fHdc; }
2152 private:
2153 HDC fHdc;
2154 HFONT fFont;
2155 HFONT fSavefont;
2156 };
2157
2158 int LogFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
2159 uint16_t userGlyphs[], int glyphCount) cons t
2160 {
2161 SkAutoHDC hdc(fLogFont);
2162
2163 TEXTMETRIC tm;
2164 if (0 == GetTextMetrics(hdc, &tm)) {
2165 call_ensure_accessible(fLogFont);
2166 if (0 == GetTextMetrics(hdc, &tm)) {
2167 tm.tmPitchAndFamily = TMPF_TRUETYPE;
2168 }
2169 }
2170 bool Ox1FHack = !(tm.tmPitchAndFamily & TMPF_VECTOR) /*&& winVer < Vista */;
2171
2172 SkAutoSTMalloc<256, uint16_t> scratchGlyphs;
2173 uint16_t* glyphs;
2174 if (userGlyphs != NULL) {
2175 glyphs = userGlyphs;
2176 } else {
2177 glyphs = scratchGlyphs.reset(glyphCount);
2178 }
2179
2180 SCRIPT_CACHE sc = 0;
2181 switch (encoding) {
2182 case SkTypeface::kUTF8_Encoding: {
2183 static const int scratchCount = 256;
2184 WCHAR scratch[scratchCount];
2185 int glyphIndex = 0;
2186 const char* currentUtf8 = reinterpret_cast<const char*>(chars);
2187 SkUnichar currentChar;
2188 if (glyphCount) {
2189 currentChar = SkUTF8_NextUnichar(&currentUtf8);
2190 }
2191 while (glyphIndex < glyphCount) {
2192 // Try a run of bmp.
2193 int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
2194 int runLength = 0;
2195 while (runLength < glyphsLeft && currentChar <= 0xFFFF) {
2196 scratch[runLength] = static_cast<WCHAR>(currentChar);
2197 ++runLength;
2198 if (runLength < glyphsLeft) {
2199 currentChar = SkUTF8_NextUnichar(&currentUtf8);
2200 }
2201 }
2202 if (runLength) {
2203 bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], O x1FHack);
2204 glyphIndex += runLength;
2205 }
2206
2207 // Try a run of non-bmp.
2208 while (glyphIndex < glyphCount && currentChar > 0xFFFF) {
2209 SkUTF16_FromUnichar(currentChar, reinterpret_cast<uint16_t*>(scr atch));
2210 glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
2211 ++glyphIndex;
2212 if (glyphIndex < glyphCount) {
2213 currentChar = SkUTF8_NextUnichar(&currentUtf8);
2214 }
2215 }
2216 }
2217 break;
2218 }
2219 case SkTypeface::kUTF16_Encoding: {
2220 int glyphIndex = 0;
2221 const WCHAR* currentUtf16 = reinterpret_cast<const WCHAR*>(chars);
2222 while (glyphIndex < glyphCount) {
2223 // Try a run of bmp.
2224 int glyphsLeft = glyphCount - glyphIndex;
2225 int runLength = 0;
2226 while (runLength < glyphsLeft && !SkUTF16_IsHighSurrogate(currentUtf 16[runLength])) {
2227 ++runLength;
2228 }
2229 if (runLength) {
2230 bmpCharsToGlyphs(hdc, currentUtf16, runLength, &glyphs[glyphInde x], Ox1FHack);
2231 glyphIndex += runLength;
2232 currentUtf16 += runLength;
2233 }
2234
2235 // Try a run of non-bmp.
2236 while (glyphIndex < glyphCount && SkUTF16_IsHighSurrogate(*currentUt f16)) {
2237 glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, currentUtf16);
2238 ++glyphIndex;
2239 currentUtf16 += 2;
2240 }
2241 }
2242 break;
2243 }
2244 case SkTypeface::kUTF32_Encoding: {
2245 static const int scratchCount = 256;
2246 WCHAR scratch[scratchCount];
2247 int glyphIndex = 0;
2248 const uint32_t* utf32 = reinterpret_cast<const uint32_t*>(chars);
2249 while (glyphIndex < glyphCount) {
2250 // Try a run of bmp.
2251 int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
2252 int runLength = 0;
2253 while (runLength < glyphsLeft && utf32[glyphIndex + runLength] <= 0x FFFF) {
2254 scratch[runLength] = static_cast<WCHAR>(utf32[glyphIndex + runLe ngth]);
2255 ++runLength;
2256 }
2257 if (runLength) {
2258 bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], O x1FHack);
2259 glyphIndex += runLength;
2260 }
2261
2262 // Try a run of non-bmp.
2263 while (glyphIndex < glyphCount && utf32[glyphIndex] > 0xFFFF) {
2264 SkUTF16_FromUnichar(utf32[glyphIndex], reinterpret_cast<uint16_t *>(scratch));
2265 glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
2266 ++glyphIndex;
2267 }
2268 }
2269 break;
2270 }
2271 default:
2272 SK_CRASH();
2273 }
2274
2275 if (sc) {
2276 ::ScriptFreeCache(&sc);
2277 }
2278
2279 for (int i = 0; i < glyphCount; ++i) {
2280 if (0 == glyphs[i]) {
2281 return i;
2282 }
2283 }
2284 return glyphCount;
2285 }
2286
2082 int LogFontTypeface::onCountGlyphs() const { 2287 int LogFontTypeface::onCountGlyphs() const {
2083 HDC hdc = ::CreateCompatibleDC(NULL); 2288 HDC hdc = ::CreateCompatibleDC(NULL);
2084 HFONT font = CreateFontIndirect(&fLogFont); 2289 HFONT font = CreateFontIndirect(&fLogFont);
2085 HFONT savefont = (HFONT)SelectObject(hdc, font); 2290 HFONT savefont = (HFONT)SelectObject(hdc, font);
2086 2291
2087 unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont); 2292 unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);
2088 2293
2089 SelectObject(hdc, savefont); 2294 SelectObject(hdc, savefont);
2090 DeleteObject(font); 2295 DeleteObject(font);
2091 DeleteDC(hdc); 2296 DeleteDC(hdc);
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 2632
2428 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { 2633 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
2429 return create_from_stream(stream); 2634 return create_from_stream(stream);
2430 } 2635 }
2431 2636
2432 #endif 2637 #endif
2433 2638
2434 SkFontMgr* SkFontMgr_New_GDI() { 2639 SkFontMgr* SkFontMgr_New_GDI() {
2435 return SkNEW(SkFontMgrGDI); 2640 return SkNEW(SkFontMgrGDI);
2436 } 2641 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698