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