FontRenderer.h revision 9b1204baf4740b4d443e72157dea98571cf84e1f
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/Vector.h>
21
22#include <SkPaint.h>
23
24#include <GLES2/gl2.h>
25
26#include "font/FontUtil.h"
27#include "font/CacheTexture.h"
28#include "font/CachedGlyphInfo.h"
29#include "font/Font.h"
30#include "Properties.h"
31
32namespace android {
33namespace uirenderer {
34
35///////////////////////////////////////////////////////////////////////////////
36// Renderer
37///////////////////////////////////////////////////////////////////////////////
38
39class FontRenderer {
40public:
41    FontRenderer();
42    ~FontRenderer();
43
44    void flushLargeCaches();
45
46    void setGammaTable(const uint8_t* gammaTable) {
47        mGammaTable = gammaTable;
48    }
49
50    void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
51
52    void precache(SkPaint* paint, const char* text, int numGlyphs);
53
54    // bounds is an out parameter
55    bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
56            uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
57    // bounds is an out parameter
58    bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
59            uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds);
60    // bounds is an out parameter
61    bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
62            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds);
63
64    struct DropShadow {
65        DropShadow() { };
66
67        DropShadow(const DropShadow& dropShadow):
68            width(dropShadow.width), height(dropShadow.height),
69            image(dropShadow.image), penX(dropShadow.penX),
70            penY(dropShadow.penY) {
71        }
72
73        uint32_t width;
74        uint32_t height;
75        uint8_t* image;
76        int32_t penX;
77        int32_t penY;
78    };
79
80    // After renderDropShadow returns, the called owns the memory in DropShadow.image
81    // and is responsible for releasing it when it's done with it
82    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
83            uint32_t len, int numGlyphs, uint32_t radius, const float* positions);
84
85    GLuint getTexture(bool linearFiltering = false) {
86        checkInit();
87
88        if (linearFiltering != mCurrentCacheTexture->mLinearFiltering) {
89            mCurrentCacheTexture->mLinearFiltering = linearFiltering;
90            mLinearFiltering = linearFiltering;
91            const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
92
93            glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->mTextureId);
94            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
95            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
96        }
97
98        return mCurrentCacheTexture->mTextureId;
99    }
100
101    uint32_t getCacheSize() const {
102        uint32_t size = 0;
103        for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
104            CacheTexture* cacheTexture = mCacheTextures[i];
105            if (cacheTexture != NULL && cacheTexture->mTexture != NULL) {
106                size += cacheTexture->mWidth * cacheTexture->mHeight;
107            }
108        }
109        return size;
110    }
111
112private:
113    friend class Font;
114
115    const uint8_t* mGammaTable;
116
117    void allocateTextureMemory(CacheTexture* cacheTexture);
118    void deallocateTextureMemory(CacheTexture* cacheTexture);
119    void initTextTexture();
120    CacheTexture* createCacheTexture(int width, int height, bool allocate);
121    void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
122            uint32_t *retOriginX, uint32_t *retOriginY, bool precaching);
123    CacheTexture* cacheBitmapInTexture(const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
124
125    void flushAllAndInvalidate();
126    void initVertexArrayBuffers();
127
128    void checkInit();
129    void initRender(const Rect* clip, Rect* bounds);
130    void finishRender();
131
132    void issueDrawCommand();
133    void appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
134            float x2, float y2, float u2, float v2,
135            float x3, float y3, float u3, float v3,
136            float x4, float y4, float u4, float v4, CacheTexture* texture);
137    void appendMeshQuad(float x1, float y1, float u1, float v1,
138            float x2, float y2, float u2, float v2,
139            float x3, float y3, float u3, float v3,
140            float x4, float y4, float u4, float v4, CacheTexture* texture);
141    void appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
142            float x2, float y2, float u2, float v2,
143            float x3, float y3, float u3, float v3,
144            float x4, float y4, float u4, float v4, CacheTexture* texture);
145
146    void removeFont(const Font* font);
147
148    void checkTextureUpdate();
149
150    void setTextureDirty() {
151        mUploadTexture = true;
152    }
153
154    uint32_t mSmallCacheWidth;
155    uint32_t mSmallCacheHeight;
156    uint32_t mLargeCacheWidth;
157    uint32_t mLargeCacheHeight;
158
159    Vector<CacheTexture*> mCacheTextures;
160
161    Font* mCurrentFont;
162    Vector<Font*> mActiveFonts;
163
164    CacheTexture* mCurrentCacheTexture;
165    CacheTexture* mLastCacheTexture;
166
167    bool mUploadTexture;
168
169    // Pointer to vertex data to speed up frame to frame work
170    float* mTextMesh;
171    uint32_t mCurrentQuadIndex;
172    uint32_t mMaxNumberOfQuads;
173
174    uint32_t mIndexBufferID;
175
176    const Rect* mClip;
177    Rect* mBounds;
178    bool mDrawn;
179
180    bool mInitialized;
181
182    bool mLinearFiltering;
183
184    /** We should consider multi-threading this code or using Renderscript **/
185    static void computeGaussianWeights(float* weights, int32_t radius);
186    static void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
187            int32_t width, int32_t height);
188    static void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
189            int32_t width, int32_t height);
190    static void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
191};
192
193}; // namespace uirenderer
194}; // namespace android
195
196#endif // ANDROID_HWUI_FONT_RENDERER_H
197