Loading core/jni/android_view_GLES20Canvas.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ #include <SkiaColorFilter.h> #include <Rect.h> #include "TextLayout.h" #include <TextLayout.h> namespace android { Loading Loading @@ -419,7 +419,7 @@ static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject clazz, static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { #if 0 // TODO: replace "0" by "RTL_USE_HARFBUZZ" when renderer->drawGlyphs() is implemented #if RTL_USE_HARFBUZZ sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue( paint, text, 0, count, count, flags); if (value == NULL) { Loading @@ -431,7 +431,8 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, #endif const jchar* glyphArray = value->getGlyphs(); int glyphCount = value->getGlyphsCount(); renderer->drawGlyphs((const char*) glyphArray, 0, glyphCount << 1, x, y, paint); int bytesCount = glyphCount * sizeof(jchar); renderer->drawText((const char*) glyphArray, bytesCount, glyphCount, x, y, paint); #else const jchar *workText; jchar* buffer = NULL; Loading @@ -446,7 +447,7 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, jint start, jint count, jint contextCount, jfloat x, jfloat y, int flags, SkPaint* paint) { #if 0 // TODO: replace "0" by "RTL_USE_HARFBUZZ" when renderer->drawGlyphs() is implemented #if RTL_USE_HARFBUZZ sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue( paint, text, start, count, contextCount, flags); if (value == NULL) { Loading @@ -458,7 +459,8 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, #endif const jchar* glyphArray = value->getGlyphs(); int glyphCount = value->getGlyphsCount(); renderer->drawGlyphs((const char*) glyphArray, 0, glyphCount << 1, x, y, paint); int bytesCount = glyphCount * sizeof(jchar); renderer->drawText((const char*) glyphArray, bytesCount, glyphCount, x, y, paint); #else uint8_t rtl = flags & 0x1; if (rtl) { Loading libs/hwui/DisplayListRenderer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1151,6 +1151,7 @@ void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint) { if (count <= 0) return; addOp(DisplayList::DrawText); addText(text, bytesCount); addInt(count); Loading libs/hwui/FontRenderer.cpp +22 −21 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ namespace uirenderer { #define DEFAULT_TEXT_CACHE_WIDTH 1024 #define DEFAULT_TEXT_CACHE_HEIGHT 256 // We should query these values from the GL context #define MAX_TEXT_CACHE_WIDTH 2048 #define MAX_TEXT_CACHE_HEIGHT 2048 Loading @@ -58,8 +59,7 @@ Font::~Font() { } for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) { CachedGlyphInfo* glyph = mCachedGlyphs.valueAt(i); delete glyph; delete mCachedGlyphs.valueAt(i); } } Loading Loading @@ -134,48 +134,49 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y, } Font::CachedGlyphInfo* Font::getCachedUTFChar(SkPaint* paint, int32_t utfChar) { Font::CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit) { CachedGlyphInfo* cachedGlyph = NULL; ssize_t index = mCachedGlyphs.indexOfKey(utfChar); ssize_t index = mCachedGlyphs.indexOfKey(textUnit); if (index >= 0) { cachedGlyph = mCachedGlyphs.valueAt(index); } else { cachedGlyph = cacheGlyph(paint, utfChar); cachedGlyph = cacheGlyph(paint, textUnit); } // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { const SkGlyph& skiaGlyph = paint->getUnicharMetrics(utfChar); const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit); updateGlyphCache(paint, skiaGlyph, cachedGlyph); } return cachedGlyph; } void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) { if (bitmap != NULL && bitmapW > 0 && bitmapH > 0) { renderUTF(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap, render(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap, bitmapW, bitmapH, NULL); } else { renderUTF(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL, 0, 0, NULL); render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL, 0, 0, NULL); } } void Font::measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, Rect *bounds) { if (bounds == NULL) { LOGE("No return rectangle provided to measure text"); return; } bounds->set(1e6, -1e6, -1e6, 1e6); renderUTF(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds); render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds); } #define SkAutoKern_AdjustF(prev, next) (((next) - (prev) + 32) >> 6 << 16) void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,Rect *bounds) { if (numGlyphs == 0 || text == NULL || len == 0) { Loading @@ -195,14 +196,14 @@ void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t text += start; while (glyphsLeft > 0) { int32_t utfChar = SkUTF16_NextUnichar((const uint16_t**) &text); glyph_t glyph = GET_GLYPH(text); // Reached the end of the string if (utfChar < 0) { if (IS_END_OF_STRING(glyph)) { break; } CachedGlyphInfo* cachedGlyph = getCachedUTFChar(paint, utfChar); CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph); penX += SkAutoKern_AdjustF(prevRsbDelta, cachedGlyph->mLsbDelta); prevRsbDelta = cachedGlyph->mRsbDelta; Loading Loading @@ -268,11 +269,11 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp mState->mUploadTexture = true; } Font::CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, int32_t glyph) { Font::CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph) { CachedGlyphInfo* newGlyph = new CachedGlyphInfo(); mCachedGlyphs.add(glyph, newGlyph); const SkGlyph& skiaGlyph = paint->getUnicharMetrics(glyph); const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph); newGlyph->mGlyphIndex = skiaGlyph.fID; newGlyph->mIsValid = false; Loading Loading @@ -672,7 +673,7 @@ void FontRenderer::precacheLatin(SkPaint* paint) { uint32_t remainingCapacity = getRemainingCacheCapacity(); uint32_t precacheIdx = 0; while (remainingCapacity > 25 && precacheIdx < mLatinPrecache.size()) { mCurrentFont->getCachedUTFChar(paint, (int32_t) mLatinPrecache[precacheIdx]); mCurrentFont->getCachedGlyph(paint, (int32_t) mLatinPrecache[precacheIdx]); remainingCapacity = getRemainingCacheCapacity(); precacheIdx ++; } Loading Loading @@ -714,7 +715,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch } Rect bounds; mCurrentFont->measureUTF(paint, text, startIndex, len, numGlyphs, &bounds); mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds); uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius; uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius; uint8_t* dataBuffer = new uint8_t[paddedWidth * paddedHeight]; Loading @@ -725,7 +726,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch int penX = radius - bounds.left; int penY = radius - bounds.bottom; mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, penX, penY, mCurrentFont->render(paint, text, startIndex, len, numGlyphs, penX, penY, dataBuffer, paddedWidth, paddedHeight); blurImage(dataBuffer, paddedWidth, paddedHeight, radius); Loading Loading @@ -755,7 +756,7 @@ bool FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text mDrawn = false; mBounds = bounds; mClip = clip; mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, x, y); mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y); mBounds = NULL; if (mCurrentQuadIndex != 0) { Loading libs/hwui/FontRenderer.h +48 −13 Original line number Diff line number Diff line Loading @@ -33,8 +33,32 @@ namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// #if RENDER_TEXT_AS_GLYPHS typedef uint16_t glyph_t; #define GET_METRICS(paint, glyph) paint->getGlyphMetrics(glyph) #define GET_GLYPH(text) nextGlyph((const uint16_t**) &text) #define IS_END_OF_STRING(glyph) false #else typedef SkUnichar glyph_t; #define GET_METRICS(paint, glyph) paint->getUnicharMetrics(glyph) #define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text) #define IS_END_OF_STRING(glyph) glyph < 0 #endif /////////////////////////////////////////////////////////////////////////////// // Declarations /////////////////////////////////////////////////////////////////////////////// class FontRenderer; /////////////////////////////////////////////////////////////////////////////// // Font /////////////////////////////////////////////////////////////////////////////// /** * Represents a font, defined by a Skia font id and a font size. A font is used * to generate glyphs and cache them in the FontState. Loading @@ -51,9 +75,9 @@ public: * Renders the specified string of text. * If bitmap is specified, it will be used as the render target */ void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0); void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0); /** * Creates a new font associated with the specified font state. */ Loading @@ -69,12 +93,11 @@ protected: MEASURE, }; void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect *bounds); void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect *bounds); void measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, Rect *bounds); struct CachedGlyphInfo { Loading Loading @@ -107,18 +130,26 @@ protected: Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle, uint32_t scaleX); DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs; // Cache of glyphs DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs; void invalidateTextureCache(); CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph); CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph); void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph); void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds); void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y); void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH); CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar); CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit); static glyph_t nextGlyph(const uint16_t** srcPtr) { const uint16_t* src = *srcPtr; glyph_t g = *src++; *srcPtr = src; return g; } FontRenderer* mState; uint32_t mFontId; Loading @@ -128,6 +159,10 @@ protected: uint32_t mScaleX; }; /////////////////////////////////////////////////////////////////////////////// // Renderer /////////////////////////////////////////////////////////////////////////////// class FontRenderer { public: FontRenderer(); Loading libs/hwui/OpenGLRenderer.cpp +10 −12 Original line number Diff line number Diff line Loading @@ -2073,11 +2073,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, drawTextDecorations(text, bytesCount, length, oldX, oldY, paint); } void OpenGLRenderer::drawGlyphs(const char* glyphs, int index, int count, float x, float y, SkPaint* paint) { // TODO } void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { if (mSnapshot->isIgnored()) return; Loading Loading @@ -2230,14 +2225,19 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float // Handle underline and strike-through uint32_t flags = paint->getFlags(); if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) { SkPaint paintCopy(*paint); #if RENDER_TEXT_AS_GLYPHS paintCopy.setTextEncoding(SkPaint::kGlyphID_TextEncoding); #endif float underlineWidth = length; // If length is > 0.0f, we already measured the text for the text alignment if (length <= 0.0f) { underlineWidth = paint->measureText(text, bytesCount); underlineWidth = paintCopy.measureText(text, bytesCount); } float offsetX = 0; switch (paint->getTextAlign()) { switch (paintCopy.getTextAlign()) { case SkPaint::kCenter_Align: offsetX = underlineWidth * 0.5f; break; Loading @@ -2249,8 +2249,7 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float } if (underlineWidth > 0.0f) { const float textSize = paint->getTextSize(); // TODO: Support stroke width < 1.0f when we have AA lines const float textSize = paintCopy.getTextSize(); const float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f); const float left = x - offsetX; Loading Loading @@ -2280,10 +2279,9 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float points[currentPoint++] = top; } SkPaint linesPaint(*paint); linesPaint.setStrokeWidth(strokeWidth); paintCopy.setStrokeWidth(strokeWidth); drawLines(&points[0], pointsCount, &linesPaint); drawLines(&points[0], pointsCount, &paintCopy); } } } Loading Loading
core/jni/android_view_GLES20Canvas.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ #include <SkiaColorFilter.h> #include <Rect.h> #include "TextLayout.h" #include <TextLayout.h> namespace android { Loading Loading @@ -419,7 +419,7 @@ static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject clazz, static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { #if 0 // TODO: replace "0" by "RTL_USE_HARFBUZZ" when renderer->drawGlyphs() is implemented #if RTL_USE_HARFBUZZ sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue( paint, text, 0, count, count, flags); if (value == NULL) { Loading @@ -431,7 +431,8 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, #endif const jchar* glyphArray = value->getGlyphs(); int glyphCount = value->getGlyphsCount(); renderer->drawGlyphs((const char*) glyphArray, 0, glyphCount << 1, x, y, paint); int bytesCount = glyphCount * sizeof(jchar); renderer->drawText((const char*) glyphArray, bytesCount, glyphCount, x, y, paint); #else const jchar *workText; jchar* buffer = NULL; Loading @@ -446,7 +447,7 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, jint start, jint count, jint contextCount, jfloat x, jfloat y, int flags, SkPaint* paint) { #if 0 // TODO: replace "0" by "RTL_USE_HARFBUZZ" when renderer->drawGlyphs() is implemented #if RTL_USE_HARFBUZZ sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue( paint, text, start, count, contextCount, flags); if (value == NULL) { Loading @@ -458,7 +459,8 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, #endif const jchar* glyphArray = value->getGlyphs(); int glyphCount = value->getGlyphsCount(); renderer->drawGlyphs((const char*) glyphArray, 0, glyphCount << 1, x, y, paint); int bytesCount = glyphCount * sizeof(jchar); renderer->drawText((const char*) glyphArray, bytesCount, glyphCount, x, y, paint); #else uint8_t rtl = flags & 0x1; if (rtl) { Loading
libs/hwui/DisplayListRenderer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1151,6 +1151,7 @@ void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint) { if (count <= 0) return; addOp(DisplayList::DrawText); addText(text, bytesCount); addInt(count); Loading
libs/hwui/FontRenderer.cpp +22 −21 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ namespace uirenderer { #define DEFAULT_TEXT_CACHE_WIDTH 1024 #define DEFAULT_TEXT_CACHE_HEIGHT 256 // We should query these values from the GL context #define MAX_TEXT_CACHE_WIDTH 2048 #define MAX_TEXT_CACHE_HEIGHT 2048 Loading @@ -58,8 +59,7 @@ Font::~Font() { } for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) { CachedGlyphInfo* glyph = mCachedGlyphs.valueAt(i); delete glyph; delete mCachedGlyphs.valueAt(i); } } Loading Loading @@ -134,48 +134,49 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y, } Font::CachedGlyphInfo* Font::getCachedUTFChar(SkPaint* paint, int32_t utfChar) { Font::CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit) { CachedGlyphInfo* cachedGlyph = NULL; ssize_t index = mCachedGlyphs.indexOfKey(utfChar); ssize_t index = mCachedGlyphs.indexOfKey(textUnit); if (index >= 0) { cachedGlyph = mCachedGlyphs.valueAt(index); } else { cachedGlyph = cacheGlyph(paint, utfChar); cachedGlyph = cacheGlyph(paint, textUnit); } // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { const SkGlyph& skiaGlyph = paint->getUnicharMetrics(utfChar); const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit); updateGlyphCache(paint, skiaGlyph, cachedGlyph); } return cachedGlyph; } void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) { if (bitmap != NULL && bitmapW > 0 && bitmapH > 0) { renderUTF(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap, render(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap, bitmapW, bitmapH, NULL); } else { renderUTF(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL, 0, 0, NULL); render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL, 0, 0, NULL); } } void Font::measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, Rect *bounds) { if (bounds == NULL) { LOGE("No return rectangle provided to measure text"); return; } bounds->set(1e6, -1e6, -1e6, 1e6); renderUTF(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds); render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds); } #define SkAutoKern_AdjustF(prev, next) (((next) - (prev) + 32) >> 6 << 16) void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,Rect *bounds) { if (numGlyphs == 0 || text == NULL || len == 0) { Loading @@ -195,14 +196,14 @@ void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t text += start; while (glyphsLeft > 0) { int32_t utfChar = SkUTF16_NextUnichar((const uint16_t**) &text); glyph_t glyph = GET_GLYPH(text); // Reached the end of the string if (utfChar < 0) { if (IS_END_OF_STRING(glyph)) { break; } CachedGlyphInfo* cachedGlyph = getCachedUTFChar(paint, utfChar); CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph); penX += SkAutoKern_AdjustF(prevRsbDelta, cachedGlyph->mLsbDelta); prevRsbDelta = cachedGlyph->mRsbDelta; Loading Loading @@ -268,11 +269,11 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp mState->mUploadTexture = true; } Font::CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, int32_t glyph) { Font::CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph) { CachedGlyphInfo* newGlyph = new CachedGlyphInfo(); mCachedGlyphs.add(glyph, newGlyph); const SkGlyph& skiaGlyph = paint->getUnicharMetrics(glyph); const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph); newGlyph->mGlyphIndex = skiaGlyph.fID; newGlyph->mIsValid = false; Loading Loading @@ -672,7 +673,7 @@ void FontRenderer::precacheLatin(SkPaint* paint) { uint32_t remainingCapacity = getRemainingCacheCapacity(); uint32_t precacheIdx = 0; while (remainingCapacity > 25 && precacheIdx < mLatinPrecache.size()) { mCurrentFont->getCachedUTFChar(paint, (int32_t) mLatinPrecache[precacheIdx]); mCurrentFont->getCachedGlyph(paint, (int32_t) mLatinPrecache[precacheIdx]); remainingCapacity = getRemainingCacheCapacity(); precacheIdx ++; } Loading Loading @@ -714,7 +715,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch } Rect bounds; mCurrentFont->measureUTF(paint, text, startIndex, len, numGlyphs, &bounds); mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds); uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius; uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius; uint8_t* dataBuffer = new uint8_t[paddedWidth * paddedHeight]; Loading @@ -725,7 +726,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch int penX = radius - bounds.left; int penY = radius - bounds.bottom; mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, penX, penY, mCurrentFont->render(paint, text, startIndex, len, numGlyphs, penX, penY, dataBuffer, paddedWidth, paddedHeight); blurImage(dataBuffer, paddedWidth, paddedHeight, radius); Loading Loading @@ -755,7 +756,7 @@ bool FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text mDrawn = false; mBounds = bounds; mClip = clip; mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, x, y); mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y); mBounds = NULL; if (mCurrentQuadIndex != 0) { Loading
libs/hwui/FontRenderer.h +48 −13 Original line number Diff line number Diff line Loading @@ -33,8 +33,32 @@ namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// #if RENDER_TEXT_AS_GLYPHS typedef uint16_t glyph_t; #define GET_METRICS(paint, glyph) paint->getGlyphMetrics(glyph) #define GET_GLYPH(text) nextGlyph((const uint16_t**) &text) #define IS_END_OF_STRING(glyph) false #else typedef SkUnichar glyph_t; #define GET_METRICS(paint, glyph) paint->getUnicharMetrics(glyph) #define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text) #define IS_END_OF_STRING(glyph) glyph < 0 #endif /////////////////////////////////////////////////////////////////////////////// // Declarations /////////////////////////////////////////////////////////////////////////////// class FontRenderer; /////////////////////////////////////////////////////////////////////////////// // Font /////////////////////////////////////////////////////////////////////////////// /** * Represents a font, defined by a Skia font id and a font size. A font is used * to generate glyphs and cache them in the FontState. Loading @@ -51,9 +75,9 @@ public: * Renders the specified string of text. * If bitmap is specified, it will be used as the render target */ void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0); void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0); /** * Creates a new font associated with the specified font state. */ Loading @@ -69,12 +93,11 @@ protected: MEASURE, }; void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect *bounds); void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect *bounds); void measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len, int numGlyphs, Rect *bounds); struct CachedGlyphInfo { Loading Loading @@ -107,18 +130,26 @@ protected: Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle, uint32_t scaleX); DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs; // Cache of glyphs DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs; void invalidateTextureCache(); CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph); CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph); void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph); void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds); void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y); void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH); CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar); CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit); static glyph_t nextGlyph(const uint16_t** srcPtr) { const uint16_t* src = *srcPtr; glyph_t g = *src++; *srcPtr = src; return g; } FontRenderer* mState; uint32_t mFontId; Loading @@ -128,6 +159,10 @@ protected: uint32_t mScaleX; }; /////////////////////////////////////////////////////////////////////////////// // Renderer /////////////////////////////////////////////////////////////////////////////// class FontRenderer { public: FontRenderer(); Loading
libs/hwui/OpenGLRenderer.cpp +10 −12 Original line number Diff line number Diff line Loading @@ -2073,11 +2073,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, drawTextDecorations(text, bytesCount, length, oldX, oldY, paint); } void OpenGLRenderer::drawGlyphs(const char* glyphs, int index, int count, float x, float y, SkPaint* paint) { // TODO } void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { if (mSnapshot->isIgnored()) return; Loading Loading @@ -2230,14 +2225,19 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float // Handle underline and strike-through uint32_t flags = paint->getFlags(); if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) { SkPaint paintCopy(*paint); #if RENDER_TEXT_AS_GLYPHS paintCopy.setTextEncoding(SkPaint::kGlyphID_TextEncoding); #endif float underlineWidth = length; // If length is > 0.0f, we already measured the text for the text alignment if (length <= 0.0f) { underlineWidth = paint->measureText(text, bytesCount); underlineWidth = paintCopy.measureText(text, bytesCount); } float offsetX = 0; switch (paint->getTextAlign()) { switch (paintCopy.getTextAlign()) { case SkPaint::kCenter_Align: offsetX = underlineWidth * 0.5f; break; Loading @@ -2249,8 +2249,7 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float } if (underlineWidth > 0.0f) { const float textSize = paint->getTextSize(); // TODO: Support stroke width < 1.0f when we have AA lines const float textSize = paintCopy.getTextSize(); const float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f); const float left = x - offsetX; Loading Loading @@ -2280,10 +2279,9 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float points[currentPoint++] = top; } SkPaint linesPaint(*paint); linesPaint.setStrokeWidth(strokeWidth); paintCopy.setStrokeWidth(strokeWidth); drawLines(&points[0], pointsCount, &linesPaint); drawLines(&points[0], pointsCount, &paintCopy); } } } Loading