FontRenderer.h revision e829bc0f0364e942bed01536d115a5c08d25d776
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 void setFont(SkPaint* paint, uint32_t fontId, float fontSize); 226 bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, 227 uint32_t len, int numGlyphs, int x, int y, Rect* bounds); 228 229 struct DropShadow { 230 DropShadow() { }; 231 232 DropShadow(const DropShadow& dropShadow): 233 width(dropShadow.width), height(dropShadow.height), 234 image(dropShadow.image), penX(dropShadow.penX), 235 penY(dropShadow.penY) { 236 } 237 238 uint32_t width; 239 uint32_t height; 240 uint8_t* image; 241 int32_t penX; 242 int32_t penY; 243 }; 244 245 // After renderDropShadow returns, the called owns the memory in DropShadow.image 246 // and is responsible for releasing it when it's done with it 247 DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex, 248 uint32_t len, int numGlyphs, uint32_t radius); 249 250 GLuint getTexture(bool linearFiltering = false) { 251 checkInit(); 252 if (linearFiltering != mLinearFiltering) { 253 mLinearFiltering = linearFiltering; 254 const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST; 255 256 glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->mTextureId); 257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); 258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); 259 } 260 return mCurrentCacheTexture->mTextureId; 261 } 262 263 uint32_t getCacheSize() const { 264 uint32_t size = 0; 265 if (mCacheTextureSmall != NULL && mCacheTextureSmall->mTexture != NULL) { 266 size += mCacheTextureSmall->mWidth * mCacheTextureSmall->mHeight; 267 } 268 if (mCacheTexture128 != NULL && mCacheTexture128->mTexture != NULL) { 269 size += mCacheTexture128->mWidth * mCacheTexture128->mHeight; 270 } 271 if (mCacheTexture256 != NULL && mCacheTexture256->mTexture != NULL) { 272 size += mCacheTexture256->mWidth * mCacheTexture256->mHeight; 273 } 274 if (mCacheTexture512 != NULL && mCacheTexture512->mTexture != NULL) { 275 size += mCacheTexture512->mWidth * mCacheTexture512->mHeight; 276 } 277 return size; 278 } 279 280protected: 281 friend class Font; 282 283 const uint8_t* mGammaTable; 284 285 uint8_t* allocateTextureMemory(int width, int height); 286 void initTextTexture(); 287 CacheTexture *createCacheTexture(int width, int height, bool allocate); 288 void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph, 289 uint32_t *retOriginX, uint32_t *retOriginY); 290 291 void flushAllAndInvalidate(); 292 void initVertexArrayBuffers(); 293 294 void checkInit(); 295 296 String16 mLatinPrecache; 297 void precacheLatin(SkPaint* paint); 298 299 void issueDrawCommand(); 300 void appendMeshQuad(float x1, float y1, float u1, float v1, 301 float x2, float y2, float u2, float v2, 302 float x3, float y3, float u3, float v3, 303 float x4, float y4, float u4, float v4, CacheTexture* texture); 304 305 uint32_t mSmallCacheWidth; 306 uint32_t mSmallCacheHeight; 307 308 Vector<CacheTextureLine*> mCacheLines; 309 uint32_t getRemainingCacheCapacity(); 310 311 Font* mCurrentFont; 312 Vector<Font*> mActiveFonts; 313 314 CacheTexture* mCurrentCacheTexture; 315 CacheTexture* mLastCacheTexture; 316 CacheTexture* mCacheTextureSmall; 317 CacheTexture* mCacheTexture128; 318 CacheTexture* mCacheTexture256; 319 CacheTexture* mCacheTexture512; 320 321 322 void checkTextureUpdate(); 323 bool mUploadTexture; 324 325 // Pointer to vertex data to speed up frame to frame work 326 float *mTextMeshPtr; 327 uint32_t mCurrentQuadIndex; 328 uint32_t mMaxNumberOfQuads; 329 330 uint32_t mIndexBufferID; 331 332 const Rect* mClip; 333 Rect* mBounds; 334 bool mDrawn; 335 336 bool mInitialized; 337 338 bool mLinearFiltering; 339 340 void computeGaussianWeights(float* weights, int32_t radius); 341 void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 342 int32_t width, int32_t height); 343 void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 344 int32_t width, int32_t height); 345 void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius); 346}; 347 348}; // namespace uirenderer 349}; // namespace android 350 351#endif // ANDROID_HWUI_FONT_RENDERER_H 352