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