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