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