/****************************************************************************
**
** 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$
**
****************************************************************************/

#ifndef QFONTENGINE_P_H
#define QFONTENGINE_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QtGui/private/qtguiglobal_p.h>
#include "QtCore/qatomic.h"
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qhashfunctions.h>
#include "private/qtextengine_p.h"
#include "private/qfont_p.h"

QT_BEGIN_NAMESPACE

class QPainterPath;
class QFontEngineGlyphCache;

struct QGlyphLayout;

#define MAKE_TAG(ch1, ch2, ch3, ch4) (\
    (((quint32)(ch1)) << 24) | \
    (((quint32)(ch2)) << 16) | \
    (((quint32)(ch3)) << 8) | \
    ((quint32)(ch4)) \
   )

// ### this only used in getPointInOutline(), refactor it and then remove these magic numbers
enum HB_Compat_Error {
    Err_Ok                           = 0x0000,
    Err_Not_Covered                  = 0xFFFF,
    Err_Invalid_Argument             = 0x1A66,
    Err_Invalid_SubTable_Format      = 0x157F,
    Err_Invalid_SubTable             = 0x1570
};

typedef void (*qt_destroy_func_t) (void *user_data);
typedef bool (*qt_get_font_table_func_t) (void *user_data, uint tag, uchar *buffer, uint *length);

class Q_GUI_EXPORT QFontEngine
{
public:
    enum Type {
        Box,
        Multi,

        // MS Windows types
        Win,

        // Apple Mac OS types
        Mac,

        // QWS types
        Freetype,
        QPF1,
        QPF2,
        Proxy,

        DirectWrite,

        TestFontEngine = 0x1000
    };

    enum GlyphFormat {
        Format_None,
        Format_Render = Format_None,
        Format_Mono,
        Format_A8,
        Format_A32,
        Format_ARGB
    };

    enum ShaperFlag {
        DesignMetrics = 0x0002,
        GlyphIndicesOnly = 0x0004
    };
    Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag)

    /* Used with the Freetype font engine. */
    struct Glyph {
        Glyph() = default;
        ~Glyph() { delete [] data; }
        short linearAdvance = 0;
        unsigned short width = 0;
        unsigned short height = 0;
        short x = 0;
        short y = 0;
        short advance = 0;
        signed char format = 0;
        uchar *data = nullptr;
    private:
        Q_DISABLE_COPY(Glyph)
    };

    virtual ~QFontEngine();

    inline Type type() const { return m_type; }

    // all of these are in unscaled metrics if the engine supports uncsaled metrics,
    // otherwise in design metrics
    struct Properties {
        QByteArray postscriptName;
        QByteArray copyright;
        QRectF boundingBox;
        QFixed emSquare;
        QFixed ascent;
        QFixed descent;
        QFixed leading;
        QFixed italicAngle;
        QFixed capHeight;
        QFixed lineWidth;
    };
    virtual Properties properties() const;
    virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
    QByteArray getSfntTable(uint tag) const;
    virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;

    struct FaceId {
        FaceId() : index(0), encoding(0) {}
        QByteArray filename;
        QByteArray uuid;
        int index;
        int encoding;
    };
    virtual FaceId faceId() const { return FaceId(); }
    enum SynthesizedFlags {
        SynthesizedItalic = 0x1,
        SynthesizedBold = 0x2,
        SynthesizedStretch = 0x4
    };
    virtual int synthesized() const { return 0; }
    virtual bool supportsSubPixelPositions() const { return false; }
    virtual QFixed subPixelPositionForX(QFixed x) const;

    virtual QFixed emSquareSize() const { return ascent(); }

    /* returns 0 as glyph index for non existent glyphs */
    virtual glyph_t glyphIndex(uint ucs4) const = 0;
    virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const = 0;
    virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const {}
    virtual void doKerning(QGlyphLayout *, ShaperFlags) const;

    virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
                                 QPainterPath *path, QTextItem::RenderFlags flags);

    void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags,
                           QVarLengthArray<glyph_t> &glyphs_out, QVarLengthArray<QFixedPoint> &positions);

    virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags);
    void addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags);
    /**
     * Create a qimage with the alpha values for the glyph.
     * Returns an image indexed_8 with index values ranging from 0=fully transparent to 255=opaque
     */
    // ### Refactor this into a smaller and more flexible API.
    virtual QImage alphaMapForGlyph(glyph_t);
    virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
    virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
    virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
    virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
    virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color = QColor());
    virtual Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition, GlyphFormat neededFormat, const QTransform &t);
    virtual bool hasInternalCaching() const { return false; }

    virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/)
    {
        return boundingBox(glyph, matrix);
    }

    virtual void removeGlyphFromCache(glyph_t);

    virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) = 0;
    virtual glyph_metrics_t boundingBox(glyph_t glyph) = 0;
    virtual glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix);
    glyph_metrics_t tightBoundingBox(const QGlyphLayout &glyphs);

    virtual QFixed ascent() const = 0;
    virtual QFixed capHeight() const = 0;
    virtual QFixed descent() const = 0;
    virtual QFixed leading() const = 0;
    virtual QFixed xHeight() const;
    virtual QFixed averageCharWidth() const;

    virtual QFixed lineThickness() const;
    virtual QFixed underlinePosition() const;

    virtual qreal maxCharWidth() const = 0;
    virtual qreal minLeftBearing() const;
    virtual qreal minRightBearing() const;

    virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = nullptr, qreal *rightBearing = nullptr);

    inline bool canRender(uint ucs4) const { return glyphIndex(ucs4) != 0; }
    virtual bool canRender(const QChar *str, int len) const;

    virtual bool supportsTransformation(const QTransform &transform) const;

    virtual int glyphCount() const;
    virtual int glyphMargin(GlyphFormat format) { return format == Format_A32 ? 2 : 0; }

    virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return nullptr; }

    virtual Qt::HANDLE handle() const;

    void *harfbuzzFont() const;
    void *harfbuzzFace() const;
    bool supportsScript(QChar::Script script) const;

    inline static bool scriptRequiresOpenType(QChar::Script script)
    {
        return ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala)
                || script == QChar::Script_Khmer || script == QChar::Script_Nko);
    }

    virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints);

    void clearGlyphCache(const void *key);
    void setGlyphCache(const void *key, QFontEngineGlyphCache *data);
    QFontEngineGlyphCache *glyphCache(const void *key, GlyphFormat format, const QTransform &transform, const QColor &color = QColor()) const;

    static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
    static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode);

    static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);

    virtual bool hasUnreliableGlyphOutline() const;
    virtual bool expectsGammaCorrectedBlending() const;

    enum HintStyle {
        HintNone,
        HintLight,
        HintMedium,
        HintFull
    };
    virtual void setDefaultHintStyle(HintStyle) { }

    enum SubpixelAntialiasingType {
        Subpixel_None,
        Subpixel_RGB,
        Subpixel_BGR,
        Subpixel_VRGB,
        Subpixel_VBGR
    };

private:
    const Type m_type;

public:
    QAtomicInt ref;
    QFontDef fontDef;

    class Holder { // replace by std::unique_ptr once available
        void *ptr;
        qt_destroy_func_t destroy_func;
    public:
        Holder() : ptr(nullptr), destroy_func(nullptr) {}
        explicit Holder(void *p, qt_destroy_func_t d) : ptr(p), destroy_func(d) {}
        ~Holder() { if (ptr && destroy_func) destroy_func(ptr); }
        Holder(Holder &&other) noexcept
            : ptr(other.ptr),
              destroy_func(other.destroy_func)
        {
            other.ptr = nullptr;
            other.destroy_func = nullptr;
        }
        Holder &operator=(Holder &&other) noexcept
        { swap(other); return *this; }

        void swap(Holder &other) noexcept
        {
            qSwap(ptr, other.ptr);
            qSwap(destroy_func, other.destroy_func);
        }

        void *get() const noexcept { return ptr; }
        void *release() noexcept {
            void *result = ptr;
            ptr = nullptr;
            destroy_func = nullptr;
            return result;
        }
        void reset() noexcept { Holder().swap(*this); }
        qt_destroy_func_t get_deleter() const noexcept { return destroy_func; }

        bool operator!() const noexcept { return !ptr; }
    };

    mutable Holder font_; // \ NOTE: Declared before m_glyphCaches, so font_, face_
    mutable Holder face_; // / are destroyed _after_ m_glyphCaches is destroyed.

    struct FaceData {
        void *user_data;
        qt_get_font_table_func_t get_font_table;
    } faceData;

    uint cache_cost; // amount of mem used in bytes by the font
    uint fsType : 16;
    bool symbol;
    bool isSmoothlyScalable;
    struct KernPair {
        uint left_right;
        QFixed adjust;

        inline bool operator<(const KernPair &other) const
        {
            return left_right < other.left_right;
        }
    };
    QVector<KernPair> kerning_pairs;
    void loadKerningPairs(QFixed scalingFactor);

    GlyphFormat glyphFormat;
    int m_subPixelPositionCount; // Number of positions within a single pixel for this cache

    inline QVariant userData() const { return m_userData; }

protected:
    explicit QFontEngine(Type type);

    QFixed lastRightBearing(const QGlyphLayout &glyphs, bool round = false);

    inline void setUserData(const QVariant &userData) { m_userData = userData; }
    QFixed calculatedCapHeight() const;

private:
    struct GlyphCacheEntry {
        GlyphCacheEntry();
        GlyphCacheEntry(const GlyphCacheEntry &);
        ~GlyphCacheEntry();

        GlyphCacheEntry &operator=(const GlyphCacheEntry &);

        QExplicitlySharedDataPointer<QFontEngineGlyphCache> cache;
        bool operator==(const GlyphCacheEntry &other) const { return cache == other.cache; }
    };
    typedef std::list<GlyphCacheEntry> GlyphCaches;
    mutable QHash<const void *, GlyphCaches> m_glyphCaches;

private:
    QVariant m_userData;

    mutable qreal m_minLeftBearing;
    mutable qreal m_minRightBearing;

};
Q_DECLARE_TYPEINFO(QFontEngine::KernPair, Q_PRIMITIVE_TYPE);

Q_DECLARE_OPERATORS_FOR_FLAGS(QFontEngine::ShaperFlags)

inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2)
{
    return f1.index == f2.index && f1.encoding == f2.encoding && f1.filename == f2.filename && f1.uuid == f2.uuid;
}

inline uint qHash(const QFontEngine::FaceId &f, uint seed = 0)
    noexcept(noexcept(qHash(f.filename)))
{
    QtPrivate::QHashCombine hash;
    seed = hash(seed, f.filename);
    seed = hash(seed, f.uuid);
    seed = hash(seed, f.index);
    seed = hash(seed, f.encoding);
    return seed;
}


class QGlyph;



class QFontEngineBox : public QFontEngine
{
public:
    QFontEngineBox(int size);
    ~QFontEngineBox();

    virtual glyph_t glyphIndex(uint ucs4) const override;
    virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;
    virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const override;

    void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si);
    virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) override;

    virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
    virtual glyph_metrics_t boundingBox(glyph_t glyph) override;
    virtual QFontEngine *cloneWithSize(qreal pixelSize) const override;

    virtual QFixed ascent() const override;
    virtual QFixed capHeight() const override;
    virtual QFixed descent() const override;
    virtual QFixed leading() const override;
    virtual qreal maxCharWidth() const override;
    virtual qreal minLeftBearing() const override { return 0; }
    virtual qreal minRightBearing() const override { return 0; }
    virtual QImage alphaMapForGlyph(glyph_t) override;

    virtual bool canRender(const QChar *string, int len) const override;

    inline int size() const { return _size; }

protected:
    explicit QFontEngineBox(Type type, int size);

private:
    friend class QFontPrivate;
    int _size;
};

class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine
{
public:
    explicit QFontEngineMulti(QFontEngine *engine, int script, const QStringList &fallbackFamilies = QStringList());
    ~QFontEngineMulti();

    virtual glyph_t glyphIndex(uint ucs4) const override;
    virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;

    virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
    virtual glyph_metrics_t boundingBox(glyph_t glyph) override;

    virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const override;
    virtual void doKerning(QGlyphLayout *, ShaperFlags) const override;
    virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags) override;
    virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = nullptr, qreal *rightBearing = nullptr) override;

    virtual QFixed ascent() const override;
    virtual QFixed capHeight() const override;
    virtual QFixed descent() const override;
    virtual QFixed leading() const override;
    virtual QFixed xHeight() const override;
    virtual QFixed averageCharWidth() const override;
    virtual QImage alphaMapForGlyph(glyph_t) override;
    virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) override;
    virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t) override;
    virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
    virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;

    virtual QFixed lineThickness() const override;
    virtual QFixed underlinePosition() const override;
    virtual qreal maxCharWidth() const override;
    virtual qreal minLeftBearing() const override;
    virtual qreal minRightBearing() const override;

    virtual bool canRender(const QChar *string, int len) const override;

    inline int fallbackFamilyCount() const { return m_fallbackFamilies.size(); }
    inline QString fallbackFamilyAt(int at) const { return m_fallbackFamilies.at(at); }

    void setFallbackFamiliesList(const QStringList &fallbackFamilies);

    static uchar highByte(glyph_t glyph); // Used for determining engine

    inline QFontEngine *engine(int at) const
    { Q_ASSERT(at < m_engines.size()); return m_engines.at(at); }

    void ensureEngineAt(int at);

    static QFontEngine *createMultiFontEngine(QFontEngine *fe, int script);

protected:
    virtual void ensureFallbackFamiliesQueried();
    virtual bool shouldLoadFontEngineForCharacter(int at, uint ucs4) const;
    virtual QFontEngine *loadEngine(int at);

private:
    QVector<QFontEngine *> m_engines;
    QStringList m_fallbackFamilies;
    const int m_script;
    bool m_fallbackFamiliesQueried;
};

class QTestFontEngine : public QFontEngineBox
{
public:
    QTestFontEngine(int size);
};

QT_END_NAMESPACE



#endif // QFONTENGINE_P_H
