FontRenderer.h revision 894df17eee708688c8a6e67941add2017239c790
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 setAttributeBindingSlots(int positionSlot, int texCoordSlot) { 142 mPositionAttrSlot = positionSlot; 143 mTexcoordAttrSlot = texCoordSlot; 144 } 145 146 void setFont(SkPaint* paint, uint32_t fontId, float fontSize); 147 bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, 148 uint32_t len, int numGlyphs, int x, int y, Rect* bounds); 149 150 struct DropShadow { 151 DropShadow() { }; 152 153 DropShadow(const DropShadow& dropShadow): 154 width(dropShadow.width), height(dropShadow.height), 155 image(dropShadow.image), penX(dropShadow.penX), 156 penY(dropShadow.penY) { 157 } 158 159 uint32_t width; 160 uint32_t height; 161 uint8_t* image; 162 int32_t penX; 163 int32_t penY; 164 }; 165 166 // After renderDropShadow returns, the called owns the memory in DropShadow.image 167 // and is responsible for releasing it when it's done with it 168 DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex, 169 uint32_t len, int numGlyphs, uint32_t radius); 170 171 GLuint getTexture(bool linearFiltering = false) { 172 checkInit(); 173 if (linearFiltering != mLinearFiltering) { 174 mLinearFiltering = linearFiltering; 175 const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST; 176 177 glBindTexture(GL_TEXTURE_2D, mTextureId); 178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); 179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); 180 } 181 return mTextureId; 182 } 183 184 uint32_t getCacheWidth() const { 185 return mCacheWidth; 186 } 187 188 uint32_t getCacheHeight() const { 189 return mCacheHeight; 190 } 191 192protected: 193 friend class Font; 194 195 const uint8_t* mGammaTable; 196 197 struct CacheTextureLine { 198 uint16_t mMaxHeight; 199 uint16_t mMaxWidth; 200 uint32_t mCurrentRow; 201 uint32_t mCurrentCol; 202 bool mDirty; 203 204 CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow, 205 uint32_t currentCol): 206 mMaxHeight(maxHeight), 207 mMaxWidth(maxWidth), 208 mCurrentRow(currentRow), 209 mCurrentCol(currentCol), 210 mDirty(false) { 211 } 212 213 bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) { 214 if (glyph.fHeight + 2 > mMaxHeight) { 215 return false; 216 } 217 218 if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) { 219 *retOriginX = mCurrentCol + 1; 220 *retOriginY = mCurrentRow + 1; 221 mCurrentCol += glyph.fWidth + 2; 222 mDirty = true; 223 return true; 224 } 225 226 return false; 227 } 228 }; 229 230 void initTextTexture(); 231 bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY); 232 233 void flushAllAndInvalidate(); 234 void initVertexArrayBuffers(); 235 236 void checkInit(); 237 238 String16 mLatinPrecache; 239 void precacheLatin(SkPaint* paint); 240 241 void issueDrawCommand(); 242 void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2, 243 float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, 244 float x4, float y4, float z4, float u4, float v4); 245 246 uint32_t mCacheWidth; 247 uint32_t mCacheHeight; 248 249 Vector<CacheTextureLine*> mCacheLines; 250 uint32_t getRemainingCacheCapacity(); 251 252 Font* mCurrentFont; 253 Vector<Font*> mActiveFonts; 254 255 // Texture to cache glyph bitmaps 256 uint8_t* mTextTexture; 257 const uint8_t* getTextTextureData() const { 258 return mTextTexture; 259 } 260 GLuint mTextureId; 261 void checkTextureUpdate(); 262 bool mUploadTexture; 263 264 // Pointer to vertex data to speed up frame to frame work 265 float *mTextMeshPtr; 266 uint32_t mCurrentQuadIndex; 267 uint32_t mMaxNumberOfQuads; 268 269 uint32_t mIndexBufferID; 270 271 int32_t mPositionAttrSlot; 272 int32_t mTexcoordAttrSlot; 273 274 const Rect* mClip; 275 Rect* mBounds; 276 bool mDrawn; 277 278 bool mInitialized; 279 280 bool mLinearFiltering; 281 282 void computeGaussianWeights(float* weights, int32_t radius); 283 void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 284 int32_t width, int32_t height); 285 void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest, 286 int32_t width, int32_t height); 287 void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius); 288}; 289 290}; // namespace uirenderer 291}; // namespace android 292 293#endif // ANDROID_HWUI_FONT_RENDERER_H 294