/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HWUI_FONT_H
#define ANDROID_HWUI_FONT_H

#include <vector>

#include <utils/KeyedVector.h>

#include <SkPaint.h>
#include <SkPathMeasure.h>
#include <SkScalar.h>
#include <SkTypeface.h>

#include "../Matrix.h"
#include "../Rect.h"
#include "FontUtil.h"

class SkGlyphCache;

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Font
///////////////////////////////////////////////////////////////////////////////

struct CachedGlyphInfo;
class CacheTexture;
class FontRenderer;

/**
 * Represents a font, defined by a Skia font id and a font size. A font is used
 * to generate glyphs and cache them in the FontState.
 */
class Font {
public:
    enum Style { kFakeBold = 1 };

    struct FontDescription {
        FontDescription(const SkPaint* paint, const SkMatrix& matrix);

        static int compare(const FontDescription& lhs, const FontDescription& rhs);

        hash_t hash() const;

        bool operator==(const FontDescription& other) const { return compare(*this, other) == 0; }

        bool operator!=(const FontDescription& other) const { return compare(*this, other) != 0; }

        SkFontID mFontId;
        float mFontSize;
        int mFlags;
        float mItalicStyle;
        float mScaleX;
        uint8_t mStyle;
        float mStrokeWidth;
        bool mAntiAliasing;
        uint8_t mHinting;
        SkMatrix mLookupTransform;
        SkMatrix mInverseLookupTransform;
    };

    ~Font();

    void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y,
                const float* positions);

    void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkPath* path,
                float hOffset, float vOffset);

    const Font::FontDescription& getDescription() const { return mDescription; }

    /**
     * Creates a new font associated with the specified font state.
     */
    static Font* create(FontRenderer* state, const SkPaint* paint, const SkMatrix& matrix);

private:
    friend class FontRenderer;

    Font(FontRenderer* state, const Font::FontDescription& desc);

    typedef void (Font::*RenderGlyph)(CachedGlyphInfo*, int, int, uint8_t*, uint32_t, uint32_t,
                                      Rect*, const float*);

    enum RenderMode {
        FRAMEBUFFER,
        BITMAP,
        MEASURE,
    };

    void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs);

    void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y,
                RenderMode mode, uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds,
                const float* positions);

    void measure(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, Rect* bounds,
                 const float* positions);

    void invalidateTextureCache(CacheTexture* cacheTexture = nullptr);

    CachedGlyphInfo* cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching);
    void updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph,
                          SkGlyphCache* skiaGlyphCache, CachedGlyphInfo* glyph, bool precaching);

    void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, uint32_t bitmapW,
                            uint32_t bitmapH, Rect* bounds, const float* pos);
    void drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, uint32_t bitmapW,
                         uint32_t bitmapH, Rect* bounds, const float* pos);
    void drawCachedGlyphTransformed(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap,
                                    uint32_t bitmapW, uint32_t bitmapH, Rect* bounds,
                                    const float* pos);
    void drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap,
                               uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos);
    void drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
                         SkPathMeasure& measure, SkPoint* position, SkVector* tangent);

    CachedGlyphInfo* getCachedGlyph(const SkPaint* paint, glyph_t textUnit,
                                    bool precaching = false);

    FontRenderer* mState;
    FontDescription mDescription;

    // Cache of glyphs
    DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;

    bool mIdentityTransform;
};

inline int strictly_order_type(const Font::FontDescription& lhs, const Font::FontDescription& rhs) {
    return Font::FontDescription::compare(lhs, rhs) < 0;
}

inline int compare_type(const Font::FontDescription& lhs, const Font::FontDescription& rhs) {
    return Font::FontDescription::compare(lhs, rhs);
}

inline hash_t hash_type(const Font::FontDescription& entry) {
    return entry.hash();
}

};  // namespace uirenderer
};  // namespace android

#endif  // ANDROID_HWUI_FONT_H
