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