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