diff options
Diffstat (limited to 'libs/hwui')
| -rw-r--r-- | libs/hwui/FontRenderer.cpp | 10 | ||||
| -rw-r--r-- | libs/hwui/FontRenderer.h | 4 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 77 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 20 | ||||
| -rw-r--r-- | libs/hwui/TextDropShadowCache.cpp | 6 | ||||
| -rw-r--r-- | libs/hwui/TextDropShadowCache.h | 21 |
6 files changed, 90 insertions, 48 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index eeb37cb..7f0ed73 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -288,13 +288,13 @@ void Font::render(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) { + int numGlyphs, Rect *bounds, const float* positions) { if (bounds == NULL) { ALOGE("No return rectangle provided to measure text"); return; } bounds->set(1e6, -1e6, -1e6, 1e6); - render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, NULL); + render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, positions); } void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len, @@ -1007,7 +1007,7 @@ void FontRenderer::setFont(SkPaint* paint, uint32_t fontId, float fontSize) { } FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text, - uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) { + uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions) { checkInit(); if (!mCurrentFont) { @@ -1025,7 +1025,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch mBounds = NULL; Rect bounds; - mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds); + mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds, positions); uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius; uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius; @@ -1039,7 +1039,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch int penY = radius - bounds.bottom; mCurrentFont->render(paint, text, startIndex, len, numGlyphs, penX, penY, - dataBuffer, paddedWidth, paddedHeight); + Font::BITMAP, dataBuffer, paddedWidth, paddedHeight, NULL, positions); blurImage(dataBuffer, paddedWidth, paddedHeight, radius); DropShadow image; diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index b7b4ec9..9ed6932 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -184,7 +184,7 @@ protected: uint32_t bitmapW, uint32_t bitmapH, Rect *bounds, const float* positions); void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len, - int numGlyphs, Rect *bounds); + int numGlyphs, Rect *bounds, const float* positions); Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle, uint32_t scaleX, SkPaint::Style style, uint32_t strokeWidth); @@ -273,7 +273,7 @@ public: // After renderDropShadow returns, the called owns the memory in DropShadow.image // and is responsible for releasing it when it's done with it DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex, - uint32_t len, int numGlyphs, uint32_t radius); + uint32_t len, int numGlyphs, uint32_t radius, const float* positions); GLuint getTexture(bool linearFiltering = false) { checkInit(); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 5fa3d3e..6d781c7 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -2303,6 +2303,44 @@ status_t OpenGLRenderer::drawRect(float left, float top, float right, float bott return DrawGlInfo::kStatusDrew; } +void OpenGLRenderer::drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count, + const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode, + float x, float y) { + mCaches.activeTexture(0); + + // NOTE: The drop shadow will not perform gamma correction + // if shader-based correction is enabled + mCaches.dropShadowCache.setFontRenderer(fontRenderer); + const ShadowTexture* shadow = mCaches.dropShadowCache.get( + paint, text, bytesCount, count, mShadowRadius, positions); + const AutoTexture autoCleanup(shadow); + + const float sx = x - shadow->left + mShadowDx; + const float sy = y - shadow->top + mShadowDy; + + const int shadowAlpha = ((mShadowColor >> 24) & 0xFF) * mSnapshot->alpha; + int shadowColor = mShadowColor; + if (mShader) { + shadowColor = 0xffffffff; + } + + setupDraw(); + setupDrawWithTexture(true); + setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha); + setupDrawColorFilter(); + setupDrawShader(); + setupDrawBlending(true, mode); + setupDrawProgram(); + setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height); + setupDrawTexture(shadow->id); + setupDrawPureColorUniforms(); + setupDrawColorFilterUniforms(); + setupDrawShaderUniforms(); + setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); +} + status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (text == NULL || count == 0 || mSnapshot->isIgnored() || @@ -2331,6 +2369,11 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); + if (CC_UNLIKELY(mHasShadow)) { + drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, alpha, mode, + 0.0f, 0.0f); + } + // Pick the appropriate texture filtering bool linearFilter = mSnapshot->transform->changesBounds(); if (pureTranslate && !linearFilter) { @@ -2424,39 +2467,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, getAlphaAndMode(paint, &alpha, &mode); if (CC_UNLIKELY(mHasShadow)) { - mCaches.activeTexture(0); - - // NOTE: The drop shadow will not perform gamma correction - // if shader-based correction is enabled - mCaches.dropShadowCache.setFontRenderer(fontRenderer); - const ShadowTexture* shadow = mCaches.dropShadowCache.get( - paint, text, bytesCount, count, mShadowRadius); - const AutoTexture autoCleanup(shadow); - - const float sx = oldX - shadow->left + mShadowDx; - const float sy = oldY - shadow->top + mShadowDy; - - const int shadowAlpha = ((mShadowColor >> 24) & 0xFF) * mSnapshot->alpha; - int shadowColor = mShadowColor; - if (mShader) { - shadowColor = 0xffffffff; - } - - setupDraw(); - setupDrawWithTexture(true); - setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha); - setupDrawColorFilter(); - setupDrawShader(); - setupDrawBlending(true, mode); - setupDrawProgram(); - setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height); - setupDrawTexture(shadow->id); - setupDrawPureColorUniforms(); - setupDrawColorFilterUniforms(); - setupDrawShaderUniforms(); - setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); + drawTextShadow(paint, text, bytesCount, count, NULL, fontRenderer, alpha, mode, oldX, oldY); } // Pick the appropriate texture filtering diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 1926575..441e9fd 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -498,6 +498,24 @@ private: void drawTextDecorations(const char* text, int bytesCount, float length, float x, float y, SkPaint* paint); + /** + * Draws shadow layer on text (with optional positions). + * + * @param paint The paint to draw the shadow with + * @param text The text to draw + * @param bytesCount The number of bytes in the text + * @param count The number of glyphs in the text + * @param positions The x, y positions of individual glyphs (or NULL) + * @param fontRenderer The font renderer object + * @param alpha The alpha value for drawing the shadow + * @param mode The xfermode for drawing the shadow + * @param x The x coordinate where the shadow will be drawn + * @param y The y coordinate where the shadow will be drawn + */ + void drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count, + const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode, + float x, float y); + /** * Draws a path texture. Path textures are alpha8 bitmaps that need special * compositing to apply colors/filters/etc. @@ -507,7 +525,7 @@ private: * @param y The y coordinate where the texture will be drawn * @param paint The paint to draw the texture with */ - void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint); + void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint); /** * Resets the texture coordinates stored in mMeshVertices. Setting the values diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index bef1373..93aa8a5 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -102,13 +102,13 @@ void TextDropShadowCache::clear() { } ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32_t len, - int numGlyphs, uint32_t radius) { - ShadowText entry(paint, radius, len, text); + int numGlyphs, uint32_t radius, const float* positions) { + ShadowText entry(paint, radius, len, text, positions); ShadowTexture* texture = mCache.get(entry); if (!texture) { FontRenderer::DropShadow shadow = mRenderer->renderDropShadow(paint, text, 0, - len, numGlyphs, radius); + len, numGlyphs, radius, positions); texture = new ShadowTexture; texture->left = shadow.penX; diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h index e2bdde1..bae0c49 100644 --- a/libs/hwui/TextDropShadowCache.h +++ b/libs/hwui/TextDropShadowCache.h @@ -35,8 +35,9 @@ struct ShadowText { ShadowText(): radius(0), len(0), textSize(0.0f), typeface(NULL) { } - ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText): - radius(radius), len(len) { + ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText, + const float* positions): + radius(radius), len(len), positions(positions) { // TODO: Propagate this through the API, we should not cast here text = (const char16_t*) srcText; @@ -66,11 +67,18 @@ struct ShadowText { uint32_t italicStyle; uint32_t scaleX; const char16_t* text; + const float* positions; String16 str; + Vector<float> positionsCopy; void copyTextLocally() { str.setTo((const char16_t*) text, len >> 1); text = str.string(); + if (positions != NULL) { + positionsCopy.clear(); + positionsCopy.appendArray(positions, len); + positions = positionsCopy.array(); + } } bool operator<(const ShadowText& rhs) const { @@ -81,7 +89,12 @@ struct ShadowText { LTE_INT(flags) { LTE_INT(italicStyle) { LTE_INT(scaleX) { - return memcmp(text, rhs.text, len) < 0; + int cmp = memcmp(text, rhs.text, len); + if (cmp < 0) return true; + if (cmp == 0 && rhs.positions != NULL) { + if (positions == NULL) return true; + return memcmp(positions, rhs.positions, len << 2) < 0; + } } } } @@ -117,7 +130,7 @@ public: void operator()(ShadowText& text, ShadowTexture*& texture); ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len, - int numGlyphs, uint32_t radius); + int numGlyphs, uint32_t radius, const float* positions); /** * Clears the cache. This causes all textures to be deleted. |
