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