FontRenderer.h revision 8668f8a633d9299091556c3b2e5ae07be8dce360
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, uint32_t scaleX);
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            uint32_t scaleX);
109
110    DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
111
112    void invalidateTextureCache();
113
114    CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
115    void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
116    void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds);
117    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
118    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
119                          uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
120
121    CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
122
123    FontRenderer* mState;
124    uint32_t mFontId;
125    float mFontSize;
126    int mFlags;
127    uint32_t mItalicStyle;
128    uint32_t mScaleX;
129};
130
131class FontRenderer {
132public:
133    FontRenderer();
134    ~FontRenderer();
135
136    void init();
137    void deinit();
138
139    void setGammaTable(const uint8_t* gammaTable) {
140        mGammaTable = gammaTable;
141    }
142
143    void setAttributeBindingSlots(int positionSlot, int texCoordSlot) {
144        mPositionAttrSlot = positionSlot;
145        mTexcoordAttrSlot = texCoordSlot;
146    }
147
148    void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
149    bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
150            uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
151
152    struct DropShadow {
153        DropShadow() { };
154
155        DropShadow(const DropShadow& dropShadow):
156            width(dropShadow.width), height(dropShadow.height),
157            image(dropShadow.image), penX(dropShadow.penX),
158            penY(dropShadow.penY) {
159        }
160
161        uint32_t width;
162        uint32_t height;
163        uint8_t* image;
164        int32_t penX;
165        int32_t penY;
166    };
167
168    // After renderDropShadow returns, the called owns the memory in DropShadow.image
169    // and is responsible for releasing it when it's done with it
170    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
171            uint32_t len, int numGlyphs, uint32_t radius);
172
173    GLuint getTexture(bool linearFiltering = false) {
174        checkInit();
175        if (linearFiltering != mLinearFiltering) {
176            mLinearFiltering = linearFiltering;
177            const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
178
179            glBindTexture(GL_TEXTURE_2D, mTextureId);
180            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
181            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
182        }
183        return mTextureId;
184    }
185
186    uint32_t getCacheWidth() const {
187        return mCacheWidth;
188    }
189
190    uint32_t getCacheHeight() const {
191        return mCacheHeight;
192    }
193
194protected:
195    friend class Font;
196
197    const uint8_t* mGammaTable;
198
199    struct CacheTextureLine {
200        uint16_t mMaxHeight;
201        uint16_t mMaxWidth;
202        uint32_t mCurrentRow;
203        uint32_t mCurrentCol;
204        bool mDirty;
205
206        CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
207                uint32_t currentCol):
208                    mMaxHeight(maxHeight),
209                    mMaxWidth(maxWidth),
210                    mCurrentRow(currentRow),
211                    mCurrentCol(currentCol),
212                    mDirty(false) {
213        }
214
215        bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
216            if (glyph.fHeight + 2 > mMaxHeight) {
217                return false;
218            }
219
220            if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) {
221                *retOriginX = mCurrentCol + 1;
222                *retOriginY = mCurrentRow + 1;
223                mCurrentCol += glyph.fWidth + 2;
224                mDirty = true;
225                return true;
226            }
227
228            return false;
229        }
230    };
231
232    void initTextTexture();
233    bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
234
235    void flushAllAndInvalidate();
236    void initVertexArrayBuffers();
237
238    void checkInit();
239
240    String16 mLatinPrecache;
241    void precacheLatin(SkPaint* paint);
242
243    void issueDrawCommand();
244    void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
245            float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
246            float x4, float y4, float z4, float u4, float v4);
247
248    uint32_t mCacheWidth;
249    uint32_t mCacheHeight;
250
251    Vector<CacheTextureLine*> mCacheLines;
252    uint32_t getRemainingCacheCapacity();
253
254    Font* mCurrentFont;
255    Vector<Font*> mActiveFonts;
256
257    // Texture to cache glyph bitmaps
258    uint8_t* mTextTexture;
259    const uint8_t* getTextTextureData() const {
260        return mTextTexture;
261    }
262    GLuint mTextureId;
263    void checkTextureUpdate();
264    bool mUploadTexture;
265
266    // Pointer to vertex data to speed up frame to frame work
267    float *mTextMeshPtr;
268    uint32_t mCurrentQuadIndex;
269    uint32_t mMaxNumberOfQuads;
270
271    uint32_t mIndexBufferID;
272
273    int32_t mPositionAttrSlot;
274    int32_t mTexcoordAttrSlot;
275
276    const Rect* mClip;
277    Rect* mBounds;
278    bool mDrawn;
279
280    bool mInitialized;
281
282    bool mLinearFiltering;
283
284    void computeGaussianWeights(float* weights, int32_t radius);
285    void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
286            int32_t width, int32_t height);
287    void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
288            int32_t width, int32_t height);
289    void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
290};
291
292}; // namespace uirenderer
293}; // namespace android
294
295#endif // ANDROID_HWUI_FONT_RENDERER_H
296