FontRenderer.h revision 2577db1ec135a1470a2c42139772ec97a6c30e78
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_HWUI_FONT_RENDERER_H
18#define ANDROID_HWUI_FONT_RENDERER_H
19
20#include <utils/String8.h>
21#include <utils/String16.h>
22#include <utils/Vector.h>
23#include <utils/KeyedVector.h>
24
25#include <SkScalerContext.h>
26#include <SkPaint.h>
27
28#include <GLES2/gl2.h>
29
30#include "Rect.h"
31#include "Properties.h"
32
33namespace android {
34namespace uirenderer {
35
36class FontRenderer;
37
38/**
39 * Represents a font, defined by a Skia font id and a font size. A font is used
40 * to generate glyphs and cache them in the FontState.
41 */
42class Font {
43public:
44    enum Style {
45        kFakeBold
46    };
47
48    ~Font();
49
50    /**
51     * Renders the specified string of text.
52     * If bitmap is specified, it will be used as the render target
53     */
54    void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
55                     int numGlyphs, int x, int y,
56                     uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
57    /**
58     * Creates a new font associated with the specified font state.
59     */
60    static Font* create(FontRenderer* state, uint32_t fontId, float fontSize,
61            int flags, uint32_t italicStyle);
62
63protected:
64    friend class FontRenderer;
65
66    enum RenderMode {
67        FRAMEBUFFER,
68        BITMAP,
69        MEASURE,
70    };
71
72    void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
73                     int numGlyphs, int x, int y, RenderMode mode,
74                     uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
75                     Rect *bounds);
76
77    void measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
78                      int numGlyphs, Rect *bounds);
79
80    struct CachedGlyphInfo {
81        // Has the cache been invalidated?
82        bool mIsValid;
83        // Location of the cached glyph in the bitmap
84        // in case we need to resize the texture or
85        // render to bitmap
86        uint32_t mStartX;
87        uint32_t mStartY;
88        uint32_t mBitmapWidth;
89        uint32_t mBitmapHeight;
90        // Also cache texture coords for the quad
91        float mBitmapMinU;
92        float mBitmapMinV;
93        float mBitmapMaxU;
94        float mBitmapMaxV;
95        // Minimize how much we call freetype
96        uint32_t mGlyphIndex;
97        uint32_t mAdvanceX;
98        uint32_t mAdvanceY;
99        // Values below contain a glyph's origin in the bitmap
100        int32_t mBitmapLeft;
101        int32_t mBitmapTop;
102        // Auto-kerning
103        SkFixed mLsbDelta;
104        SkFixed mRsbDelta;
105    };
106
107    Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle);
108
109    DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
110
111    void invalidateTextureCache();
112
113    CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
114    void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
115    void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds);
116    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
117    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
118                          uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
119
120    CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
121
122    FontRenderer* mState;
123    uint32_t mFontId;
124    float mFontSize;
125    int mFlags;
126    uint32_t mItalicStyle;
127};
128
129class FontRenderer {
130public:
131    FontRenderer();
132    ~FontRenderer();
133
134    void init();
135    void deinit();
136
137    void setGammaTable(const uint8_t* gammaTable) {
138        mGammaTable = gammaTable;
139    }
140
141    void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
142    bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
143            uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
144
145    struct DropShadow {
146        DropShadow() { };
147
148        DropShadow(const DropShadow& dropShadow):
149            width(dropShadow.width), height(dropShadow.height),
150            image(dropShadow.image), penX(dropShadow.penX),
151            penY(dropShadow.penY) {
152        }
153
154        uint32_t width;
155        uint32_t height;
156        uint8_t* image;
157        int32_t penX;
158        int32_t penY;
159    };
160
161    // After renderDropShadow returns, the called owns the memory in DropShadow.image
162    // and is responsible for releasing it when it's done with it
163    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
164            uint32_t len, int numGlyphs, uint32_t radius);
165
166    GLuint getTexture(bool linearFiltering = false) {
167        checkInit();
168        if (linearFiltering != mLinearFiltering) {
169            mLinearFiltering = linearFiltering;
170            const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
171
172            glBindTexture(GL_TEXTURE_2D, mTextureId);
173            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
174            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
175        }
176        return mTextureId;
177    }
178
179    uint32_t getCacheWidth() const {
180        return mCacheWidth;
181    }
182
183    uint32_t getCacheHeight() const {
184        return mCacheHeight;
185    }
186
187protected:
188    friend class Font;
189
190    const uint8_t* mGammaTable;
191
192    struct CacheTextureLine {
193        uint16_t mMaxHeight;
194        uint16_t mMaxWidth;
195        uint32_t mCurrentRow;
196        uint32_t mCurrentCol;
197        bool mDirty;
198
199        CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
200                uint32_t currentCol):
201                    mMaxHeight(maxHeight),
202                    mMaxWidth(maxWidth),
203                    mCurrentRow(currentRow),
204                    mCurrentCol(currentCol),
205                    mDirty(false) {
206        }
207
208        bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
209            if (glyph.fHeight + 2 > mMaxHeight) {
210                return false;
211            }
212
213            if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) {
214                *retOriginX = mCurrentCol + 1;
215                *retOriginY = mCurrentRow + 1;
216                mCurrentCol += glyph.fWidth + 2;
217                mDirty = true;
218                return true;
219            }
220
221            return false;
222        }
223    };
224
225    void initTextTexture();
226    bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
227
228    void flushAllAndInvalidate();
229    void initVertexArrayBuffers();
230
231    void checkInit();
232
233    String16 mLatinPrecache;
234    void precacheLatin(SkPaint* paint);
235
236    void issueDrawCommand();
237    void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
238            float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
239            float x4, float y4, float z4, float u4, float v4);
240
241    uint32_t mCacheWidth;
242    uint32_t mCacheHeight;
243
244    Vector<CacheTextureLine*> mCacheLines;
245    uint32_t getRemainingCacheCapacity();
246
247    Font* mCurrentFont;
248    Vector<Font*> mActiveFonts;
249
250    // Texture to cache glyph bitmaps
251    uint8_t* mTextTexture;
252    const uint8_t* getTextTextureData() const {
253        return mTextTexture;
254    }
255    GLuint mTextureId;
256    void checkTextureUpdate();
257    bool mUploadTexture;
258
259    // Pointer to vertex data to speed up frame to frame work
260    float *mTextMeshPtr;
261    uint32_t mCurrentQuadIndex;
262    uint32_t mMaxNumberOfQuads;
263
264    uint32_t mIndexBufferID;
265
266    const Rect* mClip;
267    Rect* mBounds;
268    bool mDrawn;
269
270    bool mInitialized;
271
272    bool mLinearFiltering;
273
274    void computeGaussianWeights(float* weights, int32_t radius);
275    void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
276            int32_t width, int32_t height);
277    void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
278            int32_t width, int32_t height);
279    void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
280};
281
282}; // namespace uirenderer
283}; // namespace android
284
285#endif // ANDROID_HWUI_FONT_RENDERER_H
286