FontRenderer.h revision 5b3b35296e8b2c8d3f07d32bb645d5414db41a1d
116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck/*
216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Copyright (C) 2010 The Android Open Source Project
316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Licensed under the Apache License, Version 2.0 (the "License");
516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * you may not use this file except in compliance with the License.
616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * You may obtain a copy of the License at
716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *      http://www.apache.org/licenses/LICENSE-2.0
916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
1016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Unless required by applicable law or agreed to in writing, software
1116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * distributed under the License is distributed on an "AS IS" BASIS,
1216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * See the License for the specific language governing permissions and
1416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * limitations under the License.
1516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck */
1616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
1716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#ifndef ANDROID_HWUI_FONT_RENDERER_H
1816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#define ANDROID_HWUI_FONT_RENDERER_H
1916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
2016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <utils/String8.h>
2127e58b4f54d693ff1db7ab2edb5d47ca296c1278Chris Craik#include <utils/String16.h>
2216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <utils/Vector.h>
2316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <utils/KeyedVector.h>
2416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
2516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <SkScalerContext.h>
2627e58b4f54d693ff1db7ab2edb5d47ca296c1278Chris Craik#include <SkPaint.h>
2716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
2816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <GLES2/gl2.h>
2916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include "Rect.h"
3116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include "Properties.h"
3216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Recknamespace android {
3416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Recknamespace uirenderer {
3516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckclass FontRenderer;
3716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck/**
3916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Represents a font, defined by a Skia font id and a font size. A font is used
4016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * to generate glyphs and cache them in the FontState.
4116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck */
4216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckclass Font {
4316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckpublic:
4416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    ~Font();
4516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
4616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    /**
478d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik     * Renders the specified string of text.
4816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck     * If bitmap is specified, it will be used as the render target
4916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck     */
5016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
5116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck                     int numGlyphs, int x, int y,
5216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck                     uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
5316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    /**
5416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck     * Creates a new font associated with the specified font state.
5516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck     */
5616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    static Font* create(FontRenderer* state, uint32_t fontId, float fontSize);
5716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
5816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckprotected:
5916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    friend class FontRenderer;
6016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
6116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    enum RenderMode {
6216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        FRAMEBUFFER,
6316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        BITMAP,
6416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        MEASURE,
6516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    };
6616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
6716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
68                     int numGlyphs, int x, int y, RenderMode mode,
69                     uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
70                     Rect *bounds);
71
72    void measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
73                      int numGlyphs, Rect *bounds);
74
75    struct CachedGlyphInfo {
76        // Has the cache been invalidated?
77        bool mIsValid;
78        // Location of the cached glyph in the bitmap
79        // in case we need to resize the texture or
80        // render to bitmap
81        uint32_t mStartX;
82        uint32_t mStartY;
83        uint32_t mBitmapWidth;
84        uint32_t mBitmapHeight;
85        // Also cache texture coords for the quad
86        float mBitmapMinU;
87        float mBitmapMinV;
88        float mBitmapMaxU;
89        float mBitmapMaxV;
90        // Minimize how much we call freetype
91        uint32_t mGlyphIndex;
92        uint32_t mAdvanceX;
93        uint32_t mAdvanceY;
94        // Values below contain a glyph's origin in the bitmap
95        int32_t mBitmapLeft;
96        int32_t mBitmapTop;
97        // Auto-kerning
98        SkFixed mLsbDelta;
99        SkFixed mRsbDelta;
100    };
101
102    Font(FontRenderer* state, uint32_t fontId, float fontSize);
103
104    DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
105
106    void invalidateTextureCache();
107
108    CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
109    void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
110    void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds);
111    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
112    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
113                          uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
114
115    CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
116
117    FontRenderer* mState;
118    uint32_t mFontId;
119    float mFontSize;
120};
121
122class FontRenderer {
123public:
124    FontRenderer();
125    ~FontRenderer();
126
127    void init();
128    void deinit();
129
130    void setGammaTable(const uint8_t* gammaTable) {
131        mGammaTable = gammaTable;
132    }
133
134    void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
135    bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
136            uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
137
138    struct DropShadow {
139        DropShadow() { };
140
141        DropShadow(const DropShadow& dropShadow):
142            width(dropShadow.width), height(dropShadow.height),
143            image(dropShadow.image), penX(dropShadow.penX),
144            penY(dropShadow.penY) {
145        }
146
147        uint32_t width;
148        uint32_t height;
149        uint8_t* image;
150        int32_t penX;
151        int32_t penY;
152    };
153
154    // After renderDropShadow returns, the called owns the memory in DropShadow.image
155    // and is responsible for releasing it when it's done with it
156    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
157            uint32_t len, int numGlyphs, uint32_t radius);
158
159    GLuint getTexture(bool linearFiltering = false) {
160        checkInit();
161        if (linearFiltering != mLinearFiltering) {
162            mLinearFiltering = linearFiltering;
163            const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
164
165            glBindTexture(GL_TEXTURE_2D, mTextureId);
166            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
167            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
168        }
169        return mTextureId;
170    }
171
172protected:
173    friend class Font;
174
175    const uint8_t* mGammaTable;
176
177    struct CacheTextureLine {
178        uint16_t mMaxHeight;
179        uint16_t mMaxWidth;
180        uint32_t mCurrentRow;
181        uint32_t mCurrentCol;
182        bool mDirty;
183
184        CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
185                uint32_t currentCol):
186                    mMaxHeight(maxHeight),
187                    mMaxWidth(maxWidth),
188                    mCurrentRow(currentRow),
189                    mCurrentCol(currentCol),
190                    mDirty(false) {
191        }
192
193        bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
194            if (glyph.fHeight + 2 > mMaxHeight) {
195                return false;
196            }
197
198            if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) {
199                *retOriginX = mCurrentCol + 1;
200                *retOriginY = mCurrentRow + 1;
201                mCurrentCol += glyph.fWidth + 2;
202                mDirty = true;
203                return true;
204            }
205
206            return false;
207        }
208    };
209
210    uint32_t getCacheWidth() const {
211        return mCacheWidth;
212    }
213
214    uint32_t getCacheHeight() const {
215        return mCacheHeight;
216    }
217
218    void initTextTexture();
219    bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
220
221    void flushAllAndInvalidate();
222    void initVertexArrayBuffers();
223
224    void checkInit();
225
226    String16 mLatinPrecache;
227    void precacheLatin(SkPaint* paint);
228
229    void issueDrawCommand();
230    void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
231            float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
232            float x4, float y4, float z4, float u4, float v4);
233
234    uint32_t mCacheWidth;
235    uint32_t mCacheHeight;
236
237    Vector<CacheTextureLine*> mCacheLines;
238    uint32_t getRemainingCacheCapacity();
239
240    Font* mCurrentFont;
241    Vector<Font*> mActiveFonts;
242
243    // Texture to cache glyph bitmaps
244    uint8_t* mTextTexture;
245    const uint8_t* getTextTextureData() const {
246        return mTextTexture;
247    }
248    GLuint mTextureId;
249    void checkTextureUpdate();
250    bool mUploadTexture;
251
252    // Pointer to vertex data to speed up frame to frame work
253    float *mTextMeshPtr;
254    uint32_t mCurrentQuadIndex;
255    uint32_t mMaxNumberOfQuads;
256
257    uint32_t mIndexBufferID;
258
259    const Rect* mClip;
260    Rect* mBounds;
261    bool mDrawn;
262
263    bool mInitialized;
264
265    bool mLinearFiltering;
266
267    void computeGaussianWeights(float* weights, int32_t radius);
268    void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
269            int32_t width, int32_t height);
270    void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
271            int32_t width, int32_t height);
272    void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
273};
274
275}; // namespace uirenderer
276}; // namespace android
277
278#endif // ANDROID_HWUI_FONT_RENDERER_H
279