FontRenderer.h revision 15bc6437f8b4cf10dba55c7638d349e7b9563f4f
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 void setFont(SkPaint* paint, uint32_t fontId, float fontSize); 182 bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, 183 uint32_t len, int numGlyphs, int x, int y, Rect* bounds); 184 185 struct DropShadow { 186 DropShadow() { }; 187 188 DropShadow(const DropShadow& dropShadow): 189 width(dropShadow.width), height(dropShadow.height), 190 image(dropShadow.image), penX(dropShadow.penX), 191 penY(dropShadow.penY) { 192 } 193 194 uint32_t width; 195 uint32_t height; 196 uint8_t* image; 197 int32_t penX; 198 int32_t penY; 199 }; 200 201 // After renderDropShadow returns, the called owns the memory in DropShadow.image 202 // and is responsible for releasing it when it's done with it 203 DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex, 204 uint32_t len, int numGlyphs, uint32_t radius); 205 206 GLuint getTexture(bool linearFiltering = false) { 207 checkInit(); 208 if (linearFiltering != mLinearFiltering) { 209 mLinearFiltering = linearFiltering; 210 const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST; 211 212 glBindTexture(GL_TEXTURE_2D, mTextureId); 213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); 214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); 215 } 216 return mTextureId; 217 } 218 219 uint32_t getCacheWidth() const { 220 return mCacheWidth; 221 } 222 223 uint32_t getCacheHeight() const { 224 return mCacheHeight; 225 } 226 227protected: 228 friend class Font; 229 230 const uint8_t* mGammaTable; 231 232 struct CacheTextureLine { 233 uint16_t mMaxHeight; 234 uint16_t mMaxWidth; 235 uint32_t mCurrentRow; 236 uint32_t mCurrentCol; 237 bool mDirty; 238 239 CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow, 240 uint32_t currentCol): 241 mMaxHeight(maxHeight), 242 mMaxWidth(maxWidth), 243 mCurrentRow(currentRow), 244 mCurrentCol(currentCol), 245 mDirty(false) { 246 } 247 248 bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) { 249 if (glyph.fHeight + 2 > mMaxHeight) { 250 return false; 251 } 252 253 if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) { 254 *retOriginX = mCurrentCol + 1; 255 *retOriginY = mCurrentRow + 1; 256 mCurrentCol += glyph.fWidth + 2; 257 mDirty = true; 258 return true; 259 } 260 261 return false; 262 } 263 }; 264 265 void initTextTexture(bool largeFonts = false); 266 bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY); 267 268 void flushAllAndInvalidate(); 269 void initVertexArrayBuffers(); 270 271 void checkInit(); 272 273 String16 mLatinPrecache; 274 void precacheLatin(SkPaint* paint); 275 276 void issueDrawCommand(); 277 void appendMeshQuad(float x1, float y1, float u1, float v1, 278 float x2, float y2, float u2, float v2, 279 float x3, float y3, float u3, float v3, 280 float x4, float y4, float u4, float v4); 281 282 uint32_t mCacheWidth; 283 uint32_t mCacheHeight; 284 285 Vector<CacheTextureLine*> mCacheLines; 286 uint32_t getRemainingCacheCapacity(); 287 288 Font* mCurrentFont; 289 Vector<Font*> mActiveFonts; 290 291 // Texture to cache glyph bitmaps 292 uint8_t* mTextTexture; 293 const uint8_t* getTextTextureData() const { 294 return mTextTexture; 295 } 296 GLuint mTextureId; 297 void checkTextureUpdate(); 298 bool mUploadTexture; 299 300 // Pointer to vertex data to speed up frame to frame work 301 float *mTextMeshPtr; 302 uint32_t mCurrentQuadIndex; 303 uint32_t mMaxNumberOfQuads; 304 305 uint32_t mIndexBufferID; 306 307 const Rect* mClip; 308 Rect* mBounds; 309 bool mDrawn; 310 311 bool mInitialized; 312 313 bool mLinearFiltering; 314 315 void computeGaussianWeights(float* weights, int32_t radius); 316 void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 317 int32_t width, int32_t height); 318 void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 319 int32_t width, int32_t height); 320 void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius); 321}; 322 323}; // namespace uirenderer 324}; // namespace android 325 326#endif // ANDROID_HWUI_FONT_RENDERER_H 327