blob: 2f7a8bac305a6b8f2e0f6afe2fde58fc0e04d711 [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.
48 */
49 void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
Romain Guy694b5192010-07-21 21:33:20 -070050 int numGlyphs, int x, int y);
Romain Guy51769a62010-07-23 00:28:00 -070051 /**
52 * Creates a new font associated with the specified font state.
53 */
Romain Guy694b5192010-07-21 21:33:20 -070054 static Font* create(FontRenderer* state, uint32_t fontId, float fontSize);
55
56protected:
Romain Guy694b5192010-07-21 21:33:20 -070057 friend class FontRenderer;
58
Romain Guy694b5192010-07-21 21:33:20 -070059 struct CachedGlyphInfo {
60 // Has the cache been invalidated?
61 bool mIsValid;
62 // Location of the cached glyph in the bitmap
63 // in case we need to resize the texture
64 uint32_t mBitmapWidth;
65 uint32_t mBitmapHeight;
66 // Also cache texture coords for the quad
67 float mBitmapMinU;
68 float mBitmapMinV;
69 float mBitmapMaxU;
70 float mBitmapMaxV;
71 // Minimize how much we call freetype
72 uint32_t mGlyphIndex;
73 uint32_t mAdvanceX;
74 uint32_t mAdvanceY;
75 // Values below contain a glyph's origin in the bitmap
76 uint32_t mBitmapLeft;
77 uint32_t mBitmapTop;
78 };
79
Romain Guy694b5192010-07-21 21:33:20 -070080 Font(FontRenderer* state, uint32_t fontId, float fontSize);
81
82 DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
83
Romain Guybd0e6aa2010-07-22 18:50:12 -070084 void invalidateTextureCache();
85
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -070086 CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
Romain Guy694b5192010-07-21 21:33:20 -070087 void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
88 void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
Romain Guybd0e6aa2010-07-22 18:50:12 -070089
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -070090 CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
91
Romain Guybd0e6aa2010-07-22 18:50:12 -070092 FontRenderer* mState;
93 uint32_t mFontId;
94 float mFontSize;
Romain Guy694b5192010-07-21 21:33:20 -070095};
96
97class FontRenderer {
98public:
99 FontRenderer();
100 ~FontRenderer();
101
102 void init();
103 void deinit();
104
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700105 void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
Romain Guy51769a62010-07-23 00:28:00 -0700106 void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
107 uint32_t len, int numGlyphs, int x, int y);
Romain Guy694b5192010-07-21 21:33:20 -0700108
109 GLuint getTexture() {
110 checkInit();
111 return mTextureId;
112 }
113
114protected:
115 friend class Font;
116
117 struct CacheTextureLine {
118 uint16_t mMaxHeight;
119 uint16_t mMaxWidth;
120 uint32_t mCurrentRow;
121 uint32_t mCurrentCol;
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700122 bool mDirty;
Romain Guy694b5192010-07-21 21:33:20 -0700123
Romain Guy51769a62010-07-23 00:28:00 -0700124 CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
Romain Guy694b5192010-07-21 21:33:20 -0700125 uint32_t currentCol):
Romain Guy51769a62010-07-23 00:28:00 -0700126 mMaxHeight(maxHeight),
127 mMaxWidth(maxWidth),
128 mCurrentRow(currentRow),
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700129 mCurrentCol(currentCol),
130 mDirty(false) {
Romain Guy694b5192010-07-21 21:33:20 -0700131 }
132
133 bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
134 if (glyph.fHeight > mMaxHeight) {
135 return false;
136 }
137
138 if (mCurrentCol + glyph.fWidth < mMaxWidth) {
139 *retOriginX = mCurrentCol;
140 *retOriginY = mCurrentRow;
141 mCurrentCol += glyph.fWidth;
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700142 mDirty = true;
Romain Guy694b5192010-07-21 21:33:20 -0700143 return true;
144 }
145
146 return false;
147 }
148 };
149
150 uint32_t getCacheWidth() const {
151 return mCacheWidth;
152 }
153
154 uint32_t getCacheHeight() const {
155 return mCacheHeight;
156 }
157
158 void initTextTexture();
Romain Guy694b5192010-07-21 21:33:20 -0700159 bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
160
161 void flushAllAndInvalidate();
162 void initVertexArrayBuffers();
163
164 void checkInit();
165
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700166 String16 mLatinPrecache;
167 void precacheLatin(SkPaint* paint);
168
Romain Guy694b5192010-07-21 21:33:20 -0700169 void issueDrawCommand();
Romain Guy694b5192010-07-21 21:33:20 -0700170 void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
171 float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
172 float x4, float y4, float z4, float u4, float v4);
173
174 uint32_t mCacheWidth;
175 uint32_t mCacheHeight;
176
Romain Guy694b5192010-07-21 21:33:20 -0700177 Vector<CacheTextureLine*> mCacheLines;
Alex Sakhartchouk65ef9092010-07-26 11:09:33 -0700178 uint32_t getRemainingCacheCapacity();
Romain Guy694b5192010-07-21 21:33:20 -0700179
Romain Guy09147fb2010-07-22 13:08:20 -0700180 Font* mCurrentFont;
Romain Guy694b5192010-07-21 21:33:20 -0700181 Vector<Font*> mActiveFonts;
182
183 // Texture to cache glyph bitmaps
184 unsigned char* mTextTexture;
185 GLuint mTextureId;
Alex Sakhartchouk9b9902d2010-07-23 14:45:49 -0700186 void checkTextureUpdate();
Romain Guy694b5192010-07-21 21:33:20 -0700187 bool mUploadTexture;
188
189 // Pointer to vertex data to speed up frame to frame work
190 float *mTextMeshPtr;
191 uint32_t mCurrentQuadIndex;
192 uint32_t mMaxNumberOfQuads;
193
194 uint32_t mIndexBufferID;
195
Romain Guy09147fb2010-07-22 13:08:20 -0700196 const Rect* mClip;
197
Romain Guy694b5192010-07-21 21:33:20 -0700198 bool mInitialized;
199};
200
201}; // namespace uirenderer
202}; // namespace android
203
204#endif // ANDROID_UI_FONT_RENDERER_H