blob: 96c92d5096cf12ac1529072d585b553cc19a28eb [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
17#ifndef ANDROID_UI_FONT_RENDERER_H
18#define ANDROID_UI_FONT_RENDERER_H
19
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:
44 ~Font();
45
Romain Guy51769a62010-07-23 00:28:00 -070046 /**
47 * Renders the specified string of text.
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -070048 * If bitmap is specified, it will be used as the render target
Romain Guy51769a62010-07-23 00:28:00 -070049 */
50 void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -070051 int numGlyphs, int x, int y,
52 uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
Romain Guy51769a62010-07-23 00:28:00 -070053 /**
54 * Creates a new font associated with the specified font state.
55 */
Romain Guy694b5192010-07-21 21:33:20 -070056 static Font* create(FontRenderer* state, uint32_t fontId, float fontSize);
57
58protected:
Romain Guy694b5192010-07-21 21:33:20 -070059 friend class FontRenderer;
60
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -070061 enum RenderMode {
62 FRAMEBUFFER,
63 BITMAP,
64 MEASURE,
65 };
66
67 void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
68 int numGlyphs, int x, int y, RenderMode mode,
69 uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
70 Rect *bounds);
71
72 void measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
73 int numGlyphs, Rect *bounds);
74
Romain Guy694b5192010-07-21 21:33:20 -070075 struct CachedGlyphInfo {
76 // Has the cache been invalidated?
77 bool mIsValid;
78 // Location of the cached glyph in the bitmap
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -070079 // in case we need to resize the texture or
80 // render to bitmap
81 uint32_t mStartX;
82 uint32_t mStartY;
Romain Guy694b5192010-07-21 21:33:20 -070083 uint32_t mBitmapWidth;
84 uint32_t mBitmapHeight;
85 // Also cache texture coords for the quad
86 float mBitmapMinU;
87 float mBitmapMinV;
88 float mBitmapMaxU;
89 float mBitmapMaxV;
90 // Minimize how much we call freetype
91 uint32_t mGlyphIndex;
92 uint32_t mAdvanceX;
93 uint32_t mAdvanceY;
94 // Values below contain a glyph's origin in the bitmap
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -070095 int32_t mBitmapLeft;
96 int32_t mBitmapTop;
Romain Guy694b5192010-07-21 21:33:20 -070097 };
98
Romain Guy694b5192010-07-21 21:33:20 -070099 Font(FontRenderer* state, uint32_t fontId, float fontSize);
100
101 DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
102
Romain Guybd0e6aa2010-07-22 18:50:12 -0700103 void invalidateTextureCache();
104
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700105 CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
Romain Guy694b5192010-07-21 21:33:20 -0700106 void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700107 void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds);
Romain Guy694b5192010-07-21 21:33:20 -0700108 void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700109 void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
110 uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
Romain Guybd0e6aa2010-07-22 18:50:12 -0700111
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700112 CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
113
Romain Guybd0e6aa2010-07-22 18:50:12 -0700114 FontRenderer* mState;
115 uint32_t mFontId;
116 float mFontSize;
Romain Guy694b5192010-07-21 21:33:20 -0700117};
118
119class FontRenderer {
120public:
121 FontRenderer();
122 ~FontRenderer();
123
124 void init();
125 void deinit();
126
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700127 void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
Romain Guy51769a62010-07-23 00:28:00 -0700128 void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
129 uint32_t len, int numGlyphs, int x, int y);
Romain Guy694b5192010-07-21 21:33:20 -0700130
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700131 struct DropShadow {
Romain Guy1e45aae2010-08-13 19:39:53 -0700132 DropShadow() { };
133
134 DropShadow(const DropShadow& dropShadow):
135 width(dropShadow.width), height(dropShadow.height),
136 image(dropShadow.image), penX(dropShadow.penX),
137 penY(dropShadow.penY) {
138 }
139
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700140 uint32_t width;
141 uint32_t height;
142 uint8_t* image;
143 int32_t penX;
144 int32_t penY;
145 };
146
147 // After renderDropShadow returns, the called owns the memory in DropShadow.image
148 // and is responsible for releasing it when it's done with it
149 DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
Romain Guy1e45aae2010-08-13 19:39:53 -0700150 uint32_t len, int numGlyphs, uint32_t radius);
Alex Sakhartchoukf18136c2010-08-06 14:49:04 -0700151
Romain Guy694b5192010-07-21 21:33:20 -0700152 GLuint getTexture() {
153 checkInit();
154 return mTextureId;
155 }
156
157protected:
158 friend class Font;
159
160 struct CacheTextureLine {
161 uint16_t mMaxHeight;
162 uint16_t mMaxWidth;
163 uint32_t mCurrentRow;
164 uint32_t mCurrentCol;
Romain Guy1e45aae2010-08-13 19:39:53 -0700165 bool mDirty;
Romain Guy694b5192010-07-21 21:33:20 -0700166
Romain Guy51769a62010-07-23 00:28:00 -0700167 CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
Romain Guy694b5192010-07-21 21:33:20 -0700168 uint32_t currentCol):
Romain Guy51769a62010-07-23 00:28:00 -0700169 mMaxHeight(maxHeight),
170 mMaxWidth(maxWidth),
171 mCurrentRow(currentRow),
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700172 mCurrentCol(currentCol),
173 mDirty(false) {
Romain Guy694b5192010-07-21 21:33:20 -0700174 }
175
176 bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
177 if (glyph.fHeight > mMaxHeight) {
178 return false;
179 }
180
181 if (mCurrentCol + glyph.fWidth < mMaxWidth) {
182 *retOriginX = mCurrentCol;
183 *retOriginY = mCurrentRow;
184 mCurrentCol += glyph.fWidth;
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700185 mDirty = true;
Romain Guy694b5192010-07-21 21:33:20 -0700186 return true;
187 }
188
189 return false;
190 }
191 };
192
193 uint32_t getCacheWidth() const {
194 return mCacheWidth;
195 }
196
197 uint32_t getCacheHeight() const {
198 return mCacheHeight;
199 }
200
201 void initTextTexture();
Romain Guy694b5192010-07-21 21:33:20 -0700202 bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
203
204 void flushAllAndInvalidate();
205 void initVertexArrayBuffers();
206
207 void checkInit();
208
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700209 String16 mLatinPrecache;
210 void precacheLatin(SkPaint* paint);
211
Romain Guy694b5192010-07-21 21:33:20 -0700212 void issueDrawCommand();
Romain Guy694b5192010-07-21 21:33:20 -0700213 void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
214 float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
215 float x4, float y4, float z4, float u4, float v4);
216
217 uint32_t mCacheWidth;
218 uint32_t mCacheHeight;
219
Romain Guy694b5192010-07-21 21:33:20 -0700220 Vector<CacheTextureLine*> mCacheLines;
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700221 uint32_t getRemainingCacheCapacity();
Romain Guy694b5192010-07-21 21:33:20 -0700222
Romain Guy09147fb2010-07-22 13:08:20 -0700223 Font* mCurrentFont;
Romain Guy694b5192010-07-21 21:33:20 -0700224 Vector<Font*> mActiveFonts;
225
226 // Texture to cache glyph bitmaps
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700227 uint8_t* mTextTexture;
228 const uint8_t* getTextTextureData() const {
229 return mTextTexture;
230 }
Romain Guy694b5192010-07-21 21:33:20 -0700231 GLuint mTextureId;
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700232 void checkTextureUpdate();
Romain Guy694b5192010-07-21 21:33:20 -0700233 bool mUploadTexture;
234
235 // Pointer to vertex data to speed up frame to frame work
236 float *mTextMeshPtr;
237 uint32_t mCurrentQuadIndex;
238 uint32_t mMaxNumberOfQuads;
239
240 uint32_t mIndexBufferID;
241
Romain Guy09147fb2010-07-22 13:08:20 -0700242 const Rect* mClip;
243
Romain Guy694b5192010-07-21 21:33:20 -0700244 bool mInitialized;
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700245
246 void computeGaussianWeights(float* weights, int32_t radius);
247 void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
Romain Guy1e45aae2010-08-13 19:39:53 -0700248 int32_t width, int32_t height);
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700249 void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
Romain Guy1e45aae2010-08-13 19:39:53 -0700250 int32_t width, int32_t height);
Alex Sakhartchouk89a524a2010-08-02 17:52:30 -0700251 void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
Romain Guy694b5192010-07-21 21:33:20 -0700252};
253
254}; // namespace uirenderer
255}; // namespace android
256
257#endif // ANDROID_UI_FONT_RENDERER_H