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