Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / ports / SkFontHost_win.cpp
1
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9 #include "SkAdvancedTypefaceMetrics.h"
10 #include "SkBase64.h"
11 #include "SkColorPriv.h"
12 #include "SkData.h"
13 #include "SkDescriptor.h"
14 #include "SkFontDescriptor.h"
15 #include "SkFontHost.h"
16 #include "SkGlyph.h"
17 #include "SkHRESULT.h"
18 #include "SkMaskGamma.h"
19 #include "SkMatrix22.h"
20 #include "SkOTTable_maxp.h"
21 #include "SkOTTable_name.h"
22 #include "SkOTUtils.h"
23 #include "SkPath.h"
24 #include "SkSFNTHeader.h"
25 #include "SkStream.h"
26 #include "SkString.h"
27 #include "SkTemplates.h"
28 #include "SkThread.h"
29 #include "SkTypeface_win.h"
30 #include "SkTypefaceCache.h"
31 #include "SkUtils.h"
32
33 #include "SkTypes.h"
34 #include <tchar.h>
35 #include <usp10.h>
36 #include <objbase.h>
37
38 static void (*gEnsureLOGFONTAccessibleProc)(const LOGFONT&);
39
40 void SkTypeface_SetEnsureLOGFONTAccessibleProc(void (*proc)(const LOGFONT&)) {
41     gEnsureLOGFONTAccessibleProc = proc;
42 }
43
44 static void call_ensure_accessible(const LOGFONT& lf) {
45     if (gEnsureLOGFONTAccessibleProc) {
46         gEnsureLOGFONTAccessibleProc(lf);
47     }
48 }
49
50 ///////////////////////////////////////////////////////////////////////////////
51
52 // always packed xxRRGGBB
53 typedef uint32_t SkGdiRGB;
54
55 // define this in your Makefile or .gyp to enforce AA requests
56 // which GDI ignores at small sizes. This flag guarantees AA
57 // for rotated text, regardless of GDI's notions.
58 //#define SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS
59
60 static bool isLCD(const SkScalerContext::Rec& rec) {
61     return SkMask::kLCD16_Format == rec.fMaskFormat ||
62            SkMask::kLCD32_Format == rec.fMaskFormat;
63 }
64
65 static bool bothZero(SkScalar a, SkScalar b) {
66     return 0 == a && 0 == b;
67 }
68
69 // returns false if there is any non-90-rotation or skew
70 static bool isAxisAligned(const SkScalerContext::Rec& rec) {
71     return 0 == rec.fPreSkewX &&
72            (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
73             bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
74 }
75
76 static bool needToRenderWithSkia(const SkScalerContext::Rec& rec) {
77 #ifdef SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS
78     // What we really want to catch is when GDI will ignore the AA request and give
79     // us BW instead. Smallish rotated text is one heuristic, so this code is just
80     // an approximation. We shouldn't need to do this for larger sizes, but at those
81     // sizes, the quality difference gets less and less between our general
82     // scanconverter and GDI's.
83     if (SkMask::kA8_Format == rec.fMaskFormat && !isAxisAligned(rec)) {
84         return true;
85     }
86 #endif
87     return rec.getHinting() == SkPaint::kNo_Hinting || rec.getHinting() == SkPaint::kSlight_Hinting;
88 }
89
90 using namespace skia_advanced_typeface_metrics_utils;
91
92 static void tchar_to_skstring(const TCHAR t[], SkString* s) {
93 #ifdef UNICODE
94     size_t sSize = WideCharToMultiByte(CP_UTF8, 0, t, -1, NULL, 0, NULL, NULL);
95     s->resize(sSize);
96     WideCharToMultiByte(CP_UTF8, 0, t, -1, s->writable_str(), sSize, NULL, NULL);
97 #else
98     s->set(t);
99 #endif
100 }
101
102 static void dcfontname_to_skstring(HDC deviceContext, const LOGFONT& lf, SkString* familyName) {
103     int fontNameLen; //length of fontName in TCHARS.
104     if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
105         call_ensure_accessible(lf);
106         if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
107             fontNameLen = 0;
108         }
109     }
110
111     SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1);
112     if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
113         call_ensure_accessible(lf);
114         if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
115             fontName[0] = 0;
116         }
117     }
118
119     tchar_to_skstring(fontName.get(), familyName);
120 }
121
122 static void make_canonical(LOGFONT* lf) {
123     lf->lfHeight = -64;
124     lf->lfQuality = CLEARTYPE_QUALITY;//PROOF_QUALITY;
125     lf->lfCharSet = DEFAULT_CHARSET;
126 //    lf->lfClipPrecision = 64;
127 }
128
129 static SkFontStyle get_style(const LOGFONT& lf) {
130     return SkFontStyle(lf.lfWeight,
131                        lf.lfWidth,
132                        lf.lfItalic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant);
133 }
134
135 static inline FIXED SkFixedToFIXED(SkFixed x) {
136     return *(FIXED*)(&x);
137 }
138 static inline SkFixed SkFIXEDToFixed(FIXED x) {
139     return *(SkFixed*)(&x);
140 }
141
142 static inline FIXED SkScalarToFIXED(SkScalar x) {
143     return SkFixedToFIXED(SkScalarToFixed(x));
144 }
145
146 static inline SkScalar SkFIXEDToScalar(FIXED x) {
147     return SkFixedToScalar(SkFIXEDToFixed(x));
148 }
149
150 static unsigned calculateGlyphCount(HDC hdc, const LOGFONT& lf) {
151     TEXTMETRIC textMetric;
152     if (0 == GetTextMetrics(hdc, &textMetric)) {
153         textMetric.tmPitchAndFamily = TMPF_VECTOR;
154         call_ensure_accessible(lf);
155         GetTextMetrics(hdc, &textMetric);
156     }
157
158     if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
159         return textMetric.tmLastChar;
160     }
161
162     // The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes.
163     uint16_t glyphs;
164     if (GDI_ERROR != GetFontData(hdc, SkOTTableMaximumProfile::TAG, 4, &glyphs, sizeof(glyphs))) {
165         return SkEndian_SwapBE16(glyphs);
166     }
167
168     // Binary search for glyph count.
169     static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
170     int32_t max = SK_MaxU16 + 1;
171     int32_t min = 0;
172     GLYPHMETRICS gm;
173     while (min < max) {
174         int32_t mid = min + ((max - min) / 2);
175         if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0,
176                              NULL, &mat2) == GDI_ERROR) {
177             max = mid;
178         } else {
179             min = mid + 1;
180         }
181     }
182     SkASSERT(min == max);
183     return min;
184 }
185
186 static unsigned calculateUPEM(HDC hdc, const LOGFONT& lf) {
187     TEXTMETRIC textMetric;
188     if (0 == GetTextMetrics(hdc, &textMetric)) {
189         textMetric.tmPitchAndFamily = TMPF_VECTOR;
190         call_ensure_accessible(lf);
191         GetTextMetrics(hdc, &textMetric);
192     }
193
194     if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
195         return textMetric.tmMaxCharWidth;
196     }
197
198     OUTLINETEXTMETRIC otm;
199     unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
200     if (0 == otmRet) {
201         call_ensure_accessible(lf);
202         otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
203     }
204
205     return (0 == otmRet) ? 0 : otm.otmEMSquare;
206 }
207
208 class LogFontTypeface : public SkTypeface {
209 public:
210     LogFontTypeface(const SkFontStyle& style, const LOGFONT& lf, bool serializeAsStream)
211         : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
212         , fLogFont(lf)
213         , fSerializeAsStream(serializeAsStream)
214     {
215
216         // If the font has cubic outlines, it will not be rendered with ClearType.
217         HFONT font = CreateFontIndirect(&lf);
218
219         HDC deviceContext = ::CreateCompatibleDC(NULL);
220         HFONT savefont = (HFONT)SelectObject(deviceContext, font);
221
222         TEXTMETRIC textMetric;
223         if (0 == GetTextMetrics(deviceContext, &textMetric)) {
224             call_ensure_accessible(lf);
225             if (0 == GetTextMetrics(deviceContext, &textMetric)) {
226                 textMetric.tmPitchAndFamily = TMPF_TRUETYPE;
227             }
228         }
229         if (deviceContext) {
230             ::SelectObject(deviceContext, savefont);
231             ::DeleteDC(deviceContext);
232         }
233         if (font) {
234             ::DeleteObject(font);
235         }
236
237         // The fixed pitch bit is set if the font is *not* fixed pitch.
238         this->setIsFixedPitch((textMetric.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0);
239
240         // Used a logfont on a memory context, should never get a device font.
241         // Therefore all TMPF_DEVICE will be PostScript (cubic) fonts.
242         fCanBeLCD = !((textMetric.tmPitchAndFamily & TMPF_VECTOR) &&
243                       (textMetric.tmPitchAndFamily & TMPF_DEVICE));
244     }
245
246     LOGFONT fLogFont;
247     bool fSerializeAsStream;
248     bool fCanBeLCD;
249
250     static LogFontTypeface* Create(const LOGFONT& lf) {
251         return new LogFontTypeface(get_style(lf), lf, false);
252     }
253
254     static void EnsureAccessible(const SkTypeface* face) {
255         call_ensure_accessible(static_cast<const LogFontTypeface*>(face)->fLogFont);
256     }
257
258 protected:
259     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
260     virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
261     virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
262     virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
263                                 SkAdvancedTypefaceMetrics::PerGlyphInfo,
264                                 const uint32_t*, uint32_t) const SK_OVERRIDE;
265     virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
266     virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
267                                 uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
268     virtual int onCountGlyphs() const SK_OVERRIDE;
269     virtual int onGetUPEM() const SK_OVERRIDE;
270     virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
271     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
272     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
273     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
274                                   size_t length, void* data) const SK_OVERRIDE;
275 };
276
277 class FontMemResourceTypeface : public LogFontTypeface {
278 public:
279     /**
280      *  The created FontMemResourceTypeface takes ownership of fontMemResource.
281      */
282     static FontMemResourceTypeface* Create(const LOGFONT& lf, HANDLE fontMemResource) {
283         return new FontMemResourceTypeface(get_style(lf), lf, fontMemResource);
284     }
285
286 protected:
287     virtual void weak_dispose() const SK_OVERRIDE {
288         RemoveFontMemResourceEx(fFontMemResource);
289         //SkTypefaceCache::Remove(this);
290         INHERITED::weak_dispose();
291     }
292
293 private:
294     /**
295      *  Takes ownership of fontMemResource.
296      */
297     FontMemResourceTypeface(const SkFontStyle& style, const LOGFONT& lf, HANDLE fontMemResource)
298         : LogFontTypeface(style, lf, true), fFontMemResource(fontMemResource)
299     { }
300
301     HANDLE fFontMemResource;
302
303     typedef LogFontTypeface INHERITED;
304 };
305
306 static const LOGFONT& get_default_font() {
307     static LOGFONT gDefaultFont;
308     return gDefaultFont;
309 }
310
311 static bool FindByLogFont(SkTypeface* face, const SkFontStyle& requestedStyle, void* ctx) {
312     LogFontTypeface* lface = static_cast<LogFontTypeface*>(face);
313     const LOGFONT* lf = reinterpret_cast<const LOGFONT*>(ctx);
314
315     return lface &&
316            get_style(lface->fLogFont) == requestedStyle &&
317            !memcmp(&lface->fLogFont, lf, sizeof(LOGFONT));
318 }
319
320 /**
321  *  This guy is public. It first searches the cache, and if a match is not found,
322  *  it creates a new face.
323  */
324 SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) {
325     LOGFONT lf = origLF;
326     make_canonical(&lf);
327     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByLogFont, &lf);
328     if (NULL == face) {
329         face = LogFontTypeface::Create(lf);
330         SkTypefaceCache::Add(face, get_style(lf));
331     }
332     return face;
333 }
334
335 /**
336  *  The created SkTypeface takes ownership of fontMemResource.
337  */
338 SkTypeface* SkCreateFontMemResourceTypefaceFromLOGFONT(const LOGFONT& origLF, HANDLE fontMemResource) {
339     LOGFONT lf = origLF;
340     make_canonical(&lf);
341     // We'll never get a cache hit, so no point in putting this in SkTypefaceCache.
342     return FontMemResourceTypeface::Create(lf, fontMemResource);
343 }
344
345 /**
346  *  This guy is public
347  */
348 void SkLOGFONTFromTypeface(const SkTypeface* face, LOGFONT* lf) {
349     if (NULL == face) {
350         *lf = get_default_font();
351     } else {
352         *lf = static_cast<const LogFontTypeface*>(face)->fLogFont;
353     }
354 }
355
356 // Construct Glyph to Unicode table.
357 // Unicode code points that require conjugate pairs in utf16 are not
358 // supported.
359 // TODO(arthurhsu): Add support for conjugate pairs. It looks like that may
360 // require parsing the TTF cmap table (platform 4, encoding 12) directly instead
361 // of calling GetFontUnicodeRange().
362 static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount,
363                                       SkTDArray<SkUnichar>* glyphToUnicode) {
364     DWORD glyphSetBufferSize = GetFontUnicodeRanges(fontHdc, NULL);
365     if (!glyphSetBufferSize) {
366         return;
367     }
368
369     SkAutoTDeleteArray<BYTE> glyphSetBuffer(new BYTE[glyphSetBufferSize]);
370     GLYPHSET* glyphSet =
371         reinterpret_cast<LPGLYPHSET>(glyphSetBuffer.get());
372     if (GetFontUnicodeRanges(fontHdc, glyphSet) != glyphSetBufferSize) {
373         return;
374     }
375
376     glyphToUnicode->setCount(glyphCount);
377     memset(glyphToUnicode->begin(), 0, glyphCount * sizeof(SkUnichar));
378     for (DWORD i = 0; i < glyphSet->cRanges; ++i) {
379         // There is no guarantee that within a Unicode range, the corresponding
380         // glyph id in a font file are continuous. So, even if we have ranges,
381         // we can't just use the first and last entry of the range to compute
382         // result. We need to enumerate them one by one.
383         int count = glyphSet->ranges[i].cGlyphs;
384         SkAutoTArray<WCHAR> chars(count + 1);
385         chars[count] = 0;  // termintate string
386         SkAutoTArray<WORD> glyph(count);
387         for (USHORT j = 0; j < count; ++j) {
388             chars[j] = glyphSet->ranges[i].wcLow + j;
389         }
390         GetGlyphIndicesW(fontHdc, chars.get(), count, glyph.get(),
391                          GGI_MARK_NONEXISTING_GLYPHS);
392         // If the glyph ID is valid, and the glyph is not mapped, then we will
393         // fill in the char id into the vector. If the glyph is mapped already,
394         // skip it.
395         // TODO(arthurhsu): better improve this. e.g. Get all used char ids from
396         // font cache, then generate this mapping table from there. It's
397         // unlikely to have collisions since glyph reuse happens mostly for
398         // different Unicode pages.
399         for (USHORT j = 0; j < count; ++j) {
400             if (glyph[j] != 0xffff && glyph[j] < glyphCount &&
401                 (*glyphToUnicode)[glyph[j]] == 0) {
402                 (*glyphToUnicode)[glyph[j]] = chars[j];
403             }
404         }
405     }
406 }
407
408 //////////////////////////////////////////////////////////////////////////////////////
409
410 static int alignTo32(int n) {
411     return (n + 31) & ~31;
412 }
413
414 struct MyBitmapInfo : public BITMAPINFO {
415     RGBQUAD fMoreSpaceForColors[1];
416 };
417
418 class HDCOffscreen {
419 public:
420     HDCOffscreen() {
421         fFont = 0;
422         fDC = 0;
423         fBM = 0;
424         fBits = NULL;
425         fWidth = fHeight = 0;
426         fIsBW = false;
427     }
428
429     ~HDCOffscreen() {
430         if (fDC) {
431             DeleteDC(fDC);
432         }
433         if (fBM) {
434             DeleteObject(fBM);
435         }
436     }
437
438     void init(HFONT font, const XFORM& xform) {
439         fFont = font;
440         fXform = xform;
441     }
442
443     const void* draw(const SkGlyph&, bool isBW, size_t* srcRBPtr);
444
445 private:
446     HDC     fDC;
447     HBITMAP fBM;
448     HFONT   fFont;
449     XFORM   fXform;
450     void*   fBits;  // points into fBM
451     int     fWidth;
452     int     fHeight;
453     bool    fIsBW;
454 };
455
456 const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
457                                size_t* srcRBPtr) {
458     // Can we share the scalercontext's fDDC, so we don't need to create
459     // a separate fDC here?
460     if (0 == fDC) {
461         fDC = CreateCompatibleDC(0);
462         if (0 == fDC) {
463             return NULL;
464         }
465         SetGraphicsMode(fDC, GM_ADVANCED);
466         SetBkMode(fDC, TRANSPARENT);
467         SetTextAlign(fDC, TA_LEFT | TA_BASELINE);
468         SelectObject(fDC, fFont);
469
470         COLORREF color = 0x00FFFFFF;
471         SkDEBUGCODE(COLORREF prev =) SetTextColor(fDC, color);
472         SkASSERT(prev != CLR_INVALID);
473     }
474
475     if (fBM && (fIsBW != isBW || fWidth < glyph.fWidth || fHeight < glyph.fHeight)) {
476         DeleteObject(fBM);
477         fBM = 0;
478     }
479     fIsBW = isBW;
480
481     fWidth = SkMax32(fWidth, glyph.fWidth);
482     fHeight = SkMax32(fHeight, glyph.fHeight);
483
484     int biWidth = isBW ? alignTo32(fWidth) : fWidth;
485
486     if (0 == fBM) {
487         MyBitmapInfo info;
488         sk_bzero(&info, sizeof(info));
489         if (isBW) {
490             RGBQUAD blackQuad = { 0, 0, 0, 0 };
491             RGBQUAD whiteQuad = { 0xFF, 0xFF, 0xFF, 0 };
492             info.bmiColors[0] = blackQuad;
493             info.bmiColors[1] = whiteQuad;
494         }
495         info.bmiHeader.biSize = sizeof(info.bmiHeader);
496         info.bmiHeader.biWidth = biWidth;
497         info.bmiHeader.biHeight = fHeight;
498         info.bmiHeader.biPlanes = 1;
499         info.bmiHeader.biBitCount = isBW ? 1 : 32;
500         info.bmiHeader.biCompression = BI_RGB;
501         if (isBW) {
502             info.bmiHeader.biClrUsed = 2;
503         }
504         fBM = CreateDIBSection(fDC, &info, DIB_RGB_COLORS, &fBits, 0, 0);
505         if (0 == fBM) {
506             return NULL;
507         }
508         SelectObject(fDC, fBM);
509     }
510
511     // erase
512     size_t srcRB = isBW ? (biWidth >> 3) : (fWidth << 2);
513     size_t size = fHeight * srcRB;
514     memset(fBits, 0, size);
515
516     XFORM xform = fXform;
517     xform.eDx = (float)-glyph.fLeft;
518     xform.eDy = (float)-glyph.fTop;
519     SetWorldTransform(fDC, &xform);
520
521     uint16_t glyphID = glyph.getGlyphID();
522     BOOL ret = ExtTextOutW(fDC, 0, 0, ETO_GLYPH_INDEX, NULL, reinterpret_cast<LPCWSTR>(&glyphID), 1, NULL);
523     GdiFlush();
524     if (0 == ret) {
525         return NULL;
526     }
527     *srcRBPtr = srcRB;
528     // offset to the start of the image
529     return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB;
530 }
531
532 //////////////////////////////////////////////////////////////////////////////
533 #define BUFFERSIZE (1 << 13)
534
535 class SkScalerContext_GDI : public SkScalerContext {
536 public:
537     SkScalerContext_GDI(SkTypeface*, const SkDescriptor* desc);
538     virtual ~SkScalerContext_GDI();
539
540     // Returns true if the constructor was able to complete all of its
541     // initializations (which may include calling GDI).
542     bool isValid() const;
543
544 protected:
545     virtual unsigned generateGlyphCount() SK_OVERRIDE;
546     virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE;
547     virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
548     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
549     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
550     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
551     virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
552
553 private:
554     DWORD getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
555                           SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf);
556
557     HDCOffscreen fOffscreen;
558     /** fGsA is the non-rotational part of total matrix without the text height scale.
559      *  Used to find the magnitude of advances.
560      */
561     MAT2         fGsA;
562     /** The total matrix without the textSize. */
563     MAT2         fMat22;
564     /** Scales font to EM size. */
565     MAT2         fHighResMat22;
566     HDC          fDDC;
567     HFONT        fSavefont;
568     HFONT        fFont;
569     SCRIPT_CACHE fSC;
570     int          fGlyphCount;
571
572     /** The total matrix which also removes EM scale. */
573     SkMatrix     fHiResMatrix;
574     /** fG_inv is the inverse of the rotational part of the total matrix.
575      *  Used to set the direction of advances.
576      */
577     SkMatrix     fG_inv;
578     enum Type {
579         kTrueType_Type, kBitmap_Type, kLine_Type
580     } fType;
581     TEXTMETRIC fTM;
582 };
583
584 static FIXED float2FIXED(float x) {
585     return SkFixedToFIXED(SkFloatToFixed(x));
586 }
587
588 static BYTE compute_quality(const SkScalerContext::Rec& rec) {
589     switch (rec.fMaskFormat) {
590         case SkMask::kBW_Format:
591             return NONANTIALIASED_QUALITY;
592         case SkMask::kLCD16_Format:
593         case SkMask::kLCD32_Format:
594             return CLEARTYPE_QUALITY;
595         default:
596             if (rec.fFlags & SkScalerContext::kGenA8FromLCD_Flag) {
597                 return CLEARTYPE_QUALITY;
598             } else {
599                 return ANTIALIASED_QUALITY;
600             }
601     }
602 }
603
604 SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
605                                                  const SkDescriptor* desc)
606         : SkScalerContext(rawTypeface, desc)
607         , fDDC(0)
608         , fSavefont(0)
609         , fFont(0)
610         , fSC(0)
611         , fGlyphCount(-1)
612 {
613     LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface);
614
615     fDDC = ::CreateCompatibleDC(NULL);
616     if (!fDDC) {
617         return;
618     }
619     SetGraphicsMode(fDDC, GM_ADVANCED);
620     SetBkMode(fDDC, TRANSPARENT);
621
622     SkPoint h = SkPoint::Make(SK_Scalar1, 0);
623     // A is the total matrix.
624     SkMatrix A;
625     fRec.getSingleMatrix(&A);
626     A.mapPoints(&h, 1);
627
628     // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
629     SkMatrix G;
630     SkComputeGivensRotation(h, &G);
631
632     // GA is the matrix A with rotation removed.
633     SkMatrix GA(G);
634     GA.preConcat(A);
635
636     // realTextSize is the actual device size we want (as opposed to the size the user requested).
637     // gdiTextSize is the size we request from GDI.
638     // If the scale is negative, this means the matrix will do the flip anyway.
639     SkScalar realTextSize = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
640     SkScalar gdiTextSize = SkScalarRoundToScalar(realTextSize);
641     if (gdiTextSize == 0) {
642         gdiTextSize = SK_Scalar1;
643     }
644
645     // When not hinting, remove only the gdiTextSize scale which will be applied by GDI.
646     // When GDI hinting, remove the entire Y scale to prevent 'subpixel' metrics.
647     SkScalar scale = (fRec.getHinting() == SkPaint::kNo_Hinting ||
648                       fRec.getHinting() == SkPaint::kSlight_Hinting)
649                    ? SkScalarInvert(gdiTextSize)
650                    : SkScalarInvert(realTextSize);
651
652     // sA is the total matrix A without the textSize (so GDI knows the text size separately).
653     // When this matrix is used with GetGlyphOutline, no further processing is needed.
654     SkMatrix sA(A);
655     sA.preScale(scale, scale); //remove text size
656
657     // GsA is the non-rotational part of A without the text height scale.
658     // This is what is used to find the magnitude of advances.
659     SkMatrix GsA(GA);
660     GsA.preScale(scale, scale); //remove text size, G is rotational so reorders with the scale.
661
662     fGsA.eM11 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleX));
663     fGsA.eM12 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewY)); // This should be ~0.
664     fGsA.eM21 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewX));
665     fGsA.eM22 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleY));
666
667     // fG_inv is G inverse, which is fairly simple since G is 2x2 rotational.
668     fG_inv.setAll(G.get(SkMatrix::kMScaleX), -G.get(SkMatrix::kMSkewX), G.get(SkMatrix::kMTransX),
669                   -G.get(SkMatrix::kMSkewY), G.get(SkMatrix::kMScaleY), G.get(SkMatrix::kMTransY),
670                   G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(SkMatrix::kMPersp2));
671
672     LOGFONT lf = typeface->fLogFont;
673     lf.lfHeight = -SkScalarTruncToInt(gdiTextSize);
674     lf.lfQuality = compute_quality(fRec);
675     fFont = CreateFontIndirect(&lf);
676     if (!fFont) {
677         return;
678     }
679
680     fSavefont = (HFONT)SelectObject(fDDC, fFont);
681
682     if (0 == GetTextMetrics(fDDC, &fTM)) {
683         call_ensure_accessible(lf);
684         if (0 == GetTextMetrics(fDDC, &fTM)) {
685             fTM.tmPitchAndFamily = TMPF_TRUETYPE;
686         }
687     }
688
689     XFORM xform;
690     if (fTM.tmPitchAndFamily & TMPF_VECTOR) {
691         // Used a logfont on a memory context, should never get a device font.
692         // Therefore all TMPF_DEVICE will be PostScript fonts.
693
694         // If TMPF_VECTOR is set, one of TMPF_TRUETYPE or TMPF_DEVICE means that
695         // we have an outline font. Otherwise we have a vector FON, which is
696         // scalable, but not an outline font.
697         // This was determined by testing with Type1 PFM/PFB and
698         // OpenTypeCFF OTF, as well as looking at Wine bugs and sources.
699         if (fTM.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_DEVICE)) {
700             // Truetype or PostScript.
701             fType = SkScalerContext_GDI::kTrueType_Type;
702         } else {
703             // Stroked FON.
704             fType = SkScalerContext_GDI::kLine_Type;
705         }
706
707         // fPost2x2 is column-major, left handed (y down).
708         // XFORM 2x2 is row-major, left handed (y down).
709         xform.eM11 = SkScalarToFloat(sA.get(SkMatrix::kMScaleX));
710         xform.eM12 = SkScalarToFloat(sA.get(SkMatrix::kMSkewY));
711         xform.eM21 = SkScalarToFloat(sA.get(SkMatrix::kMSkewX));
712         xform.eM22 = SkScalarToFloat(sA.get(SkMatrix::kMScaleY));
713         xform.eDx = 0;
714         xform.eDy = 0;
715
716         // MAT2 is row major, right handed (y up).
717         fMat22.eM11 = float2FIXED(xform.eM11);
718         fMat22.eM12 = float2FIXED(-xform.eM12);
719         fMat22.eM21 = float2FIXED(-xform.eM21);
720         fMat22.eM22 = float2FIXED(xform.eM22);
721
722         if (needToRenderWithSkia(fRec)) {
723             this->forceGenerateImageFromPath();
724         }
725
726         // Create a hires matrix if we need linear metrics.
727         if (this->isSubpixel()) {
728             OUTLINETEXTMETRIC otm;
729             UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
730             if (0 == success) {
731                 call_ensure_accessible(lf);
732                 success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
733             }
734             if (0 != success) {
735                 SkScalar upem = SkIntToScalar(otm.otmEMSquare);
736
737                 SkScalar gdiTextSizeToEMScale = upem / gdiTextSize;
738                 fHighResMat22.eM11 = float2FIXED(gdiTextSizeToEMScale);
739                 fHighResMat22.eM12 = float2FIXED(0);
740                 fHighResMat22.eM21 = float2FIXED(0);
741                 fHighResMat22.eM22 = float2FIXED(gdiTextSizeToEMScale);
742
743                 SkScalar removeEMScale = SkScalarInvert(upem);
744                 fHiResMatrix = A;
745                 fHiResMatrix.preScale(removeEMScale, removeEMScale);
746             }
747         }
748
749     } else {
750         // Assume bitmap
751         fType = SkScalerContext_GDI::kBitmap_Type;
752
753         xform.eM11 = 1.0f;
754         xform.eM12 = 0.0f;
755         xform.eM21 = 0.0f;
756         xform.eM22 = 1.0f;
757         xform.eDx = 0.0f;
758         xform.eDy = 0.0f;
759
760         // fPost2x2 is column-major, left handed (y down).
761         // MAT2 is row major, right handed (y up).
762         fMat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]);
763         fMat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[1][0]);
764         fMat22.eM21 = SkScalarToFIXED(-fRec.fPost2x2[0][1]);
765         fMat22.eM22 = SkScalarToFIXED(fRec.fPost2x2[1][1]);
766     }
767
768     fOffscreen.init(fFont, xform);
769 }
770
771 SkScalerContext_GDI::~SkScalerContext_GDI() {
772     if (fDDC) {
773         ::SelectObject(fDDC, fSavefont);
774         ::DeleteDC(fDDC);
775     }
776     if (fFont) {
777         ::DeleteObject(fFont);
778     }
779     if (fSC) {
780         ::ScriptFreeCache(&fSC);
781     }
782 }
783
784 bool SkScalerContext_GDI::isValid() const {
785     return fDDC && fFont;
786 }
787
788 unsigned SkScalerContext_GDI::generateGlyphCount() {
789     if (fGlyphCount < 0) {
790         fGlyphCount = calculateGlyphCount(
791                           fDDC, static_cast<const LogFontTypeface*>(this->getTypeface())->fLogFont);
792     }
793     return fGlyphCount;
794 }
795
796 uint16_t SkScalerContext_GDI::generateCharToGlyph(SkUnichar utf32) {
797     uint16_t index = 0;
798     WCHAR utf16[2];
799     // TODO(ctguil): Support characters that generate more than one glyph.
800     if (SkUTF16_FromUnichar(utf32, (uint16_t*)utf16) == 1) {
801         // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0.
802
803         /** Real documentation for GetGlyphIndiciesW:
804          *
805          *  When GGI_MARK_NONEXISTING_GLYPHS is not specified and a character does not map to a
806          *  glyph, then the 'default character's glyph is returned instead. The 'default character'
807          *  is available in fTM.tmDefaultChar. FON fonts have a default character, and there exists
808          *  a usDefaultChar in the 'OS/2' table, version 2 and later. If there is no
809          *  'default character' specified by the font, then often the first character found is used.
810          *
811          *  When GGI_MARK_NONEXISTING_GLYPHS is specified and a character does not map to a glyph,
812          *  then the glyph 0xFFFF is used. In Windows XP and earlier, Bitmap/Vector FON usually use
813          *  glyph 0x1F instead ('Terminal' appears to be special, returning 0xFFFF).
814          *  Type1 PFM/PFB, TT, OT TT, OT CFF all appear to use 0xFFFF, even on XP.
815          */
816         DWORD result = GetGlyphIndicesW(fDDC, utf16, 1, &index, GGI_MARK_NONEXISTING_GLYPHS);
817         if (result == GDI_ERROR
818             || 0xFFFF == index
819             || (0x1F == index &&
820                (fType == SkScalerContext_GDI::kBitmap_Type ||
821                 fType == SkScalerContext_GDI::kLine_Type)
822                /*&& winVer < Vista */)
823            )
824         {
825             index = 0;
826         }
827     } else {
828         // Use uniscribe to detemine glyph index for non-BMP characters.
829         static const int numWCHAR = 2;
830         static const int maxItems = 2;
831         // MSDN states that this can be NULL, but some things don't work then.
832         SCRIPT_CONTROL sc = { 0 };
833         // Add extra item to SCRIPT_ITEM to work around a bug (now documented).
834         // https://bugzilla.mozilla.org/show_bug.cgi?id=366643
835         SCRIPT_ITEM si[maxItems + 1];
836         int numItems;
837         HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &sc, NULL, si, &numItems),
838              "Could not itemize character.");
839
840         // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2 space glyphs.
841         static const int maxGlyphs = 2;
842         SCRIPT_VISATTR vsa[maxGlyphs];
843         WORD outGlyphs[maxGlyphs];
844         WORD logClust[numWCHAR];
845         int numGlyphs;
846         HRZM(ScriptShape(fDDC, &fSC, utf16, numWCHAR, maxGlyphs, &si[0].a,
847                          outGlyphs, logClust, vsa, &numGlyphs),
848              "Could not shape character.");
849         if (1 == numGlyphs) {
850             index = outGlyphs[0];
851         }
852     }
853     return index;
854 }
855
856 void SkScalerContext_GDI::generateAdvance(SkGlyph* glyph) {
857     this->generateMetrics(glyph);
858 }
859
860 void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
861     SkASSERT(fDDC);
862
863     if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
864         SIZE size;
865         WORD glyphs = glyph->getGlyphID();
866         if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) {
867             glyph->fWidth = SkToS16(fTM.tmMaxCharWidth);
868         } else {
869             glyph->fWidth = SkToS16(size.cx);
870         }
871         glyph->fHeight = SkToS16(size.cy);
872
873         glyph->fTop = SkToS16(-fTM.tmAscent);
874         // Bitmap FON cannot underhang, but vector FON may.
875         // There appears no means of determining underhang of vector FON.
876         glyph->fLeft = SkToS16(0);
877         glyph->fAdvanceX = SkIntToFixed(glyph->fWidth);
878         glyph->fAdvanceY = 0;
879
880         // Vector FON will transform nicely, but bitmap FON do not.
881         if (fType == SkScalerContext_GDI::kLine_Type) {
882             SkRect bounds = SkRect::MakeXYWH(glyph->fLeft, glyph->fTop,
883                                              glyph->fWidth, glyph->fHeight);
884             SkMatrix m;
885             m.setAll(SkFIXEDToScalar(fMat22.eM11), -SkFIXEDToScalar(fMat22.eM21), 0,
886                      -SkFIXEDToScalar(fMat22.eM12), SkFIXEDToScalar(fMat22.eM22), 0,
887                      0,  0, SkScalarToPersp(SK_Scalar1));
888             m.mapRect(&bounds);
889             bounds.roundOut();
890             glyph->fLeft = SkScalarTruncToInt(bounds.fLeft);
891             glyph->fTop = SkScalarTruncToInt(bounds.fTop);
892             glyph->fWidth = SkScalarTruncToInt(bounds.width());
893             glyph->fHeight = SkScalarTruncToInt(bounds.height());
894         }
895
896         // Apply matrix to advance.
897         glyph->fAdvanceY = SkFixedMul(-SkFIXEDToFixed(fMat22.eM12), glyph->fAdvanceX);
898         glyph->fAdvanceX = SkFixedMul(SkFIXEDToFixed(fMat22.eM11), glyph->fAdvanceX);
899
900         return;
901     }
902
903     UINT glyphId = glyph->getGlyphID();
904
905     GLYPHMETRICS gm;
906     sk_bzero(&gm, sizeof(gm));
907
908     DWORD status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
909     if (GDI_ERROR == status) {
910         LogFontTypeface::EnsureAccessible(this->getTypeface());
911         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
912         if (GDI_ERROR == status) {
913             glyph->zeroMetrics();
914             return;
915         }
916     }
917
918     bool empty = false;
919     // The black box is either the embedded bitmap size or the outline extent.
920     // It is 1x1 if nothing is to be drawn, but will also be 1x1 if something very small
921     // is to be drawn, like a '.'. We need to outset '.' but do not wish to outset ' '.
922     if (1 == gm.gmBlackBoxX && 1 == gm.gmBlackBoxY) {
923         // If GetGlyphOutline with GGO_NATIVE returns 0, we know there was no outline.
924         DWORD bufferSize = GetGlyphOutlineW(fDDC, glyphId, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
925         empty = (0 == bufferSize);
926     }
927
928     glyph->fTop = SkToS16(-gm.gmptGlyphOrigin.y);
929     glyph->fLeft = SkToS16(gm.gmptGlyphOrigin.x);
930     if (empty) {
931         glyph->fWidth = 0;
932         glyph->fHeight = 0;
933     } else {
934         // Outset, since the image may bleed out of the black box.
935         // For embedded bitmaps the black box should be exact.
936         // For outlines we need to outset by 1 in all directions for bleed.
937         // For ClearType we need to outset by 2 for bleed.
938         glyph->fWidth = gm.gmBlackBoxX + 4;
939         glyph->fHeight = gm.gmBlackBoxY + 4;
940         glyph->fTop -= 2;
941         glyph->fLeft -= 2;
942     }
943     glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX);
944     glyph->fAdvanceY = SkIntToFixed(gm.gmCellIncY);
945     glyph->fRsbDelta = 0;
946     glyph->fLsbDelta = 0;
947
948     if (this->isSubpixel()) {
949         sk_bzero(&gm, sizeof(gm));
950         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fHighResMat22);
951         if (GDI_ERROR != status) {
952             SkPoint advance;
953             fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIncY), &advance);
954             glyph->fAdvanceX = SkScalarToFixed(advance.fX);
955             glyph->fAdvanceY = SkScalarToFixed(advance.fY);
956         }
957     } else if (!isAxisAligned(this->fRec)) {
958         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fGsA);
959         if (GDI_ERROR != status) {
960             SkPoint advance;
961             fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIncY), &advance);
962             glyph->fAdvanceX = SkScalarToFixed(advance.fX);
963             glyph->fAdvanceY = SkScalarToFixed(advance.fY);
964         }
965     }
966 }
967
968 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
969 void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* metrics) {
970     if (NULL == metrics) {
971         return;
972     }
973     sk_bzero(metrics, sizeof(*metrics));
974
975     SkASSERT(fDDC);
976
977 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
978     if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
979 #endif
980         metrics->fTop = SkIntToScalar(-fTM.tmAscent);
981         metrics->fAscent = SkIntToScalar(-fTM.tmAscent);
982         metrics->fDescent = SkIntToScalar(fTM.tmDescent);
983         metrics->fBottom = SkIntToScalar(fTM.tmDescent);
984         metrics->fLeading = SkIntToScalar(fTM.tmExternalLeading);
985         metrics->fAvgCharWidth = SkIntToScalar(fTM.tmAveCharWidth);
986         metrics->fMaxCharWidth = SkIntToScalar(fTM.tmMaxCharWidth);
987         metrics->fXMin = 0;
988         metrics->fXMax = metrics->fMaxCharWidth;
989         //metrics->fXHeight = 0;
990 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
991         return;
992     }
993 #endif
994
995     OUTLINETEXTMETRIC otm;
996
997     uint32_t ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
998     if (0 == ret) {
999         LogFontTypeface::EnsureAccessible(this->getTypeface());
1000         ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
1001     }
1002     if (0 == ret) {
1003         return;
1004     }
1005
1006 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
1007     metrics->fTop = SkIntToScalar(-otm.otmrcFontBox.top);
1008     metrics->fAscent = SkIntToScalar(-otm.otmAscent);
1009     metrics->fDescent = SkIntToScalar(-otm.otmDescent);
1010     metrics->fBottom = SkIntToScalar(-otm.otmrcFontBox.bottom);
1011     metrics->fLeading = SkIntToScalar(otm.otmLineGap);
1012     metrics->fAvgCharWidth = SkIntToScalar(otm.otmTextMetrics.tmAveCharWidth);
1013     metrics->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth);
1014     metrics->fXMin = SkIntToScalar(otm.otmrcFontBox.left);
1015     metrics->fXMax = SkIntToScalar(otm.otmrcFontBox.right);
1016 #endif
1017     metrics->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
1018     metrics->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
1019
1020     metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
1021     metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
1022
1023     metrics->fXHeight = SkIntToScalar(otm.otmsXHeight);
1024     GLYPHMETRICS gm;
1025     sk_bzero(&gm, sizeof(gm));
1026     DWORD len = GetGlyphOutlineW(fDDC, 'x', GGO_METRICS, &gm, 0, 0, &gMat2Identity);
1027     if (len != GDI_ERROR && gm.gmBlackBoxY > 0) {
1028         metrics->fXHeight = SkIntToScalar(gm.gmBlackBoxY);
1029     }
1030 }
1031
1032 ////////////////////////////////////////////////////////////////////////////////////////
1033
1034 #define SK_SHOW_TEXT_BLIT_COVERAGE 0
1035
1036 static void build_power_table(uint8_t table[], float ee) {
1037     for (int i = 0; i < 256; i++) {
1038         float x = i / 255.f;
1039         x = sk_float_pow(x, ee);
1040         int xx = SkScalarRoundToInt(x * 255);
1041         table[i] = SkToU8(xx);
1042     }
1043 }
1044
1045 /**
1046  *  This will invert the gamma applied by GDI (gray-scale antialiased), so we
1047  *  can get linear values.
1048  *
1049  *  GDI grayscale appears to use a hard-coded gamma of 2.3.
1050  *
1051  *  GDI grayscale appears to draw using the black and white rasterizer at four
1052  *  times the size and then downsamples to compute the coverage mask. As a
1053  *  result there are only seventeen total grays. This lack of fidelity means
1054  *  that shifting into other color spaces is imprecise.
1055  */
1056 static const uint8_t* getInverseGammaTableGDI() {
1057     // Since build_power_table is idempotent, many threads can build gTableGdi
1058     // simultaneously.
1059
1060     // Microsoft Specific:
1061     // Making gInited volatile provides read-aquire and write-release in vc++.
1062     // In VS2012, see compiler option /volatile:(ms|iso).
1063     // Replace with C++11 atomics when possible.
1064     static volatile bool gInited;
1065     static uint8_t gTableGdi[256];
1066     if (gInited) {
1067         // Need a L/L (read) barrier (full acquire not needed). If gInited is observed
1068         // true then gTableGdi is observable, but it must be requested.
1069     } else {
1070         build_power_table(gTableGdi, 2.3f);
1071         // Need a S/S (write) barrier (full release not needed) here so that this
1072         // write to gInited becomes observable after gTableGdi.
1073         gInited = true;
1074     }
1075     return gTableGdi;
1076 }
1077
1078 /**
1079  *  This will invert the gamma applied by GDI ClearType, so we can get linear
1080  *  values.
1081  *
1082  *  GDI ClearType uses SPI_GETFONTSMOOTHINGCONTRAST / 1000 as the gamma value.
1083  *  If this value is not specified, the default is a gamma of 1.4.
1084  */
1085 static const uint8_t* getInverseGammaTableClearType() {
1086     // We don't expect SPI_GETFONTSMOOTHINGCONTRAST to ever change, so building
1087     // gTableClearType with build_power_table is effectively idempotent.
1088
1089     // Microsoft Specific:
1090     // Making gInited volatile provides read-aquire and write-release in vc++.
1091     // In VS2012, see compiler option /volatile:(ms|iso).
1092     // Replace with C++11 atomics when possible.
1093     static volatile bool gInited;
1094     static uint8_t gTableClearType[256];
1095     if (gInited) {
1096         // Need a L/L (read) barrier (acquire not needed). If gInited is observed
1097         // true then gTableClearType is observable, but it must be requested.
1098     } else {
1099         UINT level = 0;
1100         if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &level, 0) || !level) {
1101             // can't get the data, so use a default
1102             level = 1400;
1103         }
1104         build_power_table(gTableClearType, level / 1000.0f);
1105         // Need a S/S (write) barrier (release not needed) here so that this
1106         // write to gInited becomes observable after gTableClearType.
1107         gInited = true;
1108     }
1109     return gTableClearType;
1110 }
1111
1112 #include "SkColorPriv.h"
1113
1114 //Cannot assume that the input rgb is gray due to possible setting of kGenA8FromLCD_Flag.
1115 template<bool APPLY_PREBLEND>
1116 static inline uint8_t rgb_to_a8(SkGdiRGB rgb, const uint8_t* table8) {
1117     U8CPU r = (rgb >> 16) & 0xFF;
1118     U8CPU g = (rgb >>  8) & 0xFF;
1119     U8CPU b = (rgb >>  0) & 0xFF;
1120     return sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), table8);
1121 }
1122
1123 template<bool APPLY_PREBLEND>
1124 static inline uint16_t rgb_to_lcd16(SkGdiRGB rgb, const uint8_t* tableR,
1125                                                   const uint8_t* tableG,
1126                                                   const uint8_t* tableB) {
1127     U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR);
1128     U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  8) & 0xFF, tableG);
1129     U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  0) & 0xFF, tableB);
1130 #if SK_SHOW_TEXT_BLIT_COVERAGE
1131     r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
1132 #endif
1133     return SkPack888ToRGB16(r, g, b);
1134 }
1135
1136 template<bool APPLY_PREBLEND>
1137 static inline SkPMColor rgb_to_lcd32(SkGdiRGB rgb, const uint8_t* tableR,
1138                                                    const uint8_t* tableG,
1139                                                    const uint8_t* tableB) {
1140     U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR);
1141     U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  8) & 0xFF, tableG);
1142     U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  0) & 0xFF, tableB);
1143 #if SK_SHOW_TEXT_BLIT_COVERAGE
1144     r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
1145 #endif
1146     return SkPackARGB32(0xFF, r, g, b);
1147 }
1148
1149 // Is this GDI color neither black nor white? If so, we have to keep this
1150 // image as is, rather than smashing it down to a BW mask.
1151 //
1152 // returns int instead of bool, since we don't want/have to pay to convert
1153 // the zero/non-zero value into a bool
1154 static int is_not_black_or_white(SkGdiRGB c) {
1155     // same as (but faster than)
1156     //      c &= 0x00FFFFFF;
1157     //      return 0 == c || 0x00FFFFFF == c;
1158     return (c + (c & 1)) & 0x00FFFFFF;
1159 }
1160
1161 static bool is_rgb_really_bw(const SkGdiRGB* src, int width, int height, size_t srcRB) {
1162     for (int y = 0; y < height; ++y) {
1163         for (int x = 0; x < width; ++x) {
1164             if (is_not_black_or_white(src[x])) {
1165                 return false;
1166             }
1167         }
1168         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
1169     }
1170     return true;
1171 }
1172
1173 // gdi's bitmap is upside-down, so we reverse dst walking in Y
1174 // whenever we copy it into skia's buffer
1175 static void rgb_to_bw(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
1176                       const SkGlyph& glyph) {
1177     const int width = glyph.fWidth;
1178     const size_t dstRB = (width + 7) >> 3;
1179     uint8_t* SK_RESTRICT dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
1180
1181     int byteCount = width >> 3;
1182     int bitCount = width & 7;
1183
1184     // adjust srcRB to skip the values in our byteCount loop,
1185     // since we increment src locally there
1186     srcRB -= byteCount * 8 * sizeof(SkGdiRGB);
1187
1188     for (int y = 0; y < glyph.fHeight; ++y) {
1189         if (byteCount > 0) {
1190             for (int i = 0; i < byteCount; ++i) {
1191                 unsigned byte = 0;
1192                 byte |= src[0] & (1 << 7);
1193                 byte |= src[1] & (1 << 6);
1194                 byte |= src[2] & (1 << 5);
1195                 byte |= src[3] & (1 << 4);
1196                 byte |= src[4] & (1 << 3);
1197                 byte |= src[5] & (1 << 2);
1198                 byte |= src[6] & (1 << 1);
1199                 byte |= src[7] & (1 << 0);
1200                 dst[i] = byte;
1201                 src += 8;
1202             }
1203         }
1204         if (bitCount > 0) {
1205             unsigned byte = 0;
1206             unsigned mask = 0x80;
1207             for (int i = 0; i < bitCount; i++) {
1208                 byte |= src[i] & mask;
1209                 mask >>= 1;
1210             }
1211             dst[byteCount] = byte;
1212         }
1213         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
1214         dst -= dstRB;
1215     }
1216 #if SK_SHOW_TEXT_BLIT_COVERAGE
1217     if (glyph.fWidth > 0 && glyph.fHeight > 0) {
1218         uint8_t* first = (uint8_t*)glyph.fImage;
1219         uint8_t* last = (uint8_t*)((char*)glyph.fImage + glyph.fHeight * dstRB - 1);
1220         *first |= 1 << 7;
1221         *last |= bitCount == 0 ? 1 : 1 << (8 - bitCount);
1222     }
1223 #endif
1224 }
1225
1226 template<bool APPLY_PREBLEND>
1227 static void rgb_to_a8(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
1228                       const SkGlyph& glyph, const uint8_t* table8) {
1229     const size_t dstRB = glyph.rowBytes();
1230     const int width = glyph.fWidth;
1231     uint8_t* SK_RESTRICT dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
1232
1233     for (int y = 0; y < glyph.fHeight; y++) {
1234         for (int i = 0; i < width; i++) {
1235             dst[i] = rgb_to_a8<APPLY_PREBLEND>(src[i], table8);
1236 #if SK_SHOW_TEXT_BLIT_COVERAGE
1237             dst[i] = SkMax32(dst[i], 10);
1238 #endif
1239         }
1240         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
1241         dst -= dstRB;
1242     }
1243 }
1244
1245 template<bool APPLY_PREBLEND>
1246 static void rgb_to_lcd16(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
1247                          const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
1248     const size_t dstRB = glyph.rowBytes();
1249     const int width = glyph.fWidth;
1250     uint16_t* SK_RESTRICT dst = (uint16_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
1251
1252     for (int y = 0; y < glyph.fHeight; y++) {
1253         for (int i = 0; i < width; i++) {
1254             dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(src[i], tableR, tableG, tableB);
1255         }
1256         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
1257         dst = (uint16_t*)((char*)dst - dstRB);
1258     }
1259 }
1260
1261 template<bool APPLY_PREBLEND>
1262 static void rgb_to_lcd32(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
1263                          const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
1264     const size_t dstRB = glyph.rowBytes();
1265     const int width = glyph.fWidth;
1266     uint32_t* SK_RESTRICT dst = (uint32_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
1267
1268     for (int y = 0; y < glyph.fHeight; y++) {
1269         for (int i = 0; i < width; i++) {
1270             dst[i] = rgb_to_lcd32<APPLY_PREBLEND>(src[i], tableR, tableG, tableB);
1271         }
1272         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
1273         dst = (uint32_t*)((char*)dst - dstRB);
1274     }
1275 }
1276
1277 static inline unsigned clamp255(unsigned x) {
1278     SkASSERT(x <= 256);
1279     return x - (x >> 8);
1280 }
1281
1282 void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) {
1283     SkASSERT(fDDC);
1284
1285     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
1286     const bool isAA = !isLCD(fRec);
1287
1288     size_t srcRB;
1289     const void* bits = fOffscreen.draw(glyph, isBW, &srcRB);
1290     if (NULL == bits) {
1291         LogFontTypeface::EnsureAccessible(this->getTypeface());
1292         bits = fOffscreen.draw(glyph, isBW, &srcRB);
1293         if (NULL == bits) {
1294             sk_bzero(glyph.fImage, glyph.computeImageSize());
1295             return;
1296         }
1297     }
1298
1299     if (!isBW) {
1300         const uint8_t* table;
1301         //The offscreen contains a GDI blit if isAA and kGenA8FromLCD_Flag is not set.
1302         //Otherwise the offscreen contains a ClearType blit.
1303         if (isAA && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag)) {
1304             table = getInverseGammaTableGDI();
1305         } else {
1306             table = getInverseGammaTableClearType();
1307         }
1308         //Note that the following cannot really be integrated into the
1309         //pre-blend, since we may not be applying the pre-blend; when we aren't
1310         //applying the pre-blend it means that a filter wants linear anyway.
1311         //Other code may also be applying the pre-blend, so we'd need another
1312         //one with this and one without.
1313         SkGdiRGB* addr = (SkGdiRGB*)bits;
1314         for (int y = 0; y < glyph.fHeight; ++y) {
1315             for (int x = 0; x < glyph.fWidth; ++x) {
1316                 int r = (addr[x] >> 16) & 0xFF;
1317                 int g = (addr[x] >>  8) & 0xFF;
1318                 int b = (addr[x] >>  0) & 0xFF;
1319                 addr[x] = (table[r] << 16) | (table[g] << 8) | table[b];
1320             }
1321             addr = SkTAddOffset<SkGdiRGB>(addr, srcRB);
1322         }
1323     }
1324
1325     int width = glyph.fWidth;
1326     size_t dstRB = glyph.rowBytes();
1327     if (isBW) {
1328         const uint8_t* src = (const uint8_t*)bits;
1329         uint8_t* dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
1330         for (int y = 0; y < glyph.fHeight; y++) {
1331             memcpy(dst, src, dstRB);
1332             src += srcRB;
1333             dst -= dstRB;
1334         }
1335 #if SK_SHOW_TEXT_BLIT_COVERAGE
1336             if (glyph.fWidth > 0 && glyph.fHeight > 0) {
1337                 int bitCount = width & 7;
1338                 uint8_t* first = (uint8_t*)glyph.fImage;
1339                 uint8_t* last = (uint8_t*)((char*)glyph.fImage + glyph.fHeight * dstRB - 1);
1340                 *first |= 1 << 7;
1341                 *last |= bitCount == 0 ? 1 : 1 << (8 - bitCount);
1342             }
1343 #endif
1344     } else if (isAA) {
1345         // since the caller may require A8 for maskfilters, we can't check for BW
1346         // ... until we have the caller tell us that explicitly
1347         const SkGdiRGB* src = (const SkGdiRGB*)bits;
1348         if (fPreBlend.isApplicable()) {
1349             rgb_to_a8<true>(src, srcRB, glyph, fPreBlend.fG);
1350         } else {
1351             rgb_to_a8<false>(src, srcRB, glyph, fPreBlend.fG);
1352         }
1353     } else {    // LCD16
1354         const SkGdiRGB* src = (const SkGdiRGB*)bits;
1355         if (is_rgb_really_bw(src, width, glyph.fHeight, srcRB)) {
1356             rgb_to_bw(src, srcRB, glyph);
1357             ((SkGlyph*)&glyph)->fMaskFormat = SkMask::kBW_Format;
1358         } else {
1359             if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
1360                 if (fPreBlend.isApplicable()) {
1361                     rgb_to_lcd16<true>(src, srcRB, glyph,
1362                                        fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
1363                 } else {
1364                     rgb_to_lcd16<false>(src, srcRB, glyph,
1365                                         fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
1366                 }
1367             } else {
1368                 SkASSERT(SkMask::kLCD32_Format == glyph.fMaskFormat);
1369                 if (fPreBlend.isApplicable()) {
1370                     rgb_to_lcd32<true>(src, srcRB, glyph,
1371                                        fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
1372                 } else {
1373                     rgb_to_lcd32<false>(src, srcRB, glyph,
1374                                         fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
1375                 }
1376             }
1377         }
1378     }
1379 }
1380
1381 class GDIGlyphbufferPointIter {
1382 public:
1383     GDIGlyphbufferPointIter(const uint8_t* glyphbuf, DWORD total_size)
1384         : fHeaderIter(glyphbuf, total_size), fCurveIter(), fPointIter()
1385     { }
1386
1387     POINTFX const * next() {
1388 nextHeader:
1389         if (!fCurveIter.isSet()) {
1390             const TTPOLYGONHEADER* header = fHeaderIter.next();
1391             if (NULL == header) {
1392                 return NULL;
1393             }
1394             fCurveIter.set(header);
1395             const TTPOLYCURVE* curve = fCurveIter.next();
1396             if (NULL == curve) {
1397                 return NULL;
1398             }
1399             fPointIter.set(curve);
1400             return &header->pfxStart;
1401         }
1402
1403         const POINTFX* nextPoint = fPointIter.next();
1404         if (NULL == nextPoint) {
1405             const TTPOLYCURVE* curve = fCurveIter.next();
1406             if (NULL == curve) {
1407                 fCurveIter.set();
1408                 goto nextHeader;
1409             } else {
1410                 fPointIter.set(curve);
1411             }
1412             nextPoint = fPointIter.next();
1413         }
1414         return nextPoint;
1415     }
1416
1417     WORD currentCurveType() {
1418         return fPointIter.fCurveType;
1419     }
1420
1421 private:
1422     /** Iterates over all of the polygon headers in a glyphbuf. */
1423     class GDIPolygonHeaderIter {
1424     public:
1425         GDIPolygonHeaderIter(const uint8_t* glyphbuf, DWORD total_size)
1426             : fCurPolygon(reinterpret_cast<const TTPOLYGONHEADER*>(glyphbuf))
1427             , fEndPolygon(SkTAddOffset<const TTPOLYGONHEADER>(glyphbuf, total_size))
1428         { }
1429
1430         const TTPOLYGONHEADER* next() {
1431             if (fCurPolygon >= fEndPolygon) {
1432                 return NULL;
1433             }
1434             const TTPOLYGONHEADER* thisPolygon = fCurPolygon;
1435             fCurPolygon = SkTAddOffset<const TTPOLYGONHEADER>(fCurPolygon, fCurPolygon->cb);
1436             return thisPolygon;
1437         }
1438     private:
1439         const TTPOLYGONHEADER* fCurPolygon;
1440         const TTPOLYGONHEADER* fEndPolygon;
1441     };
1442
1443     /** Iterates over all of the polygon curves in a polygon header. */
1444     class GDIPolygonCurveIter {
1445     public:
1446         GDIPolygonCurveIter() : fCurCurve(NULL), fEndCurve(NULL) { }
1447
1448         GDIPolygonCurveIter(const TTPOLYGONHEADER* curPolygon)
1449             : fCurCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOLYGONHEADER)))
1450             , fEndCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->cb))
1451         { }
1452
1453         bool isSet() { return fCurCurve != NULL; }
1454
1455         void set(const TTPOLYGONHEADER* curPolygon) {
1456             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOLYGONHEADER));
1457             fEndCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->cb);
1458         }
1459         void set() {
1460             fCurCurve = NULL;
1461             fEndCurve = NULL;
1462         }
1463
1464         const TTPOLYCURVE* next() {
1465             if (fCurCurve >= fEndCurve) {
1466                 return NULL;
1467             }
1468             const TTPOLYCURVE* thisCurve = fCurCurve;
1469             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(fCurCurve, size_of_TTPOLYCURVE(*fCurCurve));
1470             return thisCurve;
1471         }
1472     private:
1473         size_t size_of_TTPOLYCURVE(const TTPOLYCURVE& curve) {
1474             return 2*sizeof(WORD) + curve.cpfx*sizeof(POINTFX);
1475         }
1476         const TTPOLYCURVE* fCurCurve;
1477         const TTPOLYCURVE* fEndCurve;
1478     };
1479
1480     /** Iterates over all of the polygon points in a polygon curve. */
1481     class GDIPolygonCurvePointIter {
1482     public:
1483         GDIPolygonCurvePointIter() : fCurveType(0), fCurPoint(NULL), fEndPoint(NULL) { }
1484
1485         GDIPolygonCurvePointIter(const TTPOLYCURVE* curPolygon)
1486             : fCurveType(curPolygon->wType)
1487             , fCurPoint(&curPolygon->apfx[0])
1488             , fEndPoint(&curPolygon->apfx[curPolygon->cpfx])
1489         { }
1490
1491         bool isSet() { return fCurPoint != NULL; }
1492
1493         void set(const TTPOLYCURVE* curPolygon) {
1494             fCurveType = curPolygon->wType;
1495             fCurPoint = &curPolygon->apfx[0];
1496             fEndPoint = &curPolygon->apfx[curPolygon->cpfx];
1497         }
1498         void set() {
1499             fCurPoint = NULL;
1500             fEndPoint = NULL;
1501         }
1502
1503         const POINTFX* next() {
1504             if (fCurPoint >= fEndPoint) {
1505                 return NULL;
1506             }
1507             const POINTFX* thisPoint = fCurPoint;
1508             ++fCurPoint;
1509             return thisPoint;
1510         }
1511
1512         WORD fCurveType;
1513     private:
1514         const POINTFX* fCurPoint;
1515         const POINTFX* fEndPoint;
1516     };
1517
1518     GDIPolygonHeaderIter fHeaderIter;
1519     GDIPolygonCurveIter fCurveIter;
1520     GDIPolygonCurvePointIter fPointIter;
1521 };
1522
1523 static void sk_path_from_gdi_path(SkPath* path, const uint8_t* glyphbuf, DWORD total_size) {
1524     const uint8_t* cur_glyph = glyphbuf;
1525     const uint8_t* end_glyph = glyphbuf + total_size;
1526
1527     while (cur_glyph < end_glyph) {
1528         const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
1529
1530         const uint8_t* end_poly = cur_glyph + th->cb;
1531         const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
1532
1533         path->moveTo(SkFixedToScalar( SkFIXEDToFixed(th->pfxStart.x)),
1534                      SkFixedToScalar(-SkFIXEDToFixed(th->pfxStart.y)));
1535
1536         while (cur_poly < end_poly) {
1537             const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
1538
1539             if (pc->wType == TT_PRIM_LINE) {
1540                 for (uint16_t i = 0; i < pc->cpfx; i++) {
1541                     path->lineTo(SkFixedToScalar( SkFIXEDToFixed(pc->apfx[i].x)),
1542                                  SkFixedToScalar(-SkFIXEDToFixed(pc->apfx[i].y)));
1543                 }
1544             }
1545
1546             if (pc->wType == TT_PRIM_QSPLINE) {
1547                 for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
1548                     POINTFX pnt_b = pc->apfx[u];    // B is always the current point
1549                     POINTFX pnt_c = pc->apfx[u+1];
1550
1551                     if (u < pc->cpfx - 2) {          // If not on last spline, compute C
1552                         pnt_c.x = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.x),
1553                                                             SkFIXEDToFixed(pnt_c.x)));
1554                         pnt_c.y = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.y),
1555                                                             SkFIXEDToFixed(pnt_c.y)));
1556                     }
1557
1558                     path->quadTo(SkFixedToScalar( SkFIXEDToFixed(pnt_b.x)),
1559                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_b.y)),
1560                                  SkFixedToScalar( SkFIXEDToFixed(pnt_c.x)),
1561                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_c.y)));
1562                 }
1563             }
1564             // Advance past this TTPOLYCURVE.
1565             cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
1566         }
1567         cur_glyph += th->cb;
1568         path->close();
1569     }
1570 }
1571
1572 #define move_next_expected_hinted_point(iter, pElem) do {\
1573     pElem = iter.next(); \
1574     if (NULL == pElem) return false; \
1575 } while(0)
1576
1577 // It is possible for the hinted and unhinted versions of the same path to have
1578 // a different number of points due to GDI's handling of flipped points.
1579 // If this is detected, this will return false.
1580 static bool sk_path_from_gdi_paths(SkPath* path, const uint8_t* glyphbuf, DWORD total_size,
1581                                    GDIGlyphbufferPointIter hintedYs) {
1582     const uint8_t* cur_glyph = glyphbuf;
1583     const uint8_t* end_glyph = glyphbuf + total_size;
1584
1585     POINTFX const * hintedPoint;
1586
1587     while (cur_glyph < end_glyph) {
1588         const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
1589
1590         const uint8_t* end_poly = cur_glyph + th->cb;
1591         const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
1592
1593         move_next_expected_hinted_point(hintedYs, hintedPoint);
1594         path->moveTo(SkFixedToScalar( SkFIXEDToFixed(th->pfxStart.x)),
1595                      SkFixedToScalar(-SkFIXEDToFixed(hintedPoint->y)));
1596
1597         while (cur_poly < end_poly) {
1598             const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
1599
1600             if (pc->wType == TT_PRIM_LINE) {
1601                 for (uint16_t i = 0; i < pc->cpfx; i++) {
1602                     move_next_expected_hinted_point(hintedYs, hintedPoint);
1603                     path->lineTo(SkFixedToScalar( SkFIXEDToFixed(pc->apfx[i].x)),
1604                                  SkFixedToScalar(-SkFIXEDToFixed(hintedPoint->y)));
1605                 }
1606             }
1607
1608             if (pc->wType == TT_PRIM_QSPLINE) {
1609                 POINTFX currentPoint = pc->apfx[0];
1610                 move_next_expected_hinted_point(hintedYs, hintedPoint);
1611                 // only take the hinted y if it wasn't flipped
1612                 if (hintedYs.currentCurveType() == TT_PRIM_QSPLINE) {
1613                     currentPoint.y = hintedPoint->y;
1614                 }
1615                 for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
1616                     POINTFX pnt_b = currentPoint;//pc->apfx[u]; // B is always the current point
1617                     POINTFX pnt_c = pc->apfx[u+1];
1618                     move_next_expected_hinted_point(hintedYs, hintedPoint);
1619                     // only take the hinted y if it wasn't flipped
1620                     if (hintedYs.currentCurveType() == TT_PRIM_QSPLINE) {
1621                         pnt_c.y = hintedPoint->y;
1622                     }
1623                     currentPoint.x = pnt_c.x;
1624                     currentPoint.y = pnt_c.y;
1625
1626                     if (u < pc->cpfx - 2) {          // If not on last spline, compute C
1627                         pnt_c.x = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.x),
1628                                                             SkFIXEDToFixed(pnt_c.x)));
1629                         pnt_c.y = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.y),
1630                                                             SkFIXEDToFixed(pnt_c.y)));
1631                     }
1632
1633                     path->quadTo(SkFixedToScalar( SkFIXEDToFixed(pnt_b.x)),
1634                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_b.y)),
1635                                  SkFixedToScalar( SkFIXEDToFixed(pnt_c.x)),
1636                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_c.y)));
1637                 }
1638             }
1639             // Advance past this TTPOLYCURVE.
1640             cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
1641         }
1642         cur_glyph += th->cb;
1643         path->close();
1644     }
1645     return true;
1646 }
1647
1648 DWORD SkScalerContext_GDI::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
1649                                                SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf)
1650 {
1651     GLYPHMETRICS gm;
1652
1653     DWORD total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, BUFFERSIZE, glyphbuf->get(), &fMat22);
1654     // Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even if BUFFERSIZE > 0.
1655     // It has been verified that this does not involve a buffer overrun.
1656     if (GDI_ERROR == total_size || total_size > BUFFERSIZE) {
1657         // GDI_ERROR because the BUFFERSIZE was too small, or because the data was not accessible.
1658         // When the data is not accessable GetGlyphOutlineW fails rather quickly,
1659         // so just try to get the size. If that fails then ensure the data is accessible.
1660         total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, 0, NULL, &fMat22);
1661         if (GDI_ERROR == total_size) {
1662             LogFontTypeface::EnsureAccessible(this->getTypeface());
1663             total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, 0, NULL, &fMat22);
1664             if (GDI_ERROR == total_size) {
1665                 // GetGlyphOutlineW is known to fail for some characters, such as spaces.
1666                 // In these cases, just return that the glyph does not have a shape.
1667                 return 0;
1668             }
1669         }
1670
1671         glyphbuf->reset(total_size);
1672
1673         DWORD ret = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, total_size, glyphbuf->get(), &fMat22);
1674         if (GDI_ERROR == ret) {
1675             LogFontTypeface::EnsureAccessible(this->getTypeface());
1676             ret = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, total_size, glyphbuf->get(), &fMat22);
1677             if (GDI_ERROR == ret) {
1678                 SkASSERT(false);
1679                 return 0;
1680             }
1681         }
1682     }
1683     return total_size;
1684 }
1685
1686 void SkScalerContext_GDI::generatePath(const SkGlyph& glyph, SkPath* path) {
1687     SkASSERT(&glyph && path);
1688     SkASSERT(fDDC);
1689
1690     path->reset();
1691
1692     // Out of all the fonts on a typical Windows box,
1693     // 25% of glyphs require more than 2KB.
1694     // 1% of glyphs require more than 4KB.
1695     // 0.01% of glyphs require more than 8KB.
1696     // 8KB is less than 1% of the normal 1MB stack on Windows.
1697     // Note that some web fonts glyphs require more than 20KB.
1698     //static const DWORD BUFFERSIZE = (1 << 13);
1699
1700     //GDI only uses hinted outlines when axis aligned.
1701     UINT format = GGO_NATIVE | GGO_GLYPH_INDEX;
1702     if (fRec.getHinting() == SkPaint::kNo_Hinting || fRec.getHinting() == SkPaint::kSlight_Hinting){
1703         format |= GGO_UNHINTED;
1704     }
1705     SkAutoSTMalloc<BUFFERSIZE, uint8_t> glyphbuf(BUFFERSIZE);
1706     DWORD total_size = getGDIGlyphPath(glyph, format, &glyphbuf);
1707     if (0 == total_size) {
1708         return;
1709     }
1710
1711     if (fRec.getHinting() != SkPaint::kSlight_Hinting) {
1712         sk_path_from_gdi_path(path, glyphbuf, total_size);
1713     } else {
1714         //GDI only uses hinted outlines when axis aligned.
1715         UINT format = GGO_NATIVE | GGO_GLYPH_INDEX;
1716
1717         SkAutoSTMalloc<BUFFERSIZE, uint8_t> hintedGlyphbuf(BUFFERSIZE);
1718         DWORD hinted_total_size = getGDIGlyphPath(glyph, format, &hintedGlyphbuf);
1719         if (0 == hinted_total_size) {
1720             return;
1721         }
1722
1723         if (!sk_path_from_gdi_paths(path, glyphbuf, total_size,
1724                                     GDIGlyphbufferPointIter(hintedGlyphbuf, hinted_total_size)))
1725         {
1726             path->reset();
1727             sk_path_from_gdi_path(path, glyphbuf, total_size);
1728         }
1729     }
1730 }
1731
1732 static void logfont_for_name(const char* familyName, LOGFONT* lf) {
1733     sk_bzero(lf, sizeof(LOGFONT));
1734 #ifdef UNICODE
1735     // Get the buffer size needed first.
1736     size_t str_len = ::MultiByteToWideChar(CP_UTF8, 0, familyName,
1737                                             -1, NULL, 0);
1738     // Allocate a buffer (str_len already has terminating null
1739     // accounted for).
1740     wchar_t *wideFamilyName = new wchar_t[str_len];
1741     // Now actually convert the string.
1742     ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1,
1743                             wideFamilyName, str_len);
1744     ::wcsncpy(lf->lfFaceName, wideFamilyName, LF_FACESIZE - 1);
1745     delete [] wideFamilyName;
1746     lf->lfFaceName[LF_FACESIZE-1] = L'\0';
1747 #else
1748     ::strncpy(lf->lfFaceName, familyName, LF_FACESIZE - 1);
1749     lf->lfFaceName[LF_FACESIZE - 1] = '\0';
1750 #endif
1751 }
1752
1753 void LogFontTypeface::onGetFamilyName(SkString* familyName) const {
1754     // Get the actual name of the typeface. The logfont may not know this.
1755     HFONT font = CreateFontIndirect(&fLogFont);
1756
1757     HDC deviceContext = ::CreateCompatibleDC(NULL);
1758     HFONT savefont = (HFONT)SelectObject(deviceContext, font);
1759
1760     dcfontname_to_skstring(deviceContext, fLogFont, familyName);
1761
1762     if (deviceContext) {
1763         ::SelectObject(deviceContext, savefont);
1764         ::DeleteDC(deviceContext);
1765     }
1766     if (font) {
1767         ::DeleteObject(font);
1768     }
1769 }
1770
1771 void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
1772                                           bool* isLocalStream) const {
1773     SkString familyName;
1774     this->onGetFamilyName(&familyName);
1775     desc->setFamilyName(familyName.c_str());
1776     *isLocalStream = this->fSerializeAsStream;
1777 }
1778
1779 static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {
1780     // Initialize the MAT2 structure to the identify transformation matrix.
1781     static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0),
1782                         SkScalarToFIXED(0), SkScalarToFIXED(1)};
1783     int flags = GGO_METRICS | GGO_GLYPH_INDEX;
1784     GLYPHMETRICS gm;
1785     if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, NULL, &mat2)) {
1786         return false;
1787     }
1788     SkASSERT(advance);
1789     *advance = gm.gmCellIncX;
1790     return true;
1791 }
1792
1793 SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics(
1794         SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
1795         const uint32_t* glyphIDs,
1796         uint32_t glyphIDsCount) const {
1797     LOGFONT lf = fLogFont;
1798     SkAdvancedTypefaceMetrics* info = NULL;
1799
1800     HDC hdc = CreateCompatibleDC(NULL);
1801     HFONT font = CreateFontIndirect(&lf);
1802     HFONT savefont = (HFONT)SelectObject(hdc, font);
1803     HFONT designFont = NULL;
1804
1805     const char stem_chars[] = {'i', 'I', '!', '1'};
1806     int16_t min_width;
1807     unsigned glyphCount;
1808
1809     // To request design units, create a logical font whose height is specified
1810     // as unitsPerEm.
1811     OUTLINETEXTMETRIC otm;
1812     unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
1813     if (0 == otmRet) {
1814         call_ensure_accessible(lf);
1815         otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
1816     }
1817     if (!otmRet || !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
1818         goto Error;
1819     }
1820     lf.lfHeight = -SkToS32(otm.otmEMSquare);
1821     designFont = CreateFontIndirect(&lf);
1822     SelectObject(hdc, designFont);
1823     if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
1824         goto Error;
1825     }
1826     glyphCount = calculateGlyphCount(hdc, fLogFont);
1827
1828     info = new SkAdvancedTypefaceMetrics;
1829     info->fEmSize = otm.otmEMSquare;
1830     info->fLastGlyphID = SkToU16(glyphCount - 1);
1831     info->fStyle = 0;
1832     tchar_to_skstring(lf.lfFaceName, &info->fFontName);
1833     info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag;
1834     // If bit 1 is set, the font may not be embedded in a document.
1835     // If bit 1 is clear, the font can be embedded.
1836     // If bit 2 is set, the embedding is read-only.
1837     if (otm.otmfsType & 0x1) {
1838         info->fFlags = SkTBitOr<SkAdvancedTypefaceMetrics::FontFlags>(
1839                 info->fFlags,
1840                 SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag);
1841     }
1842
1843     if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
1844         populate_glyph_to_unicode(hdc, glyphCount, &(info->fGlyphToUnicode));
1845     }
1846
1847     if (glyphCount > 0 &&
1848         (otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE)) {
1849         info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
1850     } else {
1851         info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
1852         info->fItalicAngle = 0;
1853         info->fAscent = 0;
1854         info->fDescent = 0;
1855         info->fStemV = 0;
1856         info->fCapHeight = 0;
1857         info->fBBox = SkIRect::MakeEmpty();
1858         goto ReturnInfo;
1859     }
1860
1861     // If this bit is clear the font is a fixed pitch font.
1862     if (!(otm.otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
1863         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
1864     }
1865     if (otm.otmTextMetrics.tmItalic) {
1866         info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
1867     }
1868     if (otm.otmTextMetrics.tmPitchAndFamily & FF_ROMAN) {
1869         info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
1870     } else if (otm.otmTextMetrics.tmPitchAndFamily & FF_SCRIPT) {
1871             info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
1872     }
1873
1874     // The main italic angle of the font, in tenths of a degree counterclockwise
1875     // from vertical.
1876     info->fItalicAngle = otm.otmItalicAngle / 10;
1877     info->fAscent = SkToS16(otm.otmTextMetrics.tmAscent);
1878     info->fDescent = SkToS16(-otm.otmTextMetrics.tmDescent);
1879     // TODO(ctguil): Use alternate cap height calculation.
1880     // MSDN says otmsCapEmHeight is not support but it is returning a value on
1881     // my Win7 box.
1882     info->fCapHeight = otm.otmsCapEmHeight;
1883     info->fBBox =
1884         SkIRect::MakeLTRB(otm.otmrcFontBox.left, otm.otmrcFontBox.top,
1885                           otm.otmrcFontBox.right, otm.otmrcFontBox.bottom);
1886
1887     // Figure out a good guess for StemV - Min width of i, I, !, 1.
1888     // This probably isn't very good with an italic font.
1889     min_width = SHRT_MAX;
1890     info->fStemV = 0;
1891     for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
1892         ABC abcWidths;
1893         if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
1894             int16_t width = abcWidths.abcB;
1895             if (width > 0 && width < min_width) {
1896                 min_width = width;
1897                 info->fStemV = min_width;
1898             }
1899         }
1900     }
1901
1902     if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
1903         if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) {
1904             appendRange(&info->fGlyphWidths, 0);
1905             info->fGlyphWidths->fAdvance.append(1, &min_width);
1906             finishRange(info->fGlyphWidths.get(), 0,
1907                         SkAdvancedTypefaceMetrics::WidthRange::kDefault);
1908         } else {
1909             info->fGlyphWidths.reset(
1910                 getAdvanceData(hdc,
1911                                glyphCount,
1912                                glyphIDs,
1913                                glyphIDsCount,
1914                                &getWidthAdvance));
1915         }
1916     }
1917
1918 Error:
1919 ReturnInfo:
1920     SelectObject(hdc, savefont);
1921     DeleteObject(designFont);
1922     DeleteObject(font);
1923     DeleteDC(hdc);
1924
1925     return info;
1926 }
1927
1928 //Dummy representation of a Base64 encoded GUID from create_unique_font_name.
1929 #define BASE64_GUID_ID "XXXXXXXXXXXXXXXXXXXXXXXX"
1930 //Length of GUID representation from create_id, including NULL terminator.
1931 #define BASE64_GUID_ID_LEN SK_ARRAY_COUNT(BASE64_GUID_ID)
1932
1933 SK_COMPILE_ASSERT(BASE64_GUID_ID_LEN < LF_FACESIZE, GUID_longer_than_facesize);
1934
1935 /**
1936    NameID 6 Postscript names cannot have the character '/'.
1937    It would be easier to hex encode the GUID, but that is 32 bytes,
1938    and many systems have issues with names longer than 28 bytes.
1939    The following need not be any standard base64 encoding.
1940    The encoded value is never decoded.
1941 */
1942 static const char postscript_safe_base64_encode[] =
1943     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1944     "abcdefghijklmnopqrstuvwxyz"
1945     "0123456789-_=";
1946
1947 /**
1948    Formats a GUID into Base64 and places it into buffer.
1949    buffer should have space for at least BASE64_GUID_ID_LEN characters.
1950    The string will always be null terminated.
1951    XXXXXXXXXXXXXXXXXXXXXXXX0
1952  */
1953 static void format_guid_b64(const GUID& guid, char* buffer, size_t bufferSize) {
1954     SkASSERT(bufferSize >= BASE64_GUID_ID_LEN);
1955     size_t written = SkBase64::Encode(&guid, sizeof(guid), buffer, postscript_safe_base64_encode);
1956     SkASSERT(written < LF_FACESIZE);
1957     buffer[written] = '\0';
1958 }
1959
1960 /**
1961    Creates a Base64 encoded GUID and places it into buffer.
1962    buffer should have space for at least BASE64_GUID_ID_LEN characters.
1963    The string will always be null terminated.
1964    XXXXXXXXXXXXXXXXXXXXXXXX0
1965  */
1966 static HRESULT create_unique_font_name(char* buffer, size_t bufferSize) {
1967     GUID guid = {};
1968     if (FAILED(CoCreateGuid(&guid))) {
1969         return E_UNEXPECTED;
1970     }
1971     format_guid_b64(guid, buffer, bufferSize);
1972
1973     return S_OK;
1974 }
1975
1976 /**
1977    Introduces a font to GDI. On failure will return NULL. The returned handle
1978    should eventually be passed to RemoveFontMemResourceEx.
1979 */
1980 static HANDLE activate_font(SkData* fontData) {
1981     DWORD numFonts = 0;
1982     //AddFontMemResourceEx just copies the data, but does not specify const.
1983     HANDLE fontHandle = AddFontMemResourceEx(const_cast<void*>(fontData->data()),
1984                                              static_cast<DWORD>(fontData->size()),
1985                                              0,
1986                                              &numFonts);
1987
1988     if (fontHandle != NULL && numFonts < 1) {
1989         RemoveFontMemResourceEx(fontHandle);
1990         return NULL;
1991     }
1992
1993     return fontHandle;
1994 }
1995
1996 static SkTypeface* create_from_stream(SkStream* stream) {
1997     // Create a unique and unpredictable font name.
1998     // Avoids collisions and access from CSS.
1999     char familyName[BASE64_GUID_ID_LEN];
2000     const int familyNameSize = SK_ARRAY_COUNT(familyName);
2001     if (FAILED(create_unique_font_name(familyName, familyNameSize))) {
2002         return NULL;
2003     }
2004
2005     // Change the name of the font.
2006     SkAutoTUnref<SkData> rewrittenFontData(SkOTUtils::RenameFont(stream, familyName, familyNameSize-1));
2007     if (NULL == rewrittenFontData.get()) {
2008         return NULL;
2009     }
2010
2011     // Register the font with GDI.
2012     HANDLE fontReference = activate_font(rewrittenFontData.get());
2013     if (NULL == fontReference) {
2014         return NULL;
2015     }
2016
2017     // Create the typeface.
2018     LOGFONT lf;
2019     logfont_for_name(familyName, &lf);
2020
2021     return SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference);
2022 }
2023
2024 SkStream* LogFontTypeface::onOpenStream(int* ttcIndex) const {
2025     *ttcIndex = 0;
2026
2027     const DWORD kTTCTag =
2028         SkEndian_SwapBE32(SkSetFourByteTag('t', 't', 'c', 'f'));
2029     LOGFONT lf = fLogFont;
2030
2031     HDC hdc = ::CreateCompatibleDC(NULL);
2032     HFONT font = CreateFontIndirect(&lf);
2033     HFONT savefont = (HFONT)SelectObject(hdc, font);
2034
2035     SkMemoryStream* stream = NULL;
2036     DWORD tables[2] = {kTTCTag, 0};
2037     for (int i = 0; i < SK_ARRAY_COUNT(tables); i++) {
2038         DWORD bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0);
2039         if (bufferSize == GDI_ERROR) {
2040             call_ensure_accessible(lf);
2041             bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0);
2042         }
2043         if (bufferSize != GDI_ERROR) {
2044             stream = new SkMemoryStream(bufferSize);
2045             if (GetFontData(hdc, tables[i], 0, (void*)stream->getMemoryBase(), bufferSize)) {
2046                 break;
2047             } else {
2048                 delete stream;
2049                 stream = NULL;
2050             }
2051         }
2052     }
2053
2054     SelectObject(hdc, savefont);
2055     DeleteObject(font);
2056     DeleteDC(hdc);
2057
2058     return stream;
2059 }
2060
2061 static void bmpCharsToGlyphs(HDC hdc, const WCHAR* bmpChars, int count, uint16_t* glyphs,
2062                              bool Ox1FHack)
2063 {
2064     DWORD result = GetGlyphIndicesW(hdc, bmpChars, count, glyphs, GGI_MARK_NONEXISTING_GLYPHS);
2065     if (GDI_ERROR == result) {
2066         for (int i = 0; i < count; ++i) {
2067             glyphs[i] = 0;
2068         }
2069         return;
2070     }
2071
2072     if (Ox1FHack) {
2073         for (int i = 0; i < count; ++i) {
2074             if (0xFFFF == glyphs[i] || 0x1F == glyphs[i]) {
2075                 glyphs[i] = 0;
2076             }
2077         }
2078     } else {
2079         for (int i = 0; i < count; ++i) {
2080             if (0xFFFF == glyphs[i]){
2081                 glyphs[i] = 0;
2082             }
2083         }
2084     }
2085 }
2086
2087 static uint16_t nonBmpCharToGlyph(HDC hdc, SCRIPT_CACHE* scriptCache, const WCHAR utf16[2]) {
2088     uint16_t index = 0;
2089     // Use uniscribe to detemine glyph index for non-BMP characters.
2090     static const int numWCHAR = 2;
2091     static const int maxItems = 2;
2092     // MSDN states that this can be NULL, but some things don't work then.
2093     SCRIPT_CONTROL scriptControl = { 0 };
2094     // Add extra item to SCRIPT_ITEM to work around a bug (now documented).
2095     // https://bugzilla.mozilla.org/show_bug.cgi?id=366643
2096     SCRIPT_ITEM si[maxItems + 1];
2097     int numItems;
2098     HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &scriptControl, NULL, si, &numItems),
2099          "Could not itemize character.");
2100
2101     // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2 space glyphs.
2102     static const int maxGlyphs = 2;
2103     SCRIPT_VISATTR vsa[maxGlyphs];
2104     WORD outGlyphs[maxGlyphs];
2105     WORD logClust[numWCHAR];
2106     int numGlyphs;
2107     HRZM(ScriptShape(hdc, scriptCache, utf16, numWCHAR, maxGlyphs, &si[0].a,
2108                      outGlyphs, logClust, vsa, &numGlyphs),
2109          "Could not shape character.");
2110     if (1 == numGlyphs) {
2111         index = outGlyphs[0];
2112     }
2113     return index;
2114 }
2115
2116 class SkAutoHDC {
2117 public:
2118     SkAutoHDC(const LOGFONT& lf)
2119         : fHdc(::CreateCompatibleDC(NULL))
2120         , fFont(::CreateFontIndirect(&lf))
2121         , fSavefont((HFONT)SelectObject(fHdc, fFont))
2122     { }
2123     ~SkAutoHDC() {
2124         SelectObject(fHdc, fSavefont);
2125         DeleteObject(fFont);
2126         DeleteDC(fHdc);
2127     }
2128     operator HDC() { return fHdc; }
2129 private:
2130     HDC fHdc;
2131     HFONT fFont;
2132     HFONT fSavefont;
2133 };
2134 #define SkAutoHDC(...) SK_REQUIRE_LOCAL_VAR(SkAutoHDC)
2135
2136 int LogFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
2137                                      uint16_t userGlyphs[], int glyphCount) const
2138 {
2139     SkAutoHDC hdc(fLogFont);
2140
2141     TEXTMETRIC tm;
2142     if (0 == GetTextMetrics(hdc, &tm)) {
2143         call_ensure_accessible(fLogFont);
2144         if (0 == GetTextMetrics(hdc, &tm)) {
2145             tm.tmPitchAndFamily = TMPF_TRUETYPE;
2146         }
2147     }
2148     bool Ox1FHack = !(tm.tmPitchAndFamily & TMPF_VECTOR) /*&& winVer < Vista */;
2149
2150     SkAutoSTMalloc<256, uint16_t> scratchGlyphs;
2151     uint16_t* glyphs;
2152     if (userGlyphs != NULL) {
2153         glyphs = userGlyphs;
2154     } else {
2155         glyphs = scratchGlyphs.reset(glyphCount);
2156     }
2157
2158     SCRIPT_CACHE sc = 0;
2159     switch (encoding) {
2160     case SkTypeface::kUTF8_Encoding: {
2161         static const int scratchCount = 256;
2162         WCHAR scratch[scratchCount];
2163         int glyphIndex = 0;
2164         const char* currentUtf8 = reinterpret_cast<const char*>(chars);
2165         SkUnichar currentChar;
2166         if (glyphCount) {
2167             currentChar = SkUTF8_NextUnichar(&currentUtf8);
2168         }
2169         while (glyphIndex < glyphCount) {
2170             // Try a run of bmp.
2171             int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
2172             int runLength = 0;
2173             while (runLength < glyphsLeft && currentChar <= 0xFFFF) {
2174                 scratch[runLength] = static_cast<WCHAR>(currentChar);
2175                 ++runLength;
2176                 if (runLength < glyphsLeft) {
2177                     currentChar = SkUTF8_NextUnichar(&currentUtf8);
2178                 }
2179             }
2180             if (runLength) {
2181                 bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], Ox1FHack);
2182                 glyphIndex += runLength;
2183             }
2184
2185             // Try a run of non-bmp.
2186             while (glyphIndex < glyphCount && currentChar > 0xFFFF) {
2187                 SkUTF16_FromUnichar(currentChar, reinterpret_cast<uint16_t*>(scratch));
2188                 glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
2189                 ++glyphIndex;
2190                 if (glyphIndex < glyphCount) {
2191                     currentChar = SkUTF8_NextUnichar(&currentUtf8);
2192                 }
2193             }
2194         }
2195         break;
2196     }
2197     case SkTypeface::kUTF16_Encoding: {
2198         int glyphIndex = 0;
2199         const WCHAR* currentUtf16 = reinterpret_cast<const WCHAR*>(chars);
2200         while (glyphIndex < glyphCount) {
2201             // Try a run of bmp.
2202             int glyphsLeft = glyphCount - glyphIndex;
2203             int runLength = 0;
2204             while (runLength < glyphsLeft && !SkUTF16_IsHighSurrogate(currentUtf16[runLength])) {
2205                 ++runLength;
2206             }
2207             if (runLength) {
2208                 bmpCharsToGlyphs(hdc, currentUtf16, runLength, &glyphs[glyphIndex], Ox1FHack);
2209                 glyphIndex += runLength;
2210                 currentUtf16 += runLength;
2211             }
2212
2213             // Try a run of non-bmp.
2214             while (glyphIndex < glyphCount && SkUTF16_IsHighSurrogate(*currentUtf16)) {
2215                 glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, currentUtf16);
2216                 ++glyphIndex;
2217                 currentUtf16 += 2;
2218             }
2219         }
2220         break;
2221     }
2222     case SkTypeface::kUTF32_Encoding: {
2223         static const int scratchCount = 256;
2224         WCHAR scratch[scratchCount];
2225         int glyphIndex = 0;
2226         const uint32_t* utf32 = reinterpret_cast<const uint32_t*>(chars);
2227         while (glyphIndex < glyphCount) {
2228             // Try a run of bmp.
2229             int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
2230             int runLength = 0;
2231             while (runLength < glyphsLeft && utf32[glyphIndex + runLength] <= 0xFFFF) {
2232                 scratch[runLength] = static_cast<WCHAR>(utf32[glyphIndex + runLength]);
2233                 ++runLength;
2234             }
2235             if (runLength) {
2236                 bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], Ox1FHack);
2237                 glyphIndex += runLength;
2238             }
2239
2240             // Try a run of non-bmp.
2241             while (glyphIndex < glyphCount && utf32[glyphIndex] > 0xFFFF) {
2242                 SkUTF16_FromUnichar(utf32[glyphIndex], reinterpret_cast<uint16_t*>(scratch));
2243                 glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
2244                 ++glyphIndex;
2245             }
2246         }
2247         break;
2248     }
2249     default:
2250         SK_CRASH();
2251     }
2252
2253     if (sc) {
2254         ::ScriptFreeCache(&sc);
2255     }
2256
2257     for (int i = 0; i < glyphCount; ++i) {
2258         if (0 == glyphs[i]) {
2259             return i;
2260         }
2261     }
2262     return glyphCount;
2263 }
2264
2265 int LogFontTypeface::onCountGlyphs() const {
2266     HDC hdc = ::CreateCompatibleDC(NULL);
2267     HFONT font = CreateFontIndirect(&fLogFont);
2268     HFONT savefont = (HFONT)SelectObject(hdc, font);
2269
2270     unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);
2271
2272     SelectObject(hdc, savefont);
2273     DeleteObject(font);
2274     DeleteDC(hdc);
2275
2276     return glyphCount;
2277 }
2278
2279 int LogFontTypeface::onGetUPEM() const {
2280     HDC hdc = ::CreateCompatibleDC(NULL);
2281     HFONT font = CreateFontIndirect(&fLogFont);
2282     HFONT savefont = (HFONT)SelectObject(hdc, font);
2283
2284     unsigned int upem = calculateUPEM(hdc, fLogFont);
2285
2286     SelectObject(hdc, savefont);
2287     DeleteObject(font);
2288     DeleteDC(hdc);
2289
2290     return upem;
2291 }
2292
2293 SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() const {
2294     SkTypeface::LocalizedStrings* nameIter =
2295         SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
2296     if (NULL == nameIter) {
2297         SkString familyName;
2298         this->getFamilyName(&familyName);
2299         SkString language("und"); //undetermined
2300         nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
2301     }
2302     return nameIter;
2303 }
2304
2305 int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
2306     SkSFNTHeader header;
2307     if (sizeof(header) != this->onGetTableData(0, 0, sizeof(header), &header)) {
2308         return 0;
2309     }
2310
2311     int numTables = SkEndian_SwapBE16(header.numTables);
2312
2313     if (tags) {
2314         size_t size = numTables * sizeof(SkSFNTHeader::TableDirectoryEntry);
2315         SkAutoSTMalloc<0x20, SkSFNTHeader::TableDirectoryEntry> dir(numTables);
2316         if (size != this->onGetTableData(0, sizeof(header), size, dir.get())) {
2317             return 0;
2318         }
2319
2320         for (int i = 0; i < numTables; ++i) {
2321             tags[i] = SkEndian_SwapBE32(dir[i].tag);
2322         }
2323     }
2324     return numTables;
2325 }
2326
2327 size_t LogFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
2328                                        size_t length, void* data) const
2329 {
2330     LOGFONT lf = fLogFont;
2331
2332     HDC hdc = ::CreateCompatibleDC(NULL);
2333     HFONT font = CreateFontIndirect(&lf);
2334     HFONT savefont = (HFONT)SelectObject(hdc, font);
2335
2336     tag = SkEndian_SwapBE32(tag);
2337     if (NULL == data) {
2338         length = 0;
2339     }
2340     DWORD bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) length);
2341     if (bufferSize == GDI_ERROR) {
2342         call_ensure_accessible(lf);
2343         bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) length);
2344     }
2345
2346     SelectObject(hdc, savefont);
2347     DeleteObject(font);
2348     DeleteDC(hdc);
2349
2350     return bufferSize == GDI_ERROR ? 0 : bufferSize;
2351 }
2352
2353 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
2354     SkScalerContext_GDI* ctx = SkNEW_ARGS(SkScalerContext_GDI,
2355                                                 (const_cast<LogFontTypeface*>(this), desc));
2356     if (!ctx->isValid()) {
2357         SkDELETE(ctx);
2358         ctx = NULL;
2359     }
2360     return ctx;
2361 }
2362
2363 void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
2364     if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
2365         rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
2366     {
2367         rec->fMaskFormat = SkMask::kA8_Format;
2368         rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag;
2369     }
2370
2371     unsigned flagsWeDontSupport = SkScalerContext::kVertical_Flag |
2372                                   SkScalerContext::kDevKernText_Flag |
2373                                   SkScalerContext::kForceAutohinting_Flag |
2374                                   SkScalerContext::kEmbeddedBitmapText_Flag |
2375                                   SkScalerContext::kEmbolden_Flag |
2376                                   SkScalerContext::kLCD_BGROrder_Flag |
2377                                   SkScalerContext::kLCD_Vertical_Flag;
2378     rec->fFlags &= ~flagsWeDontSupport;
2379
2380     SkPaint::Hinting h = rec->getHinting();
2381     switch (h) {
2382         case SkPaint::kNo_Hinting:
2383             break;
2384         case SkPaint::kSlight_Hinting:
2385             // Only do slight hinting when axis aligned.
2386             // TODO: re-enable slight hinting when FontHostTest can pass.
2387             //if (!isAxisAligned(*rec)) {
2388                 h = SkPaint::kNo_Hinting;
2389             //}
2390             break;
2391         case SkPaint::kNormal_Hinting:
2392         case SkPaint::kFull_Hinting:
2393             // TODO: need to be able to distinguish subpixel positioned glyphs
2394             // and linear metrics.
2395             //rec->fFlags &= ~SkScalerContext::kSubpixelPositioning_Flag;
2396             h = SkPaint::kNormal_Hinting;
2397             break;
2398         default:
2399             SkDEBUGFAIL("unknown hinting");
2400     }
2401     //TODO: if this is a bitmap font, squash hinting and subpixel.
2402     rec->setHinting(h);
2403
2404 // turn this off since GDI might turn A8 into BW! Need a bigger fix.
2405 #if 0
2406     // Disable LCD when rotated, since GDI's output is ugly
2407     if (isLCD(*rec) && !isAxisAligned(*rec)) {
2408         rec->fMaskFormat = SkMask::kA8_Format;
2409     }
2410 #endif
2411
2412     if (!fCanBeLCD && isLCD(*rec)) {
2413         rec->fMaskFormat = SkMask::kA8_Format;
2414         rec->fFlags &= ~SkScalerContext::kGenA8FromLCD_Flag;
2415     }
2416 }
2417
2418 ///////////////////////////////////////////////////////////////////////////////
2419
2420 #include "SkFontMgr.h"
2421 #include "SkDataTable.h"
2422
2423 static bool valid_logfont_for_enum(const LOGFONT& lf) {
2424     // TODO: Vector FON is unsupported and should not be listed.
2425     return
2426         // Ignore implicit vertical variants.
2427         lf.lfFaceName[0] && lf.lfFaceName[0] != '@'
2428
2429         // DEFAULT_CHARSET is used to get all fonts, but also implies all
2430         // character sets. Filter assuming all fonts support ANSI_CHARSET.
2431         && ANSI_CHARSET == lf.lfCharSet
2432     ;
2433 }
2434
2435 /** An EnumFontFamExProc implementation which interprets builderParam as
2436  *  an SkTDArray<ENUMLOGFONTEX>* and appends logfonts which
2437  *  pass the valid_logfont_for_enum predicate.
2438  */
2439 static int CALLBACK enum_family_proc(const LOGFONT* lf, const TEXTMETRIC*,
2440                                      DWORD fontType, LPARAM builderParam) {
2441     if (valid_logfont_for_enum(*lf)) {
2442         SkTDArray<ENUMLOGFONTEX>* array = (SkTDArray<ENUMLOGFONTEX>*)builderParam;
2443         *array->append() = *(ENUMLOGFONTEX*)lf;
2444     }
2445     return 1; // non-zero means continue
2446 }
2447
2448 class SkFontStyleSetGDI : public SkFontStyleSet {
2449 public:
2450     SkFontStyleSetGDI(const TCHAR familyName[]) {
2451         LOGFONT lf;
2452         sk_bzero(&lf, sizeof(lf));
2453         lf.lfCharSet = DEFAULT_CHARSET;
2454         _tcscpy_s(lf.lfFaceName, familyName);
2455
2456         HDC hdc = ::CreateCompatibleDC(NULL);
2457         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0);
2458         ::DeleteDC(hdc);
2459     }
2460
2461     virtual int count() SK_OVERRIDE {
2462         return fArray.count();
2463     }
2464
2465     virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OVERRIDE {
2466         if (fs) {
2467             *fs = get_style(fArray[index].elfLogFont);
2468         }
2469         if (styleName) {
2470             const ENUMLOGFONTEX& ref = fArray[index];
2471             // For some reason, ENUMLOGFONTEX and LOGFONT disagree on their type in the
2472             // non-unicode version.
2473             //      ENUMLOGFONTEX uses BYTE
2474             //      LOGFONT uses CHAR
2475             // Here we assert they that the style name is logically the same (size) as
2476             // a TCHAR, so we can use the same converter function.
2477             SkASSERT(sizeof(TCHAR) == sizeof(ref.elfStyle[0]));
2478             tchar_to_skstring((const TCHAR*)ref.elfStyle, styleName);
2479         }
2480     }
2481
2482     virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
2483         return SkCreateTypefaceFromLOGFONT(fArray[index].elfLogFont);
2484     }
2485
2486     virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE {
2487         // todo:
2488         return SkCreateTypefaceFromLOGFONT(fArray[0].elfLogFont);
2489     }
2490
2491 private:
2492     SkTDArray<ENUMLOGFONTEX> fArray;
2493 };
2494
2495 class SkFontMgrGDI : public SkFontMgr {
2496 public:
2497     SkFontMgrGDI() {
2498         LOGFONT lf;
2499         sk_bzero(&lf, sizeof(lf));
2500         lf.lfCharSet = DEFAULT_CHARSET;
2501
2502         HDC hdc = ::CreateCompatibleDC(NULL);
2503         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fLogFontArray, 0);
2504         ::DeleteDC(hdc);
2505     }
2506
2507 protected:
2508     virtual int onCountFamilies() const SK_OVERRIDE {
2509         return fLogFontArray.count();
2510     }
2511
2512     virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
2513         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
2514         tchar_to_skstring(fLogFontArray[index].elfLogFont.lfFaceName, familyName);
2515     }
2516
2517     virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE {
2518         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
2519         return SkNEW_ARGS(SkFontStyleSetGDI, (fLogFontArray[index].elfLogFont.lfFaceName));
2520     }
2521
2522     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
2523         if (NULL == familyName) {
2524             familyName = "";    // do we need this check???
2525         }
2526         LOGFONT lf;
2527         logfont_for_name(familyName, &lf);
2528         return SkNEW_ARGS(SkFontStyleSetGDI, (lf.lfFaceName));
2529     }
2530
2531     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
2532                                            const SkFontStyle& fontstyle) const SK_OVERRIDE {
2533         // could be in base impl
2534         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
2535         return sset->matchStyle(fontstyle);
2536     }
2537
2538     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
2539                                          const SkFontStyle& fontstyle) const SK_OVERRIDE {
2540         // could be in base impl
2541         SkString familyName;
2542         ((LogFontTypeface*)familyMember)->getFamilyName(&familyName);
2543         return this->matchFamilyStyle(familyName.c_str(), fontstyle);
2544     }
2545
2546     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
2547         return create_from_stream(stream);
2548     }
2549
2550     virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
2551         // could be in base impl
2552         SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
2553         return this->createFromStream(stream);
2554     }
2555
2556     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
2557         // could be in base impl
2558         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
2559         return this->createFromStream(stream);
2560     }
2561
2562     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
2563                                                unsigned styleBits) const SK_OVERRIDE {
2564         LOGFONT lf;
2565         if (NULL == familyName) {
2566             lf = get_default_font();
2567         } else {
2568             logfont_for_name(familyName, &lf);
2569         }
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);
2574         return SkCreateTypefaceFromLOGFONT(lf);
2575     }
2576
2577 private:
2578     SkTDArray<ENUMLOGFONTEX> fLogFontArray;
2579 };
2580
2581 ///////////////////////////////////////////////////////////////////////////////
2582
2583 SkFontMgr* SkFontMgr_New_GDI() {
2584     return SkNEW(SkFontMgrGDI);
2585 }