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