FontRenderer.h revision f3a910b423db7ad79cf61518bdd9278c048ad0d8
1/* 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_HWUI_FONT_RENDERER_H 18#define ANDROID_HWUI_FONT_RENDERER_H 19 20#include <utils/String8.h> 21#include <utils/String16.h> 22#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 30#include "Rect.h" 31#include "Properties.h" 32 33namespace android { 34namespace uirenderer { 35 36/////////////////////////////////////////////////////////////////////////////// 37// Defines 38/////////////////////////////////////////////////////////////////////////////// 39 40#if RENDER_TEXT_AS_GLYPHS 41 typedef uint16_t glyph_t; 42 #define GET_METRICS(paint, glyph) paint->getGlyphMetrics(glyph) 43 #define GET_GLYPH(text) nextGlyph((const uint16_t**) &text) 44 #define IS_END_OF_STRING(glyph) false 45#else 46 typedef SkUnichar glyph_t; 47 #define GET_METRICS(paint, glyph) paint->getUnicharMetrics(glyph) 48 #define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text) 49 #define IS_END_OF_STRING(glyph) glyph < 0 50#endif 51 52/////////////////////////////////////////////////////////////////////////////// 53// Declarations 54/////////////////////////////////////////////////////////////////////////////// 55 56class FontRenderer; 57 58/////////////////////////////////////////////////////////////////////////////// 59// Font 60/////////////////////////////////////////////////////////////////////////////// 61 62/** 63 * Represents a font, defined by a Skia font id and a font size. A font is used 64 * to generate glyphs and cache them in the FontState. 65 */ 66class Font { 67public: 68 enum Style { 69 kFakeBold = 1 70 }; 71 72 ~Font(); 73 74 /** 75 * Renders the specified string of text. 76 * If bitmap is specified, it will be used as the render target 77 */ 78 void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len, 79 int numGlyphs, int x, int y, uint8_t *bitmap = NULL, 80 uint32_t bitmapW = 0, uint32_t bitmapH = 0); 81 /** 82 * Creates a new font associated with the specified font state. 83 */ 84 static Font* create(FontRenderer* state, uint32_t fontId, float fontSize, 85 int flags, uint32_t italicStyle, uint32_t scaleX, SkPaint::Style style, 86 uint32_t strokeWidth); 87 88protected: 89 friend class FontRenderer; 90 91 enum RenderMode { 92 FRAMEBUFFER, 93 BITMAP, 94 MEASURE, 95 }; 96 97 void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len, 98 int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, 99 uint32_t bitmapW, uint32_t bitmapH, Rect *bounds); 100 101 void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len, 102 int numGlyphs, Rect *bounds); 103 104 struct CachedGlyphInfo { 105 // Has the cache been invalidated? 106 bool mIsValid; 107 // Location of the cached glyph in the bitmap 108 // in case we need to resize the texture or 109 // render to bitmap 110 uint32_t mStartX; 111 uint32_t mStartY; 112 uint32_t mBitmapWidth; 113 uint32_t mBitmapHeight; 114 // Also cache texture coords for the quad 115 float mBitmapMinU; 116 float mBitmapMinV; 117 float mBitmapMaxU; 118 float mBitmapMaxV; 119 // Minimize how much we call freetype 120 uint32_t mGlyphIndex; 121 uint32_t mAdvanceX; 122 uint32_t mAdvanceY; 123 // Values below contain a glyph's origin in the bitmap 124 int32_t mBitmapLeft; 125 int32_t mBitmapTop; 126 // Auto-kerning 127 SkFixed mLsbDelta; 128 SkFixed mRsbDelta; 129 }; 130 131 Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle, 132 uint32_t scaleX, SkPaint::Style style, uint32_t strokeWidth); 133 134 // Cache of glyphs 135 DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs; 136 137 void invalidateTextureCache(); 138 139 CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph); 140 void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph); 141 void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds); 142 void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y); 143 void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y, 144 uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH); 145 146 CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit); 147 148 static glyph_t nextGlyph(const uint16_t** srcPtr) { 149 const uint16_t* src = *srcPtr; 150 glyph_t g = *src++; 151 *srcPtr = src; 152 return g; 153 } 154 155 FontRenderer* mState; 156 uint32_t mFontId; 157 float mFontSize; 158 int mFlags; 159 uint32_t mItalicStyle; 160 uint32_t mScaleX; 161 SkPaint::Style mStyle; 162 uint32_t mStrokeWidth; 163}; 164 165/////////////////////////////////////////////////////////////////////////////// 166// Renderer 167/////////////////////////////////////////////////////////////////////////////// 168 169class FontRenderer { 170public: 171 FontRenderer(); 172 ~FontRenderer(); 173 174 void init(); 175 void deinit(); 176 177 void setGammaTable(const uint8_t* gammaTable) { 178 mGammaTable = gammaTable; 179 } 180 181 inline float* getMeshBuffer() { 182 checkInit(); 183 return mTextMeshPtr; 184 } 185 186 inline int getMeshTexCoordsOffset() const { 187 return 2; 188 } 189 190 void setFont(SkPaint* paint, uint32_t fontId, float fontSize); 191 bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, 192 uint32_t len, int numGlyphs, int x, int y, Rect* bounds); 193 194 struct DropShadow { 195 DropShadow() { }; 196 197 DropShadow(const DropShadow& dropShadow): 198 width(dropShadow.width), height(dropShadow.height), 199 image(dropShadow.image), penX(dropShadow.penX), 200 penY(dropShadow.penY) { 201 } 202 203 uint32_t width; 204 uint32_t height; 205 uint8_t* image; 206 int32_t penX; 207 int32_t penY; 208 }; 209 210 // After renderDropShadow returns, the called owns the memory in DropShadow.image 211 // and is responsible for releasing it when it's done with it 212 DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex, 213 uint32_t len, int numGlyphs, uint32_t radius); 214 215 GLuint getTexture(bool linearFiltering = false) { 216 checkInit(); 217 if (linearFiltering != mLinearFiltering) { 218 mLinearFiltering = linearFiltering; 219 const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST; 220 221 glBindTexture(GL_TEXTURE_2D, mTextureId); 222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); 223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); 224 } 225 return mTextureId; 226 } 227 228 uint32_t getCacheWidth() const { 229 return mCacheWidth; 230 } 231 232 uint32_t getCacheHeight() const { 233 return mCacheHeight; 234 } 235 236protected: 237 friend class Font; 238 239 const uint8_t* mGammaTable; 240 241 struct CacheTextureLine { 242 uint16_t mMaxHeight; 243 uint16_t mMaxWidth; 244 uint32_t mCurrentRow; 245 uint32_t mCurrentCol; 246 bool mDirty; 247 248 CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow, 249 uint32_t currentCol): 250 mMaxHeight(maxHeight), 251 mMaxWidth(maxWidth), 252 mCurrentRow(currentRow), 253 mCurrentCol(currentCol), 254 mDirty(false) { 255 } 256 257 bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) { 258 if (glyph.fHeight + 2 > mMaxHeight) { 259 return false; 260 } 261 262 if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) { 263 *retOriginX = mCurrentCol + 1; 264 *retOriginY = mCurrentRow + 1; 265 mCurrentCol += glyph.fWidth + 2; 266 mDirty = true; 267 return true; 268 } 269 270 return false; 271 } 272 }; 273 274 void initTextTexture(bool largeFonts = false); 275 bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY); 276 277 void flushAllAndInvalidate(); 278 void initVertexArrayBuffers(); 279 280 void checkInit(); 281 282 String16 mLatinPrecache; 283 void precacheLatin(SkPaint* paint); 284 285 void issueDrawCommand(); 286 void appendMeshQuad(float x1, float y1, float u1, float v1, 287 float x2, float y2, float u2, float v2, 288 float x3, float y3, float u3, float v3, 289 float x4, float y4, float u4, float v4); 290 291 uint32_t mCacheWidth; 292 uint32_t mCacheHeight; 293 294 Vector<CacheTextureLine*> mCacheLines; 295 uint32_t getRemainingCacheCapacity(); 296 297 Font* mCurrentFont; 298 Vector<Font*> mActiveFonts; 299 300 // Texture to cache glyph bitmaps 301 uint8_t* mTextTexture; 302 const uint8_t* getTextTextureData() const { 303 return mTextTexture; 304 } 305 GLuint mTextureId; 306 void checkTextureUpdate(); 307 bool mUploadTexture; 308 309 // Pointer to vertex data to speed up frame to frame work 310 float *mTextMeshPtr; 311 uint32_t mCurrentQuadIndex; 312 uint32_t mMaxNumberOfQuads; 313 314 uint32_t mIndexBufferID; 315 316 const Rect* mClip; 317 Rect* mBounds; 318 bool mDrawn; 319 320 bool mInitialized; 321 322 bool mLinearFiltering; 323 324 void computeGaussianWeights(float* weights, int32_t radius); 325 void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 326 int32_t width, int32_t height); 327 void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 328 int32_t width, int32_t height); 329 void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius); 330}; 331 332}; // namespace uirenderer 333}; // namespace android 334 335#endif // ANDROID_HWUI_FONT_RENDERER_H 336