/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwindowsfontengine_p.h"
#include "qwindowsnativeimage_p.h"
#include "qwindowsfontdatabase_p.h"
#include <QtCore/qt_windows.h>
#include "qwindowsfontenginedirectwrite_p.h"

#include <QtGui/qpa/qplatformintegration.h>
#include <QtGui/private/qtextengine_p.h> // glyph_metrics_t
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QPaintDevice>
#include <QtGui/QBitmap>
#include <QtGui/QPainter>
#include <QtGui/private/qpainter_p.h>
#include <QtGui/QPaintEngine>
#include <QtGui/private/qpaintengine_raster_p.h>

#include <QtCore/QtEndian>
#include <QtCore/QFile>
#include <QtCore/qmath.h>
#include <QtCore/QTextStream>
#include <QtCore/QThreadStorage>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtCore/private/qstringiterator_p.h>

#include <QtCore/QDebug>

#include <limits.h>

#if !defined(QT_NO_DIRECTWRITE)
#  include <dwrite.h>
#  include <comdef.h>
#endif

QT_BEGIN_NAMESPACE

//### mingw needed define
#ifndef TT_PRIM_CSPLINE
#define TT_PRIM_CSPLINE 3
#endif

// GetFontData expects the tags in little endian ;(
#define MAKE_LITTLE_ENDIAN_TAG(ch1, ch2, ch3, ch4) (\
    (((quint32)(ch4)) << 24) | \
    (((quint32)(ch3)) << 16) | \
    (((quint32)(ch2)) << 8) | \
    ((quint32)(ch1)) \
   )

// common DC for all fonts

typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
static PtrGetCharWidthI ptrGetCharWidthI = 0;
static bool resolvedGetCharWidthI = false;

static void resolveGetCharWidthI()
{
    if (resolvedGetCharWidthI)
        return;
    resolvedGetCharWidthI = true;
    ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QStringLiteral("gdi32"), "GetCharWidthI");
}

// general font engine

QFixed QWindowsFontEngine::lineThickness() const
{
    if(lineWidth > 0)
        return lineWidth;

    return QFontEngine::lineThickness();
}

static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
{
    const auto size = GetOutlineTextMetrics(hdc, 0, nullptr);
    auto otm = reinterpret_cast<OUTLINETEXTMETRIC *>(malloc(size));
    GetOutlineTextMetrics(hdc, size, otm);
    return otm;
}

bool QWindowsFontEngine::hasCFFTable() const
{
    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);
    return GetFontData(hdc, MAKE_LITTLE_ENDIAN_TAG('C', 'F', 'F', ' '), 0, 0, 0) != GDI_ERROR;
}

bool QWindowsFontEngine::hasCMapTable() const
{
    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);
    return GetFontData(hdc, MAKE_LITTLE_ENDIAN_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR;
}

static inline QString stringFromOutLineTextMetric(const OUTLINETEXTMETRIC *otm, PSTR offset)
{
    const uchar *p = reinterpret_cast<const uchar *>(otm) + quintptr(offset);
    return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(p));
}

void QWindowsFontEngine::getCMap()
{
    ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable();

    cffTable = hasCFFTable();

    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);
    bool symb = false;
    if (ttf) {
        cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
        cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
                       cmapTable.size(), &symb, &cmapSize);
    }
    if (!cmap) {
        ttf = false;
        symb = false;
    }
    symbol = symb;
    designToDevice = 1;
    _faceId.index = 0;
    if(cmap) {
        OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
        unitsPerEm = int(otm->otmEMSquare);
        const QFixed unitsPerEmF(unitsPerEm);
        designToDevice = unitsPerEmF / QFixed::fromReal(fontDef.pixelSize);
        x_height = int(otm->otmsXHeight);
        loadKerningPairs(designToDevice);
        _faceId.filename = QFile::encodeName(stringFromOutLineTextMetric(otm, otm->otmpFullName));
        lineWidth = otm->otmsUnderscoreSize;
        fsType = otm->otmfsType;
        free(otm);

    } else {
        unitsPerEm = tm.tmHeight;
    }
}

int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs) const
{
    int glyph_pos = 0;
    {
        if (symbol) {
            QStringIterator it(str, str + numChars);
            while (it.hasNext()) {
                const uint uc = it.next();
                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
                if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
                    glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
                ++glyph_pos;
            }
        } else if (ttf) {
            QStringIterator it(str, str + numChars);
            while (it.hasNext()) {
                const uint uc = it.next();
                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
                ++glyph_pos;
            }
        } else {
            QStringIterator it(str, str + numChars);
            while (it.hasNext()) {
                const uint uc = it.next();
                if (uc >= tm.tmFirstChar && uc <= tm.tmLastChar)
                    glyphs->glyphs[glyph_pos] = uc;
                else
                    glyphs->glyphs[glyph_pos] = 0;
                ++glyph_pos;
            }
        }
    }
    glyphs->numGlyphs = glyph_pos;
    return glyph_pos;
}

/*!
    \class QWindowsFontEngine
    \brief Standard Windows font engine.
    \internal

    Will probably be superseded by a common Free Type font engine in Qt 5.X.
*/

QWindowsFontEngine::QWindowsFontEngine(const QString &name,
                                       LOGFONT lf,
                               const QSharedPointer<QWindowsFontEngineData> &fontEngineData)
    : QFontEngine(Win),
    m_fontEngineData(fontEngineData),
    _name(name),
    m_logfont(lf),
    ttf(0),
    hasOutline(0)
{
    qCDebug(lcQpaFonts) << __FUNCTION__ << name << lf.lfHeight;
    hfont = CreateFontIndirect(&m_logfont);
    if (!hfont) {
        qErrnoWarning("%s: CreateFontIndirect failed for family '%s'", __FUNCTION__, qPrintable(name));
        hfont = QWindowsFontDatabase::systemFont();
    }

    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);
    const BOOL res = GetTextMetrics(hdc, &tm);
    if (!res) {
        qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__);
        ZeroMemory(&tm, sizeof(TEXTMETRIC));
    }

    fontDef.pixelSize = -lf.lfHeight;
    fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);

    cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
    getCMap();

    if (!resolvedGetCharWidthI)
        resolveGetCharWidthI();

    // ### Properties accessed by QWin32PrintEngine (QtPrintSupport)
    QVariantMap userData;
    userData.insert(QStringLiteral("logFont"), QVariant::fromValue(m_logfont));
    userData.insert(QStringLiteral("hFont"), QVariant::fromValue(hfont));
    userData.insert(QStringLiteral("trueType"), QVariant(bool(ttf)));
    setUserData(userData);

    hasUnreliableOutline = (tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) == 0;
}

QWindowsFontEngine::~QWindowsFontEngine()
{
    if (designAdvances)
        free(designAdvances);

    if (widthCache)
        free(widthCache);

    // make sure we aren't by accident still selected
    SelectObject(m_fontEngineData->hdc, QWindowsFontDatabase::systemFont());

    if (!DeleteObject(hfont))
        qErrnoWarning("%s: QFontEngineWin: failed to delete font...", __FUNCTION__);
    qCDebug(lcQpaFonts) << __FUNCTION__ << _name;

    if (!uniqueFamilyName.isEmpty()) {
        if (QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration()) {
            QPlatformFontDatabase *pfdb = pi->fontDatabase();
            static_cast<QWindowsFontDatabase *>(pfdb)->derefUniqueFont(uniqueFamilyName);
        }
    }
}

glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const
{
    glyph_t glyph = 0;

    if (symbol) {
        glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
        if (glyph == 0 && ucs4 < 0x100)
            glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
    } else if (ttf) {
        glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
    } else if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) {
        glyph = ucs4;
    }

    return glyph;
}

HGDIOBJ QWindowsFontEngine::selectDesignFont() const
{
    LOGFONT f = m_logfont;
    f.lfHeight = -unitsPerEm;
    f.lfWidth = 0;
    HFONT designFont = CreateFontIndirect(&f);
    return SelectObject(m_fontEngineData->hdc, designFont);
}

bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const
{
    Q_ASSERT(glyphs->numGlyphs >= *nglyphs);
    if (*nglyphs < len) {
        *nglyphs = len;
        return false;
    }

    glyphs->numGlyphs = *nglyphs;
    *nglyphs = getGlyphIndexes(str, len, glyphs);

    if (!(flags & GlyphIndicesOnly))
        recalcAdvances(glyphs, flags);

    return true;
}

inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
{
    if (ptrGetCharWidthI)
        ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
}

void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
{
    HGDIOBJ oldFont = 0;
    HDC hdc = m_fontEngineData->hdc;
    if (ttf && (flags & DesignMetrics)) {
        for(int i = 0; i < glyphs->numGlyphs; i++) {
            unsigned int glyph = glyphs->glyphs[i];
            if(int(glyph) >= designAdvancesSize) {
                const int newSize = int(glyph + 256) >> 8 << 8;
                designAdvances = reinterpret_cast<QFixed *>(realloc(designAdvances, size_t(newSize) * sizeof(QFixed)));
                Q_CHECK_PTR(designAdvances);
                for(int i = designAdvancesSize; i < newSize; ++i)
                    designAdvances[i] = -1000000;
                designAdvancesSize = newSize;
            }
            if (designAdvances[glyph] < -999999) {
                if (!oldFont)
                    oldFont = selectDesignFont();

                int width = 0;
                calculateTTFGlyphWidth(hdc, glyph, width);
                designAdvances[glyph] = QFixed(width) / designToDevice;
            }
            glyphs->advances[i] = designAdvances[glyph];
        }
        if(oldFont)
            DeleteObject(SelectObject(hdc, oldFont));
    } else {
        for(int i = 0; i < glyphs->numGlyphs; i++) {
            unsigned int glyph = glyphs->glyphs[i];

            if (glyph >= widthCacheSize) {
                const uint newSize = (glyph + 256) >> 8 << 8;
                widthCache = reinterpret_cast<unsigned char *>(realloc(widthCache, newSize * sizeof(QFixed)));
                Q_CHECK_PTR(widthCache);
                memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
                widthCacheSize = newSize;
            }
            glyphs->advances[i] = widthCache[glyph];
            // font-width cache failed
            if (glyphs->advances[i].value() == 0) {
                int width = 0;
                if (!oldFont)
                    oldFont = SelectObject(hdc, hfont);

                if (!ttf) {
                    QChar ch[2] = { ushort(glyph), 0 };
                    int chrLen = 1;
                    if (QChar::requiresSurrogates(glyph)) {
                        ch[0] = QChar::highSurrogate(glyph);
                        ch[1] = QChar::lowSurrogate(glyph);
                        ++chrLen;
                    }
                    SIZE size = {0, 0};
                    GetTextExtentPoint32(hdc, reinterpret_cast<const wchar_t *>(ch), chrLen, &size);
                    width = size.cx;
                } else {
                    calculateTTFGlyphWidth(hdc, glyph, width);
                }
                glyphs->advances[i] = width;
                // if glyph's within cache range, store it for later
                if (width > 0 && width < 0x100)
                    widthCache[glyph] = uchar(width);
            }
        }

        if (oldFont)
            SelectObject(hdc, oldFont);
    }
}

glyph_metrics_t QWindowsFontEngine::boundingBox(const QGlyphLayout &glyphs)
{
    if (glyphs.numGlyphs == 0)
        return glyph_metrics_t();

    QFixed w = 0;
    for (int i = 0; i < glyphs.numGlyphs; ++i)
        w += glyphs.effectiveAdvance(i);

    return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0);
}

bool QWindowsFontEngine::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const
{
    Q_ASSERT(metrics != 0);

    HDC hdc = m_fontEngineData->hdc;

    GLYPHMETRICS gm;
    DWORD res = 0;
    MAT2 mat;
    mat.eM11.value = mat.eM22.value = 1;
    mat.eM11.fract = mat.eM22.fract = 0;
    mat.eM21.value = mat.eM12.value = 0;
    mat.eM21.fract = mat.eM12.fract = 0;

    if (t.type() > QTransform::TxTranslate) {
        // We need to set the transform using the HDC's world
        // matrix rather than using the MAT2 above, because the
        // results provided when transforming via MAT2 does not
        // match the glyphs that are drawn using a WorldTransform
        XFORM xform;
        xform.eM11 = FLOAT(t.m11());
        xform.eM12 = FLOAT(t.m12());
        xform.eM21 = FLOAT(t.m21());
        xform.eM22 = FLOAT(t.m22());
        xform.eDx = 0;
        xform.eDy = 0;
        SetGraphicsMode(hdc, GM_ADVANCED);
        SetWorldTransform(hdc, &xform);
    }

    uint format = GGO_METRICS;
    if (ttf)
        format |= GGO_GLYPH_INDEX;
    res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat);

    if (t.type() > QTransform::TxTranslate) {
        XFORM xform;
        xform.eM11 = xform.eM22 = 1;
        xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
        SetWorldTransform(hdc, &xform);
        SetGraphicsMode(hdc, GM_COMPATIBLE);
    }

    if (res != GDI_ERROR) {
        *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
                                   int(gm.gmBlackBoxX), int(gm.gmBlackBoxY),
                                   gm.gmCellIncX, gm.gmCellIncY);
        return true;
    } else {
        return false;
    }
}

glyph_metrics_t QWindowsFontEngine::boundingBox(glyph_t glyph, const QTransform &t)
{
    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);

    glyph_metrics_t glyphMetrics;
    bool success = getOutlineMetrics(glyph, t, &glyphMetrics);

    if (!ttf && !success) {
        // Bitmap fonts
        wchar_t ch = wchar_t(glyph);
        ABCFLOAT abc;
        GetCharABCWidthsFloat(hdc, ch, ch, &abc);
        int width = qRound(abc.abcfB);

        return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t);
    }

    return glyphMetrics;
}

QFixed QWindowsFontEngine::ascent() const
{
    return tm.tmAscent;
}

QFixed QWindowsFontEngine::descent() const
{
    return tm.tmDescent;
}

QFixed QWindowsFontEngine::leading() const
{
    return tm.tmExternalLeading;
}

namespace {
#   pragma pack(1)

    struct OS2Table
    {
        quint16 version;
        qint16  avgCharWidth;
        quint16 weightClass;
        quint16 widthClass;
        quint16 type;
        qint16  subscriptXSize;
        qint16  subscriptYSize;
        qint16  subscriptXOffset;
        qint16  subscriptYOffset;
        qint16  superscriptXSize;
        qint16  superscriptYSize;
        qint16  superscriptXOffset;
        qint16  superscriptYOffset;
        qint16  strikeOutSize;
        qint16  strikeOutPosition;
        qint16  familyClass;
        quint8  panose[10];
        quint32 unicodeRanges[4];
        quint8  vendorID[4];
        quint16 selection;
        quint16 firstCharIndex;
        quint16 lastCharIndex;
        qint16  typoAscender;
        qint16  typoDescender;
        qint16  typoLineGap;
        quint16 winAscent;
        quint16 winDescent;
        quint32 codepageRanges[2];
        qint16  height;
        qint16  capHeight;
        quint16 defaultChar;
        quint16 breakChar;
        quint16 maxContext;
    };

#   pragma pack()
}

QFixed QWindowsFontEngine::capHeight() const
{
    const QByteArray tableData = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
    if (size_t(tableData.size()) >= sizeof(OS2Table)) {
        const OS2Table *table = reinterpret_cast<const OS2Table *>(tableData.constData());
        if (qFromBigEndian<quint16>(table->version) >= 2) {
            qint16 capHeight = qFromBigEndian<qint16>(table->capHeight);
            if (capHeight > 0)
                return QFixed(capHeight) / designToDevice;
        }
    }
    return calculatedCapHeight();
}

QFixed QWindowsFontEngine::xHeight() const
{
    if(x_height >= 0)
        return x_height;
    return QFontEngine::xHeight();
}

QFixed QWindowsFontEngine::averageCharWidth() const
{
    return tm.tmAveCharWidth;
}

qreal QWindowsFontEngine::maxCharWidth() const
{
    return tm.tmMaxCharWidth;
}

enum { max_font_count = 256 };
static const ushort char_table[] = {
        40,
        67,
        70,
        75,
        86,
        88,
        89,
        91,
        102,
        114,
        124,
        127,
        205,
        645,
        884,
        922,
        1070,
        12386,
        0
};

static const int char_table_entries = sizeof(char_table)/sizeof(ushort);

#ifndef Q_CC_MINGW
void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
{
    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);

    if (ttf) {
        ABC abcWidths;
        GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
        if (leftBearing)
            *leftBearing = abcWidths.abcA;
        if (rightBearing)
            *rightBearing = abcWidths.abcC;
    } else {
        QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
    }
}
#endif // Q_CC_MINGW

bool QWindowsFontEngine::hasUnreliableGlyphOutline() const
{
    return hasUnreliableOutline || QFontEngine::hasUnreliableGlyphOutline();
}

qreal QWindowsFontEngine::minLeftBearing() const
{
    if (lbearing == SHRT_MIN)
        minRightBearing(); // calculates both

    return lbearing;
}

qreal QWindowsFontEngine::minRightBearing() const
{
    if (rbearing == SHRT_MIN) {
        int ml = 0;
        int mr = 0;
        HDC hdc = m_fontEngineData->hdc;
        SelectObject(hdc, hfont);
        if (ttf) {
            ABC *abc = 0;
            int n = tm.tmLastChar - tm.tmFirstChar;
            if (n <= max_font_count) {
                abc = new ABC[n+1];
                GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
            } else {
                abc = new ABC[char_table_entries+1];
                for(int i = 0; i < char_table_entries; i++)
                    GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i);
                n = char_table_entries;
            }
            ml = abc[0].abcA;
            mr = abc[0].abcC;
            for (int i = 1; i < n; i++) {
                if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
                    ml = qMin(ml,abc[i].abcA);
                    mr = qMin(mr,abc[i].abcC);
                }
            }
            delete [] abc;
        } else {
            ABCFLOAT *abc = 0;
            int n = tm.tmLastChar - tm.tmFirstChar+1;
            if (n <= max_font_count) {
                abc = new ABCFLOAT[n];
                GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
            } else {
                abc = new ABCFLOAT[char_table_entries];
                for(int i = 0; i < char_table_entries; i++)
                    GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
                n = char_table_entries;
            }
            float fml = abc[0].abcfA;
            float fmr = abc[0].abcfC;
            for (int i=1; i<n; i++) {
                if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
                    fml = qMin(fml,abc[i].abcfA);
                    fmr = qMin(fmr,abc[i].abcfC);
                }
            }
            ml = int(fml - 0.9999);
            mr = int(fmr - 0.9999);
            delete [] abc;
        }
        lbearing = ml;
        rbearing = mr;
    }

    return rbearing;
}

static inline double qt_fixed_to_double(const FIXED &p) {
    return ((p.value << 16) + p.fract) / 65536.0;
}

static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale, qreal stretch) {
    return QPointF(qt_fixed_to_double(pt.x) * scale * stretch, -qt_fixed_to_double(pt.y) * scale);
}

#ifndef GGO_UNHINTED
#define GGO_UNHINTED 0x0100
#endif

static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
                           QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0,
                           qreal scale = 1.0, qreal stretch = 1.0)
{
    MAT2 mat;
    mat.eM11.value = mat.eM22.value = 1;
    mat.eM11.fract = mat.eM22.fract = 0;
    mat.eM21.value = mat.eM12.value = 0;
    mat.eM21.fract = mat.eM12.fract = 0;

    GLYPHMETRICS gMetric;
    memset(&gMetric, 0, sizeof(GLYPHMETRICS));

    if (metric) {
        // If metrics requested, retrieve first using GGO_METRICS, because the returned
        // values are incorrect for OpenType PS fonts if obtained at the same time as the
        // glyph paths themselves (ie. with GGO_NATIVE as the format).
        uint format = GGO_METRICS;
        if (ttf)
            format |= GGO_GLYPH_INDEX;
        if (GetGlyphOutline(hdc, glyph, format, &gMetric, 0, 0, &mat) == GDI_ERROR)
            return false;
        // #### obey scale
        *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
                                  int(gMetric.gmBlackBoxX), int(gMetric.gmBlackBoxY),
                                  gMetric.gmCellIncX, gMetric.gmCellIncY);
    }

    uint glyphFormat = GGO_NATIVE;

    if (ttf)
        glyphFormat |= GGO_GLYPH_INDEX;

    const DWORD bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
    if (bufferSize == GDI_ERROR)
        return false;

    char *dataBuffer = new char[bufferSize];
    DWORD ret = GDI_ERROR;
    ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat);
    if (ret == GDI_ERROR) {
        delete [] dataBuffer;
        return false;
    }

    DWORD offset = 0;
    DWORD headerOffset = 0;

    QPointF oset = position.toPointF();
    while (headerOffset < bufferSize) {
        const TTPOLYGONHEADER *ttph = reinterpret_cast<const TTPOLYGONHEADER *>(dataBuffer + headerOffset);

        QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale, stretch));
        path->moveTo(lastPoint + oset);
        offset += sizeof(TTPOLYGONHEADER);
        while (offset < headerOffset + ttph->cb) {
            const TTPOLYCURVE *curve = reinterpret_cast<const TTPOLYCURVE *>(dataBuffer + offset);
            switch (curve->wType) {
            case TT_PRIM_LINE: {
                for (int i=0; i<curve->cpfx; ++i) {
                    QPointF p = qt_to_qpointf(curve->apfx[i], scale, stretch) + oset;
                    path->lineTo(p);
                }
                break;
            }
            case TT_PRIM_QSPLINE: {
                const QPainterPath::Element &elm = path->elementAt(path->elementCount()-1);
                QPointF prev(elm.x, elm.y);
                QPointF endPoint;
                for (int i=0; i<curve->cpfx - 1; ++i) {
                    QPointF p1 = qt_to_qpointf(curve->apfx[i], scale, stretch) + oset;
                    QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale, stretch) + oset;
                    if (i < curve->cpfx - 2) {
                        endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);
                    } else {
                        endPoint = p2;
                    }

                    path->quadTo(p1, endPoint);
                    prev = endPoint;
                }

                break;
            }
            case TT_PRIM_CSPLINE: {
                for (int i=0; i<curve->cpfx; ) {
                    QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset;
                    QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset;
                    QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset;
                    path->cubicTo(p2, p3, p4);
                }
                break;
            }
            default:
                qWarning("QFontEngineWin::addOutlineToPath, unhandled switch case");
            }
            offset += sizeof(TTPOLYCURVE) + (curve->cpfx-1) * sizeof(POINTFX);
        }
        path->closeSubpath();
        headerOffset += ttph->cb;
    }
    delete [] dataBuffer;

    return true;
}

void QWindowsFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
                                     QPainterPath *path, QTextItem::RenderFlags)
{
    LOGFONT lf = m_logfont;
    // The sign must be negative here to make sure we match against character height instead of
    // hinted cell height. This ensures that we get linear matching, and we need this for
    // paths since we later on apply a scaling transform to the glyph outline to get the
    // font at the correct pixel size.
    lf.lfHeight = -unitsPerEm;
    lf.lfWidth = 0;
    HFONT hf = CreateFontIndirect(&lf);
    HDC hdc = m_fontEngineData->hdc;
    HGDIOBJ oldfont = SelectObject(hdc, hf);

    qreal scale = qreal(fontDef.pixelSize) / unitsPerEm;
    qreal stretch = fontDef.stretch ? qreal(fontDef.stretch) / 100 : 1.0;
    for(int i = 0; i < nglyphs; ++i) {
        if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
                            scale, stretch)) {
            // Some windows fonts, like "Modern", are vector stroke
            // fonts, which are reported as TMPF_VECTOR but do not
            // support GetGlyphOutline, and thus we set this bit so
            // that addOutLineToPath can check it and return safely...
            hasOutline = false;
            break;
        }
    }
    DeleteObject(SelectObject(hdc, oldfont));
}

void QWindowsFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
                                      QPainterPath *path, QTextItem::RenderFlags flags)
{
    if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
        hasOutline = true;
        QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
        if (hasOutline)  {
            // has_outline is set to false if addGlyphToPath gets
            // false from GetGlyphOutline, meaning its not an outline
            // font.
            return;
        }
    }
    QFontEngine::addBitmapFontToPath(x, y, glyphs, path, flags);
}

QFontEngine::FaceId QWindowsFontEngine::faceId() const
{
    return _faceId;
}

QT_BEGIN_INCLUDE_NAMESPACE
#include <qdebug.h>
QT_END_INCLUDE_NAMESPACE

int QWindowsFontEngine::synthesized() const
{
    if(synthesized_flags == -1) {
        synthesized_flags = 0;
        if(ttf) {
            const DWORD HEAD = MAKE_LITTLE_ENDIAN_TAG('h', 'e', 'a', 'd');
            HDC hdc = m_fontEngineData->hdc;
            SelectObject(hdc, hfont);
            uchar data[4];
            GetFontData(hdc, HEAD, 44, &data, 4);
            USHORT macStyle = qt_getUShort(data);
            if (tm.tmItalic && !(macStyle & 2))
                synthesized_flags = SynthesizedItalic;
            if (fontDef.stretch != 100 && ttf)
                synthesized_flags |= SynthesizedStretch;
            if (tm.tmWeight >= 500 && tm.tmWeight < 750 && !(macStyle & 1))
                synthesized_flags |= SynthesizedBold;
            //qDebug() << "font is" << _name <<
            //    "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags;
        }
    }
    return synthesized_flags;
}

QFixed QWindowsFontEngine::emSquareSize() const
{
    return unitsPerEm;
}

QFontEngine::Properties QWindowsFontEngine::properties() const
{
    LOGFONT lf = m_logfont;
    lf.lfHeight = unitsPerEm;
    HFONT hf = CreateFontIndirect(&lf);
    HDC hdc = m_fontEngineData->hdc;
    HGDIOBJ oldfont = SelectObject(hdc, hf);
    OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
    Properties p;
    p.emSquare = unitsPerEm;
    p.italicAngle = otm->otmItalicAngle;
    const QByteArray name = stringFromOutLineTextMetric(otm, otm->otmpFamilyName).toLatin1()
        + stringFromOutLineTextMetric(otm, otm->otmpStyleName).toLatin1();
    p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(name);
    p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top,
                           otm->otmrcFontBox.right - otm->otmrcFontBox.left,
                           otm->otmrcFontBox.top - otm->otmrcFontBox.bottom);
    p.ascent = otm->otmAscent;
    p.descent = -otm->otmDescent;
    p.leading = int(otm->otmLineGap);
    p.capHeight = 0;
    p.lineWidth = otm->otmsUnderscoreSize;
    free(otm);
    DeleteObject(SelectObject(hdc, oldfont));
    return p;
}

void QWindowsFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
{
    LOGFONT lf = m_logfont;
    lf.lfHeight = -unitsPerEm;
    int flags = synthesized();
    if(flags & SynthesizedItalic)
        lf.lfItalic = false;
    lf.lfWidth = 0;
    HFONT hf = CreateFontIndirect(&lf);
    HDC hdc = m_fontEngineData->hdc;
    HGDIOBJ oldfont = SelectObject(hdc, hf);
    QFixedPoint p;
    p.x = 0;
    p.y = 0;
    addGlyphToPath(glyph, p, hdc, path, ttf, metrics);
    DeleteObject(SelectObject(hdc, oldfont));
}

bool QWindowsFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
    if (!ttf && !cffTable)
        return false;
    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);
    DWORD t = qbswap<quint32>(tag);
    *length = GetFontData(hdc, t, 0, buffer, *length);
    Q_ASSERT(*length == GDI_ERROR || int(*length) > 0);
    return *length != GDI_ERROR;
}

#if !defined(CLEARTYPE_QUALITY)
#    define CLEARTYPE_QUALITY       5
#endif

QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, int margin,
                                                  const QTransform &t,
                                                  QImage::Format mask_format)
{
    Q_UNUSED(mask_format)
    glyph_metrics_t gm = boundingBox(glyph);

//     printf(" -> for glyph %4x\n", glyph);

    int gx = gm.x.toInt();
    int gy = gm.y.toInt();
    int iw = gm.width.toInt();
    int ih = gm.height.toInt();

    if (iw <= 0 || ih <= 0)
        return 0;

    bool has_transformation = t.type() > QTransform::TxTranslate;

    unsigned int options = ttf ? ETO_GLYPH_INDEX : 0;
    XFORM xform;

    if (has_transformation) {
        xform.eM11 = FLOAT(t.m11());
        xform.eM12 = FLOAT(t.m12());
        xform.eM21 = FLOAT(t.m21());
        xform.eM22 = FLOAT(t.m22());
        xform.eDx = margin;
        xform.eDy = margin;

        const HDC hdc = m_fontEngineData->hdc;

        SetGraphicsMode(hdc, GM_ADVANCED);
        SetWorldTransform(hdc, &xform);
        HGDIOBJ old_font = SelectObject(hdc, font);

        const UINT ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0);
        GLYPHMETRICS tgm;
        MAT2 mat;
        memset(&mat, 0, sizeof(mat));
        mat.eM11.value = mat.eM22.value = 1;

        const DWORD result = GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat);

        XFORM identity = {1, 0, 0, 1, 0, 0};
        SetWorldTransform(hdc, &identity);
        SetGraphicsMode(hdc, GM_COMPATIBLE);
        SelectObject(hdc, old_font);

        if (result == GDI_ERROR) {
            const int errorCode = int(GetLastError());
            qErrnoWarning(errorCode, "QWinFontEngine: unable to query transformed glyph metrics (GetGlyphOutline() failed, error %d)...", errorCode);
            return 0;
        }

        iw = int(tgm.gmBlackBoxX);
        ih = int(tgm.gmBlackBoxY);

        xform.eDx -= tgm.gmptGlyphOrigin.x;
        xform.eDy += tgm.gmptGlyphOrigin.y;
    }

    // The padding here needs to be kept in sync with the values in alphaMapBoundingBox.
    QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin,
                                                      ih + 2 * margin,
                                                      QWindowsNativeImage::systemFormat());

    /*If cleartype is enabled we use the standard system format even on Windows CE
      and not the special textbuffer format we have to use if cleartype is disabled*/

    ni->image().fill(0xffffffff);

    HDC hdc = ni->hdc();

    SelectObject(hdc, GetStockObject(NULL_BRUSH));
    SelectObject(hdc, GetStockObject(BLACK_PEN));
    SetTextColor(hdc, RGB(0,0,0));
    SetBkMode(hdc, TRANSPARENT);
    SetTextAlign(hdc, TA_BASELINE);

    HGDIOBJ old_font = SelectObject(hdc, font);

    if (has_transformation) {
        SetGraphicsMode(hdc, GM_ADVANCED);
        SetWorldTransform(hdc, &xform);
        ExtTextOut(hdc, 0, 0, options, 0, reinterpret_cast<LPCWSTR>(&glyph), 1, 0);
    } else {
        ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, reinterpret_cast<LPCWSTR>(&glyph), 1, 0);
    }

    SelectObject(hdc, old_font);
    return ni;
}

glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat format)
{
    int margin = 0;
    if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
        margin = glyphMargin(QFontEngine::Format_A32);
    glyph_metrics_t gm = boundingBox(glyph, matrix);
    gm.width += margin * 2;
    gm.height += margin * 2;
    return gm;
}

QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
{
    HFONT font = hfont;

    bool clearTypeTemporarilyDisabled = (m_fontEngineData->clearTypeEnabled && m_logfont.lfQuality != NONANTIALIASED_QUALITY);
    if (clearTypeTemporarilyDisabled) {
        LOGFONT lf = m_logfont;
        lf.lfQuality = ANTIALIASED_QUALITY;
        font = CreateFontIndirect(&lf);
    }
    QImage::Format mask_format = QWindowsNativeImage::systemFormat();
    mask_format = QImage::Format_RGB32;

    const QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
    if (mask == 0) {
        if (m_fontEngineData->clearTypeEnabled)
            DeleteObject(font);
        return QImage();
    }

    QImage alphaMap(mask->width(), mask->height(), QImage::Format_Alpha8);


    // Copy data... Cannot use QPainter here as GDI has messed up the
    // Alpha channel of the ni.image pixels...
    for (int y=0; y<mask->height(); ++y) {
        uchar *dest = alphaMap.scanLine(y);
        if (mask->image().format() == QImage::Format_RGB16) {
            const qint16 *src = reinterpret_cast<const qint16 *>(mask->image().constScanLine(y));
            for (int x=0; x<mask->width(); ++x)
                dest[x] = 255 - qGray(src[x]);
        } else {
            const uint *src = reinterpret_cast<const uint *>(mask->image().constScanLine(y));
            for (int x=0; x<mask->width(); ++x) {
                if (QWindowsNativeImage::systemFormat() == QImage::Format_RGB16)
                    dest[x] = 255 - qGray(src[x]);
                else
                    dest[x] = 255 - (m_fontEngineData->pow_gamma[qGray(src[x])] * 255. / 2047.);
            }
        }
    }

    // Cleanup...
    delete mask;
    if (clearTypeTemporarilyDisabled) {
        DeleteObject(font);
    }

    return alphaMap;
}

#define SPI_GETFONTSMOOTHINGCONTRAST           0x200C
#define SPI_SETFONTSMOOTHINGCONTRAST           0x200D

QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTransform &t)
{
    HFONT font = hfont;

    UINT contrast;
    SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0);
    SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, reinterpret_cast<void *>(quintptr(1000)), 0);

    int margin = glyphMargin(QFontEngine::Format_A32);
    QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32);
    SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, reinterpret_cast<void *>(quintptr(contrast)), 0);

    if (mask == 0)
        return QImage();

    // Gracefully handle the odd case when the display is 16-bit
    const QImage source = mask->image().depth() == 32
                          ? mask->image()
                          : mask->image().convertToFormat(QImage::Format_RGB32);

    QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
    for (int y=0; y<mask->height(); ++y) {
        auto dest = reinterpret_cast<uint *>(rgbMask.scanLine(y));
        const uint *src = reinterpret_cast<const uint *>(source.constScanLine(y));
        for (int x=0; x<mask->width(); ++x) {
            dest[x] = 0xffffffff - (0x00ffffff & src[x]);
        }
    }

    delete mask;

    return rgbMask;
}

QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const
{
    QFontDef request = fontDef;
    QString actualFontName = request.family;
    if (!uniqueFamilyName.isEmpty())
        request.family = uniqueFamilyName;
    request.pixelSize = pixelSize;
    const QString faceName = QString::fromWCharArray(m_logfont.lfFaceName);

    QFontEngine *fontEngine =
        QWindowsFontDatabase::createEngine(request, faceName,
                                           QWindowsFontDatabase::defaultVerticalDPI(),
                                           m_fontEngineData);
    if (fontEngine) {
        fontEngine->fontDef.family = actualFontName;
        if (!uniqueFamilyName.isEmpty()) {
            static_cast<QWindowsFontEngine *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName);
            if (QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration()) {
                QPlatformFontDatabase *pfdb = pi->fontDatabase();
                static_cast<QWindowsFontDatabase *>(pfdb)->refUniqueFont(uniqueFamilyName);
            }
        }
    }
    return fontEngine;
}

Qt::HANDLE QWindowsFontEngine::handle() const
{
    return hfont;
}

void QWindowsFontEngine::initFontInfo(const QFontDef &request,
                                      int dpi)
{
    fontDef = request; // most settings are equal
    HDC dc = m_fontEngineData->hdc;
    SelectObject(dc, hfont);
    wchar_t n[64];
    GetTextFace(dc, 64, n);
    fontDef.family = QString::fromWCharArray(n);
    fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
    if (fontDef.pointSize < 0) {
        fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
    } else if (fontDef.pixelSize == -1) {
        fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
    }
}

bool QWindowsFontEngine::supportsTransformation(const QTransform &transform) const
{
    // Support all transformations for ttf files, and translations for raster fonts
    return ttf || transform.type() <= QTransform::TxTranslate;
}

QT_END_NAMESPACE
