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