blob: 40572c6667b900d135575722a931b0e5d677c381 [file] [log] [blame]
Romain Guy694b5192010-07-21 21:33:20 -07001/*
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
Romain Guy5b3b3522010-10-27 18:57:51 -070017#ifndef ANDROID_HWUI_FONT_RENDERER_H
18#define ANDROID_HWUI_FONT_RENDERER_H
Romain Guy694b5192010-07-21 21:33:20 -070019
20#include <utils/String8.h>
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -070021#include <utils/String16.h>
Romain Guy694b5192010-07-21 21:33:20 -070022#include <utils/Vector.h>
23#include <utils/KeyedVector.h>
24
25#include <SkScalerContext.h>
26#include <SkPaint.h>
27
28#include <GLES2/gl2.h>
29
Romain Guy09147fb2010-07-22 13:08:20 -070030#include "Rect.h"
Romain Guy51769a62010-07-23 00:28:00 -070031#include "Properties.h"
Romain Guy09147fb2010-07-22 13:08:20 -070032
Romain Guy694b5192010-07-21 21:33:20 -070033namespace android {
34namespace uirenderer {
35
36class FontRenderer;
37
Romain Guy51769a62010-07-23 00:28:00 -070038/**
39 * Represents a font, defined by a Skia font id and a font size. A font is used
40 * to generate glyphs and cache them in the FontState.
41 */
Romain Guy694b5192010-07-21 21:33:20 -070042class Font {
43public:
Romain Guy325a0f92011-01-05 15:26:55 -080044 enum Style {
45 kFakeBold
46 };
47
Romain Guy694b5192010-07-21 21:33:20 -070048 ~Font();
49
Romain Guy51769a62010-07-23 00:28:00 -070050 /**
51 * Renders the specified string of text.
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -070052 * If bitmap is specified, it will be used as the render target
Romain Guy51769a62010-07-23 00:28:00 -070053 */
54 void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -070055 int numGlyphs, int x, int y,
56 uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
Romain Guy51769a62010-07-23 00:28:00 -070057 /**
58 * Creates a new font associated with the specified font state.
59 */
Romain Guy325a0f92011-01-05 15:26:55 -080060 static Font* create(FontRenderer* state, uint32_t fontId, float fontSize, int flags);
Romain Guy694b5192010-07-21 21:33:20 -070061
62protected:
Romain Guy694b5192010-07-21 21:33:20 -070063 friend class FontRenderer;
64
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -070065 enum RenderMode {
66 FRAMEBUFFER,
67 BITMAP,
68 MEASURE,
69 };
70
71 void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
72 int numGlyphs, int x, int y, RenderMode mode,
73 uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
74 Rect *bounds);
75
76 void measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
77 int numGlyphs, Rect *bounds);
78
Romain Guy694b5192010-07-21 21:33:20 -070079 struct CachedGlyphInfo {
80 // Has the cache been invalidated?
81 bool mIsValid;
82 // Location of the cached glyph in the bitmap
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -070083 // in case we need to resize the texture or
84 // render to bitmap
85 uint32_t mStartX;
86 uint32_t mStartY;
Romain Guy694b5192010-07-21 21:33:20 -070087 uint32_t mBitmapWidth;
88 uint32_t mBitmapHeight;
89 // Also cache texture coords for the quad
90 float mBitmapMinU;
91 float mBitmapMinV;
92 float mBitmapMaxU;
93 float mBitmapMaxV;
94 // Minimize how much we call freetype
95 uint32_t mGlyphIndex;
96 uint32_t mAdvanceX;
97 uint32_t mAdvanceY;
98 // Values below contain a glyph's origin in the bitmap
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -070099 int32_t mBitmapLeft;
100 int32_t mBitmapTop;
Romain Guy2bffd262010-09-12 17:40:02 -0700101 // Auto-kerning
102 SkFixed mLsbDelta;
103 SkFixed mRsbDelta;
Romain Guy694b5192010-07-21 21:33:20 -0700104 };
105
Romain Guy325a0f92011-01-05 15:26:55 -0800106 Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags);
Romain Guy694b5192010-07-21 21:33:20 -0700107
108 DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
109
Romain Guybd0e6aa2010-07-22 18:50:12 -0700110 void invalidateTextureCache();
111
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700112 CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
Romain Guy694b5192010-07-21 21:33:20 -0700113 void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700114 void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds);
Romain Guy694b5192010-07-21 21:33:20 -0700115 void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700116 void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
117 uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
Romain Guybd0e6aa2010-07-22 18:50:12 -0700118
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700119 CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
120
Romain Guybd0e6aa2010-07-22 18:50:12 -0700121 FontRenderer* mState;
122 uint32_t mFontId;
123 float mFontSize;
Romain Guy325a0f92011-01-05 15:26:55 -0800124 int mFlags;
Romain Guy694b5192010-07-21 21:33:20 -0700125};
126
127class FontRenderer {
128public:
129 FontRenderer();
130 ~FontRenderer();
131
132 void init();
133 void deinit();
134
Romain Guyb45c0c92010-08-26 20:35:23 -0700135 void setGammaTable(const uint8_t* gammaTable) {
136 mGammaTable = gammaTable;
137 }
138
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700139 void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
Romain Guy5b3b3522010-10-27 18:57:51 -0700140 bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
141 uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
Romain Guy694b5192010-07-21 21:33:20 -0700142
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700143 struct DropShadow {
Romain Guy1e45aae2010-08-13 19:39:53 -0700144 DropShadow() { };
145
146 DropShadow(const DropShadow& dropShadow):
147 width(dropShadow.width), height(dropShadow.height),
148 image(dropShadow.image), penX(dropShadow.penX),
149 penY(dropShadow.penY) {
150 }
151
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700152 uint32_t width;
153 uint32_t height;
154 uint8_t* image;
155 int32_t penX;
156 int32_t penY;
157 };
158
159 // After renderDropShadow returns, the called owns the memory in DropShadow.image
160 // and is responsible for releasing it when it's done with it
161 DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
Romain Guy1e45aae2010-08-13 19:39:53 -0700162 uint32_t len, int numGlyphs, uint32_t radius);
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700163
Romain Guye8cb9c142010-10-04 14:14:11 -0700164 GLuint getTexture(bool linearFiltering = false) {
Romain Guy694b5192010-07-21 21:33:20 -0700165 checkInit();
Romain Guye8cb9c142010-10-04 14:14:11 -0700166 if (linearFiltering != mLinearFiltering) {
167 mLinearFiltering = linearFiltering;
168 const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
169
170 glBindTexture(GL_TEXTURE_2D, mTextureId);
171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
173 }
Romain Guy694b5192010-07-21 21:33:20 -0700174 return mTextureId;
175 }
176
Romain Guyc15008e2010-11-10 11:59:15 -0800177 uint32_t getCacheWidth() const {
178 return mCacheWidth;
179 }
180
181 uint32_t getCacheHeight() const {
182 return mCacheHeight;
183 }
184
Romain Guy694b5192010-07-21 21:33:20 -0700185protected:
186 friend class Font;
187
Romain Guyb45c0c92010-08-26 20:35:23 -0700188 const uint8_t* mGammaTable;
189
Romain Guy694b5192010-07-21 21:33:20 -0700190 struct CacheTextureLine {
191 uint16_t mMaxHeight;
192 uint16_t mMaxWidth;
193 uint32_t mCurrentRow;
194 uint32_t mCurrentCol;
Romain Guy1e45aae2010-08-13 19:39:53 -0700195 bool mDirty;
Romain Guy694b5192010-07-21 21:33:20 -0700196
Romain Guy51769a62010-07-23 00:28:00 -0700197 CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
Romain Guy694b5192010-07-21 21:33:20 -0700198 uint32_t currentCol):
Romain Guy51769a62010-07-23 00:28:00 -0700199 mMaxHeight(maxHeight),
200 mMaxWidth(maxWidth),
201 mCurrentRow(currentRow),
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700202 mCurrentCol(currentCol),
203 mDirty(false) {
Romain Guy694b5192010-07-21 21:33:20 -0700204 }
205
206 bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
Romain Guy7975fb62010-10-01 16:36:14 -0700207 if (glyph.fHeight + 2 > mMaxHeight) {
Romain Guy694b5192010-07-21 21:33:20 -0700208 return false;
209 }
210
Romain Guy7975fb62010-10-01 16:36:14 -0700211 if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) {
212 *retOriginX = mCurrentCol + 1;
213 *retOriginY = mCurrentRow + 1;
214 mCurrentCol += glyph.fWidth + 2;
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700215 mDirty = true;
Romain Guy694b5192010-07-21 21:33:20 -0700216 return true;
217 }
218
219 return false;
220 }
221 };
222
Romain Guy694b5192010-07-21 21:33:20 -0700223 void initTextTexture();
Romain Guy694b5192010-07-21 21:33:20 -0700224 bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
225
226 void flushAllAndInvalidate();
227 void initVertexArrayBuffers();
228
229 void checkInit();
230
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700231 String16 mLatinPrecache;
232 void precacheLatin(SkPaint* paint);
233
Romain Guy694b5192010-07-21 21:33:20 -0700234 void issueDrawCommand();
Romain Guy694b5192010-07-21 21:33:20 -0700235 void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
236 float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
237 float x4, float y4, float z4, float u4, float v4);
238
239 uint32_t mCacheWidth;
240 uint32_t mCacheHeight;
241
Romain Guy694b5192010-07-21 21:33:20 -0700242 Vector<CacheTextureLine*> mCacheLines;
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700243 uint32_t getRemainingCacheCapacity();
Romain Guy694b5192010-07-21 21:33:20 -0700244
Romain Guy09147fb2010-07-22 13:08:20 -0700245 Font* mCurrentFont;
Romain Guy694b5192010-07-21 21:33:20 -0700246 Vector<Font*> mActiveFonts;
247
248 // Texture to cache glyph bitmaps
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700249 uint8_t* mTextTexture;
250 const uint8_t* getTextTextureData() const {
251 return mTextTexture;
252 }
Romain Guy694b5192010-07-21 21:33:20 -0700253 GLuint mTextureId;
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700254 void checkTextureUpdate();
Romain Guy694b5192010-07-21 21:33:20 -0700255 bool mUploadTexture;
256
257 // Pointer to vertex data to speed up frame to frame work
258 float *mTextMeshPtr;
259 uint32_t mCurrentQuadIndex;
260 uint32_t mMaxNumberOfQuads;
261
262 uint32_t mIndexBufferID;
263
Romain Guy09147fb2010-07-22 13:08:20 -0700264 const Rect* mClip;
Romain Guy5b3b3522010-10-27 18:57:51 -0700265 Rect* mBounds;
266 bool mDrawn;
Romain Guy09147fb2010-07-22 13:08:20 -0700267
Romain Guy694b5192010-07-21 21:33:20 -0700268 bool mInitialized;
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700269
Romain Guye8cb9c142010-10-04 14:14:11 -0700270 bool mLinearFiltering;
271
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700272 void computeGaussianWeights(float* weights, int32_t radius);
273 void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
Romain Guy1e45aae2010-08-13 19:39:53 -0700274 int32_t width, int32_t height);
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700275 void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
Romain Guy1e45aae2010-08-13 19:39:53 -0700276 int32_t width, int32_t height);
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700277 void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
Romain Guy694b5192010-07-21 21:33:20 -0700278};
279
280}; // namespace uirenderer
281}; // namespace android
282
Romain Guy5b3b3522010-10-27 18:57:51 -0700283#endif // ANDROID_HWUI_FONT_RENDERER_H