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/Functor.h>
21#include <utils/LruCache.h>
22#include <utils/Vector.h>
23#include <utils/StrongPointer.h>
24
25#include <SkPaint.h>
26
27#include <GLES2/gl2.h>
28
29#include "font/FontUtil.h"
30#include "font/CacheTexture.h"
31#include "font/CachedGlyphInfo.h"
32#include "font/Font.h"
33#include "utils/SortedList.h"
34#include "Matrix.h"
35#include "Properties.h"
36
37#ifdef ANDROID_ENABLE_RENDERSCRIPT
38#include "RenderScript.h"
39namespace RSC {
40    class Element;
41    class RS;
42    class ScriptIntrinsicBlur;
43    class sp;
44}
45#endif
46
47class Functor;
48
49namespace android {
50namespace uirenderer {
51
52class OpenGLRenderer;
53
54///////////////////////////////////////////////////////////////////////////////
55// TextSetupFunctor
56///////////////////////////////////////////////////////////////////////////////
57class TextSetupFunctor: public Functor {
58public:
59    struct Data {
60        Data(GLenum glyphFormat) : glyphFormat(glyphFormat) {
61        }
62
63        GLenum glyphFormat;
64    };
65
66    TextSetupFunctor(OpenGLRenderer* renderer, float x, float y, bool pureTranslate,
67            int alpha, SkXfermode::Mode mode, SkPaint* paint): Functor(),
68            renderer(renderer), x(x), y(y), pureTranslate(pureTranslate),
69            alpha(alpha), mode(mode), paint(paint) {
70    }
71    ~TextSetupFunctor() { }
72
73    status_t operator ()(int what, void* data);
74
75    OpenGLRenderer* renderer;
76    float x;
77    float y;
78    bool pureTranslate;
79    int alpha;
80    SkXfermode::Mode mode;
81    SkPaint* paint;
82};
83
84///////////////////////////////////////////////////////////////////////////////
85// FontRenderer
86///////////////////////////////////////////////////////////////////////////////
87
88class FontRenderer {
89public:
90    FontRenderer();
91    ~FontRenderer();
92
93    void flushLargeCaches(Vector<CacheTexture*>& cacheTextures);
94    void flushLargeCaches();
95
96    void setGammaTable(const uint8_t* gammaTable) {
97        mGammaTable = gammaTable;
98    }
99
100    void setFont(SkPaint* paint, const mat4& matrix);
101
102    void precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix);
103    void endPrecaching();
104
105    // bounds is an out parameter
106    bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
107            uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds,
108            Functor* functor, bool forceFinish = true);
109
110    // bounds is an out parameter
111    bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
112            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds,
113            Functor* functor);
114
115    struct DropShadow {
116        DropShadow() { };
117
118        DropShadow(const DropShadow& dropShadow):
119            width(dropShadow.width), height(dropShadow.height),
120            image(dropShadow.image), penX(dropShadow.penX),
121            penY(dropShadow.penY) {
122        }
123
124        uint32_t width;
125        uint32_t height;
126        uint8_t* image;
127        int32_t penX;
128        int32_t penY;
129    };
130
131    // After renderDropShadow returns, the called owns the memory in DropShadow.image
132    // and is responsible for releasing it when it's done with it
133    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
134            uint32_t len, int numGlyphs, uint32_t radius, const float* positions);
135
136    void setTextureFiltering(bool linearFiltering) {
137        mLinearFiltering = linearFiltering;
138    }
139
140    uint32_t getCacheSize(GLenum format) const;
141
142private:
143    friend class Font;
144
145    const uint8_t* mGammaTable;
146
147    void allocateTextureMemory(CacheTexture* cacheTexture);
148    void deallocateTextureMemory(CacheTexture* cacheTexture);
149    void initTextTexture();
150    CacheTexture* createCacheTexture(int width, int height, GLenum format, bool allocate);
151    void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
152            uint32_t *retOriginX, uint32_t *retOriginY, bool precaching);
153    CacheTexture* cacheBitmapInTexture(Vector<CacheTexture*>& cacheTextures, const SkGlyph& glyph,
154            uint32_t* startX, uint32_t* startY);
155
156    void flushAllAndInvalidate();
157
158    void checkInit();
159    void initRender(const Rect* clip, Rect* bounds, Functor* functor);
160    void finishRender();
161
162    void issueDrawCommand(Vector<CacheTexture*>& cacheTextures);
163    void issueDrawCommand();
164    void appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
165            float x2, float y2, float u2, float v2,
166            float x3, float y3, float u3, float v3,
167            float x4, float y4, float u4, float v4, CacheTexture* texture);
168    void appendMeshQuad(float x1, float y1, float u1, float v1,
169            float x2, float y2, float u2, float v2,
170            float x3, float y3, float u3, float v3,
171            float x4, float y4, float u4, float v4, CacheTexture* texture);
172    void appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
173            float x2, float y2, float u2, float v2,
174            float x3, float y3, float u3, float v3,
175            float x4, float y4, float u4, float v4, CacheTexture* texture);
176
177    void removeFont(const Font* font);
178
179    void checkTextureUpdate();
180
181    void setTextureDirty() {
182        mUploadTexture = true;
183    }
184
185    uint32_t mSmallCacheWidth;
186    uint32_t mSmallCacheHeight;
187    uint32_t mLargeCacheWidth;
188    uint32_t mLargeCacheHeight;
189
190    Vector<CacheTexture*> mACacheTextures;
191    Vector<CacheTexture*> mRGBACacheTextures;
192
193    Font* mCurrentFont;
194    LruCache<Font::FontDescription, Font*> mActiveFonts;
195
196    CacheTexture* mCurrentCacheTexture;
197
198    bool mUploadTexture;
199
200    Functor* mFunctor;
201    const Rect* mClip;
202    Rect* mBounds;
203    bool mDrawn;
204
205    bool mInitialized;
206
207    bool mLinearFiltering;
208
209#ifdef ANDROID_ENABLE_RENDERSCRIPT
210    // RS constructs
211    RSC::sp<RSC::RS> mRs;
212    RSC::sp<const RSC::Element> mRsElement;
213    RSC::sp<RSC::ScriptIntrinsicBlur> mRsScript;
214#endif
215
216    static void computeGaussianWeights(float* weights, int32_t radius);
217    static void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
218            int32_t width, int32_t height);
219    static void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
220            int32_t width, int32_t height);
221
222    // the input image handle may have its pointer replaced (to avoid copies)
223    void blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius);
224};
225
226}; // namespace uirenderer
227}; // namespace android
228
229#endif // ANDROID_HWUI_FONT_RENDERER_H
230