FontRenderer.h revision 09147fbdc8206a0cac78bfe9083e7e15b3c5689c
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_UI_FONT_RENDERER_H
18#define ANDROID_UI_FONT_RENDERER_H
19
20#include <utils/String8.h>
21#include <utils/Vector.h>
22#include <utils/KeyedVector.h>
23
24#include <SkScalerContext.h>
25#include <SkPaint.h>
26
27#include <GLES2/gl2.h>
28
29#include "Rect.h"
30
31namespace android {
32namespace uirenderer {
33
34class FontRenderer;
35
36class Font {
37public:
38    ~Font();
39
40    void renderUTF(SkPaint* paint, const char *text, uint32_t len, uint32_t start,
41            int numGlyphs, int x, int y);
42
43    static Font* create(FontRenderer* state, uint32_t fontId, float fontSize);
44
45protected:
46
47    friend class FontRenderer;
48
49    void invalidateTextureCache();
50    struct CachedGlyphInfo {
51        // Has the cache been invalidated?
52        bool mIsValid;
53        // Location of the cached glyph in the bitmap
54        // in case we need to resize the texture
55        uint32_t mBitmapWidth;
56        uint32_t mBitmapHeight;
57        // Also cache texture coords for the quad
58        float mBitmapMinU;
59        float mBitmapMinV;
60        float mBitmapMaxU;
61        float mBitmapMaxV;
62        // Minimize how much we call freetype
63        uint32_t mGlyphIndex;
64        uint32_t mAdvanceX;
65        uint32_t mAdvanceY;
66        // Values below contain a glyph's origin in the bitmap
67        uint32_t mBitmapLeft;
68        uint32_t mBitmapTop;
69    };
70
71    FontRenderer* mState;
72    uint32_t mFontId;
73    float mFontSize;
74
75    Font(FontRenderer* state, uint32_t fontId, float fontSize);
76
77    DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
78
79    CachedGlyphInfo *cacheGlyph(SkPaint* paint, int32_t glyph);
80    void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
81    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
82};
83
84class FontRenderer {
85public:
86    FontRenderer();
87    ~FontRenderer();
88
89    void init();
90    void deinit();
91
92    void setFont(uint32_t fontId, float fontSize);
93    void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t len,
94            uint32_t startIndex, int numGlyphs, int x, int y);
95
96    GLuint getTexture() {
97        checkInit();
98        return mTextureId;
99    }
100
101protected:
102    friend class Font;
103
104    struct CacheTextureLine {
105        uint16_t mMaxHeight;
106        uint16_t mMaxWidth;
107        uint32_t mCurrentRow;
108        uint32_t mCurrentCol;
109
110        CacheTextureLine(uint16_t maxHeight, uint16_t maxWidth, uint32_t currentRow,
111                uint32_t currentCol):
112            mMaxHeight(maxHeight), mMaxWidth(maxWidth), mCurrentRow(currentRow),
113            mCurrentCol(currentCol) {
114        }
115
116        bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
117            if (glyph.fHeight > mMaxHeight) {
118                return false;
119            }
120
121            if (mCurrentCol + glyph.fWidth < mMaxWidth) {
122                *retOriginX = mCurrentCol;
123                *retOriginY = mCurrentRow;
124                mCurrentCol += glyph.fWidth;
125                return true;
126            }
127
128            return false;
129        }
130    };
131
132    uint32_t getCacheWidth() const {
133        return mCacheWidth;
134    }
135
136    uint32_t getCacheHeight() const {
137        return mCacheHeight;
138    }
139
140    void initTextTexture();
141    bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
142
143    void flushAllAndInvalidate();
144    void initVertexArrayBuffers();
145
146    void checkInit();
147
148    void issueDrawCommand();
149    void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
150            float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
151            float x4, float y4, float z4, float u4, float v4);
152
153    uint32_t mCacheWidth;
154    uint32_t mCacheHeight;
155
156    Vector<CacheTextureLine*> mCacheLines;
157
158    Font* mCurrentFont;
159    Vector<Font*> mActiveFonts;
160
161    // Texture to cache glyph bitmaps
162    unsigned char* mTextTexture;
163    GLuint mTextureId;
164    bool mUploadTexture;
165
166    // Pointer to vertex data to speed up frame to frame work
167    float *mTextMeshPtr;
168    uint32_t mCurrentQuadIndex;
169    uint32_t mMaxNumberOfQuads;
170
171    uint32_t mIndexBufferID;
172
173    const Rect* mClip;
174
175    bool mInitialized;
176};
177
178}; // namespace uirenderer
179}; // namespace android
180
181#endif // ANDROID_UI_FONT_RENDERER_H
182