blob: 00d77c84587cbdaa8498a7030e6bfeaddcfaee6f [file] [log] [blame]
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -07001/*
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
Alex Sakhartchoukc9fa3052010-10-01 15:20:41 -070034// 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
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070043class FontState;
44
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080045class Font : public ObjectBase {
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070046public:
Alex Sakhartchouk09c67352010-10-05 11:33:27 -070047 enum RenderMode {
48 FRAMEBUFFER,
49 BITMAP,
50 MEASURE,
51 };
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070052
Alex Sakhartchouk09c67352010-10-05 11:33:27 -070053 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();
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070067
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
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080076 static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi,
77 const void *data = NULL, uint32_t dataLen = 0);
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070078
79protected:
80
81 friend class FontState;
82
Alex Sakhartchouk09c67352010-10-05 11:33:27 -070083 // Pointer to the utf data, length of data, where to start, number of glyphs ot read
84 // (each glyph may be longer than a char because we are dealing with utf data)
85 // Last two variables are the initial pen position
86 void renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
87 uint32_t start, int32_t numGlyphs,
88 RenderMode mode = FRAMEBUFFER, Rect *bounds = NULL,
89 uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
90
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070091 void invalidateTextureCache();
92 struct CachedGlyphInfo
93 {
94 // Has the cache been invalidated?
95 bool mIsValid;
96 // Location of the cached glyph in the bitmap
97 // in case we need to resize the texture
98 uint32_t mBitmapMinX;
99 uint32_t mBitmapMinY;
100 uint32_t mBitmapWidth;
101 uint32_t mBitmapHeight;
102 // Also cache texture coords for the quad
103 float mBitmapMinU;
104 float mBitmapMinV;
105 float mBitmapMaxU;
106 float mBitmapMaxV;
107 // Minimize how much we call freetype
108 FT_UInt mGlyphIndex;
109 FT_Vector mAdvance;
110 // Values below contain a glyph's origin in the bitmap
111 FT_Int mBitmapLeft;
112 FT_Int mBitmapTop;
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700113 };
114
115 String8 mFontName;
Alex Sakhartchoukc17ace22010-12-17 11:41:08 -0800116 float mFontSize;
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700117 uint32_t mDpi;
118
119 Font(Context *rsc);
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800120 bool init(const char *name, float fontSize, uint32_t dpi, const void *data = NULL, uint32_t dataLen = 0);
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700121
122 FT_Face mFace;
123 bool mInitialized;
124 bool mHasKerning;
125
126 DefaultKeyedVector<uint32_t, CachedGlyphInfo* > mCachedGlyphs;
Alex Sakhartchouk01bcef62010-08-17 11:09:49 -0700127 CachedGlyphInfo* getCachedUTFChar(int32_t utfChar);
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700128
129 CachedGlyphInfo *cacheGlyph(uint32_t glyph);
130 void updateGlyphCache(CachedGlyphInfo *glyph);
Alex Sakhartchouk09c67352010-10-05 11:33:27 -0700131 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);
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700135};
136
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800137class FontState {
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700138public:
139 FontState();
140 ~FontState();
141
142 void init(Context *rsc);
143 void deinit(Context *rsc);
144
145 ObjectBaseRef<Font> mDefault;
146 ObjectBaseRef<Font> mLast;
147
Alex Sakhartchouk09c67352010-10-05 11:33:27 -0700148 void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
149 uint32_t startIndex = 0, int numGlyphs = -1,
150 Font::RenderMode mode = Font::FRAMEBUFFER,
151 Font::Rect *bounds = NULL,
152 uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
153
154 void measureText(const char *text, uint32_t len, Font::Rect *bounds);
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700155
Alex Sakhartchouk9fc9f032010-08-04 14:45:48 -0700156 void setFontColor(float r, float g, float b, float a);
Alex Sakhartchoukca5a4542010-08-05 11:24:14 -0700157 void getFontColor(float *r, float *g, float *b, float *a) const;
Alex Sakhartchouk9fc9f032010-08-04 14:45:48 -0700158
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700159protected:
160
161 friend class Font;
162
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800163 struct CacheTextureLine {
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700164 uint32_t mMaxHeight;
165 uint32_t mMaxWidth;
166 uint32_t mCurrentRow;
167 uint32_t mCurrentCol;
Alex Sakhartchouk01bcef62010-08-17 11:09:49 -0700168 bool mDirty;
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700169
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800170 CacheTextureLine(uint32_t maxHeight, uint32_t maxWidth, uint32_t currentRow, uint32_t currentCol)
171 : mMaxHeight(maxHeight), mMaxWidth(maxWidth), mCurrentRow(currentRow),
172 mCurrentCol(currentCol), mDirty(false) {
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700173 }
174
175 bool fitBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800176 if ((uint32_t)bitmap->rows > mMaxHeight) {
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700177 return false;
178 }
179
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800180 if (mCurrentCol + (uint32_t)bitmap->width < mMaxWidth) {
181 *retOriginX = mCurrentCol;
182 *retOriginY = mCurrentRow;
183 mCurrentCol += bitmap->width;
184 mDirty = true;
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700185 return true;
186 }
187
188 return false;
189 }
190 };
191
192 Vector<CacheTextureLine*> mCacheLines;
Alex Sakhartchouk01bcef62010-08-17 11:09:49 -0700193 uint32_t getRemainingCacheCapacity();
194
195 void precacheLatin(Font *font);
196 String8 mLatinPrecache;
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700197
198 Context *mRSC;
199
Alex Sakhartchoukc9fa3052010-10-01 15:20:41 -0700200 struct {
201 float mFontColor[4];
202 float mGamma;
203 } mConstants;
204 bool mConstantsDirty;
205
206 float mBlackGamma;
207 float mWhiteGamma;
208
209 float mBlackThreshold;
210 float mWhiteThreshold;
Alex Sakhartchouk9fc9f032010-08-04 14:45:48 -0700211
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700212 // Free type library, we only need one copy
213 FT_Library mLibrary;
Alex Sakhartchouka1ccecd2010-06-30 12:49:27 -0700214 FT_Library getLib();
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700215 Vector<Font*> mActiveFonts;
216
217 // Render state for the font
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700218 ObjectBaseRef<Allocation> mFontShaderFConstant;
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700219 ObjectBaseRef<ProgramFragment> mFontShaderF;
220 ObjectBaseRef<Sampler> mFontSampler;
221 ObjectBaseRef<ProgramStore> mFontProgramStore;
222 void initRenderState();
223
224 // Texture to cache glyph bitmaps
225 ObjectBaseRef<Allocation> mTextTexture;
226 void initTextTexture();
Alex Sakhartchouk09c67352010-10-05 11:33:27 -0700227 const uint8_t* getTextTextureData() const {
228 return (uint8_t*)mTextTexture->getPtr();
229 }
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700230
231 bool cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
232 const Type* getCacheTextureType() {
233 return mTextTexture->getType();
234 }
235
236 void flushAllAndInvalidate();
237
238 // Pointer to vertex data to speed up frame to frame work
239 float *mTextMeshPtr;
240 uint32_t mCurrentQuadIndex;
241 uint32_t mMaxNumberOfQuads;
242
243 void initVertexArrayBuffers();
244 ObjectBaseRef<Allocation> mIndexBuffer;
245 ObjectBaseRef<Allocation> mVertexArray;
246
247
248 bool mInitialized;
249
250 void checkInit();
251
252 void issueDrawCommand();
253
254 void appendMeshQuad(float x1, float y1, float z1,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800255 float u1, float v1,
256 float x2, float y2, float z2,
257 float u2, float v2,
258 float x3, float y3, float z3,
259 float u3, float v3,
260 float x4, float y4, float z4,
261 float u4, float v4);
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700262};
263
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -0700264}
265}
266
267#endif