/****************************************************************************
**
** 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 "qdir.h"
#include "qmetatype.h"
#include "qtextstream.h"
#include "qvariant.h"
#include "qfontengine_ft_p.h"
#include "private/qimage_p.h"
#include <private/qstringiterator_p.h>
#include <qguiapplication.h>
#include <qscreen.h>
#include <qpa/qplatformscreen.h>
#include <QtCore/QUuid>

#ifndef QT_NO_FREETYPE

#include "qfile.h"
#include "qfileinfo.h"
#include <qscopedvaluerollback.h>
#include "qthreadstorage.h"
#include <qmath.h>
#include <qendian.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include FT_SYNTHESIS_H
#include FT_TRUETYPE_TABLES_H
#include FT_TYPE1_TABLES_H
#include FT_GLYPH_H
#include FT_MODULE_H
#include FT_LCD_FILTER_H

#if defined(FT_CONFIG_OPTIONS_H)
#include FT_CONFIG_OPTIONS_H
#endif

#if defined(FT_FONT_FORMATS_H)
#include FT_FONT_FORMATS_H
#endif

#ifdef QT_LINUXBASE
#include FT_ERRORS_H
#endif

#if !defined(QT_MAX_CACHED_GLYPH_SIZE)
#  define QT_MAX_CACHED_GLYPH_SIZE 64
#endif

QT_BEGIN_NAMESPACE

#define FLOOR(x)    ((x) & -64)
#define CEIL(x)     (((x)+63) & -64)
#define TRUNC(x)    ((x) >> 6)
#define ROUND(x)    (((x)+32) & -64)

static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
{
    FT_Face face = (FT_Face)user_data;

    bool result = false;
    if (FT_IS_SFNT(face)) {
        FT_ULong len = *length;
        result = FT_Load_Sfnt_Table(face, tag, 0, buffer, &len) == FT_Err_Ok;
        *length = len;
        Q_ASSERT(!result || int(*length) > 0);
    }

    return result;
}

static QFontEngineFT::Glyph emptyGlyph;

static const QFontEngine::HintStyle ftInitialDefaultHintStyle =
#ifdef Q_OS_WIN
    QFontEngineFT::HintFull;
#else
    QFontEngineFT::HintNone;
#endif

// -------------------------- Freetype support ------------------------------

class QtFreetypeData
{
public:
    QtFreetypeData()
        : library(0)
    { }
    ~QtFreetypeData();

    FT_Library library;
    QHash<QFontEngine::FaceId, QFreetypeFace *> faces;
};

QtFreetypeData::~QtFreetypeData()
{
    for (QHash<QFontEngine::FaceId, QFreetypeFace *>::ConstIterator iter = faces.cbegin(); iter != faces.cend(); ++iter)
        iter.value()->cleanup();
    faces.clear();
    FT_Done_FreeType(library);
    library = 0;
}

Q_GLOBAL_STATIC(QThreadStorage<QtFreetypeData *>, theFreetypeData)

QtFreetypeData *qt_getFreetypeData()
{
    QtFreetypeData *&freetypeData = theFreetypeData()->localData();
    if (!freetypeData)
        freetypeData = new QtFreetypeData;
    if (!freetypeData->library) {
        FT_Init_FreeType(&freetypeData->library);
#if defined(FT_FONT_FORMATS_H)
        // Freetype defaults to disabling stem-darkening on CFF, we re-enable it.
        FT_Bool no_darkening = false;
        FT_Property_Set(freetypeData->library, "cff", "no-stem-darkening", &no_darkening);
#endif
    }
    return freetypeData;
}

FT_Library qt_getFreetype()
{
    QtFreetypeData *freetypeData = qt_getFreetypeData();
    Q_ASSERT(freetypeData->library);
    return freetypeData->library;
}

int QFreetypeFace::fsType() const
{
    int fsType = 0;
    TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
    if (os2)
        fsType = os2->fsType;
    return fsType;
}

int QFreetypeFace::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints)
{
    if (int error = FT_Load_Glyph(face, glyph, flags))
        return error;

    if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
        return Err_Invalid_SubTable;

    *nPoints = face->glyph->outline.n_points;
    if (!(*nPoints))
        return Err_Ok;

    if (point > *nPoints)
        return Err_Invalid_SubTable;

    *xpos = QFixed::fromFixed(face->glyph->outline.points[point].x);
    *ypos = QFixed::fromFixed(face->glyph->outline.points[point].y);

    return Err_Ok;
}

bool QFreetypeFace::isScalableBitmap() const
{
#ifdef FT_HAS_COLOR
    return !FT_IS_SCALABLE(face) && FT_HAS_COLOR(face);
#else
    return false;
#endif
}

extern QByteArray qt_fontdata_from_index(int);

/*
 * One font file can contain more than one font (bold/italic for example)
 * find the right one and return it.
 *
 * Returns the freetype face or 0 in case of an empty file or any other problems
 * (like not being able to open the file)
 */
QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
                                      const QByteArray &fontData)
{
    if (face_id.filename.isEmpty() && fontData.isEmpty())
        return 0;

    QtFreetypeData *freetypeData = qt_getFreetypeData();

    QFreetypeFace *freetype = freetypeData->faces.value(face_id, 0);
    if (freetype) {
        freetype->ref.ref();
    } else {
        QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace);
        FT_Face face;
        if (!face_id.filename.isEmpty()) {
            QString fileName = QFile::decodeName(face_id.filename);
            if (face_id.filename.startsWith(":qmemoryfonts/")) {
                // from qfontdatabase.cpp
                QByteArray idx = face_id.filename;
                idx.remove(0, 14); // remove ':qmemoryfonts/'
                bool ok = false;
                newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
                if (!ok)
                    newFreetype->fontData = QByteArray();
            } else if (!QFileInfo(fileName).isNativePath()) {
                QFile file(fileName);
                if (!file.open(QIODevice::ReadOnly)) {
                    return 0;
                }
                newFreetype->fontData = file.readAll();
            }
        } else {
            newFreetype->fontData = fontData;
        }
        if (!newFreetype->fontData.isEmpty()) {
            if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) {
                return 0;
            }
        } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) {
            return 0;
        }
        newFreetype->face = face;

        newFreetype->ref.storeRelaxed(1);
        newFreetype->xsize = 0;
        newFreetype->ysize = 0;
        newFreetype->matrix.xx = 0x10000;
        newFreetype->matrix.yy = 0x10000;
        newFreetype->matrix.xy = 0;
        newFreetype->matrix.yx = 0;
        newFreetype->unicode_map = 0;
        newFreetype->symbol_map = 0;

        memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache));

        for (int i = 0; i < newFreetype->face->num_charmaps; ++i) {
            FT_CharMap cm = newFreetype->face->charmaps[i];
            switch(cm->encoding) {
            case FT_ENCODING_UNICODE:
                newFreetype->unicode_map = cm;
                break;
            case FT_ENCODING_APPLE_ROMAN:
            case FT_ENCODING_ADOBE_LATIN_1:
                if (!newFreetype->unicode_map || newFreetype->unicode_map->encoding != FT_ENCODING_UNICODE)
                    newFreetype->unicode_map = cm;
                break;
            case FT_ENCODING_ADOBE_CUSTOM:
            case FT_ENCODING_MS_SYMBOL:
                if (!newFreetype->symbol_map)
                    newFreetype->symbol_map = cm;
                break;
            default:
                break;
            }
        }

        if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1)
            FT_Set_Char_Size(face, newFreetype->face->available_sizes[0].x_ppem, newFreetype->face->available_sizes[0].y_ppem, 0, 0);

        FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map);
        QT_TRY {
            freetypeData->faces.insert(face_id, newFreetype.data());
        } QT_CATCH(...) {
            newFreetype.take()->release(face_id);
            // we could return null in principle instead of throwing
            QT_RETHROW;
        }
        freetype = newFreetype.take();
    }
    return freetype;
}

void QFreetypeFace::cleanup()
{
    hbFace.reset();
    FT_Done_Face(face);
    face = 0;
}

void QFreetypeFace::release(const QFontEngine::FaceId &face_id)
{
    if (!ref.deref()) {
        if (face) {
            QtFreetypeData *freetypeData = qt_getFreetypeData();

            cleanup();

            auto it = freetypeData->faces.constFind(face_id);
            if (it != freetypeData->faces.constEnd())
                freetypeData->faces.erase(it);

            if (freetypeData->faces.isEmpty()) {
                FT_Done_FreeType(freetypeData->library);
                freetypeData->library = 0;
            }
        }

        delete this;
    }
}


void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing, QFixed *scalableBitmapScaleFactor)
{
    *ysize = qRound(fontDef.pixelSize * 64);
    *xsize = *ysize * fontDef.stretch / 100;
    *scalableBitmapScaleFactor = 1;
    *outline_drawing = false;

    if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) {
        int best = 0;
        if (!isScalableBitmap()) {
            /*
             * Bitmap only faces must match exactly, so find the closest
             * one (height dominant search)
             */
            for (int i = 1; i < face->num_fixed_sizes; i++) {
                if (qAbs(*ysize -  face->available_sizes[i].y_ppem) <
                    qAbs(*ysize - face->available_sizes[best].y_ppem) ||
                    (qAbs(*ysize - face->available_sizes[i].y_ppem) ==
                     qAbs(*ysize - face->available_sizes[best].y_ppem) &&
                     qAbs(*xsize - face->available_sizes[i].x_ppem) <
                     qAbs(*xsize - face->available_sizes[best].x_ppem))) {
                    best = i;
                }
            }
        } else {
            // Select the shortest bitmap strike whose height is larger than the desired height
            for (int i = 1; i < face->num_fixed_sizes; i++) {
                if (face->available_sizes[i].y_ppem < *ysize) {
                    if (face->available_sizes[i].y_ppem > face->available_sizes[best].y_ppem)
                        best = i;
                } else if (face->available_sizes[best].y_ppem < *ysize) {
                    best = i;
                } else if (face->available_sizes[i].y_ppem < face->available_sizes[best].y_ppem) {
                    best = i;
                }
            }
        }

        // According to freetype documentation we must use FT_Select_Size
        // to make sure we can select the desired bitmap strike index
        if (FT_Select_Size(face, best) == 0) {
            if (isScalableBitmap())
                *scalableBitmapScaleFactor = QFixed::fromReal((qreal)fontDef.pixelSize / face->available_sizes[best].height);
            *xsize = face->available_sizes[best].x_ppem;
            *ysize = face->available_sizes[best].y_ppem;
        } else {
            *xsize = *ysize = 0;
        }
    } else {
        *outline_drawing = (*xsize > (QT_MAX_CACHED_GLYPH_SIZE<<6) || *ysize > (QT_MAX_CACHED_GLYPH_SIZE<<6));
    }
}

QFontEngine::Properties QFreetypeFace::properties() const
{
    QFontEngine::Properties p;
    p.postscriptName = FT_Get_Postscript_Name(face);
    PS_FontInfoRec font_info;
    if (FT_Get_PS_Font_Info(face, &font_info) == 0)
        p.copyright = font_info.notice;
    if (FT_IS_SCALABLE(face)) {
        p.ascent = face->ascender;
        p.descent = -face->descender;
        p.leading = face->height - face->ascender + face->descender;
        p.emSquare = face->units_per_EM;
        p.boundingBox = QRectF(face->bbox.xMin, -face->bbox.yMax,
                               face->bbox.xMax - face->bbox.xMin,
                               face->bbox.yMax - face->bbox.yMin);
    } else {
        p.ascent = QFixed::fromFixed(face->size->metrics.ascender);
        p.descent = QFixed::fromFixed(-face->size->metrics.descender);
        p.leading = QFixed::fromFixed(face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender);
        p.emSquare = face->size->metrics.y_ppem;
//        p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
        p.boundingBox = QRectF(0, -p.ascent.toReal(),
                               face->size->metrics.max_advance/64, (p.ascent + p.descent).toReal() );
    }
    p.italicAngle = 0;
    p.capHeight = p.ascent;
    p.lineWidth = face->underline_thickness;

    return p;
}

bool QFreetypeFace::getSfntTable(uint tag, uchar *buffer, uint *length) const
{
    return ft_getSfntTable(face, tag, buffer, length);
}

/* Some fonts (such as MingLiu rely on hinting to scale different
   components to their correct sizes. While this is really broken (it
   should be done in the component glyph itself, not the hinter) we
   will have to live with it.

   This means we can not use FT_LOAD_NO_HINTING to get the glyph
   outline. All we can do is to load the unscaled glyph and scale it
   down manually when required.
*/
static void scaleOutline(FT_Face face, FT_GlyphSlot g, FT_Fixed x_scale, FT_Fixed y_scale)
{
    x_scale = FT_MulDiv(x_scale, 1 << 10, face->units_per_EM);
    y_scale = FT_MulDiv(y_scale, 1 << 10, face->units_per_EM);
    FT_Vector *p = g->outline.points;
    const FT_Vector *e = p + g->outline.n_points;
    while (p < e) {
        p->x = FT_MulFix(p->x, x_scale);
        p->y = FT_MulFix(p->y, y_scale);
        ++p;
    }
}

#define GLYPH2PATH_DEBUG QT_NO_QDEBUG_MACRO // qDebug
void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale)
{
    const qreal factor = 1/64.;
    scaleOutline(face, g, x_scale, y_scale);

    QPointF cp = point.toPointF();

    // convert the outline to a painter path
    int i = 0;
    for (int j = 0; j < g->outline.n_contours; ++j) {
        int last_point = g->outline.contours[j];
        GLYPH2PATH_DEBUG() << "contour:" << i << "to" << last_point;
        QPointF start = QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
        if (!(g->outline.tags[i] & 1)) {               // start point is not on curve:
            if (!(g->outline.tags[last_point] & 1)) {  // end point is not on curve:
                GLYPH2PATH_DEBUG() << "  start and end point are not on curve";
                start = (QPointF(g->outline.points[last_point].x*factor,
                                -g->outline.points[last_point].y*factor) + start) / 2.0;
            } else {
                GLYPH2PATH_DEBUG() << "  end point is on curve, start is not";
                start = QPointF(g->outline.points[last_point].x*factor,
                               -g->outline.points[last_point].y*factor);
            }
            --i;   // to use original start point as control point below
        }
        start += cp;
        GLYPH2PATH_DEBUG() << "  start at" << start;

        path->moveTo(start);
        QPointF c[4];
        c[0] = start;
        int n = 1;
        while (i < last_point) {
            ++i;
            c[n] = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
            GLYPH2PATH_DEBUG() << "    " << i << c[n] << "tag =" << (int)g->outline.tags[i]
                               << ": on curve =" << (bool)(g->outline.tags[i] & 1);
            ++n;
            switch (g->outline.tags[i] & 3) {
            case 2:
                // cubic bezier element
                if (n < 4)
                    continue;
                c[3] = (c[3] + c[2])/2;
                --i;
                break;
            case 0:
                // quadratic bezier element
                if (n < 3)
                    continue;
                c[3] = (c[1] + c[2])/2;
                c[2] = (2*c[1] + c[3])/3;
                c[1] = (2*c[1] + c[0])/3;
                --i;
                break;
            case 1:
            case 3:
                if (n == 2) {
                    GLYPH2PATH_DEBUG() << "  lineTo" << c[1];
                    path->lineTo(c[1]);
                    c[0] = c[1];
                    n = 1;
                    continue;
                } else if (n == 3) {
                    c[3] = c[2];
                    c[2] = (2*c[1] + c[3])/3;
                    c[1] = (2*c[1] + c[0])/3;
                }
                break;
            }
            GLYPH2PATH_DEBUG() << "  cubicTo" << c[1] << c[2] << c[3];
            path->cubicTo(c[1], c[2], c[3]);
            c[0] = c[3];
            n = 1;
        }

        if (n == 1) {
            GLYPH2PATH_DEBUG() << "  closeSubpath";
            path->closeSubpath();
        } else {
            c[3] = start;
            if (n == 2) {
                c[2] = (2*c[1] + c[3])/3;
                c[1] = (2*c[1] + c[0])/3;
            }
            GLYPH2PATH_DEBUG() << "  close cubicTo" << c[1] << c[2] << c[3];
            path->cubicTo(c[1], c[2], c[3]);
        }
        ++i;
    }
}

extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path);

void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path)
{
    if (slot->format != FT_GLYPH_FORMAT_BITMAP
        || slot->bitmap.pixel_mode != FT_PIXEL_MODE_MONO)
        return;

    QPointF cp = point.toPointF();
    qt_addBitmapToPath(cp.x() + TRUNC(slot->metrics.horiBearingX), cp.y() - TRUNC(slot->metrics.horiBearingY),
                       slot->bitmap.buffer, slot->bitmap.pitch, slot->bitmap.width, slot->bitmap.rows, path);
}

static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
{
    const int offs = bgr ? -1 : 1;
    const int w = width * 3;
    while (height--) {
        uint *dd = dst;
        for (int x = 0; x < w; x += 3) {
            uchar red = src[x + 1 - offs];
            uchar green = src[x + 1];
            uchar blue = src[x + 1 + offs];
            *dd++ = (0xFFU << 24) | (red << 16) | (green << 8) | blue;
        }
        dst += width;
        src += src_pitch;
    }
}

static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
{
    const int offs = bgr ? -src_pitch : src_pitch;
    while (height--) {
        for (int x = 0; x < width; x++) {
            uchar red = src[x + src_pitch - offs];
            uchar green = src[x + src_pitch];
            uchar blue = src[x + src_pitch + offs];
            *dst++ = (0XFFU << 24) | (red << 16) | (green << 8) | blue;
        }
        src += 3*src_pitch;
    }
}

static QFontEngine::SubpixelAntialiasingType subpixelAntialiasingTypeHint()
{
    static int type = -1;
    if (type == -1) {
        if (QScreen *screen = QGuiApplication::primaryScreen())
            type = screen->handle()->subpixelAntialiasingTypeHint();
    }
    return static_cast<QFontEngine::SubpixelAntialiasingType>(type);
}

QFontEngineFT *QFontEngineFT::create(const QFontDef &fontDef, FaceId faceId, const QByteArray &fontData)
{
    QScopedPointer<QFontEngineFT> engine(new QFontEngineFT(fontDef));

    QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_Mono;
    const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);

    if (antialias) {
        QFontEngine::SubpixelAntialiasingType subpixelType = subpixelAntialiasingTypeHint();
        if (subpixelType == QFontEngine::Subpixel_None || (fontDef.styleStrategy & QFont::NoSubpixelAntialias)) {
            format = QFontEngineFT::Format_A8;
            engine->subpixelType = QFontEngine::Subpixel_None;
        } else {
            format = QFontEngineFT::Format_A32;
            engine->subpixelType = subpixelType;
        }
    }

    if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) {
        qWarning("QFontEngineFT: Failed to create FreeType font engine");
        return nullptr;
    }

    engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
    return engine.take();
}

namespace {
    class QFontEngineFTRawData: public QFontEngineFT
    {
    public:
        QFontEngineFTRawData(const QFontDef &fontDef) : QFontEngineFT(fontDef)
        {
        }

        void updateFamilyNameAndStyle()
        {
            fontDef.family = QString::fromLatin1(freetype->face->family_name);

            if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)
                fontDef.style = QFont::StyleItalic;

            if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD)
                fontDef.weight = QFont::Bold;
        }

        bool initFromData(const QByteArray &fontData)
        {
            FaceId faceId;
            faceId.filename = "";
            faceId.index = 0;
            faceId.uuid = QUuid::createUuid().toByteArray();

            return init(faceId, true, Format_None, fontData);
        }
    };
}

QFontEngineFT *QFontEngineFT::create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
{
    QFontDef fontDef;
    fontDef.pixelSize = pixelSize;
    fontDef.stretch = QFont::Unstretched;
    fontDef.hintingPreference = hintingPreference;

    QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
    if (!fe->initFromData(fontData)) {
        delete fe;
        return 0;
    }

    fe->updateFamilyNameAndStyle();
    fe->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));

    return fe;
}

QFontEngineFT::QFontEngineFT(const QFontDef &fd)
    : QFontEngine(Freetype)
{
    fontDef = fd;
    matrix.xx = 0x10000;
    matrix.yy = 0x10000;
    matrix.xy = 0;
    matrix.yx = 0;
    cache_cost = 100 * 1024;
    kerning_pairs_loaded = false;
    transform = false;
    embolden = false;
    obliquen = false;
    antialias = true;
    freetype = 0;
    default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
    default_hint_style = ftInitialDefaultHintStyle;
    subpixelType = Subpixel_None;
    lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
    defaultFormat = Format_None;
    embeddedbitmap = false;
    const QByteArray env = qgetenv("QT_NO_FT_CACHE");
    cacheEnabled = env.isEmpty() || env.toInt() == 0;
    m_subPixelPositionCount = 4;
    forceAutoHint = false;
    stemDarkeningDriver = false;
}

QFontEngineFT::~QFontEngineFT()
{
    if (freetype)
        freetype->release(face_id);
}

bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
                         const QByteArray &fontData)
{
    return init(faceId, antialias, format, QFreetypeFace::getFace(faceId, fontData));
}

static void dont_delete(void*) {}

bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
                         QFreetypeFace *freetypeFace)
{
    freetype = freetypeFace;
    if (!freetype) {
        xsize = 0;
        ysize = 0;
        return false;
    }
    defaultFormat = format;
    this->antialias = antialias;

    if (!antialias)
        glyphFormat = QFontEngine::Format_Mono;
    else
        glyphFormat = defaultFormat;

    face_id = faceId;

    symbol = freetype->symbol_map != 0;
    PS_FontInfoRec psrec;
    // don't assume that type1 fonts are symbol fonts by default
    if (FT_Get_PS_Font_Info(freetype->face, &psrec) == FT_Err_Ok) {
        symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive));
    }

    freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing, &scalableBitmapScaleFactor);

    FT_Face face = lockFace();

    if (FT_IS_SCALABLE(face)) {
        bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC);
        if (fake_oblique)
            obliquen = true;
        FT_Set_Transform(face, &matrix, 0);
        freetype->matrix = matrix;
        // fake bold
        if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face)) {
            if (const TT_OS2 *os2 = reinterpret_cast<const TT_OS2 *>(FT_Get_Sfnt_Table(face, ft_sfnt_os2))) {
                if (os2->usWeightClass < 750)
                    embolden = true;
            }
        }
        // underline metrics
        line_thickness =  QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));
        underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale));
    } else {
        // ad hoc algorithm
        int score = fontDef.weight * fontDef.pixelSize;
        line_thickness = score / 700;
        // looks better with thicker line for small pointsizes
        if (line_thickness < 2 && score >= 1050)
            line_thickness = 2;
        underline_position =  ((line_thickness * 2) + 3) / 6;

        if (isScalableBitmap()) {
            glyphFormat = defaultFormat = GlyphFormat::Format_ARGB;
            cacheEnabled = false;
        }
    }
    if (line_thickness < 1)
        line_thickness = 1;

    metrics = face->size->metrics;

    /*
       TrueType fonts with embedded bitmaps may have a bitmap font specific
       ascent/descent in the EBLC table. There is no direct public API
       to extract those values. The only way we've found is to trick freetype
       into thinking that it's not a scalable font in FT_SelectSize so that
       the metrics are retrieved from the bitmap strikes.
    */
    if (FT_IS_SCALABLE(face)) {
        for (int i = 0; i < face->num_fixed_sizes; ++i) {
            if (xsize == face->available_sizes[i].x_ppem && ysize == face->available_sizes[i].y_ppem) {
                face->face_flags &= ~FT_FACE_FLAG_SCALABLE;

                FT_Select_Size(face, i);
                if (face->size->metrics.ascender + face->size->metrics.descender > 0) {
                    FT_Pos leading = metrics.height - metrics.ascender + metrics.descender;
                    metrics.ascender = face->size->metrics.ascender;
                    metrics.descender = face->size->metrics.descender;
                    if (metrics.descender > 0
                            && QString::fromUtf8(face->family_name) == QLatin1String("Courier New")) {
                        metrics.descender *= -1;
                    }
                    metrics.height = metrics.ascender - metrics.descender + leading;
                }
                FT_Set_Char_Size(face, xsize, ysize, 0, 0);

                face->face_flags |= FT_FACE_FLAG_SCALABLE;
                break;
            }
        }
    }
#if defined(FT_FONT_FORMATS_H)
    const char *fmt = FT_Get_Font_Format(face);
    if (fmt && qstrncmp(fmt, "CFF", 4) == 0) {
        FT_Bool no_stem_darkening = true;
        FT_Error err = FT_Property_Get(qt_getFreetype(), "cff", "no-stem-darkening", &no_stem_darkening);
        if (err == FT_Err_Ok)
            stemDarkeningDriver = !no_stem_darkening;
        else
            stemDarkeningDriver = false;
    }
#endif

    fontDef.styleName = QString::fromUtf8(face->style_name);

    if (!freetype->hbFace) {
        faceData.user_data = face;
        faceData.get_font_table = ft_getSfntTable;
        (void)harfbuzzFace(); // populates face_
        freetype->hbFace = std::move(face_);
    } else {
        Q_ASSERT(!face_);
    }
    // we share the HB face in QFreeTypeFace, so do not let ~QFontEngine() destroy it
    face_ = Holder(freetype->hbFace.get(), dont_delete);

    unlockFace();

    fsType = freetype->fsType();
    return true;
}

void QFontEngineFT::setQtDefaultHintStyle(QFont::HintingPreference hintingPreference)
{
    switch (hintingPreference) {
    case QFont::PreferNoHinting:
        setDefaultHintStyle(HintNone);
        break;
    case QFont::PreferFullHinting:
        setDefaultHintStyle(HintFull);
        break;
    case QFont::PreferVerticalHinting:
        setDefaultHintStyle(HintLight);
        break;
    case QFont::PreferDefaultHinting:
        setDefaultHintStyle(ftInitialDefaultHintStyle);
        break;
    }
}

void QFontEngineFT::setDefaultHintStyle(HintStyle style)
{
    default_hint_style = style;
}

bool QFontEngineFT::expectsGammaCorrectedBlending() const
{
    return stemDarkeningDriver;
}

int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
                             bool &hsubpixel, int &vfactor) const
{
    int load_flags = FT_LOAD_DEFAULT | default_load_flags;
    int load_target = default_hint_style == HintLight
                      ? FT_LOAD_TARGET_LIGHT
                      : FT_LOAD_TARGET_NORMAL;

    if (format == Format_Mono) {
        load_target = FT_LOAD_TARGET_MONO;
    } else if (format == Format_A32) {
        if (subpixelType == Subpixel_RGB || subpixelType == Subpixel_BGR)
            hsubpixel = true;
        else if (subpixelType == Subpixel_VRGB || subpixelType == Subpixel_VBGR)
            vfactor = 3;
    } else if (format == Format_ARGB) {
#ifdef FT_LOAD_COLOR
        load_flags |= FT_LOAD_COLOR;
#endif
    }

    if (set && set->outline_drawing)
        load_flags |= FT_LOAD_NO_BITMAP;

    if (default_hint_style == HintNone || (flags & DesignMetrics) || (set && set->outline_drawing))
        load_flags |= FT_LOAD_NO_HINTING;
    else
        load_flags |= load_target;

    if (forceAutoHint)
        load_flags |= FT_LOAD_FORCE_AUTOHINT;

    return load_flags;
}

static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info)
{
    // false if exceeds QFontEngineFT::Glyph metrics
    return info.width > 0xFF || info.height > 0xFF;
}

static inline void transformBoundingBox(int *left, int *top, int *right, int *bottom, FT_Matrix *matrix)
{
    int l, r, t, b;
    FT_Vector vector;
    vector.x = *left;
    vector.y = *top;
    FT_Vector_Transform(&vector, matrix);
    l = r = vector.x;
    t = b = vector.y;
    vector.x = *right;
    vector.y = *top;
    FT_Vector_Transform(&vector, matrix);
    if (l > vector.x) l = vector.x;
    if (r < vector.x) r = vector.x;
    if (t < vector.y) t = vector.y;
    if (b > vector.y) b = vector.y;
    vector.x = *right;
    vector.y = *bottom;
    FT_Vector_Transform(&vector, matrix);
    if (l > vector.x) l = vector.x;
    if (r < vector.x) r = vector.x;
    if (t < vector.y) t = vector.y;
    if (b > vector.y) b = vector.y;
    vector.x = *left;
    vector.y = *bottom;
    FT_Vector_Transform(&vector, matrix);
    if (l > vector.x) l = vector.x;
    if (r < vector.x) r = vector.x;
    if (t < vector.y) t = vector.y;
    if (b > vector.y) b = vector.y;
    *left = l;
    *right = r;
    *top = t;
    *bottom = b;
}

QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
                                               QFixed subPixelPosition,
                                               GlyphFormat format,
                                               bool fetchMetricsOnly,
                                               bool disableOutlineDrawing) const
{
//     Q_ASSERT(freetype->lock == 1);

    if (format == Format_None)
        format = defaultFormat != Format_None ? defaultFormat : Format_Mono;
    Q_ASSERT(format != Format_None);

    Glyph *g = set ? set->getGlyph(glyph, subPixelPosition) : 0;
    if (g && g->format == format && (fetchMetricsOnly || g->data))
        return g;

    if (!g && set && set->isGlyphMissing(glyph))
        return &emptyGlyph;


    FT_Face face = freetype->face;

    FT_Matrix matrix = freetype->matrix;

    FT_Vector v;
    v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.value());
    v.y = 0;
    FT_Set_Transform(face, &matrix, &v);

    bool hsubpixel = false;
    int vfactor = 1;
    int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor);

    bool transform = matrix.xx != 0x10000
                     || matrix.yy != 0x10000
                     || matrix.xy != 0
                     || matrix.yx != 0;

    if (transform || obliquen || (format != Format_Mono && !isScalableBitmap()))
        load_flags |= FT_LOAD_NO_BITMAP;

    FT_Error err = FT_Load_Glyph(face, glyph, load_flags);
    if (err && (load_flags & FT_LOAD_NO_BITMAP)) {
        load_flags &= ~FT_LOAD_NO_BITMAP;
        err = FT_Load_Glyph(face, glyph, load_flags);
    }
    if (err == FT_Err_Too_Few_Arguments) {
        // this is an error in the bytecode interpreter, just try to run without it
        load_flags |= FT_LOAD_FORCE_AUTOHINT;
        err = FT_Load_Glyph(face, glyph, load_flags);
    } else if (err == FT_Err_Execution_Too_Long) {
        // This is an error in the bytecode, probably a web font made by someone who
        // didn't test bytecode hinting at all so disable for it for all glyphs.
        qWarning("load glyph failed due to broken hinting bytecode in font, switching to auto hinting");
        default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
        load_flags |= FT_LOAD_FORCE_AUTOHINT;
        err = FT_Load_Glyph(face, glyph, load_flags);
    }
    if (err != FT_Err_Ok) {
        qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
        if (set)
            set->setGlyphMissing(glyph);
        return &emptyGlyph;
    }

    FT_GlyphSlot slot = face->glyph;

    if (embolden)
        FT_GlyphSlot_Embolden(slot);
    if (obliquen) {
        FT_GlyphSlot_Oblique(slot);

        // While Embolden alters the metrics of the slot, oblique does not, so we need
        // to fix this ourselves.
        transform = true;
        FT_Matrix m;
        m.xx = 0x10000;
        m.yx = 0x0;
        m.xy = 0x6000;
        m.yy = 0x10000;

        FT_Matrix_Multiply(&m, &matrix);
    }

    GlyphInfo info;
    info.linearAdvance = slot->linearHoriAdvance >> 10;
    info.xOff = TRUNC(ROUND(slot->advance.x));
    info.yOff = 0;

    if ((set && set->outline_drawing && !disableOutlineDrawing) || fetchMetricsOnly) {
        int left  = slot->metrics.horiBearingX;
        int right = slot->metrics.horiBearingX + slot->metrics.width;
        int top    = slot->metrics.horiBearingY;
        int bottom = slot->metrics.horiBearingY - slot->metrics.height;

        if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP)
            transformBoundingBox(&left, &top, &right, &bottom, &matrix);

        left = FLOOR(left);
        right = CEIL(right);
        bottom = FLOOR(bottom);
        top = CEIL(top);

        info.x = TRUNC(left);
        info.y = TRUNC(top);
        info.width = TRUNC(right - left);
        info.height = TRUNC(top - bottom);

        // If any of the metrics are too large to fit, don't cache them
        if (areMetricsTooLarge(info))
            return 0;

        g = new Glyph;
        g->data = 0;
        g->linearAdvance = info.linearAdvance;
        g->width = info.width;
        g->height = info.height;
        g->x = info.x;
        g->y = info.y;
        g->advance = info.xOff;
        g->format = format;

        if (set)
            set->setGlyph(glyph, subPixelPosition, g);

        return g;
    }

    int glyph_buffer_size = 0;
    QScopedArrayPointer<uchar> glyph_buffer;
    FT_Render_Mode renderMode = (default_hint_style == HintLight) ? FT_RENDER_MODE_LIGHT : FT_RENDER_MODE_NORMAL;
    switch (format) {
    case Format_Mono:
        renderMode = FT_RENDER_MODE_MONO;
        break;
    case Format_A32:
        Q_ASSERT(hsubpixel || vfactor != 1);
        renderMode = hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V;
        break;
    case Format_A8:
    case Format_ARGB:
        break;
    default:
        Q_UNREACHABLE();
    }
    FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);

    err = FT_Render_Glyph(slot, renderMode);
    if (err != FT_Err_Ok)
        qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph);

    FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE);

    info.height = slot->bitmap.rows;
    info.width = slot->bitmap.width;
    info.x = slot->bitmap_left;
    info.y = slot->bitmap_top;
    if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD)
        info.width = info.width / 3;
    if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V)
        info.height = info.height / vfactor;

    int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 :
                 (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4));

    glyph_buffer_size = info.height * pitch;
    glyph_buffer.reset(new uchar[glyph_buffer_size]);

    if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
        uchar *src = slot->bitmap.buffer;
        uchar *dst = glyph_buffer.data();
        int h = slot->bitmap.rows;
        // Some fonts return bitmaps even when we requested something else:
        if (format == Format_Mono) {
            int bytes = ((info.width + 7) & ~7) >> 3;
            while (h--) {
                memcpy (dst, src, bytes);
                dst += pitch;
                src += slot->bitmap.pitch;
            }
        } else if (format == Format_A8) {
            while (h--) {
                for (int x = 0; x < int{info.width}; x++)
                    dst[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
                dst += pitch;
                src += slot->bitmap.pitch;
            }
        } else {
            while (h--) {
                uint *dd = reinterpret_cast<uint *>(dst);
                for (int x = 0; x < int{info.width}; x++)
                    dd[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffffff : 0x00000000);
                dst += pitch;
                src += slot->bitmap.pitch;
            }
        }
    } else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) {
        Q_ASSERT(format == Format_ARGB);
        uchar *src = slot->bitmap.buffer;
        uchar *dst = glyph_buffer.data();
        int h = slot->bitmap.rows;
        while (h--) {
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
            const quint32 *srcPixel = (const quint32 *)src;
            quint32 *dstPixel = (quint32 *)dst;
            for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++, srcPixel++, dstPixel++) {
                const quint32 pixel = *srcPixel;
                *dstPixel = qbswap(pixel);
            }
#else
            memcpy(dst, src, slot->bitmap.width * 4);
#endif
            dst += slot->bitmap.pitch;
            src += slot->bitmap.pitch;
        }
        info.linearAdvance = info.xOff = slot->bitmap.width;
    } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
        Q_ASSERT(format == Format_A8);
        uchar *src = slot->bitmap.buffer;
        uchar *dst = glyph_buffer.data();
        int h = slot->bitmap.rows;
        int bytes = info.width;
        while (h--) {
            memcpy (dst, src, bytes);
            dst += pitch;
            src += slot->bitmap.pitch;
        }
    } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) {
        Q_ASSERT(format == Format_A32);
        convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB);
    } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) {
        Q_ASSERT(format == Format_A32);
        convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB);
    } else {
        qWarning("QFontEngine: Glyph rendered in unknown pixel_mode=%d", slot->bitmap.pixel_mode);
        return 0;
    }

    if (!g) {
        g = new Glyph;
        g->data = 0;
    }

    g->linearAdvance = info.linearAdvance;
    g->width = info.width;
    g->height = info.height;
    g->x = info.x;
    g->y = info.y;
    g->advance = info.xOff;
    g->format = format;
    delete [] g->data;
    g->data = glyph_buffer.take();

    if (set)
        set->setGlyph(glyph, subPixelPosition, g);

    return g;
}

QFontEngine::FaceId QFontEngineFT::faceId() const
{
    return face_id;
}

QFontEngine::Properties QFontEngineFT::properties() const
{
    Properties p = freetype->properties();
    if (p.postscriptName.isEmpty()) {
        p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(fontDef.family.toUtf8());
    }

    return freetype->properties();
}

QFixed QFontEngineFT::emSquareSize() const
{
    if (FT_IS_SCALABLE(freetype->face))
        return freetype->face->units_per_EM;
    else
        return freetype->face->size->metrics.y_ppem;
}

bool QFontEngineFT::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
    return ft_getSfntTable(freetype->face, tag, buffer, length);
}

int QFontEngineFT::synthesized() const
{
    int s = 0;
    if ((fontDef.style != QFont::StyleNormal) && !(freetype->face->style_flags & FT_STYLE_FLAG_ITALIC))
        s = SynthesizedItalic;
    if ((fontDef.weight >= QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD))
        s |= SynthesizedBold;
    if (fontDef.stretch != 100 && FT_IS_SCALABLE(freetype->face))
        s |= SynthesizedStretch;
    return s;
}

QFixed QFontEngineFT::ascent() const
{
    QFixed v = QFixed::fromFixed(metrics.ascender);
    if (scalableBitmapScaleFactor != 1)
        v *= scalableBitmapScaleFactor;
    return v;
}

QFixed QFontEngineFT::capHeight() const
{
    TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
    if (os2 && os2->version >= 2) {
        lockFace();
        QFixed answer = QFixed::fromFixed(FT_MulFix(os2->sCapHeight, freetype->face->size->metrics.y_scale));
        unlockFace();
        return answer;
    }
    return calculatedCapHeight();
}

QFixed QFontEngineFT::descent() const
{
    QFixed v = QFixed::fromFixed(-metrics.descender);
    if (scalableBitmapScaleFactor != 1)
        v *= scalableBitmapScaleFactor;
    return v;
}

QFixed QFontEngineFT::leading() const
{
    QFixed v = QFixed::fromFixed(metrics.height - metrics.ascender + metrics.descender);
    if (scalableBitmapScaleFactor != 1)
        v *= scalableBitmapScaleFactor;
    return v;
}

QFixed QFontEngineFT::xHeight() const
{
    TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
    if (os2 && os2->sxHeight) {
        lockFace();
        QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize();
        unlockFace();
        return answer;
    }

    return QFontEngine::xHeight();
}

QFixed QFontEngineFT::averageCharWidth() const
{
     TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
     if (os2 && os2->xAvgCharWidth) {
         lockFace();
         QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize();
         unlockFace();
         return answer;
     }

     return QFontEngine::averageCharWidth();
}

qreal QFontEngineFT::maxCharWidth() const
{
    QFixed max_advance = QFixed::fromFixed(metrics.max_advance);
    if (scalableBitmapScaleFactor != 1)
        max_advance *= scalableBitmapScaleFactor;
    return max_advance.toReal();
}

QFixed QFontEngineFT::lineThickness() const
{
    return line_thickness;
}

QFixed QFontEngineFT::underlinePosition() const
{
    return underline_position;
}

void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) const
{
    if (!kerning_pairs_loaded) {
        kerning_pairs_loaded = true;
        lockFace();
        if (freetype->face->size->metrics.x_ppem != 0) {
            QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem);
            unlockFace();
            const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor);
        } else {
            unlockFace();
        }
    }

    if (shouldUseDesignMetrics(flags) && !(fontDef.styleStrategy & QFont::ForceIntegerMetrics))
        flags |= DesignMetrics;
    else
        flags &= ~DesignMetrics;

    QFontEngine::doKerning(g, flags);
}

static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix)
{
    FT_Matrix m;

    m.xx = FT_Fixed(matrix.m11() * 65536);
    m.xy = FT_Fixed(-matrix.m21() * 65536);
    m.yx = FT_Fixed(-matrix.m12() * 65536);
    m.yy = FT_Fixed(matrix.m22() * 65536);

    return m;
}

QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix)
{
    if (matrix.type() > QTransform::TxShear || !cacheEnabled)
        return 0;

    // FT_Set_Transform only supports scalable fonts
    if (!FT_IS_SCALABLE(freetype->face))
        return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : nullptr;

    FT_Matrix m = QTransformToFTMatrix(matrix);

    QGlyphSet *gs = 0;

    for (int i = 0; i < transformedGlyphSets.count(); ++i) {
        const QGlyphSet &g = transformedGlyphSets.at(i);
        if (g.transformationMatrix.xx == m.xx
            && g.transformationMatrix.xy == m.xy
            && g.transformationMatrix.yx == m.yx
            && g.transformationMatrix.yy == m.yy) {

            // found a match, move it to the front
            transformedGlyphSets.move(i, 0);
            gs = &transformedGlyphSets[0];
            break;
        }
    }

    if (!gs) {
        // don't cache more than 10 transformations
        if (transformedGlyphSets.count() >= 10) {
            transformedGlyphSets.move(transformedGlyphSets.size() - 1, 0);
        } else {
            transformedGlyphSets.prepend(QGlyphSet());
        }
        gs = &transformedGlyphSets[0];
        gs->clear();
        gs->transformationMatrix = m;
        gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.determinant()) > QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
    }
    Q_ASSERT(gs != 0);

    return gs;
}

void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
{
    FT_Face face = lockFace(Unscaled);
    FT_Set_Transform(face, 0, 0);
    FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);

    int left  = face->glyph->metrics.horiBearingX;
    int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;
    int top    = face->glyph->metrics.horiBearingY;
    int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;

    QFixedPoint p;
    p.x = 0;
    p.y = 0;

    metrics->width = QFixed::fromFixed(right-left);
    metrics->height = QFixed::fromFixed(top-bottom);
    metrics->x = QFixed::fromFixed(left);
    metrics->y = QFixed::fromFixed(-top);
    metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);

    if (!FT_IS_SCALABLE(freetype->face))
        QFreetypeFace::addBitmapToPath(face->glyph, p, path);
    else
        QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);

    FT_Set_Transform(face, &freetype->matrix, 0);
    unlockFace();
}

bool QFontEngineFT::supportsTransformation(const QTransform &transform) const
{
    return transform.type() <= QTransform::TxRotate;
}

void QFontEngineFT::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
{
    if (!glyphs.numGlyphs)
        return;

    if (FT_IS_SCALABLE(freetype->face)) {
        QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
    } else {
        QVarLengthArray<QFixedPoint> positions;
        QVarLengthArray<glyph_t> positioned_glyphs;
        QTransform matrix;
        matrix.translate(x, y);
        getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions);

        FT_Face face = lockFace(Unscaled);
        for (int gl = 0; gl < glyphs.numGlyphs; gl++) {
            FT_UInt glyph = positioned_glyphs[gl];
            FT_Load_Glyph(face, glyph, FT_LOAD_TARGET_MONO);
            QFreetypeFace::addBitmapToPath(face->glyph, positions[gl], path);
        }
        unlockFace();
    }
}

void QFontEngineFT::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,
                                    QPainterPath *path, QTextItem::RenderFlags)
{
    FT_Face face = lockFace(Unscaled);

    for (int gl = 0; gl < numGlyphs; gl++) {
        FT_UInt glyph = glyphs[gl];

        FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);

        FT_GlyphSlot g = face->glyph;
        if (g->format != FT_GLYPH_FORMAT_OUTLINE)
            continue;
        if (embolden)
            FT_GlyphSlot_Embolden(g);
        if (obliquen)
            FT_GlyphSlot_Oblique(g);
        QFreetypeFace::addGlyphToPath(face, g, positions[gl], path, xsize, ysize);
    }
    unlockFace();
}

glyph_t QFontEngineFT::glyphIndex(uint ucs4) const
{
    glyph_t glyph = ucs4 < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[ucs4] : 0;
    if (glyph == 0) {
        FT_Face face = freetype->face;
        glyph = FT_Get_Char_Index(face, ucs4);
        if (glyph == 0) {
            // Certain fonts don't have no-break space and tab,
            // while we usually want to render them as space
            if (ucs4 == QChar::Nbsp || ucs4 == QChar::Tabulation) {
                glyph = FT_Get_Char_Index(face, QChar::Space);
            } else if (freetype->symbol_map) {
                // Symbol fonts can have more than one CMAPs, FreeType should take the
                // correct one for us by default, so we always try FT_Get_Char_Index
                // first. If it didn't work (returns 0), we will explicitly set the
                // CMAP to symbol font one and try again. symbol_map is not always the
                // correct one because in certain fonts like Wingdings symbol_map only
                // contains PUA codepoints instead of the common ones.
                FT_Set_Charmap(face, freetype->symbol_map);
                glyph = FT_Get_Char_Index(face, ucs4);
                FT_Set_Charmap(face, freetype->unicode_map);
            }
        }
        if (ucs4 < QFreetypeFace::cmapCacheSize)
            freetype->cmapCache[ucs4] = glyph;
    }

    return glyph;
}

bool QFontEngineFT::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;
    }

    int glyph_pos = 0;
    if (freetype->symbol_map) {
        FT_Face face = freetype->face;
        QStringIterator it(str, str + len);
        while (it.hasNext()) {
            uint uc = it.next();
            glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
            if ( !glyphs->glyphs[glyph_pos] ) {
                // Symbol fonts can have more than one CMAPs, FreeType should take the
                // correct one for us by default, so we always try FT_Get_Char_Index
                // first. If it didn't work (returns 0), we will explicitly set the
                // CMAP to symbol font one and try again. symbol_map is not always the
                // correct one because in certain fonts like Wingdings symbol_map only
                // contains PUA codepoints instead of the common ones.
                glyph_t glyph = FT_Get_Char_Index(face, uc);
                // Certain symbol fonts don't have no-break space (0xa0) and tab (0x9),
                // while we usually want to render them as space
                if (!glyph && (uc == 0xa0 || uc == 0x9)) {
                    uc = 0x20;
                    glyph = FT_Get_Char_Index(face, uc);
                }
                if (!glyph) {
                    FT_Set_Charmap(face, freetype->symbol_map);
                    glyph = FT_Get_Char_Index(face, uc);
                    FT_Set_Charmap(face, freetype->unicode_map);
                }
                glyphs->glyphs[glyph_pos] = glyph;
                if (uc < QFreetypeFace::cmapCacheSize)
                    freetype->cmapCache[uc] = glyph;
            }
            ++glyph_pos;
        }
    } else {
        FT_Face face = freetype->face;
        QStringIterator it(str, str + len);
        while (it.hasNext()) {
            uint uc = it.next();
            glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
            if (!glyphs->glyphs[glyph_pos]) {
                {
                redo:
                    glyph_t glyph = FT_Get_Char_Index(face, uc);
                    if (!glyph && (uc == 0xa0 || uc == 0x9)) {
                        uc = 0x20;
                        goto redo;
                    }
                    glyphs->glyphs[glyph_pos] = glyph;
                    if (uc < QFreetypeFace::cmapCacheSize)
                        freetype->cmapCache[uc] = glyph;
                }
            }
            ++glyph_pos;
        }
    }

    *nglyphs = glyph_pos;
    glyphs->numGlyphs = glyph_pos;

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

    return true;
}

bool QFontEngineFT::shouldUseDesignMetrics(QFontEngine::ShaperFlags flags) const
{
    if (!FT_IS_SCALABLE(freetype->face))
        return false;

    return default_hint_style == HintNone || default_hint_style == HintLight || (flags & DesignMetrics);
}

QFixed QFontEngineFT::scaledBitmapMetrics(QFixed m) const
{
    return m * scalableBitmapScaleFactor;
}

glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &t) const
{
    QTransform trans;
    trans.setMatrix(t.m11(), t.m12(), t.m13(),
                    t.m21(), t.m22(), t.m23(),
                    0, 0, t.m33());
    const qreal scaleFactor = scalableBitmapScaleFactor.toReal();
    trans.scale(scaleFactor, scaleFactor);

    QRectF rect(m.x.toReal(), m.y.toReal(), m.width.toReal(), m.height.toReal());
    QPointF offset(m.xoff.toReal(), m.yoff.toReal());

    rect = trans.mapRect(rect);
    offset = trans.map(offset);

    glyph_metrics_t metrics;
    metrics.x = QFixed::fromReal(rect.x());
    metrics.y = QFixed::fromReal(rect.y());
    metrics.width = QFixed::fromReal(rect.width());
    metrics.height = QFixed::fromReal(rect.height());
    metrics.xoff = QFixed::fromReal(offset.x());
    metrics.yoff = QFixed::fromReal(offset.y());
    return metrics;
}

void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
{
    FT_Face face = 0;
    bool design = shouldUseDesignMetrics(flags);
    for (int i = 0; i < glyphs->numGlyphs; i++) {
        Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs->glyphs[i]) : 0;
        // Since we are passing Format_None to loadGlyph, use same default format logic as loadGlyph
        GlyphFormat acceptableFormat = (defaultFormat != Format_None) ? defaultFormat : Format_Mono;
        if (g && g->format == acceptableFormat) {
            glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
        } else {
            if (!face)
                face = lockFace();
            g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs->glyphs[i], 0, Format_None, true);
            if (g)
                glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
            else
                glyphs->advances[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
                                             : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
            if (!cacheEnabled && g != &emptyGlyph)
                delete g;
        }

        if (scalableBitmapScaleFactor != 1)
            glyphs->advances[i] *= scalableBitmapScaleFactor;
    }
    if (face)
        unlockFace();

    if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
        for (int i = 0; i < glyphs->numGlyphs; ++i)
            glyphs->advances[i] = glyphs->advances[i].round();
    }
}

glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
{
    FT_Face face = 0;

    glyph_metrics_t overall;
    // initialize with line height, we get the same behaviour on all platforms
    if (!isScalableBitmap()) {
        overall.y = -ascent();
        overall.height = ascent() + descent();
    } else {
        overall.y = QFixed::fromFixed(-metrics.ascender);
        overall.height = QFixed::fromFixed(metrics.ascender - metrics.descender);
    }

    QFixed ymax = 0;
    QFixed xmax = 0;
    for (int i = 0; i < glyphs.numGlyphs; i++) {
        Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : 0;
        if (!g) {
            if (!face)
                face = lockFace();
            g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs.glyphs[i], 0, Format_None, true);
        }
        if (g) {
            QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
            QFixed y = overall.yoff + glyphs.offsets[i].y - g->y;
            overall.x = qMin(overall.x, x);
            overall.y = qMin(overall.y, y);
            xmax = qMax(xmax, x + g->width);
            ymax = qMax(ymax, y + g->height);
            overall.xoff += g->advance;
            if (!cacheEnabled && g != &emptyGlyph)
                delete g;
        } else {
            int left  = FLOOR(face->glyph->metrics.horiBearingX);
            int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
            int top    = CEIL(face->glyph->metrics.horiBearingY);
            int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);

            QFixed x = overall.xoff + glyphs.offsets[i].x - (-TRUNC(left));
            QFixed y = overall.yoff + glyphs.offsets[i].y - TRUNC(top);
            overall.x = qMin(overall.x, x);
            overall.y = qMin(overall.y, y);
            xmax = qMax(xmax, x + TRUNC(right - left));
            ymax = qMax(ymax, y + TRUNC(top - bottom));
            overall.xoff += int(TRUNC(ROUND(face->glyph->advance.x)));
        }
    }
    overall.height = qMax(overall.height, ymax - overall.y);
    overall.width = xmax - overall.x;

    if (face)
        unlockFace();

    if (isScalableBitmap())
        overall = scaledBitmapMetrics(overall, QTransform());
    return overall;
}

glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
{
    FT_Face face = 0;
    glyph_metrics_t overall;
    Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyph) : 0;
    if (!g) {
        face = lockFace();
        g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, 0, Format_None, true);
    }
    if (g) {
        overall.x = g->x;
        overall.y = -g->y;
        overall.width = g->width;
        overall.height = g->height;
        overall.xoff = g->advance;
        if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
            overall.xoff = overall.xoff.round();
        if (!cacheEnabled && g != &emptyGlyph)
            delete g;
    } else {
        int left  = FLOOR(face->glyph->metrics.horiBearingX);
        int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
        int top    = CEIL(face->glyph->metrics.horiBearingY);
        int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);

        overall.width = TRUNC(right-left);
        overall.height = TRUNC(top-bottom);
        overall.x = TRUNC(left);
        overall.y = -TRUNC(top);
        overall.xoff = TRUNC(ROUND(face->glyph->advance.x));
    }
    if (face)
        unlockFace();

    if (isScalableBitmap())
        overall = scaledBitmapMetrics(overall, QTransform());
    return overall;
}

glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matrix)
{
    return alphaMapBoundingBox(glyph, 0, matrix, QFontEngine::Format_None);
}

glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, QFontEngine::GlyphFormat format)
{
    Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix, true);

    glyph_metrics_t overall;
    if (g) {
        overall.x = g->x;
        overall.y = -g->y;
        overall.width = g->width;
        overall.height = g->height;
        overall.xoff = g->advance;
        if (!cacheEnabled && g != &emptyGlyph)
            delete g;
    } else {
        FT_Face face = lockFace();
        int left  = FLOOR(face->glyph->metrics.horiBearingX);
        int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
        int top    = CEIL(face->glyph->metrics.horiBearingY);
        int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);

        overall.width = TRUNC(right-left);
        overall.height = TRUNC(top-bottom);
        overall.x = TRUNC(left);
        overall.y = -TRUNC(top);
        overall.xoff = TRUNC(ROUND(face->glyph->advance.x));
        unlockFace();
    }

    if (isScalableBitmap())
        overall = scaledBitmapMetrics(overall, matrix);
    return overall;
}

static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEngine::GlyphFormat glyphFormat)
{
    if (glyph == nullptr || glyph->height == 0 || glyph->width == 0)
        return QImage();

    QImage::Format format = QImage::Format_Invalid;
    int bytesPerLine = -1;
    switch (glyphFormat) {
    case QFontEngine::Format_Mono:
        format = QImage::Format_Mono;
        bytesPerLine = ((glyph->width + 31) & ~31) >> 3;
        break;
    case QFontEngine::Format_A8:
        format = QImage::Format_Alpha8;
        bytesPerLine = (glyph->width + 3) & ~3;
        break;
    case QFontEngine::Format_A32:
        format = QImage::Format_RGB32;
        bytesPerLine = glyph->width * 4;
        break;
    default:
        Q_UNREACHABLE();
    };

    QImage img(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format);
    if (format == QImage::Format_Mono)
        img.setColor(1, QColor(Qt::white).rgba());  // Expands color table to 2 items; item 0 set to transparent.
    return img;
}

QFontEngine::Glyph *QFontEngineFT::glyphData(glyph_t glyphIndex, QFixed subPixelPosition,
                                             QFontEngine::GlyphFormat neededFormat, const QTransform &t)
{
    Q_ASSERT(cacheEnabled);

    if (isBitmapFont())
        neededFormat = Format_Mono;
    else if (neededFormat == Format_None && defaultFormat != Format_None)
        neededFormat = defaultFormat;
    else if (neededFormat == Format_None)
        neededFormat = Format_A8;

    Glyph *glyph = loadGlyphFor(glyphIndex, subPixelPosition, neededFormat, t);
    if (!glyph || !glyph->width || !glyph->height)
        return nullptr;

    return glyph;
}

static inline bool is2dRotation(const QTransform &t)
{
    return qFuzzyCompare(t.m11(), t.m22()) && qFuzzyCompare(t.m12(), -t.m21())
        && qFuzzyCompare(t.m11()*t.m22() - t.m12()*t.m21(), qreal(1.0));
}

QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
                                                  QFixed subPixelPosition,
                                                  GlyphFormat format,
                                                  const QTransform &t,
                                                  bool fetchBoundingBox,
                                                  bool disableOutlineDrawing)
{
    QGlyphSet *glyphSet = loadGlyphSet(t);
    if (glyphSet != 0 && glyphSet->outline_drawing && !disableOutlineDrawing && !fetchBoundingBox)
        return 0;

    Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0;
    if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) {
        QScopedValueRollback<HintStyle> saved_default_hint_style(default_hint_style);
        if (t.type() >= QTransform::TxScale && !is2dRotation(t))
            default_hint_style = HintNone; // disable hinting if the glyphs are transformed

        lockFace();
        FT_Matrix m = this->matrix;
        FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t);
        FT_Matrix_Multiply(&ftMatrix, &m);
        freetype->matrix = m;
        glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false, disableOutlineDrawing);
        unlockFace();
    }

    return glyph;
}

QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
{
    return alphaMapForGlyph(g, subPixelPosition, QTransform());
}

QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
{
    const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono;

    Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true);

    QImage img = alphaMapFromGlyphData(glyph, neededFormat);
    img = img.copy();

    if (!cacheEnabled && glyph != &emptyGlyph)
        delete glyph;

    return img;
}

QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
{
    if (t.type() > QTransform::TxRotate)
        return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);

    const GlyphFormat neededFormat = Format_A32;

    Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true);

    QImage img = alphaMapFromGlyphData(glyph, neededFormat);
    img = img.copy();

    if (!cacheEnabled && glyph != &emptyGlyph)
        delete glyph;

    if (!img.isNull())
        return img;

    return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
}

QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t, const QColor &color)
{
    Q_UNUSED(color);

    Glyph *glyph = loadGlyphFor(g, subPixelPosition, defaultFormat, t);
    if (glyph == nullptr)
        return QImage();

    QImage img;
    if (defaultFormat == GlyphFormat::Format_ARGB)
        img = QImage(glyph->data, glyph->width, glyph->height, QImage::Format_ARGB32_Premultiplied).copy();
    else if (defaultFormat == GlyphFormat::Format_Mono)
        img = QImage(glyph->data, glyph->width, glyph->height, QImage::Format_Mono).copy();

    if (!img.isNull() && (!t.isIdentity() || scalableBitmapScaleFactor != 1)) {
        QTransform trans(t);
        const qreal scaleFactor = scalableBitmapScaleFactor.toReal();
        trans.scale(scaleFactor, scaleFactor);
        img = img.transformed(trans, Qt::SmoothTransformation);
    }

    if (!cacheEnabled && glyph != &emptyGlyph)
        delete glyph;

    return img;
}

void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
{
    defaultGlyphSet.removeGlyphFromCache(glyph, 0);
}

int QFontEngineFT::glyphCount() const
{
    int count = 0;
    FT_Face face = lockFace();
    if (face) {
        count = face->num_glyphs;
        unlockFace();
    }
    return count;
}

FT_Face QFontEngineFT::lockFace(Scaling scale) const
{
    freetype->lock();
    FT_Face face = freetype->face;
    if (scale == Unscaled) {
        if (FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0) == 0) {
            freetype->xsize = face->units_per_EM << 6;
            freetype->ysize = face->units_per_EM << 6;
        }
    } else if (freetype->xsize != xsize || freetype->ysize != ysize) {
        FT_Set_Char_Size(face, xsize, ysize, 0, 0);
        freetype->xsize = xsize;
        freetype->ysize = ysize;
    }
    if (freetype->matrix.xx != matrix.xx ||
        freetype->matrix.yy != matrix.yy ||
        freetype->matrix.xy != matrix.xy ||
        freetype->matrix.yx != matrix.yx) {
        freetype->matrix = matrix;
        FT_Set_Transform(face, &freetype->matrix, 0);
    }

    return face;
}

void QFontEngineFT::unlockFace() const
{
    freetype->unlock();
}

FT_Face QFontEngineFT::non_locked_face() const
{
    return freetype->face;
}


QFontEngineFT::QGlyphSet::QGlyphSet()
    : outline_drawing(false)
{
    transformationMatrix.xx = 0x10000;
    transformationMatrix.yy = 0x10000;
    transformationMatrix.xy = 0;
    transformationMatrix.yx = 0;
    memset(fast_glyph_data, 0, sizeof(fast_glyph_data));
    fast_glyph_count = 0;
}

QFontEngineFT::QGlyphSet::~QGlyphSet()
{
    clear();
}

void QFontEngineFT::QGlyphSet::clear()
{
    if (fast_glyph_count > 0) {
        for (int i = 0; i < 256; ++i) {
            if (fast_glyph_data[i]) {
                delete fast_glyph_data[i];
                fast_glyph_data[i] = 0;
            }
        }
        fast_glyph_count = 0;
    }
    qDeleteAll(glyph_data);
    glyph_data.clear();
}

void QFontEngineFT::QGlyphSet::removeGlyphFromCache(glyph_t index, QFixed subPixelPosition)
{
    if (useFastGlyphData(index, subPixelPosition)) {
        if (fast_glyph_data[index]) {
            delete fast_glyph_data[index];
            fast_glyph_data[index] = 0;
            if (fast_glyph_count > 0)
                --fast_glyph_count;
        }
    } else {
        delete glyph_data.take(GlyphAndSubPixelPosition(index, subPixelPosition));
    }
}

void QFontEngineFT::QGlyphSet::setGlyph(glyph_t index, QFixed subPixelPosition, Glyph *glyph)
{
    if (useFastGlyphData(index, subPixelPosition)) {
        if (!fast_glyph_data[index])
            ++fast_glyph_count;
        fast_glyph_data[index] = glyph;
    } else {
        glyph_data.insert(GlyphAndSubPixelPosition(index, subPixelPosition), glyph);
    }
}

int QFontEngineFT::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints)
{
    lockFace();
    bool hsubpixel = true;
    int vfactor = 1;
    int load_flags = loadFlags(0, Format_A8, flags, hsubpixel, vfactor);
    int result = freetype->getPointInOutline(glyph, load_flags, point, xpos, ypos, nPoints);
    unlockFace();
    return result;
}

bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe)
{
    if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
        return false;

    // Increase the reference of this QFreetypeFace since one more QFontEngineFT
    // will be using it
    freetype->ref.ref();

    default_load_flags = fe->default_load_flags;
    default_hint_style = fe->default_hint_style;
    antialias = fe->antialias;
    transform = fe->transform;
    embolden = fe->embolden;
    obliquen = fe->obliquen;
    subpixelType = fe->subpixelType;
    lcdFilterType = fe->lcdFilterType;
    embeddedbitmap = fe->embeddedbitmap;

    return true;
}

QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const
{
    QFontDef fontDef(this->fontDef);
    fontDef.pixelSize = pixelSize;
    QFontEngineFT *fe = new QFontEngineFT(fontDef);
    if (!fe->initFromFontEngine(this)) {
        delete fe;
        return 0;
    } else {
        return fe;
    }
}

Qt::HANDLE QFontEngineFT::handle() const
{
    return non_locked_face();
}

QT_END_NAMESPACE

#endif // QT_NO_FREETYPE
