rsFont.h revision 82e135c4bbe18855d8ed02632bb074f8da0b96e0
1/*
2 * Copyright (C) 2009 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_RS_FONT_H
18#define ANDROID_RS_FONT_H
19
20#include "rsStream.h"
21#include <utils/KeyedVector.h>
22
23struct FT_LibraryRec_;
24struct FT_FaceRec_;
25struct FT_Bitmap_;
26
27// ---------------------------------------------------------------------------
28namespace android {
29
30namespace renderscript {
31
32// Gamma (>= 1.0, <= 10.0)
33#define PROPERTY_TEXT_GAMMA "ro.text_gamma"
34#define PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD "ro.text_gamma.black_threshold"
35#define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "ro.text_gamma.white_threshold"
36
37#define DEFAULT_TEXT_GAMMA 1.4f
38#define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64
39#define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192
40
41class FontState;
42
43class Font : public ObjectBase {
44public:
45    enum RenderMode {
46        FRAMEBUFFER,
47        BITMAP,
48        MEASURE,
49    };
50
51    struct Rect {
52        int32_t left;
53        int32_t top;
54        int32_t right;
55        int32_t bottom;
56        void set(int32_t l, int32_t r, int32_t t, int32_t b) {
57            left = l;
58            right = r;
59            top = t;
60            bottom = b;
61        }
62    };
63
64    ~Font();
65
66    // Currently files do not get serialized,
67    // but we need to inherit from ObjectBase for ref tracking
68    virtual void serialize(Context *rsc, OStream *stream) const {
69    }
70    virtual RsA3DClassID getClassId() const {
71        return RS_A3D_CLASS_ID_UNKNOWN;
72    }
73
74    static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi,
75                         const void *data = nullptr, uint32_t dataLen = 0);
76
77protected:
78
79    friend class FontState;
80
81    // Pointer to the utf data, length of data, where to start, number of glyphs ot read
82    // (each glyph may be longer than a char because we are dealing with utf data)
83    // Last two variables are the initial pen position
84    void renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
85                   uint32_t start, int32_t numGlyphs,
86                   RenderMode mode = FRAMEBUFFER, Rect *bounds = nullptr,
87                   uint8_t *bitmap = nullptr, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
88
89    void invalidateTextureCache();
90    struct CachedGlyphInfo
91    {
92        // Has the cache been invalidated?
93        bool mIsValid;
94        // Location of the cached glyph in the bitmap
95        // in case we need to resize the texture
96        uint32_t mBitmapMinX;
97        uint32_t mBitmapMinY;
98        uint32_t mBitmapWidth;
99        uint32_t mBitmapHeight;
100        // Also cache texture coords for the quad
101        float mBitmapMinU;
102        float mBitmapMinV;
103        float mBitmapMaxU;
104        float mBitmapMaxV;
105        // Minimize how much we call freetype
106        int32_t mGlyphIndex;
107        int32_t mAdvanceX;
108        int32_t mAdvanceY;
109        // Values below contain a glyph's origin in the bitmap
110        int32_t mBitmapLeft;
111        int32_t mBitmapTop;
112    };
113
114    const char *mFontName;
115    float mFontSize;
116    uint32_t mDpi;
117
118    explicit Font(Context *rsc);
119    bool init(const char *name, float fontSize, uint32_t dpi, const void *data = nullptr, uint32_t dataLen = 0);
120
121    virtual void preDestroy() const;
122    FT_FaceRec_ *mFace;
123    bool mInitialized;
124    bool mHasKerning;
125
126    DefaultKeyedVector<uint32_t, CachedGlyphInfo* > mCachedGlyphs;
127    CachedGlyphInfo* getCachedUTFChar(int32_t utfChar);
128
129    CachedGlyphInfo *cacheGlyph(uint32_t glyph);
130    void updateGlyphCache(CachedGlyphInfo *glyph);
131    void measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds);
132    void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y);
133    void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y,
134                         uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
135};
136
137class FontState {
138public:
139    FontState();
140    ~FontState();
141
142    void init(Context *rsc);
143    void deinit(Context *rsc);
144
145    ObjectBaseRef<Font> mDefault;
146
147    void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
148                    uint32_t startIndex = 0, int numGlyphs = -1,
149                    Font::RenderMode mode = Font::FRAMEBUFFER,
150                    Font::Rect *bounds = nullptr,
151                    uint8_t *bitmap = nullptr, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
152
153    void measureText(const char *text, uint32_t len, Font::Rect *bounds);
154
155    void setFontColor(float r, float g, float b, float a);
156    void getFontColor(float *r, float *g, float *b, float *a) const;
157
158protected:
159
160    float mSurfaceWidth;
161    float mSurfaceHeight;
162
163    friend class Font;
164
165    struct CacheTextureLine {
166        uint32_t mMaxHeight;
167        uint32_t mMaxWidth;
168        uint32_t mCurrentRow;
169        uint32_t mCurrentCol;
170        bool mDirty;
171
172        CacheTextureLine(uint32_t maxHeight, uint32_t maxWidth, uint32_t currentRow, uint32_t currentCol)
173            : mMaxHeight(maxHeight), mMaxWidth(maxWidth), mCurrentRow(currentRow),
174              mCurrentCol(currentCol), mDirty(false)  {
175        }
176
177        bool fitBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
178    };
179
180    std::vector<CacheTextureLine*> mCacheLines;
181    uint32_t getRemainingCacheCapacity();
182
183    void precacheLatin(Font *font);
184    const char *mLatinPrecache;
185
186    Context *mRSC;
187
188    struct {
189        float mFontColor[4];
190        float mGamma;
191    } mConstants;
192    bool mConstantsDirty;
193
194    float mBlackGamma;
195    float mWhiteGamma;
196
197    float mBlackThreshold;
198    float mWhiteThreshold;
199
200    // Free type library, we only need one copy
201#ifndef ANDROID_RS_SERIALIZE
202    FT_LibraryRec_ *mLibrary;
203    FT_LibraryRec_ *getLib();
204#endif //ANDROID_RS_SERIALIZE
205    std::vector<Font*> mActiveFonts;
206
207    // Render state for the font
208    ObjectBaseRef<Allocation> mFontShaderFConstant;
209    ObjectBaseRef<ProgramFragment> mFontShaderF;
210    ObjectBaseRef<Sampler> mFontSampler;
211    ObjectBaseRef<ProgramStore> mFontProgramStore;
212    void initRenderState();
213
214    // Texture to cache glyph bitmaps
215    ObjectBaseRef<Allocation> mTextTexture;
216    uint8_t *mCacheBuffer;
217    uint32_t mCacheWidth;
218    uint32_t mCacheHeight;
219
220    void initTextTexture();
221
222#ifndef ANDROID_RS_SERIALIZE
223    bool cacheBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
224#endif //ANDROID_RS_SERIALIZE
225    const Type* getCacheTextureType() {
226        return mTextTexture->getType();
227    }
228
229    void flushAllAndInvalidate();
230
231    // Pointer to vertex data to speed up frame to frame work
232    float *mTextMeshPtr;
233    uint32_t mCurrentQuadIndex;
234    uint32_t mMaxNumberOfQuads;
235
236    void initVertexArrayBuffers();
237    ObjectBaseRef<Mesh> mMesh;
238
239    bool mInitialized;
240
241    void checkInit();
242
243    void issueDrawCommand();
244
245    void appendMeshQuad(float x1, float y1, float z1,
246                        float u1, float v1,
247                        float x2, float y2, float z2,
248                        float u2, float v2,
249                        float x3, float y3, float z3,
250                        float u3, float v3,
251                        float x4, float y4, float z4,
252                        float u4, float v4);
253};
254
255} // namespace renderscript
256} // namespace android
257
258#endif
259