/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkTypes.h"
#if defined(SK_BUILD_FOR_WIN)

#include "include/core/SkData.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkPath.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/ports/SkTypeface_win.h"
#include "include/private/SkColorData.h"
#include "include/private/SkMacros.h"
#include "include/private/SkOnce.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkTo.h"
#include "include/utils/SkBase64.h"
#include "src/core/SkAdvancedTypefaceMetrics.h"
#include "src/core/SkDescriptor.h"
#include "src/core/SkFontDescriptor.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkLeanWindows.h"
#include "src/core/SkMakeUnique.h"
#include "src/core/SkMaskGamma.h"
#include "src/core/SkTypefaceCache.h"
#include "src/core/SkUtils.h"
#include "src/sfnt/SkOTTable_OS_2.h"
#include "src/sfnt/SkOTTable_maxp.h"
#include "src/sfnt/SkOTTable_name.h"
#include "src/sfnt/SkOTUtils.h"
#include "src/sfnt/SkSFNTHeader.h"
#include "src/utils/SkMatrix22.h"
#include "src/utils/win/SkHRESULT.h"

#include <tchar.h>
#include <usp10.h>
#include <objbase.h>

static void (*gEnsureLOGFONTAccessibleProc)(const LOGFONT&);

void SkTypeface_SetEnsureLOGFONTAccessibleProc(void (*proc)(const LOGFONT&)) {
    gEnsureLOGFONTAccessibleProc = proc;
}

static void call_ensure_accessible(const LOGFONT& lf) {
    if (gEnsureLOGFONTAccessibleProc) {
        gEnsureLOGFONTAccessibleProc(lf);
    }
}

///////////////////////////////////////////////////////////////////////////////

// always packed xxRRGGBB
typedef uint32_t SkGdiRGB;

// define this in your Makefile or .gyp to enforce AA requests
// which GDI ignores at small sizes. This flag guarantees AA
// for rotated text, regardless of GDI's notions.
//#define SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS

static bool isLCD(const SkScalerContextRec& rec) {
    return SkMask::kLCD16_Format == rec.fMaskFormat;
}

static bool bothZero(SkScalar a, SkScalar b) {
    return 0 == a && 0 == b;
}

// returns false if there is any non-90-rotation or skew
static bool isAxisAligned(const SkScalerContextRec& rec) {
    return 0 == rec.fPreSkewX &&
           (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
            bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
}

static bool needToRenderWithSkia(const SkScalerContextRec& rec) {
#ifdef SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS
    // What we really want to catch is when GDI will ignore the AA request and give
    // us BW instead. Smallish rotated text is one heuristic, so this code is just
    // an approximation. We shouldn't need to do this for larger sizes, but at those
    // sizes, the quality difference gets less and less between our general
    // scanconverter and GDI's.
    if (SkMask::kA8_Format == rec.fMaskFormat && !isAxisAligned(rec)) {
        return true;
    }
#endif
    return rec.getHinting() == SkFontHinting::kNone || rec.getHinting() == SkFontHinting::kSlight;
}

static void tchar_to_skstring(const TCHAR t[], SkString* s) {
#ifdef UNICODE
    size_t sSize = WideCharToMultiByte(CP_UTF8, 0, t, -1, nullptr, 0, nullptr, nullptr);
    s->resize(sSize);
    WideCharToMultiByte(CP_UTF8, 0, t, -1, s->writable_str(), sSize, nullptr, nullptr);
#else
    s->set(t);
#endif
}

static void dcfontname_to_skstring(HDC deviceContext, const LOGFONT& lf, SkString* familyName) {
    int fontNameLen; //length of fontName in TCHARS.
    if (0 == (fontNameLen = GetTextFace(deviceContext, 0, nullptr))) {
        call_ensure_accessible(lf);
        if (0 == (fontNameLen = GetTextFace(deviceContext, 0, nullptr))) {
            fontNameLen = 0;
        }
    }

    SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1);
    if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
        call_ensure_accessible(lf);
        if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
            fontName[0] = 0;
        }
    }

    tchar_to_skstring(fontName.get(), familyName);
}

static void make_canonical(LOGFONT* lf) {
    lf->lfHeight = -64;
    lf->lfWidth = 0;  // lfWidth is related to lfHeight, not to the OS/2::usWidthClass.
    lf->lfQuality = CLEARTYPE_QUALITY;//PROOF_QUALITY;
    lf->lfCharSet = DEFAULT_CHARSET;
//    lf->lfClipPrecision = 64;
}

static SkFontStyle get_style(const LOGFONT& lf) {
    return SkFontStyle(lf.lfWeight,
                       SkFontStyle::kNormal_Width,
                       lf.lfItalic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant);
}

static inline FIXED SkFixedToFIXED(SkFixed x) {
    return *(FIXED*)(&x);
}
static inline SkFixed SkFIXEDToFixed(FIXED x) {
    return *(SkFixed*)(&x);
}

static inline FIXED SkScalarToFIXED(SkScalar x) {
    return SkFixedToFIXED(SkScalarToFixed(x));
}

static inline SkScalar SkFIXEDToScalar(FIXED x) {
    return SkFixedToScalar(SkFIXEDToFixed(x));
}

static unsigned calculateGlyphCount(HDC hdc, const LOGFONT& lf) {
    TEXTMETRIC textMetric;
    if (0 == GetTextMetrics(hdc, &textMetric)) {
        textMetric.tmPitchAndFamily = TMPF_VECTOR;
        call_ensure_accessible(lf);
        GetTextMetrics(hdc, &textMetric);
    }

    if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
        return textMetric.tmLastChar;
    }

    // The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes.
    uint16_t glyphs;
    if (GDI_ERROR != GetFontData(hdc, SkOTTableMaximumProfile::TAG, 4, &glyphs, sizeof(glyphs))) {
        return SkEndian_SwapBE16(glyphs);
    }

    // Binary search for glyph count.
    static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
    int32_t max = UINT16_MAX + 1;
    int32_t min = 0;
    GLYPHMETRICS gm;
    while (min < max) {
        int32_t mid = min + ((max - min) / 2);
        if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0,
                             nullptr, &mat2) == GDI_ERROR) {
            max = mid;
        } else {
            min = mid + 1;
        }
    }
    SkASSERT(min == max);
    return min;
}

static unsigned calculateUPEM(HDC hdc, const LOGFONT& lf) {
    TEXTMETRIC textMetric;
    if (0 == GetTextMetrics(hdc, &textMetric)) {
        textMetric.tmPitchAndFamily = TMPF_VECTOR;
        call_ensure_accessible(lf);
        GetTextMetrics(hdc, &textMetric);
    }

    if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
        return textMetric.tmMaxCharWidth;
    }

    OUTLINETEXTMETRIC otm;
    unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
    if (0 == otmRet) {
        call_ensure_accessible(lf);
        otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
    }

    return (0 == otmRet) ? 0 : otm.otmEMSquare;
}

class LogFontTypeface : public SkTypeface {
public:
    LogFontTypeface(const SkFontStyle& style, const LOGFONT& lf, bool serializeAsStream)
        : SkTypeface(style, false)
        , fLogFont(lf)
        , fSerializeAsStream(serializeAsStream)
    {
        HFONT font = CreateFontIndirect(&lf);

        HDC deviceContext = ::CreateCompatibleDC(nullptr);
        HFONT savefont = (HFONT)SelectObject(deviceContext, font);

        TEXTMETRIC textMetric;
        if (0 == GetTextMetrics(deviceContext, &textMetric)) {
            call_ensure_accessible(lf);
            if (0 == GetTextMetrics(deviceContext, &textMetric)) {
                textMetric.tmPitchAndFamily = TMPF_TRUETYPE;
            }
        }
        if (deviceContext) {
            ::SelectObject(deviceContext, savefont);
            ::DeleteDC(deviceContext);
        }
        if (font) {
            ::DeleteObject(font);
        }

        // The fixed pitch bit is set if the font is *not* fixed pitch.
        this->setIsFixedPitch((textMetric.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0);
        this->setFontStyle(SkFontStyle(textMetric.tmWeight, style.width(), style.slant()));

        // Used a logfont on a memory context, should never get a device font.
        // Therefore all TMPF_DEVICE will be PostScript (cubic) fonts.
        // If the font has cubic outlines, it will not be rendered with ClearType.
        fCanBeLCD = !((textMetric.tmPitchAndFamily & TMPF_VECTOR) &&
                      (textMetric.tmPitchAndFamily & TMPF_DEVICE));
    }

    LOGFONT fLogFont;
    bool fSerializeAsStream;
    bool fCanBeLCD;

    static sk_sp<LogFontTypeface> Make(const LOGFONT& lf) {
        return sk_sp<LogFontTypeface>(new LogFontTypeface(get_style(lf), lf, false));
    }

    static void EnsureAccessible(const SkTypeface* face) {
        call_ensure_accessible(static_cast<const LogFontTypeface*>(face)->fLogFont);
    }

protected:
    std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
    sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override;
    SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
                                           const SkDescriptor*) const override;
    void onFilterRec(SkScalerContextRec*) const override;
    void getGlyphToUnicodeMap(SkUnichar*) const override;
    std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
    void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
    void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
    int onCountGlyphs() const override;
    void getPostScriptGlyphNames(SkString*) const override;
    int onGetUPEM() const override;
    void onGetFamilyName(SkString* familyName) const override;
    SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
    int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
                                     int coordinateCount) const override
    {
        return -1;
    }
    int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
                                       int parameterCount) const override
    {
        return -1;
    }
    int onGetTableTags(SkFontTableTag tags[]) const override;
    size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override;
};

class FontMemResourceTypeface : public LogFontTypeface {
public:
    /**
     *  The created FontMemResourceTypeface takes ownership of fontMemResource.
     */
    static sk_sp<FontMemResourceTypeface> Make(const LOGFONT& lf, HANDLE fontMemResource) {
        return sk_sp<FontMemResourceTypeface>(
            new FontMemResourceTypeface(get_style(lf), lf, fontMemResource));
    }

protected:
    void weak_dispose() const override {
        RemoveFontMemResourceEx(fFontMemResource);
        //SkTypefaceCache::Remove(this);
        INHERITED::weak_dispose();
    }

private:
    /**
     *  Takes ownership of fontMemResource.
     */
    FontMemResourceTypeface(const SkFontStyle& style, const LOGFONT& lf, HANDLE fontMemResource)
        : LogFontTypeface(style, lf, true), fFontMemResource(fontMemResource)
    { }

    HANDLE fFontMemResource;

    typedef LogFontTypeface INHERITED;
};

static const LOGFONT& get_default_font() {
    static LOGFONT gDefaultFont;
    return gDefaultFont;
}

static bool FindByLogFont(SkTypeface* face, void* ctx) {
    LogFontTypeface* lface = static_cast<LogFontTypeface*>(face);
    const LOGFONT* lf = reinterpret_cast<const LOGFONT*>(ctx);

    return !memcmp(&lface->fLogFont, lf, sizeof(LOGFONT));
}

/**
 *  This guy is public. It first searches the cache, and if a match is not found,
 *  it creates a new face.
 */
SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) {
    LOGFONT lf = origLF;
    make_canonical(&lf);
    sk_sp<SkTypeface> face = SkTypefaceCache::FindByProcAndRef(FindByLogFont, &lf);
    if (!face) {
        face = LogFontTypeface::Make(lf);
        SkTypefaceCache::Add(face);
    }
    return face.release();
}

/**
 *  The created SkTypeface takes ownership of fontMemResource.
 */
sk_sp<SkTypeface> SkCreateFontMemResourceTypefaceFromLOGFONT(const LOGFONT& origLF, HANDLE fontMemResource) {
    LOGFONT lf = origLF;
    make_canonical(&lf);
    // We'll never get a cache hit, so no point in putting this in SkTypefaceCache.
    return FontMemResourceTypeface::Make(lf, fontMemResource);
}

/**
 *  This guy is public
 */
void SkLOGFONTFromTypeface(const SkTypeface* face, LOGFONT* lf) {
    if (nullptr == face) {
        *lf = get_default_font();
    } else {
        *lf = static_cast<const LogFontTypeface*>(face)->fLogFont;
    }
}

// Construct Glyph to Unicode table.
// Unicode code points that require conjugate pairs in utf16 are not
// supported.
// TODO(arthurhsu): Add support for conjugate pairs. It looks like that may
// require parsing the TTF cmap table (platform 4, encoding 12) directly instead
// of calling GetFontUnicodeRange().
static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount,
                                      SkUnichar* glyphToUnicode) {
    sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount);
    DWORD glyphSetBufferSize = GetFontUnicodeRanges(fontHdc, nullptr);
    if (!glyphSetBufferSize) {
        return;
    }

    std::unique_ptr<BYTE[]> glyphSetBuffer(new BYTE[glyphSetBufferSize]);
    GLYPHSET* glyphSet =
        reinterpret_cast<LPGLYPHSET>(glyphSetBuffer.get());
    if (GetFontUnicodeRanges(fontHdc, glyphSet) != glyphSetBufferSize) {
        return;
    }

    for (DWORD i = 0; i < glyphSet->cRanges; ++i) {
        // There is no guarantee that within a Unicode range, the corresponding
        // glyph id in a font file are continuous. So, even if we have ranges,
        // we can't just use the first and last entry of the range to compute
        // result. We need to enumerate them one by one.
        int count = glyphSet->ranges[i].cGlyphs;
        SkAutoTArray<WCHAR> chars(count + 1);
        chars[count] = 0;  // termintate string
        SkAutoTArray<WORD> glyph(count);
        for (USHORT j = 0; j < count; ++j) {
            chars[j] = glyphSet->ranges[i].wcLow + j;
        }
        GetGlyphIndicesW(fontHdc, chars.get(), count, glyph.get(),
                         GGI_MARK_NONEXISTING_GLYPHS);
        // If the glyph ID is valid, and the glyph is not mapped, then we will
        // fill in the char id into the vector. If the glyph is mapped already,
        // skip it.
        // TODO(arthurhsu): better improve this. e.g. Get all used char ids from
        // font cache, then generate this mapping table from there. It's
        // unlikely to have collisions since glyph reuse happens mostly for
        // different Unicode pages.
        for (USHORT j = 0; j < count; ++j) {
            if (glyph[j] != 0xFFFF && glyph[j] < glyphCount && glyphToUnicode[glyph[j]] == 0) {
                glyphToUnicode[glyph[j]] = chars[j];
            }
        }
    }
}

//////////////////////////////////////////////////////////////////////////////////////

static int alignTo32(int n) {
    return (n + 31) & ~31;
}

struct MyBitmapInfo : public BITMAPINFO {
    RGBQUAD fMoreSpaceForColors[1];
};

class HDCOffscreen {
public:
    HDCOffscreen() {
        fFont = 0;
        fDC = 0;
        fBM = 0;
        fBits = nullptr;
        fWidth = fHeight = 0;
        fIsBW = false;
    }

    ~HDCOffscreen() {
        if (fDC) {
            DeleteDC(fDC);
        }
        if (fBM) {
            DeleteObject(fBM);
        }
    }

    void init(HFONT font, const XFORM& xform) {
        fFont = font;
        fXform = xform;
    }

    const void* draw(const SkGlyph&, bool isBW, size_t* srcRBPtr);

private:
    HDC     fDC;
    HBITMAP fBM;
    HFONT   fFont;
    XFORM   fXform;
    void*   fBits;  // points into fBM
    int     fWidth;
    int     fHeight;
    bool    fIsBW;
};

const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
                               size_t* srcRBPtr) {
    // Can we share the scalercontext's fDDC, so we don't need to create
    // a separate fDC here?
    if (0 == fDC) {
        fDC = CreateCompatibleDC(0);
        if (0 == fDC) {
            return nullptr;
        }
        SetGraphicsMode(fDC, GM_ADVANCED);
        SetBkMode(fDC, TRANSPARENT);
        SetTextAlign(fDC, TA_LEFT | TA_BASELINE);
        SelectObject(fDC, fFont);

        COLORREF color = 0x00FFFFFF;
        SkDEBUGCODE(COLORREF prev =) SetTextColor(fDC, color);
        SkASSERT(prev != CLR_INVALID);
    }

    if (fBM && (fIsBW != isBW || fWidth < glyph.fWidth || fHeight < glyph.fHeight)) {
        DeleteObject(fBM);
        fBM = 0;
    }
    fIsBW = isBW;

    fWidth = SkMax32(fWidth, glyph.fWidth);
    fHeight = SkMax32(fHeight, glyph.fHeight);

    int biWidth = isBW ? alignTo32(fWidth) : fWidth;

    if (0 == fBM) {
        MyBitmapInfo info;
        sk_bzero(&info, sizeof(info));
        if (isBW) {
            RGBQUAD blackQuad = { 0, 0, 0, 0 };
            RGBQUAD whiteQuad = { 0xFF, 0xFF, 0xFF, 0 };
            info.bmiColors[0] = blackQuad;
            info.bmiColors[1] = whiteQuad;
        }
        info.bmiHeader.biSize = sizeof(info.bmiHeader);
        info.bmiHeader.biWidth = biWidth;
        info.bmiHeader.biHeight = fHeight;
        info.bmiHeader.biPlanes = 1;
        info.bmiHeader.biBitCount = isBW ? 1 : 32;
        info.bmiHeader.biCompression = BI_RGB;
        if (isBW) {
            info.bmiHeader.biClrUsed = 2;
        }
        fBM = CreateDIBSection(fDC, &info, DIB_RGB_COLORS, &fBits, 0, 0);
        if (0 == fBM) {
            return nullptr;
        }
        SelectObject(fDC, fBM);
    }

    // erase
    size_t srcRB = isBW ? (biWidth >> 3) : (fWidth << 2);
    size_t size = fHeight * srcRB;
    memset(fBits, 0, size);

    XFORM xform = fXform;
    xform.eDx = (float)-glyph.fLeft;
    xform.eDy = (float)-glyph.fTop;
    SetWorldTransform(fDC, &xform);

    uint16_t glyphID = glyph.getGlyphID();
    BOOL ret = ExtTextOutW(fDC, 0, 0, ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>(&glyphID), 1, nullptr);
    GdiFlush();
    if (0 == ret) {
        return nullptr;
    }
    *srcRBPtr = srcRB;
    // offset to the start of the image
    return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB;
}

//////////////////////////////////////////////////////////////////////////////
#define BUFFERSIZE (1 << 13)

class SkScalerContext_GDI : public SkScalerContext {
public:
    SkScalerContext_GDI(sk_sp<LogFontTypeface>,
                        const SkScalerContextEffects&,
                        const SkDescriptor* desc);
    ~SkScalerContext_GDI() override;

    // Returns true if the constructor was able to complete all of its
    // initializations (which may include calling GDI).
    bool isValid() const;

protected:
    unsigned generateGlyphCount() override;
    bool generateAdvance(SkGlyph* glyph) override;
    void generateMetrics(SkGlyph* glyph) override;
    void generateImage(const SkGlyph& glyph) override;
    bool generatePath(SkGlyphID glyph, SkPath* path) override;
    void generateFontMetrics(SkFontMetrics*) override;

private:
    DWORD getGDIGlyphPath(SkGlyphID glyph, UINT flags,
                          SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf);

    HDCOffscreen fOffscreen;
    /** fGsA is the non-rotational part of total matrix without the text height scale.
     *  Used to find the magnitude of advances.
     */
    MAT2         fGsA;
    /** The total matrix without the textSize. */
    MAT2         fMat22;
    /** Scales font to EM size. */
    MAT2         fHighResMat22;
    HDC          fDDC;
    HFONT        fSavefont;
    HFONT        fFont;
    SCRIPT_CACHE fSC;
    int          fGlyphCount;

    /** The total matrix which also removes EM scale. */
    SkMatrix     fHiResMatrix;
    /** fG_inv is the inverse of the rotational part of the total matrix.
     *  Used to set the direction of advances.
     */
    SkMatrix     fG_inv;
    enum Type {
        kTrueType_Type, kBitmap_Type, kLine_Type
    } fType;
    TEXTMETRIC fTM;
};

static FIXED float2FIXED(float x) {
    return SkFixedToFIXED(SkFloatToFixed(x));
}

static inline float FIXED2float(FIXED x) {
    return SkFixedToFloat(SkFIXEDToFixed(x));
}

static BYTE compute_quality(const SkScalerContextRec& rec) {
    switch (rec.fMaskFormat) {
        case SkMask::kBW_Format:
            return NONANTIALIASED_QUALITY;
        case SkMask::kLCD16_Format:
            return CLEARTYPE_QUALITY;
        default:
            if (rec.fFlags & SkScalerContext::kGenA8FromLCD_Flag) {
                return CLEARTYPE_QUALITY;
            } else {
                return ANTIALIASED_QUALITY;
            }
    }
}

SkScalerContext_GDI::SkScalerContext_GDI(sk_sp<LogFontTypeface> rawTypeface,
                                         const SkScalerContextEffects& effects,
                                         const SkDescriptor* desc)
        : SkScalerContext(std::move(rawTypeface), effects, desc)
        , fDDC(0)
        , fSavefont(0)
        , fFont(0)
        , fSC(0)
        , fGlyphCount(-1)
{
    LogFontTypeface* typeface = static_cast<LogFontTypeface*>(this->getTypeface());

    fDDC = ::CreateCompatibleDC(nullptr);
    if (!fDDC) {
        return;
    }
    SetGraphicsMode(fDDC, GM_ADVANCED);
    SetBkMode(fDDC, TRANSPARENT);

    // When GDI hinting, remove the entire Y scale from sA and GsA. (Prevents 'linear' metrics.)
    // When not hinting, remove only the integer Y scale from sA and GsA. (Applied by GDI.)
    SkScalerContextRec::PreMatrixScale scaleConstraints =
        (fRec.getHinting() == SkFontHinting::kNone || fRec.getHinting() == SkFontHinting::kSlight)
                   ? SkScalerContextRec::kVerticalInteger_PreMatrixScale
                   : SkScalerContextRec::kVertical_PreMatrixScale;
    SkVector scale;
    SkMatrix sA;
    SkMatrix GsA;
    SkMatrix A;
    fRec.computeMatrices(scaleConstraints, &scale, &sA, &GsA, &fG_inv, &A);

    fGsA.eM11 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleX));
    fGsA.eM12 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewY)); // This should be ~0.
    fGsA.eM21 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewX));
    fGsA.eM22 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleY));

    // When not hinting, scale was computed with kVerticalInteger, so is already an integer.
    // The sA and GsA transforms will be used to create 'linear' metrics.

    // When hinting, scale was computed with kVertical, stating that our port can handle
    // non-integer scales. This is done so that sA and GsA are computed without any 'residual'
    // scale in them, preventing 'linear' metrics. However, GDI cannot actually handle non-integer
    // scales so we need to round in this case. This is fine, since all of the scale has been
    // removed from sA and GsA, so GDI will be handling the scale completely.
    SkScalar gdiTextSize = SkScalarRoundToScalar(scale.fY);

    // GDI will not accept a size of zero, so round the range [0, 1] to 1.
    // If the size was non-zero, the scale factors will also be non-zero and 1px tall text is drawn.
    // If the size actually was zero, the scale factors will also be zero, so GDI will draw nothing.
    if (gdiTextSize == 0) {
        gdiTextSize = SK_Scalar1;
    }

    LOGFONT lf = typeface->fLogFont;
    lf.lfHeight = -SkScalarTruncToInt(gdiTextSize);
    lf.lfQuality = compute_quality(fRec);
    fFont = CreateFontIndirect(&lf);
    if (!fFont) {
        return;
    }

    fSavefont = (HFONT)SelectObject(fDDC, fFont);

    if (0 == GetTextMetrics(fDDC, &fTM)) {
        call_ensure_accessible(lf);
        if (0 == GetTextMetrics(fDDC, &fTM)) {
            fTM.tmPitchAndFamily = TMPF_TRUETYPE;
        }
    }

    XFORM xform;
    if (fTM.tmPitchAndFamily & TMPF_VECTOR) {
        // Used a logfont on a memory context, should never get a device font.
        // Therefore all TMPF_DEVICE will be PostScript fonts.

        // If TMPF_VECTOR is set, one of TMPF_TRUETYPE or TMPF_DEVICE means that
        // we have an outline font. Otherwise we have a vector FON, which is
        // scalable, but not an outline font.
        // This was determined by testing with Type1 PFM/PFB and
        // OpenTypeCFF OTF, as well as looking at Wine bugs and sources.
        if (fTM.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_DEVICE)) {
            // Truetype or PostScript.
            fType = SkScalerContext_GDI::kTrueType_Type;
        } else {
            // Stroked FON.
            fType = SkScalerContext_GDI::kLine_Type;
        }

        // fPost2x2 is column-major, left handed (y down).
        // XFORM 2x2 is row-major, left handed (y down).
        xform.eM11 = SkScalarToFloat(sA.get(SkMatrix::kMScaleX));
        xform.eM12 = SkScalarToFloat(sA.get(SkMatrix::kMSkewY));
        xform.eM21 = SkScalarToFloat(sA.get(SkMatrix::kMSkewX));
        xform.eM22 = SkScalarToFloat(sA.get(SkMatrix::kMScaleY));
        xform.eDx = 0;
        xform.eDy = 0;

        // MAT2 is row major, right handed (y up).
        fMat22.eM11 = float2FIXED(xform.eM11);
        fMat22.eM12 = float2FIXED(-xform.eM12);
        fMat22.eM21 = float2FIXED(-xform.eM21);
        fMat22.eM22 = float2FIXED(xform.eM22);

        if (needToRenderWithSkia(fRec)) {
            this->forceGenerateImageFromPath();
        }

        // Create a hires matrix if we need linear metrics.
        if (this->isLinearMetrics()) {
            OUTLINETEXTMETRIC otm;
            UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
            if (0 == success) {
                call_ensure_accessible(lf);
                success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
            }
            if (0 != success) {
                SkScalar upem = SkIntToScalar(otm.otmEMSquare);

                SkScalar gdiTextSizeToEMScale = upem / gdiTextSize;
                fHighResMat22.eM11 = float2FIXED(gdiTextSizeToEMScale);
                fHighResMat22.eM12 = float2FIXED(0);
                fHighResMat22.eM21 = float2FIXED(0);
                fHighResMat22.eM22 = float2FIXED(gdiTextSizeToEMScale);

                SkScalar removeEMScale = SkScalarInvert(upem);
                fHiResMatrix = A;
                fHiResMatrix.preScale(removeEMScale, removeEMScale);
            }
        }

    } else {
        // Assume bitmap
        fType = SkScalerContext_GDI::kBitmap_Type;

        xform.eM11 = 1.0f;
        xform.eM12 = 0.0f;
        xform.eM21 = 0.0f;
        xform.eM22 = 1.0f;
        xform.eDx = 0.0f;
        xform.eDy = 0.0f;

        // fPost2x2 is column-major, left handed (y down).
        // MAT2 is row major, right handed (y up).
        fMat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]);
        fMat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[1][0]);
        fMat22.eM21 = SkScalarToFIXED(-fRec.fPost2x2[0][1]);
        fMat22.eM22 = SkScalarToFIXED(fRec.fPost2x2[1][1]);
    }

    fOffscreen.init(fFont, xform);
}

SkScalerContext_GDI::~SkScalerContext_GDI() {
    if (fDDC) {
        ::SelectObject(fDDC, fSavefont);
        ::DeleteDC(fDDC);
    }
    if (fFont) {
        ::DeleteObject(fFont);
    }
    if (fSC) {
        ::ScriptFreeCache(&fSC);
    }
}

bool SkScalerContext_GDI::isValid() const {
    return fDDC && fFont;
}

unsigned SkScalerContext_GDI::generateGlyphCount() {
    if (fGlyphCount < 0) {
        fGlyphCount = calculateGlyphCount(
                          fDDC, static_cast<const LogFontTypeface*>(this->getTypeface())->fLogFont);
    }
    return fGlyphCount;
}

bool SkScalerContext_GDI::generateAdvance(SkGlyph* glyph) {
    return false;
}

void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
    SkASSERT(fDDC);

    glyph->fMaskFormat = fRec.fMaskFormat;

    if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
        SIZE size;
        WORD glyphs = glyph->getGlyphID();
        if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) {
            glyph->fWidth = SkToS16(fTM.tmMaxCharWidth);
        } else {
            glyph->fWidth = SkToS16(size.cx);
        }
        glyph->fHeight = SkToS16(size.cy);

        glyph->fTop = SkToS16(-fTM.tmAscent);
        // Bitmap FON cannot underhang, but vector FON may.
        // There appears no means of determining underhang of vector FON.
        glyph->fLeft = SkToS16(0);
        glyph->fAdvanceX = glyph->fWidth;
        glyph->fAdvanceY = 0;

        // Vector FON will transform nicely, but bitmap FON do not.
        if (fType == SkScalerContext_GDI::kLine_Type) {
            SkRect bounds = SkRect::MakeXYWH(glyph->fLeft, glyph->fTop,
                                             glyph->fWidth, glyph->fHeight);
            SkMatrix m;
            m.setAll(SkFIXEDToScalar(fMat22.eM11), -SkFIXEDToScalar(fMat22.eM21), 0,
                     -SkFIXEDToScalar(fMat22.eM12), SkFIXEDToScalar(fMat22.eM22), 0,
                     0,  0, 1);
            m.mapRect(&bounds);
            bounds.roundOut(&bounds);
            glyph->fLeft = SkScalarTruncToInt(bounds.fLeft);
            glyph->fTop = SkScalarTruncToInt(bounds.fTop);
            glyph->fWidth = SkScalarTruncToInt(bounds.width());
            glyph->fHeight = SkScalarTruncToInt(bounds.height());
        }

        // Apply matrix to advance.
        glyph->fAdvanceY = -FIXED2float(fMat22.eM12) * glyph->fAdvanceX;
        glyph->fAdvanceX *= FIXED2float(fMat22.eM11);

        return;
    }

    UINT glyphId = glyph->getGlyphID();

    GLYPHMETRICS gm;
    sk_bzero(&gm, sizeof(gm));

    DWORD status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, nullptr, &fMat22);
    if (GDI_ERROR == status) {
        LogFontTypeface::EnsureAccessible(this->getTypeface());
        status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, nullptr, &fMat22);
        if (GDI_ERROR == status) {
            glyph->zeroMetrics();
            return;
        }
    }

    bool empty = false;
    // The black box is either the embedded bitmap size or the outline extent.
    // It is 1x1 if nothing is to be drawn, but will also be 1x1 if something very small
    // is to be drawn, like a '.'. We need to outset '.' but do not wish to outset ' '.
    if (1 == gm.gmBlackBoxX && 1 == gm.gmBlackBoxY) {
        // If GetGlyphOutline with GGO_NATIVE returns 0, we know there was no outline.
        DWORD bufferSize = GetGlyphOutlineW(fDDC, glyphId, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, 0, nullptr, &fMat22);
        empty = (0 == bufferSize);
    }

    glyph->fTop = SkToS16(-gm.gmptGlyphOrigin.y);
    glyph->fLeft = SkToS16(gm.gmptGlyphOrigin.x);
    if (empty) {
        glyph->fWidth = 0;
        glyph->fHeight = 0;
    } else {
        // Outset, since the image may bleed out of the black box.
        // For embedded bitmaps the black box should be exact.
        // For outlines we need to outset by 1 in all directions for bleed.
        // For ClearType we need to outset by 2 for bleed.
        glyph->fWidth = gm.gmBlackBoxX + 4;
        glyph->fHeight = gm.gmBlackBoxY + 4;
        glyph->fTop -= 2;
        glyph->fLeft -= 2;
    }
    // TODO(benjaminwagner): What is the type of gm.gmCellInc[XY]?
    glyph->fAdvanceX = (float)((int)gm.gmCellIncX);
    glyph->fAdvanceY = (float)((int)gm.gmCellIncY);

    if ((fTM.tmPitchAndFamily & TMPF_VECTOR) && this->isLinearMetrics()) {
        sk_bzero(&gm, sizeof(gm));
        status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, nullptr, &fHighResMat22);
        if (GDI_ERROR != status) {
            SkPoint advance;
            fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIncY), &advance);
            glyph->fAdvanceX = SkScalarToFloat(advance.fX);
            glyph->fAdvanceY = SkScalarToFloat(advance.fY);
        }
    } else if (!isAxisAligned(this->fRec)) {
        status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, nullptr, &fGsA);
        if (GDI_ERROR != status) {
            SkPoint advance;
            fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIncY), &advance);
            glyph->fAdvanceX = SkScalarToFloat(advance.fX);
            glyph->fAdvanceY = SkScalarToFloat(advance.fY);
        }
    }
}

static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
void SkScalerContext_GDI::generateFontMetrics(SkFontMetrics* metrics) {
    if (nullptr == metrics) {
        return;
    }
    sk_bzero(metrics, sizeof(*metrics));

    SkASSERT(fDDC);

#ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
    if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
#endif
        metrics->fTop = SkIntToScalar(-fTM.tmAscent);
        metrics->fAscent = SkIntToScalar(-fTM.tmAscent);
        metrics->fDescent = SkIntToScalar(fTM.tmDescent);
        metrics->fBottom = SkIntToScalar(fTM.tmDescent);
        metrics->fLeading = SkIntToScalar(fTM.tmExternalLeading);
        metrics->fAvgCharWidth = SkIntToScalar(fTM.tmAveCharWidth);
        metrics->fMaxCharWidth = SkIntToScalar(fTM.tmMaxCharWidth);
        metrics->fXMin = 0;
        metrics->fXMax = metrics->fMaxCharWidth;
        //metrics->fXHeight = 0;
#ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
        return;
    }
#endif

    OUTLINETEXTMETRIC otm;

    uint32_t ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
    if (0 == ret) {
        LogFontTypeface::EnsureAccessible(this->getTypeface());
        ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
    }
    if (0 == ret) {
        return;
    }

#ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
    metrics->fTop = SkIntToScalar(-otm.otmrcFontBox.top);
    metrics->fAscent = SkIntToScalar(-otm.otmAscent);
    metrics->fDescent = SkIntToScalar(-otm.otmDescent);
    metrics->fBottom = SkIntToScalar(-otm.otmrcFontBox.bottom);
    metrics->fLeading = SkIntToScalar(otm.otmLineGap);
    metrics->fAvgCharWidth = SkIntToScalar(otm.otmTextMetrics.tmAveCharWidth);
    metrics->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth);
    metrics->fXMin = SkIntToScalar(otm.otmrcFontBox.left);
    metrics->fXMax = SkIntToScalar(otm.otmrcFontBox.right);
#endif
    metrics->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
    metrics->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);

    metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
    metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;

    metrics->fXHeight = SkIntToScalar(otm.otmsXHeight);
    GLYPHMETRICS gm;
    sk_bzero(&gm, sizeof(gm));
    DWORD len = GetGlyphOutlineW(fDDC, 'x', GGO_METRICS, &gm, 0, 0, &gMat2Identity);
    if (len != GDI_ERROR && gm.gmBlackBoxY > 0) {
        metrics->fXHeight = SkIntToScalar(gm.gmBlackBoxY);
    }
}

////////////////////////////////////////////////////////////////////////////////////////

#define SK_SHOW_TEXT_BLIT_COVERAGE 0

static void build_power_table(uint8_t table[], float ee) {
    for (int i = 0; i < 256; i++) {
        float x = i / 255.f;
        x = sk_float_pow(x, ee);
        int xx = SkScalarRoundToInt(x * 255);
        table[i] = SkToU8(xx);
    }
}

/**
 *  This will invert the gamma applied by GDI (gray-scale antialiased), so we
 *  can get linear values.
 *
 *  GDI grayscale appears to use a hard-coded gamma of 2.3.
 *
 *  GDI grayscale appears to draw using the black and white rasterizer at four
 *  times the size and then downsamples to compute the coverage mask. As a
 *  result there are only seventeen total grays. This lack of fidelity means
 *  that shifting into other color spaces is imprecise.
 */
static const uint8_t* getInverseGammaTableGDI() {
    static SkOnce once;
    static uint8_t gTableGdi[256];
    once([]{
        build_power_table(gTableGdi, 2.3f);
    });
    return gTableGdi;
}

/**
 *  This will invert the gamma applied by GDI ClearType, so we can get linear
 *  values.
 *
 *  GDI ClearType uses SPI_GETFONTSMOOTHINGCONTRAST / 1000 as the gamma value.
 *  If this value is not specified, the default is a gamma of 1.4.
 */
static const uint8_t* getInverseGammaTableClearType() {
    static SkOnce once;
    static uint8_t gTableClearType[256];
    once([]{
        UINT level = 0;
        if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &level, 0) || !level) {
            // can't get the data, so use a default
            level = 1400;
        }
        build_power_table(gTableClearType, level / 1000.0f);
    });
    return gTableClearType;
}

#include "include/private/SkColorData.h"

//Cannot assume that the input rgb is gray due to possible setting of kGenA8FromLCD_Flag.
template<bool APPLY_PREBLEND>
static inline uint8_t rgb_to_a8(SkGdiRGB rgb, const uint8_t* table8) {
    U8CPU r = (rgb >> 16) & 0xFF;
    U8CPU g = (rgb >>  8) & 0xFF;
    U8CPU b = (rgb >>  0) & 0xFF;
    return sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), table8);
}

template<bool APPLY_PREBLEND>
static inline uint16_t rgb_to_lcd16(SkGdiRGB rgb, const uint8_t* tableR,
                                                  const uint8_t* tableG,
                                                  const uint8_t* tableB) {
    U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR);
    U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  8) & 0xFF, tableG);
    U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  0) & 0xFF, tableB);
#if SK_SHOW_TEXT_BLIT_COVERAGE
    r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
#endif
    return SkPack888ToRGB16(r, g, b);
}

template<bool APPLY_PREBLEND>
static void rgb_to_a8(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
                      const SkGlyph& glyph, const uint8_t* table8) {
    const size_t dstRB = glyph.rowBytes();
    const int width = glyph.fWidth;
    uint8_t* SK_RESTRICT dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);

    for (int y = 0; y < glyph.fHeight; y++) {
        for (int i = 0; i < width; i++) {
            dst[i] = rgb_to_a8<APPLY_PREBLEND>(src[i], table8);
#if SK_SHOW_TEXT_BLIT_COVERAGE
            dst[i] = SkMax32(dst[i], 10);
#endif
        }
        src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
        dst -= dstRB;
    }
}

template<bool APPLY_PREBLEND>
static void rgb_to_lcd16(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
                         const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
    const size_t dstRB = glyph.rowBytes();
    const int width = glyph.fWidth;
    uint16_t* SK_RESTRICT dst = (uint16_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);

    for (int y = 0; y < glyph.fHeight; y++) {
        for (int i = 0; i < width; i++) {
            dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(src[i], tableR, tableG, tableB);
        }
        src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
        dst = (uint16_t*)((char*)dst - dstRB);
    }
}

void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) {
    SkASSERT(fDDC);

    const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
    const bool isAA = !isLCD(fRec);

    size_t srcRB;
    const void* bits = fOffscreen.draw(glyph, isBW, &srcRB);
    if (nullptr == bits) {
        LogFontTypeface::EnsureAccessible(this->getTypeface());
        bits = fOffscreen.draw(glyph, isBW, &srcRB);
        if (nullptr == bits) {
            sk_bzero(glyph.fImage, glyph.imageSize());
            return;
        }
    }

    if (!isBW) {
        const uint8_t* table;
        //The offscreen contains a GDI blit if isAA and kGenA8FromLCD_Flag is not set.
        //Otherwise the offscreen contains a ClearType blit.
        if (isAA && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag)) {
            table = getInverseGammaTableGDI();
        } else {
            table = getInverseGammaTableClearType();
        }
        //Note that the following cannot really be integrated into the
        //pre-blend, since we may not be applying the pre-blend; when we aren't
        //applying the pre-blend it means that a filter wants linear anyway.
        //Other code may also be applying the pre-blend, so we'd need another
        //one with this and one without.
        SkGdiRGB* addr = (SkGdiRGB*)bits;
        for (int y = 0; y < glyph.fHeight; ++y) {
            for (int x = 0; x < glyph.fWidth; ++x) {
                int r = (addr[x] >> 16) & 0xFF;
                int g = (addr[x] >>  8) & 0xFF;
                int b = (addr[x] >>  0) & 0xFF;
                addr[x] = (table[r] << 16) | (table[g] << 8) | table[b];
            }
            addr = SkTAddOffset<SkGdiRGB>(addr, srcRB);
        }
    }

    size_t dstRB = glyph.rowBytes();
    if (isBW) {
        const uint8_t* src = (const uint8_t*)bits;
        uint8_t* dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
        for (int y = 0; y < glyph.fHeight; y++) {
            memcpy(dst, src, dstRB);
            src += srcRB;
            dst -= dstRB;
        }
#if SK_SHOW_TEXT_BLIT_COVERAGE
            if (glyph.fWidth > 0 && glyph.fHeight > 0) {
                int bitCount = glyph.fWidth & 7;
                uint8_t* first = (uint8_t*)glyph.fImage;
                uint8_t* last = (uint8_t*)((char*)glyph.fImage + glyph.fHeight * dstRB - 1);
                *first |= 1 << 7;
                *last |= bitCount == 0 ? 1 : 1 << (8 - bitCount);
            }
#endif
    } else if (isAA) {
        // since the caller may require A8 for maskfilters, we can't check for BW
        // ... until we have the caller tell us that explicitly
        const SkGdiRGB* src = (const SkGdiRGB*)bits;
        if (fPreBlend.isApplicable()) {
            rgb_to_a8<true>(src, srcRB, glyph, fPreBlend.fG);
        } else {
            rgb_to_a8<false>(src, srcRB, glyph, fPreBlend.fG);
        }
    } else {    // LCD16
        const SkGdiRGB* src = (const SkGdiRGB*)bits;
        SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
        if (fPreBlend.isApplicable()) {
            rgb_to_lcd16<true>(src, srcRB, glyph,
                               fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
        } else {
            rgb_to_lcd16<false>(src, srcRB, glyph,
                                fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
        }
    }
}

class GDIGlyphbufferPointIter {
public:
    GDIGlyphbufferPointIter(const uint8_t* glyphbuf, DWORD total_size)
        : fHeaderIter(glyphbuf, total_size), fCurveIter(), fPointIter()
    { }

    POINTFX const * next() {
nextHeader:
        if (!fCurveIter.isSet()) {
            const TTPOLYGONHEADER* header = fHeaderIter.next();
            if (nullptr == header) {
                return nullptr;
            }
            fCurveIter.set(header);
            const TTPOLYCURVE* curve = fCurveIter.next();
            if (nullptr == curve) {
                return nullptr;
            }
            fPointIter.set(curve);
            return &header->pfxStart;
        }

        const POINTFX* nextPoint = fPointIter.next();
        if (nullptr == nextPoint) {
            const TTPOLYCURVE* curve = fCurveIter.next();
            if (nullptr == curve) {
                fCurveIter.set();
                goto nextHeader;
            } else {
                fPointIter.set(curve);
            }
            nextPoint = fPointIter.next();
        }
        return nextPoint;
    }

    WORD currentCurveType() {
        return fPointIter.fCurveType;
    }

private:
    /** Iterates over all of the polygon headers in a glyphbuf. */
    class GDIPolygonHeaderIter {
    public:
        GDIPolygonHeaderIter(const uint8_t* glyphbuf, DWORD total_size)
            : fCurPolygon(reinterpret_cast<const TTPOLYGONHEADER*>(glyphbuf))
            , fEndPolygon(SkTAddOffset<const TTPOLYGONHEADER>(glyphbuf, total_size))
        { }

        const TTPOLYGONHEADER* next() {
            if (fCurPolygon >= fEndPolygon) {
                return nullptr;
            }
            const TTPOLYGONHEADER* thisPolygon = fCurPolygon;
            fCurPolygon = SkTAddOffset<const TTPOLYGONHEADER>(fCurPolygon, fCurPolygon->cb);
            return thisPolygon;
        }
    private:
        const TTPOLYGONHEADER* fCurPolygon;
        const TTPOLYGONHEADER* fEndPolygon;
    };

    /** Iterates over all of the polygon curves in a polygon header. */
    class GDIPolygonCurveIter {
    public:
        GDIPolygonCurveIter() : fCurCurve(nullptr), fEndCurve(nullptr) { }

        GDIPolygonCurveIter(const TTPOLYGONHEADER* curPolygon)
            : fCurCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOLYGONHEADER)))
            , fEndCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->cb))
        { }

        bool isSet() { return fCurCurve != nullptr; }

        void set(const TTPOLYGONHEADER* curPolygon) {
            fCurCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOLYGONHEADER));
            fEndCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->cb);
        }
        void set() {
            fCurCurve = nullptr;
            fEndCurve = nullptr;
        }

        const TTPOLYCURVE* next() {
            if (fCurCurve >= fEndCurve) {
                return nullptr;
            }
            const TTPOLYCURVE* thisCurve = fCurCurve;
            fCurCurve = SkTAddOffset<const TTPOLYCURVE>(fCurCurve, size_of_TTPOLYCURVE(*fCurCurve));
            return thisCurve;
        }
    private:
        size_t size_of_TTPOLYCURVE(const TTPOLYCURVE& curve) {
            return 2*sizeof(WORD) + curve.cpfx*sizeof(POINTFX);
        }
        const TTPOLYCURVE* fCurCurve;
        const TTPOLYCURVE* fEndCurve;
    };

    /** Iterates over all of the polygon points in a polygon curve. */
    class GDIPolygonCurvePointIter {
    public:
        GDIPolygonCurvePointIter() : fCurveType(0), fCurPoint(nullptr), fEndPoint(nullptr) { }

        GDIPolygonCurvePointIter(const TTPOLYCURVE* curPolygon)
            : fCurveType(curPolygon->wType)
            , fCurPoint(&curPolygon->apfx[0])
            , fEndPoint(&curPolygon->apfx[curPolygon->cpfx])
        { }

        bool isSet() { return fCurPoint != nullptr; }

        void set(const TTPOLYCURVE* curPolygon) {
            fCurveType = curPolygon->wType;
            fCurPoint = &curPolygon->apfx[0];
            fEndPoint = &curPolygon->apfx[curPolygon->cpfx];
        }
        void set() {
            fCurPoint = nullptr;
            fEndPoint = nullptr;
        }

        const POINTFX* next() {
            if (fCurPoint >= fEndPoint) {
                return nullptr;
            }
            const POINTFX* thisPoint = fCurPoint;
            ++fCurPoint;
            return thisPoint;
        }

        WORD fCurveType;
    private:
        const POINTFX* fCurPoint;
        const POINTFX* fEndPoint;
    };

    GDIPolygonHeaderIter fHeaderIter;
    GDIPolygonCurveIter fCurveIter;
    GDIPolygonCurvePointIter fPointIter;
};

static void sk_path_from_gdi_path(SkPath* path, const uint8_t* glyphbuf, DWORD total_size) {
    const uint8_t* cur_glyph = glyphbuf;
    const uint8_t* end_glyph = glyphbuf + total_size;

    while (cur_glyph < end_glyph) {
        const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;

        const uint8_t* end_poly = cur_glyph + th->cb;
        const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);

        path->moveTo(SkFixedToScalar( SkFIXEDToFixed(th->pfxStart.x)),
                     SkFixedToScalar(-SkFIXEDToFixed(th->pfxStart.y)));

        while (cur_poly < end_poly) {
            const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;

            if (pc->wType == TT_PRIM_LINE) {
                for (uint16_t i = 0; i < pc->cpfx; i++) {
                    path->lineTo(SkFixedToScalar( SkFIXEDToFixed(pc->apfx[i].x)),
                                 SkFixedToScalar(-SkFIXEDToFixed(pc->apfx[i].y)));
                }
            }

            if (pc->wType == TT_PRIM_QSPLINE) {
                for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
                    POINTFX pnt_b = pc->apfx[u];    // B is always the current point
                    POINTFX pnt_c = pc->apfx[u+1];

                    if (u < pc->cpfx - 2) {          // If not on last spline, compute C
                        pnt_c.x = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.x),
                                                            SkFIXEDToFixed(pnt_c.x)));
                        pnt_c.y = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.y),
                                                            SkFIXEDToFixed(pnt_c.y)));
                    }

                    path->quadTo(SkFixedToScalar( SkFIXEDToFixed(pnt_b.x)),
                                 SkFixedToScalar(-SkFIXEDToFixed(pnt_b.y)),
                                 SkFixedToScalar( SkFIXEDToFixed(pnt_c.x)),
                                 SkFixedToScalar(-SkFIXEDToFixed(pnt_c.y)));
                }
            }
            // Advance past this TTPOLYCURVE.
            cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
        }
        cur_glyph += th->cb;
        path->close();
    }
}

#define move_next_expected_hinted_point(iter, pElem) do {\
    pElem = iter.next(); \
    if (nullptr == pElem) return false; \
} while(0)

// It is possible for the hinted and unhinted versions of the same path to have
// a different number of points due to GDI's handling of flipped points.
// If this is detected, this will return false.
static bool sk_path_from_gdi_paths(SkPath* path, const uint8_t* glyphbuf, DWORD total_size,
                                   GDIGlyphbufferPointIter hintedYs) {
    const uint8_t* cur_glyph = glyphbuf;
    const uint8_t* end_glyph = glyphbuf + total_size;

    POINTFX const * hintedPoint;

    while (cur_glyph < end_glyph) {
        const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;

        const uint8_t* end_poly = cur_glyph + th->cb;
        const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);

        move_next_expected_hinted_point(hintedYs, hintedPoint);
        path->moveTo(SkFixedToScalar( SkFIXEDToFixed(th->pfxStart.x)),
                     SkFixedToScalar(-SkFIXEDToFixed(hintedPoint->y)));

        while (cur_poly < end_poly) {
            const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;

            if (pc->wType == TT_PRIM_LINE) {
                for (uint16_t i = 0; i < pc->cpfx; i++) {
                    move_next_expected_hinted_point(hintedYs, hintedPoint);
                    path->lineTo(SkFixedToScalar( SkFIXEDToFixed(pc->apfx[i].x)),
                                 SkFixedToScalar(-SkFIXEDToFixed(hintedPoint->y)));
                }
            }

            if (pc->wType == TT_PRIM_QSPLINE) {
                POINTFX currentPoint = pc->apfx[0];
                move_next_expected_hinted_point(hintedYs, hintedPoint);
                // only take the hinted y if it wasn't flipped
                if (hintedYs.currentCurveType() == TT_PRIM_QSPLINE) {
                    currentPoint.y = hintedPoint->y;
                }
                for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
                    POINTFX pnt_b = currentPoint;//pc->apfx[u]; // B is always the current point
                    POINTFX pnt_c = pc->apfx[u+1];
                    move_next_expected_hinted_point(hintedYs, hintedPoint);
                    // only take the hinted y if it wasn't flipped
                    if (hintedYs.currentCurveType() == TT_PRIM_QSPLINE) {
                        pnt_c.y = hintedPoint->y;
                    }
                    currentPoint.x = pnt_c.x;
                    currentPoint.y = pnt_c.y;

                    if (u < pc->cpfx - 2) {          // If not on last spline, compute C
                        pnt_c.x = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.x),
                                                            SkFIXEDToFixed(pnt_c.x)));
                        pnt_c.y = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.y),
                                                            SkFIXEDToFixed(pnt_c.y)));
                    }

                    path->quadTo(SkFixedToScalar( SkFIXEDToFixed(pnt_b.x)),
                                 SkFixedToScalar(-SkFIXEDToFixed(pnt_b.y)),
                                 SkFixedToScalar( SkFIXEDToFixed(pnt_c.x)),
                                 SkFixedToScalar(-SkFIXEDToFixed(pnt_c.y)));
                }
            }
            // Advance past this TTPOLYCURVE.
            cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
        }
        cur_glyph += th->cb;
        path->close();
    }
    return true;
}

DWORD SkScalerContext_GDI::getGDIGlyphPath(SkGlyphID glyph, UINT flags,
                                           SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf)
{
    GLYPHMETRICS gm;

    DWORD total_size = GetGlyphOutlineW(fDDC, glyph, flags, &gm, BUFFERSIZE, glyphbuf->get(), &fMat22);
    // Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even if BUFFERSIZE > 0.
    // It has been verified that this does not involve a buffer overrun.
    if (GDI_ERROR == total_size || total_size > BUFFERSIZE) {
        // GDI_ERROR because the BUFFERSIZE was too small, or because the data was not accessible.
        // When the data is not accessable GetGlyphOutlineW fails rather quickly,
        // so just try to get the size. If that fails then ensure the data is accessible.
        total_size = GetGlyphOutlineW(fDDC, glyph, flags, &gm, 0, nullptr, &fMat22);
        if (GDI_ERROR == total_size) {
            LogFontTypeface::EnsureAccessible(this->getTypeface());
            total_size = GetGlyphOutlineW(fDDC, glyph, flags, &gm, 0, nullptr, &fMat22);
            if (GDI_ERROR == total_size) {
                // GetGlyphOutlineW is known to fail for some characters, such as spaces.
                // In these cases, just return that the glyph does not have a shape.
                return 0;
            }
        }

        glyphbuf->reset(total_size);

        DWORD ret = GetGlyphOutlineW(fDDC, glyph, flags, &gm, total_size, glyphbuf->get(), &fMat22);
        if (GDI_ERROR == ret) {
            LogFontTypeface::EnsureAccessible(this->getTypeface());
            ret = GetGlyphOutlineW(fDDC, glyph, flags, &gm, total_size, glyphbuf->get(), &fMat22);
            if (GDI_ERROR == ret) {
                SkASSERT(false);
                return 0;
            }
        }
    }
    return total_size;
}

bool SkScalerContext_GDI::generatePath(SkGlyphID glyph, SkPath* path) {
    SkASSERT(path);
    SkASSERT(fDDC);

    path->reset();

    // Out of all the fonts on a typical Windows box,
    // 25% of glyphs require more than 2KB.
    // 1% of glyphs require more than 4KB.
    // 0.01% of glyphs require more than 8KB.
    // 8KB is less than 1% of the normal 1MB stack on Windows.
    // Note that some web fonts glyphs require more than 20KB.
    //static const DWORD BUFFERSIZE = (1 << 13);

    //GDI only uses hinted outlines when axis aligned.
    UINT format = GGO_NATIVE | GGO_GLYPH_INDEX;
    if (fRec.getHinting() == SkFontHinting::kNone || fRec.getHinting() == SkFontHinting::kSlight){
        format |= GGO_UNHINTED;
    }
    SkAutoSTMalloc<BUFFERSIZE, uint8_t> glyphbuf(BUFFERSIZE);
    DWORD total_size = getGDIGlyphPath(glyph, format, &glyphbuf);
    if (0 == total_size) {
        return false;
    }

    if (fRec.getHinting() != SkFontHinting::kSlight) {
        sk_path_from_gdi_path(path, glyphbuf, total_size);
    } else {
        //GDI only uses hinted outlines when axis aligned.
        UINT format = GGO_NATIVE | GGO_GLYPH_INDEX;

        SkAutoSTMalloc<BUFFERSIZE, uint8_t> hintedGlyphbuf(BUFFERSIZE);
        DWORD hinted_total_size = getGDIGlyphPath(glyph, format, &hintedGlyphbuf);
        if (0 == hinted_total_size) {
            return false;
        }

        if (!sk_path_from_gdi_paths(path, glyphbuf, total_size,
                                    GDIGlyphbufferPointIter(hintedGlyphbuf, hinted_total_size)))
        {
            path->reset();
            sk_path_from_gdi_path(path, glyphbuf, total_size);
        }
    }
    return true;
}

static void logfont_for_name(const char* familyName, LOGFONT* lf) {
    sk_bzero(lf, sizeof(LOGFONT));
#ifdef UNICODE
    // Get the buffer size needed first.
    size_t str_len = ::MultiByteToWideChar(CP_UTF8, 0, familyName,
                                            -1, nullptr, 0);
    // Allocate a buffer (str_len already has terminating null
    // accounted for).
    wchar_t *wideFamilyName = new wchar_t[str_len];
    // Now actually convert the string.
    ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1,
                            wideFamilyName, str_len);
    ::wcsncpy(lf->lfFaceName, wideFamilyName, LF_FACESIZE - 1);
    delete [] wideFamilyName;
    lf->lfFaceName[LF_FACESIZE-1] = L'\0';
#else
    ::strncpy(lf->lfFaceName, familyName, LF_FACESIZE - 1);
    lf->lfFaceName[LF_FACESIZE - 1] = '\0';
#endif
}

void LogFontTypeface::onGetFamilyName(SkString* familyName) const {
    // Get the actual name of the typeface. The logfont may not know this.
    HFONT font = CreateFontIndirect(&fLogFont);

    HDC deviceContext = ::CreateCompatibleDC(nullptr);
    HFONT savefont = (HFONT)SelectObject(deviceContext, font);

    dcfontname_to_skstring(deviceContext, fLogFont, familyName);

    if (deviceContext) {
        ::SelectObject(deviceContext, savefont);
        ::DeleteDC(deviceContext);
    }
    if (font) {
        ::DeleteObject(font);
    }
}

void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
                                          bool* isLocalStream) const {
    SkString familyName;
    this->onGetFamilyName(&familyName);
    desc->setFamilyName(familyName.c_str());
    desc->setStyle(this->fontStyle());
    *isLocalStream = this->fSerializeAsStream;
}

void LogFontTypeface::getGlyphToUnicodeMap(SkUnichar* dstArray) const {
    HDC hdc = ::CreateCompatibleDC(nullptr);
    HFONT font = CreateFontIndirect(&fLogFont);
    HFONT savefont = (HFONT)SelectObject(hdc, font);
    LOGFONT lf = fLogFont;
    HFONT designFont = CreateFontIndirect(&lf);
    SelectObject(hdc, designFont);

    unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);
    populate_glyph_to_unicode(hdc, glyphCount, dstArray);

    SelectObject(hdc, savefont);
    DeleteObject(designFont);
    DeleteObject(font);
    DeleteDC(hdc);
}

std::unique_ptr<SkAdvancedTypefaceMetrics> LogFontTypeface::onGetAdvancedMetrics() const {
    LOGFONT lf = fLogFont;
    std::unique_ptr<SkAdvancedTypefaceMetrics> info(nullptr);

    HDC hdc = CreateCompatibleDC(nullptr);
    HFONT font = CreateFontIndirect(&lf);
    HFONT savefont = (HFONT)SelectObject(hdc, font);
    HFONT designFont = nullptr;

    const char stem_chars[] = {'i', 'I', '!', '1'};
    int16_t min_width;
    unsigned glyphCount;

    // To request design units, create a logical font whose height is specified
    // as unitsPerEm.
    OUTLINETEXTMETRIC otm;
    unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
    if (0 == otmRet) {
        call_ensure_accessible(lf);
        otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
    }
    if (!otmRet || !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
        goto Error;
    }
    lf.lfHeight = -SkToS32(otm.otmEMSquare);
    designFont = CreateFontIndirect(&lf);
    SelectObject(hdc, designFont);
    if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
        goto Error;
    }
    glyphCount = calculateGlyphCount(hdc, fLogFont);

    info.reset(new SkAdvancedTypefaceMetrics);
    tchar_to_skstring(lf.lfFaceName, &info->fFontName);

    SkOTTableOS2_V4::Type fsType;
    if (sizeof(fsType) == this->getTableData(SkTEndian_SwapBE32(SkOTTableOS2::TAG),
                                             offsetof(SkOTTableOS2_V4, fsType),
                                             sizeof(fsType),
                                             &fsType)) {
        SkOTUtils::SetAdvancedTypefaceFlags(fsType, info.get());
    } else {
        // If bit 1 is set, the font may not be embedded in a document.
        // If bit 1 is clear, the font can be embedded.
        // If bit 2 is set, the embedding is read-only.
        if (otm.otmfsType & 0x1) {
            info->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag;
        }
    }

    if (glyphCount > 0 &&
        (otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE)) {
        info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
    } else {
        goto ReturnInfo;
    }

    // If this bit is clear the font is a fixed pitch font.
    if (!(otm.otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
    }
    if (otm.otmTextMetrics.tmItalic) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
    }
    if (otm.otmTextMetrics.tmPitchAndFamily & FF_ROMAN) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
    } else if (otm.otmTextMetrics.tmPitchAndFamily & FF_SCRIPT) {
            info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
    }

    // The main italic angle of the font, in tenths of a degree counterclockwise
    // from vertical.
    info->fItalicAngle = otm.otmItalicAngle / 10;
    info->fAscent = SkToS16(otm.otmTextMetrics.tmAscent);
    info->fDescent = SkToS16(-otm.otmTextMetrics.tmDescent);
    // TODO(ctguil): Use alternate cap height calculation.
    // MSDN says otmsCapEmHeight is not support but it is returning a value on
    // my Win7 box.
    info->fCapHeight = otm.otmsCapEmHeight;
    info->fBBox =
        SkIRect::MakeLTRB(otm.otmrcFontBox.left, otm.otmrcFontBox.top,
                          otm.otmrcFontBox.right, otm.otmrcFontBox.bottom);

    // Figure out a good guess for StemV - Min width of i, I, !, 1.
    // This probably isn't very good with an italic font.
    min_width = SHRT_MAX;
    info->fStemV = 0;
    for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
        ABC abcWidths;
        if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
            int16_t width = abcWidths.abcB;
            if (width > 0 && width < min_width) {
                min_width = width;
                info->fStemV = min_width;
            }
        }
    }

Error:
ReturnInfo:
    SelectObject(hdc, savefont);
    DeleteObject(designFont);
    DeleteObject(font);
    DeleteDC(hdc);

    return info;
}

//Dummy representation of a Base64 encoded GUID from create_unique_font_name.
#define BASE64_GUID_ID "XXXXXXXXXXXXXXXXXXXXXXXX"
//Length of GUID representation from create_id, including nullptr terminator.
#define BASE64_GUID_ID_LEN SK_ARRAY_COUNT(BASE64_GUID_ID)

static_assert(BASE64_GUID_ID_LEN < LF_FACESIZE, "GUID_longer_than_facesize");

/**
   NameID 6 Postscript names cannot have the character '/'.
   It would be easier to hex encode the GUID, but that is 32 bytes,
   and many systems have issues with names longer than 28 bytes.
   The following need not be any standard base64 encoding.
   The encoded value is never decoded.
*/
static const char postscript_safe_base64_encode[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789-_=";

/**
   Formats a GUID into Base64 and places it into buffer.
   buffer should have space for at least BASE64_GUID_ID_LEN characters.
   The string will always be null terminated.
   XXXXXXXXXXXXXXXXXXXXXXXX0
 */
static void format_guid_b64(const GUID& guid, char* buffer, size_t bufferSize) {
    SkASSERT(bufferSize >= BASE64_GUID_ID_LEN);
    size_t written = SkBase64::Encode(&guid, sizeof(guid), buffer, postscript_safe_base64_encode);
    SkASSERT(written < LF_FACESIZE);
    buffer[written] = '\0';
}

/**
   Creates a Base64 encoded GUID and places it into buffer.
   buffer should have space for at least BASE64_GUID_ID_LEN characters.
   The string will always be null terminated.
   XXXXXXXXXXXXXXXXXXXXXXXX0
 */
static HRESULT create_unique_font_name(char* buffer, size_t bufferSize) {
    GUID guid = {};
    if (FAILED(CoCreateGuid(&guid))) {
        return E_UNEXPECTED;
    }
    format_guid_b64(guid, buffer, bufferSize);

    return S_OK;
}

/**
   Introduces a font to GDI. On failure will return nullptr. The returned handle
   should eventually be passed to RemoveFontMemResourceEx.
*/
static HANDLE activate_font(SkData* fontData) {
    DWORD numFonts = 0;
    //AddFontMemResourceEx just copies the data, but does not specify const.
    HANDLE fontHandle = AddFontMemResourceEx(const_cast<void*>(fontData->data()),
                                             static_cast<DWORD>(fontData->size()),
                                             0,
                                             &numFonts);

    if (fontHandle != nullptr && numFonts < 1) {
        RemoveFontMemResourceEx(fontHandle);
        return nullptr;
    }

    return fontHandle;
}

// Does not affect ownership of stream.
static sk_sp<SkTypeface> create_from_stream(std::unique_ptr<SkStreamAsset> stream) {
    // Create a unique and unpredictable font name.
    // Avoids collisions and access from CSS.
    char familyName[BASE64_GUID_ID_LEN];
    const int familyNameSize = SK_ARRAY_COUNT(familyName);
    if (FAILED(create_unique_font_name(familyName, familyNameSize))) {
        return nullptr;
    }

    // Change the name of the font.
    sk_sp<SkData> rewrittenFontData(SkOTUtils::RenameFont(stream.get(), familyName, familyNameSize-1));
    if (nullptr == rewrittenFontData.get()) {
        return nullptr;
    }

    // Register the font with GDI.
    HANDLE fontReference = activate_font(rewrittenFontData.get());
    if (nullptr == fontReference) {
        return nullptr;
    }

    // Create the typeface.
    LOGFONT lf;
    logfont_for_name(familyName, &lf);

    return sk_sp<SkTypeface>(SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference));
}

std::unique_ptr<SkStreamAsset> LogFontTypeface::onOpenStream(int* ttcIndex) const {
    *ttcIndex = 0;

    const DWORD kTTCTag = SkEndian_SwapBE32(SkSetFourByteTag('t', 't', 'c', 'f'));
    LOGFONT lf = fLogFont;

    HDC hdc = ::CreateCompatibleDC(nullptr);
    HFONT font = CreateFontIndirect(&lf);
    HFONT savefont = (HFONT)SelectObject(hdc, font);

    std::unique_ptr<SkStreamAsset> stream;
    DWORD tables[2] = {kTTCTag, 0};
    for (size_t i = 0; i < SK_ARRAY_COUNT(tables); i++) {
        DWORD bufferSize = GetFontData(hdc, tables[i], 0, nullptr, 0);
        if (bufferSize == GDI_ERROR) {
            call_ensure_accessible(lf);
            bufferSize = GetFontData(hdc, tables[i], 0, nullptr, 0);
        }
        if (bufferSize != GDI_ERROR) {
            stream.reset(new SkMemoryStream(bufferSize));
            if (GetFontData(hdc, tables[i], 0, (void*)stream->getMemoryBase(), bufferSize)) {
                break;
            } else {
                stream.reset();
            }
        }
    }

    SelectObject(hdc, savefont);
    DeleteObject(font);
    DeleteDC(hdc);

    return stream;
}

sk_sp<SkTypeface> LogFontTypeface::onMakeClone(const SkFontArguments& args) const {
    return sk_ref_sp(this);
}

static void bmpCharsToGlyphs(HDC hdc, const WCHAR* bmpChars, int count, uint16_t* glyphs,
                             bool Ox1FHack)
{
    // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0.

    /** Real documentation for GetGlyphIndicesW:
     *
     *  When GGI_MARK_NONEXISTING_GLYPHS is not specified and a character does not map to a
     *  glyph, then the 'default character's glyph is returned instead. The 'default character'
     *  is available in fTM.tmDefaultChar. FON fonts have a default character, and there exists
     *  a usDefaultChar in the 'OS/2' table, version 2 and later. If there is no
     *  'default character' specified by the font, then often the first character found is used.
     *
     *  When GGI_MARK_NONEXISTING_GLYPHS is specified and a character does not map to a glyph,
     *  then the glyph 0xFFFF is used. In Windows XP and earlier, Bitmap/Vector FON usually use
     *  glyph 0x1F instead ('Terminal' appears to be special, returning 0xFFFF).
     *  Type1 PFM/PFB, TT, OT TT, OT CFF all appear to use 0xFFFF, even on XP.
     */
    DWORD result = GetGlyphIndicesW(hdc, bmpChars, count, glyphs, GGI_MARK_NONEXISTING_GLYPHS);
    if (GDI_ERROR == result) {
        for (int i = 0; i < count; ++i) {
            glyphs[i] = 0;
        }
        return;
    }

    if (Ox1FHack) {
        for (int i = 0; i < count; ++i) {
            if (0xFFFF == glyphs[i] || 0x1F == glyphs[i]) {
                glyphs[i] = 0;
            }
        }
    } else {
        for (int i = 0; i < count; ++i) {
            if (0xFFFF == glyphs[i]){
                glyphs[i] = 0;
            }
        }
    }
}

static uint16_t nonBmpCharToGlyph(HDC hdc, SCRIPT_CACHE* scriptCache, const WCHAR utf16[2]) {
    uint16_t index = 0;
    // Use uniscribe to detemine glyph index for non-BMP characters.
    static const int numWCHAR = 2;
    static const int maxItems = 2;
    // MSDN states that this can be nullptr, but some things don't work then.
    SCRIPT_CONTROL scriptControl;
    memset(&scriptControl, 0, sizeof(scriptControl));
    // Add extra item to SCRIPT_ITEM to work around a bug (now documented).
    // https://bugzilla.mozilla.org/show_bug.cgi?id=366643
    SCRIPT_ITEM si[maxItems + 1];
    int numItems;
    HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &scriptControl, nullptr, si, &numItems),
         "Could not itemize character.");

    // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2 space glyphs.
    static const int maxGlyphs = 2;
    SCRIPT_VISATTR vsa[maxGlyphs];
    WORD outGlyphs[maxGlyphs];
    WORD logClust[numWCHAR];
    int numGlyphs;
    SCRIPT_ANALYSIS& script = si[0].a;
    script.eScript = SCRIPT_UNDEFINED;
    script.fRTL = FALSE;
    script.fLayoutRTL = FALSE;
    script.fLinkBefore = FALSE;
    script.fLinkAfter = FALSE;
    script.fLogicalOrder = FALSE;
    script.fNoGlyphIndex = FALSE;
    script.s.uBidiLevel = 0;
    script.s.fOverrideDirection = 0;
    script.s.fInhibitSymSwap = TRUE;
    script.s.fCharShape = FALSE;
    script.s.fDigitSubstitute = FALSE;
    script.s.fInhibitLigate = FALSE;
    script.s.fDisplayZWG = TRUE;
    script.s.fArabicNumContext = FALSE;
    script.s.fGcpClusters = FALSE;
    script.s.fReserved = 0;
    script.s.fEngineReserved = 0;
    // For the future, 0x80040200 from here is USP_E_SCRIPT_NOT_IN_FONT
    HRZM(ScriptShape(hdc, scriptCache, utf16, numWCHAR, maxGlyphs, &script,
                     outGlyphs, logClust, vsa, &numGlyphs),
         "Could not shape character.");
    if (1 == numGlyphs) {
        index = outGlyphs[0];
    }
    return index;
}

class SkAutoHDC {
public:
    SkAutoHDC(const LOGFONT& lf)
        : fHdc(::CreateCompatibleDC(nullptr))
        , fFont(::CreateFontIndirect(&lf))
        , fSavefont((HFONT)SelectObject(fHdc, fFont))
    { }
    ~SkAutoHDC() {
        SelectObject(fHdc, fSavefont);
        DeleteObject(fFont);
        DeleteDC(fHdc);
    }
    operator HDC() { return fHdc; }
private:
    HDC fHdc;
    HFONT fFont;
    HFONT fSavefont;
};
#define SkAutoHDC(...) SK_REQUIRE_LOCAL_VAR(SkAutoHDC)

void LogFontTypeface::onCharsToGlyphs(const SkUnichar uni[], int glyphCount,
                                      SkGlyphID glyphs[]) const
{
    SkAutoHDC hdc(fLogFont);

    TEXTMETRIC tm;
    if (0 == GetTextMetrics(hdc, &tm)) {
        call_ensure_accessible(fLogFont);
        if (0 == GetTextMetrics(hdc, &tm)) {
            tm.tmPitchAndFamily = TMPF_TRUETYPE;
        }
    }
    bool Ox1FHack = !(tm.tmPitchAndFamily & TMPF_VECTOR) /*&& winVer < Vista */;

    SCRIPT_CACHE sc = 0;
    static const int scratchCount = 256;
    WCHAR scratch[scratchCount];
    int glyphIndex = 0;
    const uint32_t* utf32 = reinterpret_cast<const uint32_t*>(uni);
    while (glyphIndex < glyphCount) {
        // Try a run of bmp.
        int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
        int runLength = 0;
        while (runLength < glyphsLeft && utf32[glyphIndex + runLength] <= 0xFFFF) {
            scratch[runLength] = static_cast<WCHAR>(utf32[glyphIndex + runLength]);
            ++runLength;
        }
        if (runLength) {
            bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], Ox1FHack);
            glyphIndex += runLength;
        }

        // Try a run of non-bmp.
        while (glyphIndex < glyphCount && utf32[glyphIndex] > 0xFFFF) {
            SkUTF::ToUTF16(utf32[glyphIndex], reinterpret_cast<uint16_t*>(scratch));
            glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
            ++glyphIndex;
        }
    }

    if (sc) {
        ::ScriptFreeCache(&sc);
    }
}

int LogFontTypeface::onCountGlyphs() const {
    HDC hdc = ::CreateCompatibleDC(nullptr);
    HFONT font = CreateFontIndirect(&fLogFont);
    HFONT savefont = (HFONT)SelectObject(hdc, font);

    unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);

    SelectObject(hdc, savefont);
    DeleteObject(font);
    DeleteDC(hdc);

    return glyphCount;
}

void LogFontTypeface::getPostScriptGlyphNames(SkString*) const {}

int LogFontTypeface::onGetUPEM() const {
    HDC hdc = ::CreateCompatibleDC(nullptr);
    HFONT font = CreateFontIndirect(&fLogFont);
    HFONT savefont = (HFONT)SelectObject(hdc, font);

    unsigned int upem = calculateUPEM(hdc, fLogFont);

    SelectObject(hdc, savefont);
    DeleteObject(font);
    DeleteDC(hdc);

    return upem;
}

SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() const {
    sk_sp<SkTypeface::LocalizedStrings> nameIter =
        SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
    if (!nameIter) {
        SkString familyName;
        this->getFamilyName(&familyName);
        SkString language("und"); //undetermined
        nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(familyName, language);
    }
    return nameIter.release();
}

int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
    SkSFNTHeader header;
    if (sizeof(header) != this->onGetTableData(0, 0, sizeof(header), &header)) {
        return 0;
    }

    int numTables = SkEndian_SwapBE16(header.numTables);

    if (tags) {
        size_t size = numTables * sizeof(SkSFNTHeader::TableDirectoryEntry);
        SkAutoSTMalloc<0x20, SkSFNTHeader::TableDirectoryEntry> dir(numTables);
        if (size != this->onGetTableData(0, sizeof(header), size, dir.get())) {
            return 0;
        }

        for (int i = 0; i < numTables; ++i) {
            tags[i] = SkEndian_SwapBE32(dir[i].tag);
        }
    }
    return numTables;
}

size_t LogFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
                                       size_t length, void* data) const
{
    LOGFONT lf = fLogFont;

    HDC hdc = ::CreateCompatibleDC(nullptr);
    HFONT font = CreateFontIndirect(&lf);
    HFONT savefont = (HFONT)SelectObject(hdc, font);

    tag = SkEndian_SwapBE32(tag);
    if (nullptr == data) {
        length = 0;
    }
    DWORD bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) length);
    if (bufferSize == GDI_ERROR) {
        call_ensure_accessible(lf);
        bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) length);
    }

    SelectObject(hdc, savefont);
    DeleteObject(font);
    DeleteDC(hdc);

    return bufferSize == GDI_ERROR ? 0 : bufferSize;
}

SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
                                                        const SkDescriptor* desc) const {
    auto ctx = skstd::make_unique<SkScalerContext_GDI>(
            sk_ref_sp(const_cast<LogFontTypeface*>(this)), effects, desc);
    if (!ctx->isValid()) {
        return nullptr;
    }
    return ctx.release();
}

void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
    if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
        rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
    {
        rec->fMaskFormat = SkMask::kA8_Format;
        rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag;
    }

    unsigned flagsWeDontSupport = SkScalerContext::kForceAutohinting_Flag |
                                  SkScalerContext::kEmbeddedBitmapText_Flag |
                                  SkScalerContext::kEmbolden_Flag |
                                  SkScalerContext::kLCD_BGROrder_Flag |
                                  SkScalerContext::kLCD_Vertical_Flag;
    rec->fFlags &= ~flagsWeDontSupport;

    SkFontHinting h = rec->getHinting();
    switch (h) {
        case SkFontHinting::kNone:
            break;
        case SkFontHinting::kSlight:
            // Only do slight hinting when axis aligned.
            // TODO: re-enable slight hinting when FontHostTest can pass.
            //if (!isAxisAligned(*rec)) {
                h = SkFontHinting::kNone;
            //}
            break;
        case SkFontHinting::kNormal:
        case SkFontHinting::kFull:
            // TODO: need to be able to distinguish subpixel positioned glyphs
            // and linear metrics.
            //rec->fFlags &= ~SkScalerContext::kSubpixelPositioning_Flag;
            h = SkFontHinting::kNormal;
            break;
        default:
            SkDEBUGFAIL("unknown hinting");
    }
    //TODO: if this is a bitmap font, squash hinting and subpixel.
    rec->setHinting(h);

// turn this off since GDI might turn A8 into BW! Need a bigger fix.
#if 0
    // Disable LCD when rotated, since GDI's output is ugly
    if (isLCD(*rec) && !isAxisAligned(*rec)) {
        rec->fMaskFormat = SkMask::kA8_Format;
    }
#endif

    if (!fCanBeLCD && isLCD(*rec)) {
        rec->fMaskFormat = SkMask::kA8_Format;
        rec->fFlags &= ~SkScalerContext::kGenA8FromLCD_Flag;
    }
}

///////////////////////////////////////////////////////////////////////////////

#include "include/core/SkDataTable.h"
#include "include/core/SkFontMgr.h"

static bool valid_logfont_for_enum(const LOGFONT& lf) {
    // TODO: Vector FON is unsupported and should not be listed.
    return
        // Ignore implicit vertical variants.
        lf.lfFaceName[0] && lf.lfFaceName[0] != '@'

        // DEFAULT_CHARSET is used to get all fonts, but also implies all
        // character sets. Filter assuming all fonts support ANSI_CHARSET.
        && ANSI_CHARSET == lf.lfCharSet
    ;
}

/** An EnumFontFamExProc implementation which interprets builderParam as
 *  an SkTDArray<ENUMLOGFONTEX>* and appends logfonts which
 *  pass the valid_logfont_for_enum predicate.
 */
static int CALLBACK enum_family_proc(const LOGFONT* lf, const TEXTMETRIC*,
                                     DWORD fontType, LPARAM builderParam) {
    if (valid_logfont_for_enum(*lf)) {
        SkTDArray<ENUMLOGFONTEX>* array = (SkTDArray<ENUMLOGFONTEX>*)builderParam;
        *array->append() = *(ENUMLOGFONTEX*)lf;
    }
    return 1; // non-zero means continue
}

class SkFontStyleSetGDI : public SkFontStyleSet {
public:
    SkFontStyleSetGDI(const TCHAR familyName[]) {
        LOGFONT lf;
        sk_bzero(&lf, sizeof(lf));
        lf.lfCharSet = DEFAULT_CHARSET;
        _tcscpy_s(lf.lfFaceName, familyName);

        HDC hdc = ::CreateCompatibleDC(nullptr);
        ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0);
        ::DeleteDC(hdc);
    }

    int count() override {
        return fArray.count();
    }

    void getStyle(int index, SkFontStyle* fs, SkString* styleName) override {
        if (fs) {
            *fs = get_style(fArray[index].elfLogFont);
        }
        if (styleName) {
            const ENUMLOGFONTEX& ref = fArray[index];
            // For some reason, ENUMLOGFONTEX and LOGFONT disagree on their type in the
            // non-unicode version.
            //      ENUMLOGFONTEX uses BYTE
            //      LOGFONT uses CHAR
            // Here we assert they that the style name is logically the same (size) as
            // a TCHAR, so we can use the same converter function.
            SkASSERT(sizeof(TCHAR) == sizeof(ref.elfStyle[0]));
            tchar_to_skstring((const TCHAR*)ref.elfStyle, styleName);
        }
    }

    SkTypeface* createTypeface(int index) override {
        return SkCreateTypefaceFromLOGFONT(fArray[index].elfLogFont);
    }

    SkTypeface* matchStyle(const SkFontStyle& pattern) override {
        return this->matchStyleCSS3(pattern);
    }

private:
    SkTDArray<ENUMLOGFONTEX> fArray;
};

class SkFontMgrGDI : public SkFontMgr {
public:
    SkFontMgrGDI() {
        LOGFONT lf;
        sk_bzero(&lf, sizeof(lf));
        lf.lfCharSet = DEFAULT_CHARSET;

        HDC hdc = ::CreateCompatibleDC(nullptr);
        ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fLogFontArray, 0);
        ::DeleteDC(hdc);
    }

protected:
    int onCountFamilies() const override {
        return fLogFontArray.count();
    }

    void onGetFamilyName(int index, SkString* familyName) const override {
        SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
        tchar_to_skstring(fLogFontArray[index].elfLogFont.lfFaceName, familyName);
    }

    SkFontStyleSet* onCreateStyleSet(int index) const override {
        SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
        return new SkFontStyleSetGDI(fLogFontArray[index].elfLogFont.lfFaceName);
    }

    SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
        if (nullptr == familyName) {
            familyName = "";    // do we need this check???
        }
        LOGFONT lf;
        logfont_for_name(familyName, &lf);
        return new SkFontStyleSetGDI(lf.lfFaceName);
    }

    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
                                           const SkFontStyle& fontstyle) const override {
        // could be in base impl
        sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
        return sset->matchStyle(fontstyle);
    }

    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
                                                    const char* bcp47[], int bcp47Count,
                                                    SkUnichar character) const override {
        return nullptr;
    }

    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
                                         const SkFontStyle& fontstyle) const override {
        // could be in base impl
        SkString familyName;
        ((LogFontTypeface*)familyMember)->getFamilyName(&familyName);
        return this->matchFamilyStyle(familyName.c_str(), fontstyle);
    }

    sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
                                            int ttcIndex) const override {
        if (ttcIndex != 0) {
            return nullptr;
        }
        return create_from_stream(std::move(stream));
    }

    sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override {
        // could be in base impl
        return this->makeFromStream(std::unique_ptr<SkStreamAsset>(new SkMemoryStream(std::move(data))),
                                    ttcIndex);
    }

    sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override {
        // could be in base impl
        auto stream = SkStream::MakeFromFile(path);
        return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
    }

    sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override {
        LOGFONT lf;
        if (nullptr == familyName) {
            lf = get_default_font();
        } else {
            logfont_for_name(familyName, &lf);
        }

        lf.lfWeight = style.weight();
        lf.lfItalic = style.slant() == SkFontStyle::kUpright_Slant ? FALSE : TRUE;
        return sk_sp<SkTypeface>(SkCreateTypefaceFromLOGFONT(lf));
    }

private:
    SkTDArray<ENUMLOGFONTEX> fLogFontArray;
};

///////////////////////////////////////////////////////////////////////////////

sk_sp<SkFontMgr> SkFontMgr_New_GDI() { return sk_make_sp<SkFontMgrGDI>(); }

#endif//defined(SK_BUILD_FOR_WIN)
