Skip to content

Commit 00755fe

Browse files
raphlinusAndroid (Google) Code Review
authored andcommitted
Merge "Add drop shadow for drawPosText in hwui renderer."
2 parents 0cb4870 + 416a847 commit 00755fe

File tree

6 files changed

+90
-48
lines changed

6 files changed

+90
-48
lines changed

libs/hwui/FontRenderer.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,13 @@ void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len
288288
}
289289

290290
void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
291-
int numGlyphs, Rect *bounds) {
291+
int numGlyphs, Rect *bounds, const float* positions) {
292292
if (bounds == NULL) {
293293
ALOGE("No return rectangle provided to measure text");
294294
return;
295295
}
296296
bounds->set(1e6, -1e6, -1e6, 1e6);
297-
render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, NULL);
297+
render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, positions);
298298
}
299299

300300
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) {
10071007
}
10081008

10091009
FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
1010-
uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) {
1010+
uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions) {
10111011
checkInit();
10121012

10131013
if (!mCurrentFont) {
@@ -1025,7 +1025,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch
10251025
mBounds = NULL;
10261026

10271027
Rect bounds;
1028-
mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds);
1028+
mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds, positions);
10291029

10301030
uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius;
10311031
uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius;
@@ -1039,7 +1039,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch
10391039
int penY = radius - bounds.bottom;
10401040

10411041
mCurrentFont->render(paint, text, startIndex, len, numGlyphs, penX, penY,
1042-
dataBuffer, paddedWidth, paddedHeight);
1042+
Font::BITMAP, dataBuffer, paddedWidth, paddedHeight, NULL, positions);
10431043
blurImage(dataBuffer, paddedWidth, paddedHeight, radius);
10441044

10451045
DropShadow image;

libs/hwui/FontRenderer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class Font {
184184
uint32_t bitmapW, uint32_t bitmapH, Rect *bounds, const float* positions);
185185

186186
void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
187-
int numGlyphs, Rect *bounds);
187+
int numGlyphs, Rect *bounds, const float* positions);
188188

189189
Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle,
190190
uint32_t scaleX, SkPaint::Style style, uint32_t strokeWidth);
@@ -273,7 +273,7 @@ class FontRenderer {
273273
// After renderDropShadow returns, the called owns the memory in DropShadow.image
274274
// and is responsible for releasing it when it's done with it
275275
DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
276-
uint32_t len, int numGlyphs, uint32_t radius);
276+
uint32_t len, int numGlyphs, uint32_t radius, const float* positions);
277277

278278
GLuint getTexture(bool linearFiltering = false) {
279279
checkInit();

libs/hwui/OpenGLRenderer.cpp

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,6 +2303,44 @@ status_t OpenGLRenderer::drawRect(float left, float top, float right, float bott
23032303
return DrawGlInfo::kStatusDrew;
23042304
}
23052305

2306+
void OpenGLRenderer::drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count,
2307+
const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode,
2308+
float x, float y) {
2309+
mCaches.activeTexture(0);
2310+
2311+
// NOTE: The drop shadow will not perform gamma correction
2312+
// if shader-based correction is enabled
2313+
mCaches.dropShadowCache.setFontRenderer(fontRenderer);
2314+
const ShadowTexture* shadow = mCaches.dropShadowCache.get(
2315+
paint, text, bytesCount, count, mShadowRadius, positions);
2316+
const AutoTexture autoCleanup(shadow);
2317+
2318+
const float sx = x - shadow->left + mShadowDx;
2319+
const float sy = y - shadow->top + mShadowDy;
2320+
2321+
const int shadowAlpha = ((mShadowColor >> 24) & 0xFF) * mSnapshot->alpha;
2322+
int shadowColor = mShadowColor;
2323+
if (mShader) {
2324+
shadowColor = 0xffffffff;
2325+
}
2326+
2327+
setupDraw();
2328+
setupDrawWithTexture(true);
2329+
setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha);
2330+
setupDrawColorFilter();
2331+
setupDrawShader();
2332+
setupDrawBlending(true, mode);
2333+
setupDrawProgram();
2334+
setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height);
2335+
setupDrawTexture(shadow->id);
2336+
setupDrawPureColorUniforms();
2337+
setupDrawColorFilterUniforms();
2338+
setupDrawShaderUniforms();
2339+
setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
2340+
2341+
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
2342+
}
2343+
23062344
status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
23072345
const float* positions, SkPaint* paint) {
23082346
if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
@@ -2331,6 +2369,11 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count
23312369
SkXfermode::Mode mode;
23322370
getAlphaAndMode(paint, &alpha, &mode);
23332371

2372+
if (CC_UNLIKELY(mHasShadow)) {
2373+
drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, alpha, mode,
2374+
0.0f, 0.0f);
2375+
}
2376+
23342377
// Pick the appropriate texture filtering
23352378
bool linearFilter = mSnapshot->transform->changesBounds();
23362379
if (pureTranslate && !linearFilter) {
@@ -2424,39 +2467,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
24242467
getAlphaAndMode(paint, &alpha, &mode);
24252468

24262469
if (CC_UNLIKELY(mHasShadow)) {
2427-
mCaches.activeTexture(0);
2428-
2429-
// NOTE: The drop shadow will not perform gamma correction
2430-
// if shader-based correction is enabled
2431-
mCaches.dropShadowCache.setFontRenderer(fontRenderer);
2432-
const ShadowTexture* shadow = mCaches.dropShadowCache.get(
2433-
paint, text, bytesCount, count, mShadowRadius);
2434-
const AutoTexture autoCleanup(shadow);
2435-
2436-
const float sx = oldX - shadow->left + mShadowDx;
2437-
const float sy = oldY - shadow->top + mShadowDy;
2438-
2439-
const int shadowAlpha = ((mShadowColor >> 24) & 0xFF) * mSnapshot->alpha;
2440-
int shadowColor = mShadowColor;
2441-
if (mShader) {
2442-
shadowColor = 0xffffffff;
2443-
}
2444-
2445-
setupDraw();
2446-
setupDrawWithTexture(true);
2447-
setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha);
2448-
setupDrawColorFilter();
2449-
setupDrawShader();
2450-
setupDrawBlending(true, mode);
2451-
setupDrawProgram();
2452-
setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height);
2453-
setupDrawTexture(shadow->id);
2454-
setupDrawPureColorUniforms();
2455-
setupDrawColorFilterUniforms();
2456-
setupDrawShaderUniforms();
2457-
setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
2458-
2459-
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
2470+
drawTextShadow(paint, text, bytesCount, count, NULL, fontRenderer, alpha, mode, oldX, oldY);
24602471
}
24612472

24622473
// Pick the appropriate texture filtering

libs/hwui/OpenGLRenderer.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,24 @@ class OpenGLRenderer {
498498
void drawTextDecorations(const char* text, int bytesCount, float length,
499499
float x, float y, SkPaint* paint);
500500

501+
/**
502+
* Draws shadow layer on text (with optional positions).
503+
*
504+
* @param paint The paint to draw the shadow with
505+
* @param text The text to draw
506+
* @param bytesCount The number of bytes in the text
507+
* @param count The number of glyphs in the text
508+
* @param positions The x, y positions of individual glyphs (or NULL)
509+
* @param fontRenderer The font renderer object
510+
* @param alpha The alpha value for drawing the shadow
511+
* @param mode The xfermode for drawing the shadow
512+
* @param x The x coordinate where the shadow will be drawn
513+
* @param y The y coordinate where the shadow will be drawn
514+
*/
515+
void drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count,
516+
const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode,
517+
float x, float y);
518+
501519
/**
502520
* Draws a path texture. Path textures are alpha8 bitmaps that need special
503521
* compositing to apply colors/filters/etc.
@@ -507,7 +525,7 @@ class OpenGLRenderer {
507525
* @param y The y coordinate where the texture will be drawn
508526
* @param paint The paint to draw the texture with
509527
*/
510-
void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
528+
void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
511529

512530
/**
513531
* Resets the texture coordinates stored in mMeshVertices. Setting the values

libs/hwui/TextDropShadowCache.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,13 @@ void TextDropShadowCache::clear() {
102102
}
103103

104104
ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32_t len,
105-
int numGlyphs, uint32_t radius) {
106-
ShadowText entry(paint, radius, len, text);
105+
int numGlyphs, uint32_t radius, const float* positions) {
106+
ShadowText entry(paint, radius, len, text, positions);
107107
ShadowTexture* texture = mCache.get(entry);
108108

109109
if (!texture) {
110110
FontRenderer::DropShadow shadow = mRenderer->renderDropShadow(paint, text, 0,
111-
len, numGlyphs, radius);
111+
len, numGlyphs, radius, positions);
112112

113113
texture = new ShadowTexture;
114114
texture->left = shadow.penX;

libs/hwui/TextDropShadowCache.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ struct ShadowText {
3535
ShadowText(): radius(0), len(0), textSize(0.0f), typeface(NULL) {
3636
}
3737

38-
ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText):
39-
radius(radius), len(len) {
38+
ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText,
39+
const float* positions):
40+
radius(radius), len(len), positions(positions) {
4041
// TODO: Propagate this through the API, we should not cast here
4142
text = (const char16_t*) srcText;
4243

@@ -66,11 +67,18 @@ struct ShadowText {
6667
uint32_t italicStyle;
6768
uint32_t scaleX;
6869
const char16_t* text;
70+
const float* positions;
6971
String16 str;
72+
Vector<float> positionsCopy;
7073

7174
void copyTextLocally() {
7275
str.setTo((const char16_t*) text, len >> 1);
7376
text = str.string();
77+
if (positions != NULL) {
78+
positionsCopy.clear();
79+
positionsCopy.appendArray(positions, len);
80+
positions = positionsCopy.array();
81+
}
7482
}
7583

7684
bool operator<(const ShadowText& rhs) const {
@@ -81,7 +89,12 @@ struct ShadowText {
8189
LTE_INT(flags) {
8290
LTE_INT(italicStyle) {
8391
LTE_INT(scaleX) {
84-
return memcmp(text, rhs.text, len) < 0;
92+
int cmp = memcmp(text, rhs.text, len);
93+
if (cmp < 0) return true;
94+
if (cmp == 0 && rhs.positions != NULL) {
95+
if (positions == NULL) return true;
96+
return memcmp(positions, rhs.positions, len << 2) < 0;
97+
}
8598
}
8699
}
87100
}
@@ -117,7 +130,7 @@ class TextDropShadowCache: public OnEntryRemoved<ShadowText, ShadowTexture*> {
117130
void operator()(ShadowText& text, ShadowTexture*& texture);
118131

119132
ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len,
120-
int numGlyphs, uint32_t radius);
133+
int numGlyphs, uint32_t radius, const float* positions);
121134

122135
/**
123136
* Clears the cache. This causes all textures to be deleted.

0 commit comments

Comments
 (0)