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