OLD | NEW |
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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 tchar_to_skstring(fontName.get(), familyName); | 119 tchar_to_skstring(fontName.get(), familyName); |
120 } | 120 } |
121 | 121 |
122 static void make_canonical(LOGFONT* lf) { | 122 static void make_canonical(LOGFONT* lf) { |
123 lf->lfHeight = -64; | 123 lf->lfHeight = -64; |
124 lf->lfQuality = CLEARTYPE_QUALITY;//PROOF_QUALITY; | 124 lf->lfQuality = CLEARTYPE_QUALITY;//PROOF_QUALITY; |
125 lf->lfCharSet = DEFAULT_CHARSET; | 125 lf->lfCharSet = DEFAULT_CHARSET; |
126 // lf->lfClipPrecision = 64; | 126 // lf->lfClipPrecision = 64; |
127 } | 127 } |
128 | 128 |
129 static SkTypeface::Style get_style(const LOGFONT& lf) { | 129 static SkFontStyle get_style(const LOGFONT& lf) { |
130 unsigned style = 0; | 130 return SkFontStyle(lf.lfWeight, |
131 if (lf.lfWeight >= FW_BOLD) { | 131 lf.lfWidth, |
132 style |= SkTypeface::kBold; | 132 lf.lfItalic ? SkFontStyle::kItalic_Slant : SkFontStyle::k
Upright_Slant); |
133 } | |
134 if (lf.lfItalic) { | |
135 style |= SkTypeface::kItalic; | |
136 } | |
137 return static_cast<SkTypeface::Style>(style); | |
138 } | |
139 | |
140 static void setStyle(LOGFONT* lf, SkTypeface::Style style) { | |
141 lf->lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ; | |
142 lf->lfItalic = ((style & SkTypeface::kItalic) != 0); | |
143 } | 133 } |
144 | 134 |
145 static inline FIXED SkFixedToFIXED(SkFixed x) { | 135 static inline FIXED SkFixedToFIXED(SkFixed x) { |
146 return *(FIXED*)(&x); | 136 return *(FIXED*)(&x); |
147 } | 137 } |
148 static inline SkFixed SkFIXEDToFixed(FIXED x) { | 138 static inline SkFixed SkFIXEDToFixed(FIXED x) { |
149 return *(SkFixed*)(&x); | 139 return *(SkFixed*)(&x); |
150 } | 140 } |
151 | 141 |
152 static inline FIXED SkScalarToFIXED(SkScalar x) { | 142 static inline FIXED SkScalarToFIXED(SkScalar x) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 if (0 == otmRet) { | 200 if (0 == otmRet) { |
211 call_ensure_accessible(lf); | 201 call_ensure_accessible(lf); |
212 otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm); | 202 otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm); |
213 } | 203 } |
214 | 204 |
215 return (0 == otmRet) ? 0 : otm.otmEMSquare; | 205 return (0 == otmRet) ? 0 : otm.otmEMSquare; |
216 } | 206 } |
217 | 207 |
218 class LogFontTypeface : public SkTypeface { | 208 class LogFontTypeface : public SkTypeface { |
219 public: | 209 public: |
220 LogFontTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf,
bool serializeAsStream = false) : | 210 LogFontTypeface(SkFontStyle style, SkFontID fontID, const LOGFONT& lf, bool
serializeAsStream = false) : |
221 SkTypeface(style, fontID, false), fLogFont(lf), fSerializeAsStream(seria
lizeAsStream) { | 211 SkTypeface(style, fontID, false), fLogFont(lf), fSerializeAsStream(seria
lizeAsStream) { |
222 | 212 |
223 // If the font has cubic outlines, it will not be rendered with ClearTyp
e. | 213 // If the font has cubic outlines, it will not be rendered with ClearTyp
e. |
224 HFONT font = CreateFontIndirect(&lf); | 214 HFONT font = CreateFontIndirect(&lf); |
225 | 215 |
226 HDC deviceContext = ::CreateCompatibleDC(NULL); | 216 HDC deviceContext = ::CreateCompatibleDC(NULL); |
227 HFONT savefont = (HFONT)SelectObject(deviceContext, font); | 217 HFONT savefont = (HFONT)SelectObject(deviceContext, font); |
228 | 218 |
229 TEXTMETRIC textMetric; | 219 TEXTMETRIC textMetric; |
230 if (0 == GetTextMetrics(deviceContext, &textMetric)) { | 220 if (0 == GetTextMetrics(deviceContext, &textMetric)) { |
(...skipping 17 matching lines...) Expand all Loading... |
248 // Therefore all TMPF_DEVICE will be PostScript (cubic) fonts. | 238 // Therefore all TMPF_DEVICE will be PostScript (cubic) fonts. |
249 fCanBeLCD = !((textMetric.tmPitchAndFamily & TMPF_VECTOR) && | 239 fCanBeLCD = !((textMetric.tmPitchAndFamily & TMPF_VECTOR) && |
250 (textMetric.tmPitchAndFamily & TMPF_DEVICE)); | 240 (textMetric.tmPitchAndFamily & TMPF_DEVICE)); |
251 } | 241 } |
252 | 242 |
253 LOGFONT fLogFont; | 243 LOGFONT fLogFont; |
254 bool fSerializeAsStream; | 244 bool fSerializeAsStream; |
255 bool fCanBeLCD; | 245 bool fCanBeLCD; |
256 | 246 |
257 static LogFontTypeface* Create(const LOGFONT& lf) { | 247 static LogFontTypeface* Create(const LOGFONT& lf) { |
258 SkTypeface::Style style = get_style(lf); | |
259 SkFontID fontID = SkTypefaceCache::NewFontID(); | 248 SkFontID fontID = SkTypefaceCache::NewFontID(); |
260 return new LogFontTypeface(style, fontID, lf); | 249 return new LogFontTypeface(get_style(lf), fontID, lf); |
261 } | 250 } |
262 | 251 |
263 static void EnsureAccessible(const SkTypeface* face) { | 252 static void EnsureAccessible(const SkTypeface* face) { |
264 call_ensure_accessible(static_cast<const LogFontTypeface*>(face)->fLogFo
nt); | 253 call_ensure_accessible(static_cast<const LogFontTypeface*>(face)->fLogFo
nt); |
265 } | 254 } |
266 | 255 |
267 protected: | 256 protected: |
268 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; | 257 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; |
269 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; | 258 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; |
270 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; | 259 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; |
(...skipping 11 matching lines...) Expand all Loading... |
282 virtual size_t onGetTableData(SkFontTableTag, size_t offset, | 271 virtual size_t onGetTableData(SkFontTableTag, size_t offset, |
283 size_t length, void* data) const SK_OVERRIDE; | 272 size_t length, void* data) const SK_OVERRIDE; |
284 }; | 273 }; |
285 | 274 |
286 class FontMemResourceTypeface : public LogFontTypeface { | 275 class FontMemResourceTypeface : public LogFontTypeface { |
287 public: | 276 public: |
288 /** | 277 /** |
289 * The created FontMemResourceTypeface takes ownership of fontMemResource. | 278 * The created FontMemResourceTypeface takes ownership of fontMemResource. |
290 */ | 279 */ |
291 static FontMemResourceTypeface* Create(const LOGFONT& lf, HANDLE fontMemReso
urce) { | 280 static FontMemResourceTypeface* Create(const LOGFONT& lf, HANDLE fontMemReso
urce) { |
292 SkTypeface::Style style = get_style(lf); | |
293 SkFontID fontID = SkTypefaceCache::NewFontID(); | 281 SkFontID fontID = SkTypefaceCache::NewFontID(); |
294 return new FontMemResourceTypeface(style, fontID, lf, fontMemResource); | 282 return new FontMemResourceTypeface(get_style(lf), fontID, lf, fontMemRes
ource); |
295 } | 283 } |
296 | 284 |
297 protected: | 285 protected: |
298 virtual void weak_dispose() const SK_OVERRIDE { | 286 virtual void weak_dispose() const SK_OVERRIDE { |
299 RemoveFontMemResourceEx(fFontMemResource); | 287 RemoveFontMemResourceEx(fFontMemResource); |
300 //SkTypefaceCache::Remove(this); | 288 //SkTypefaceCache::Remove(this); |
301 INHERITED::weak_dispose(); | 289 INHERITED::weak_dispose(); |
302 } | 290 } |
303 | 291 |
304 private: | 292 private: |
305 /** | 293 /** |
306 * Takes ownership of fontMemResource. | 294 * Takes ownership of fontMemResource. |
307 */ | 295 */ |
308 FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGF
ONT& lf, HANDLE fontMemResource) : | 296 FontMemResourceTypeface(SkFontStyle style, SkFontID fontID, const LOGFONT& l
f, HANDLE fontMemResource) : |
309 LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResour
ce) { | 297 LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResour
ce) { |
310 } | 298 } |
311 | 299 |
312 HANDLE fFontMemResource; | 300 HANDLE fFontMemResource; |
313 | 301 |
314 typedef LogFontTypeface INHERITED; | 302 typedef LogFontTypeface INHERITED; |
315 }; | 303 }; |
316 | 304 |
317 static const LOGFONT& get_default_font() { | 305 static const LOGFONT& get_default_font() { |
318 static LOGFONT gDefaultFont; | 306 static LOGFONT gDefaultFont; |
319 return gDefaultFont; | 307 return gDefaultFont; |
320 } | 308 } |
321 | 309 |
322 static bool FindByLogFont(SkTypeface* face, SkTypeface::Style requestedStyle, vo
id* ctx) { | 310 static bool FindByLogFont(SkTypeface* face, SkFontStyle requestedStyle, void* ct
x) { |
323 LogFontTypeface* lface = static_cast<LogFontTypeface*>(face); | 311 LogFontTypeface* lface = static_cast<LogFontTypeface*>(face); |
324 const LOGFONT* lf = reinterpret_cast<const LOGFONT*>(ctx); | 312 const LOGFONT* lf = reinterpret_cast<const LOGFONT*>(ctx); |
325 | 313 |
326 return lface && | 314 return lface && |
327 get_style(lface->fLogFont) == requestedStyle && | 315 get_style(lface->fLogFont) == requestedStyle && |
328 !memcmp(&lface->fLogFont, lf, sizeof(LOGFONT)); | 316 !memcmp(&lface->fLogFont, lf, sizeof(LOGFONT)); |
329 } | 317 } |
330 | 318 |
331 /** | 319 /** |
332 * This guy is public. It first searches the cache, and if a match is not found
, | 320 * This guy is public. It first searches the cache, and if a match is not found
, |
(...skipping 2117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2450 */ | 2438 */ |
2451 static int CALLBACK enum_family_proc(const LOGFONT* lf, const TEXTMETRIC*, | 2439 static int CALLBACK enum_family_proc(const LOGFONT* lf, const TEXTMETRIC*, |
2452 DWORD fontType, LPARAM builderParam) { | 2440 DWORD fontType, LPARAM builderParam) { |
2453 if (valid_logfont_for_enum(*lf)) { | 2441 if (valid_logfont_for_enum(*lf)) { |
2454 SkTDArray<ENUMLOGFONTEX>* array = (SkTDArray<ENUMLOGFONTEX>*)builderPara
m; | 2442 SkTDArray<ENUMLOGFONTEX>* array = (SkTDArray<ENUMLOGFONTEX>*)builderPara
m; |
2455 *array->append() = *(ENUMLOGFONTEX*)lf; | 2443 *array->append() = *(ENUMLOGFONTEX*)lf; |
2456 } | 2444 } |
2457 return 1; // non-zero means continue | 2445 return 1; // non-zero means continue |
2458 } | 2446 } |
2459 | 2447 |
2460 static SkFontStyle compute_fontstyle(const LOGFONT& lf) { | |
2461 return SkFontStyle(lf.lfWeight, SkFontStyle::kNormal_Width, | |
2462 lf.lfItalic ? SkFontStyle::kItalic_Slant | |
2463 : SkFontStyle::kUpright_Slant); | |
2464 } | |
2465 | |
2466 class SkFontStyleSetGDI : public SkFontStyleSet { | 2448 class SkFontStyleSetGDI : public SkFontStyleSet { |
2467 public: | 2449 public: |
2468 SkFontStyleSetGDI(const TCHAR familyName[]) { | 2450 SkFontStyleSetGDI(const TCHAR familyName[]) { |
2469 LOGFONT lf; | 2451 LOGFONT lf; |
2470 sk_bzero(&lf, sizeof(lf)); | 2452 sk_bzero(&lf, sizeof(lf)); |
2471 lf.lfCharSet = DEFAULT_CHARSET; | 2453 lf.lfCharSet = DEFAULT_CHARSET; |
2472 _tcscpy_s(lf.lfFaceName, familyName); | 2454 _tcscpy_s(lf.lfFaceName, familyName); |
2473 | 2455 |
2474 HDC hdc = ::CreateCompatibleDC(NULL); | 2456 HDC hdc = ::CreateCompatibleDC(NULL); |
2475 ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0); | 2457 ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0); |
2476 ::DeleteDC(hdc); | 2458 ::DeleteDC(hdc); |
2477 } | 2459 } |
2478 | 2460 |
2479 virtual int count() SK_OVERRIDE { | 2461 virtual int count() SK_OVERRIDE { |
2480 return fArray.count(); | 2462 return fArray.count(); |
2481 } | 2463 } |
2482 | 2464 |
2483 virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OV
ERRIDE { | 2465 virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OV
ERRIDE { |
2484 if (fs) { | 2466 if (fs) { |
2485 *fs = compute_fontstyle(fArray[index].elfLogFont); | 2467 *fs = get_style(fArray[index].elfLogFont); |
2486 } | 2468 } |
2487 if (styleName) { | 2469 if (styleName) { |
2488 const ENUMLOGFONTEX& ref = fArray[index]; | 2470 const ENUMLOGFONTEX& ref = fArray[index]; |
2489 // For some reason, ENUMLOGFONTEX and LOGFONT disagree on their type
in the | 2471 // For some reason, ENUMLOGFONTEX and LOGFONT disagree on their type
in the |
2490 // non-unicode version. | 2472 // non-unicode version. |
2491 // ENUMLOGFONTEX uses BYTE | 2473 // ENUMLOGFONTEX uses BYTE |
2492 // LOGFONT uses CHAR | 2474 // LOGFONT uses CHAR |
2493 // Here we assert they that the style name is logically the same (si
ze) as | 2475 // Here we assert they that the style name is logically the same (si
ze) as |
2494 // a TCHAR, so we can use the same converter function. | 2476 // a TCHAR, so we can use the same converter function. |
2495 SkASSERT(sizeof(TCHAR) == sizeof(ref.elfStyle[0])); | 2477 SkASSERT(sizeof(TCHAR) == sizeof(ref.elfStyle[0])); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 } | 2560 } |
2579 | 2561 |
2580 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 2562 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
2581 unsigned styleBits) const SK_OVER
RIDE { | 2563 unsigned styleBits) const SK_OVER
RIDE { |
2582 LOGFONT lf; | 2564 LOGFONT lf; |
2583 if (NULL == familyName) { | 2565 if (NULL == familyName) { |
2584 lf = get_default_font(); | 2566 lf = get_default_font(); |
2585 } else { | 2567 } else { |
2586 logfont_for_name(familyName, &lf); | 2568 logfont_for_name(familyName, &lf); |
2587 } | 2569 } |
2588 setStyle(&lf, (SkTypeface::Style)styleBits); | 2570 |
| 2571 SkTypeface::Style style = (SkTypeface::Style)styleBits; |
| 2572 lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL; |
| 2573 lf.lfItalic = ((style & SkTypeface::kItalic) != 0); |
2589 return SkCreateTypefaceFromLOGFONT(lf); | 2574 return SkCreateTypefaceFromLOGFONT(lf); |
2590 } | 2575 } |
2591 | 2576 |
2592 private: | 2577 private: |
2593 SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 2578 SkTDArray<ENUMLOGFONTEX> fLogFontArray; |
2594 }; | 2579 }; |
2595 | 2580 |
2596 /////////////////////////////////////////////////////////////////////////////// | 2581 /////////////////////////////////////////////////////////////////////////////// |
2597 | 2582 |
2598 SkFontMgr* SkFontMgr_New_GDI() { | 2583 SkFontMgr* SkFontMgr_New_GDI() { |
2599 return SkNEW(SkFontMgrGDI); | 2584 return SkNEW(SkFontMgrGDI); |
2600 } | 2585 } |
OLD | NEW |