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