FontRenderer.h revision 8087246d9964b11de8ce116bc63b156faa4197e0
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        mCurrentCacheTexture->setLinearFiltering(linearFiltering);
89        mLinearFiltering = linearFiltering;
90
91        return mCurrentCacheTexture->getTextureId();
92    }
93
94    uint32_t getCacheSize() const {
95        uint32_t size = 0;
96        for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
97            CacheTexture* cacheTexture = mCacheTextures[i];
98            if (cacheTexture && cacheTexture->getTexture()) {
99                size += cacheTexture->getWidth() * cacheTexture->getHeight();
100            }
101        }
102        return size;
103    }
104
105private:
106    friend class Font;
107
108    const uint8_t* mGammaTable;
109
110    void allocateTextureMemory(CacheTexture* cacheTexture);
111    void deallocateTextureMemory(CacheTexture* cacheTexture);
112    void initTextTexture();
113    CacheTexture* createCacheTexture(int width, int height, bool allocate);
114    void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
115            uint32_t *retOriginX, uint32_t *retOriginY, bool precaching);
116    CacheTexture* cacheBitmapInTexture(const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
117
118    void flushAllAndInvalidate();
119    void initVertexArrayBuffers();
120
121    void checkInit();
122    void initRender(const Rect* clip, Rect* bounds);
123    void finishRender();
124
125    void issueDrawCommand();
126    void appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
127            float x2, float y2, float u2, float v2,
128            float x3, float y3, float u3, float v3,
129            float x4, float y4, float u4, float v4, CacheTexture* texture);
130    void appendMeshQuad(float x1, float y1, float u1, float v1,
131            float x2, float y2, float u2, float v2,
132            float x3, float y3, float u3, float v3,
133            float x4, float y4, float u4, float v4, CacheTexture* texture);
134    void appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
135            float x2, float y2, float u2, float v2,
136            float x3, float y3, float u3, float v3,
137            float x4, float y4, float u4, float v4, CacheTexture* texture);
138
139    void removeFont(const Font* font);
140
141    void checkTextureUpdate();
142
143    void setTextureDirty() {
144        mUploadTexture = true;
145    }
146
147    uint32_t mSmallCacheWidth;
148    uint32_t mSmallCacheHeight;
149    uint32_t mLargeCacheWidth;
150    uint32_t mLargeCacheHeight;
151
152    Vector<CacheTexture*> mCacheTextures;
153
154    Font* mCurrentFont;
155    Vector<Font*> mActiveFonts;
156
157    CacheTexture* mCurrentCacheTexture;
158    CacheTexture* mLastCacheTexture;
159
160    bool mUploadTexture;
161
162    // Pointer to vertex data to speed up frame to frame work
163    float* mTextMesh;
164    uint32_t mCurrentQuadIndex;
165    uint32_t mMaxNumberOfQuads;
166
167    uint32_t mIndexBufferID;
168
169    const Rect* mClip;
170    Rect* mBounds;
171    bool mDrawn;
172
173    bool mInitialized;
174
175    bool mLinearFiltering;
176
177    /** We should consider multi-threading this code or using Renderscript **/
178    static void computeGaussianWeights(float* weights, int32_t radius);
179    static void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
180            int32_t width, int32_t height);
181    static void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
182            int32_t width, int32_t height);
183    static void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
184};
185
186}; // namespace uirenderer
187}; // namespace android
188
189#endif // ANDROID_HWUI_FONT_RENDERER_H
190