diff options
| author | 2012-07-23 15:22:52 -0700 | |
|---|---|---|
| committer | 2012-07-23 16:52:20 -0700 | |
| commit | 996e57c84368058be793897ebc355b917a59abc2 (patch) | |
| tree | 11d598d07a5153872cd496fd3ca7d4a1a3bdecb8 | |
| parent | 219dfa4d392851c1ffd7147cb78d4236658a79d8 (diff) | |
Hardware implementation of glyph positioning (bug 5443796)
This implementation adds a drawGeneralText() method to the OpenGL
Renderer, which supports both a global x, y position, an array of
individual glyph positions, and also a length parameter (which enables
drawing of underline and strikethrough. It also adds the method to the
display list (with marshalling and unmarshalling).
With this change, the existing drawText() method is removed entirely, as
it's subsumed by the new method. It's easy enough to revert to the old
functionality if needed by passing in a NULL positions array.
Change-Id: I8c9e6ce4309fd51cc5511db85df99f6de8f4f6f5
| -rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 10 | ||||
| -rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 114 | ||||
| -rw-r--r-- | libs/hwui/DisplayListRenderer.h | 6 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 22 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 4 |
5 files changed, 88 insertions, 68 deletions
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 9040941fc195..ade3180bb4b8 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -528,8 +528,11 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, } const jchar* glyphs = value->getGlyphs(); size_t glyphsCount = value->getGlyphsCount(); + jfloat totalAdvance = value->getTotalAdvance(); + const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); - renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); + renderer->drawGeneralText((const char*) glyphs, bytesCount, glyphsCount, x, y, + positions, paint, totalAdvance); } static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count, @@ -556,8 +559,11 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, } const jchar* glyphs = value->getGlyphs(); size_t glyphsCount = value->getGlyphsCount(); + jfloat totalAdvance = value->getTotalAdvance(); + const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); - renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); + renderer->drawGeneralText((const char*) glyphs, bytesCount, glyphsCount, x, y, + positions, paint, totalAdvance); } static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 133f63f249c3..7161c589b191 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -61,9 +61,9 @@ const char* DisplayList::OP_NAMES[] = { "DrawPath", "DrawLines", "DrawPoints", - "DrawText", "DrawTextOnPath", "DrawPosText", + "DrawGeneralText", "ResetShader", "SetupShader", "ResetColorFilter", @@ -572,17 +572,6 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { ALOGD("%s%s", (char*) indent, OP_NAMES[op]); } break; - case DrawText: { - getText(&text); - int32_t count = getInt(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - float length = getFloat(); - ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], - text.text(), text.length(), count, x, y, paint, length); - } - break; case DrawTextOnPath: { getText(&text); int32_t count = getInt(); @@ -603,6 +592,17 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, paint); } + break; + case DrawGeneralText: { + getText(&text); + int count = getInt(); + int positionsCount = 0; + float* positions = getFloats(positionsCount); + SkPaint* paint = getPaint(renderer); + ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], + text.text(), text.length(), count, paint); + } + break; case ResetShader: { ALOGD("%s%s", (char*) indent, OP_NAMES[op]); } @@ -1196,19 +1196,6 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag drawGlStatus |= renderer.drawPoints(points, count, paint); } break; - case DrawText: { - getText(&text); - int32_t count = getInt(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - float length = getFloat(); - DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, - OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); - drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y, - paint, length); - } - break; case DrawTextOnPath: { getText(&text); int32_t count = getInt(); @@ -1234,6 +1221,21 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag positions, paint); } break; + case DrawGeneralText: { + getText(&text); + int32_t count = getInt(); + float x = getFloat(); + float y = getFloat(); + int32_t positionsCount = 0; + float* positions = getFloats(positionsCount); + SkPaint* paint = getPaint(renderer); + float length = getFloat(); + DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, + OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); + drawGlStatus |= renderer.drawGeneralText(text.text(), text.length(), count, + x, y, positions, paint, length); + } + break; case ResetShader: { DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.resetShader(); @@ -1684,8 +1686,34 @@ status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* pain return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, - float x, float y, SkPaint* paint, float length) { +status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, + SkPath* path, float hOffset, float vOffset, SkPaint* paint) { + if (!text || count <= 0) return DrawGlInfo::kStatusDone; + addOp(DisplayList::DrawTextOnPath); + addText(text, bytesCount); + addInt(count); + addPath(path); + addFloat(hOffset); + addFloat(vOffset); + paint->setAntiAlias(true); + addPaint(paint); + return DrawGlInfo::kStatusDone; +} + +status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, + const float* positions, SkPaint* paint) { + if (!text || count <= 0) return DrawGlInfo::kStatusDone; + addOp(DisplayList::DrawPosText); + addText(text, bytesCount); + addInt(count); + addFloats(positions, count * 2); + paint->setAntiAlias(true); + addPaint(paint); + return DrawGlInfo::kStatusDone; +} + +status_t DisplayListRenderer::drawGeneralText(const char* text, int bytesCount, int count, + float x, float y, const float* positions, SkPaint* paint, float length) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; // TODO: We should probably make a copy of the paint instead of modifying @@ -1705,42 +1733,18 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom); } - uint32_t* location = addOp(DisplayList::DrawText, reject); + uint32_t* location = addOp(DisplayList::DrawGeneralText, reject); addText(text, bytesCount); addInt(count); - addPoint(x, y); + addFloat(x); + addFloat(y); + addFloats(positions, count * 2); addPaint(paint); addFloat(length); addSkip(location); return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, - SkPath* path, float hOffset, float vOffset, SkPaint* paint) { - if (!text || count <= 0) return DrawGlInfo::kStatusDone; - addOp(DisplayList::DrawTextOnPath); - addText(text, bytesCount); - addInt(count); - addPath(path); - addFloat(hOffset); - addFloat(vOffset); - paint->setAntiAlias(true); - addPaint(paint); - return DrawGlInfo::kStatusDone; -} - -status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, - const float* positions, SkPaint* paint) { - if (!text || count <= 0) return DrawGlInfo::kStatusDone; - addOp(DisplayList::DrawPosText); - addText(text, bytesCount); - addInt(count); - addFloats(positions, count * 2); - paint->setAntiAlias(true); - addPaint(paint); - return DrawGlInfo::kStatusDone; -} - void DisplayListRenderer::resetShader() { addOp(DisplayList::ResetShader); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 6b4c6b20d863..f3041dd8be7e 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -103,9 +103,9 @@ public: DrawPath, DrawLines, DrawPoints, - DrawText, DrawTextOnPath, DrawPosText, + DrawGeneralText, ResetShader, SetupShader, ResetColorFilter, @@ -599,12 +599,12 @@ public: virtual status_t drawPath(SkPath* path, SkPaint* paint); virtual status_t drawLines(float* points, int count, SkPaint* paint); virtual status_t drawPoints(float* points, int count, SkPaint* paint); - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, - SkPaint* paint, float length = -1.0f); virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); virtual status_t drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); + virtual status_t drawGeneralText(const char* text, int bytesCount, int count, + float x, float y, const float* positions, SkPaint* paint, float length); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 6d781c77fa7a..07281ccf19c9 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -2421,8 +2421,8 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count return DrawGlInfo::kStatusDrew; } -status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, - float x, float y, SkPaint* paint, float length) { +status_t OpenGLRenderer::drawGeneralText(const char* text, int bytesCount, int count, + float x, float y, const float* positions, SkPaint* paint, float length) { if (text == NULL || count == 0 || mSnapshot->isIgnored() || (paint->getAlpha() * mSnapshot->alpha == 0 && paint->getXfermode() == NULL)) { return DrawGlInfo::kStatusDone; @@ -2455,7 +2455,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, } #if DEBUG_GLYPHS - ALOGD("OpenGLRenderer drawText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface())); + ALOGD("OpenGLRenderer drawGeneralText() with FontID=%d", + SkTypeface::UniqueID(paint->getTypeface())); #endif FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); @@ -2467,7 +2468,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, getAlphaAndMode(paint, &alpha, &mode); if (CC_UNLIKELY(mHasShadow)) { - drawTextShadow(paint, text, bytesCount, count, NULL, fontRenderer, alpha, mode, oldX, oldY); + drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, alpha, mode, + oldX, oldY); } // Pick the appropriate texture filtering @@ -2505,8 +2507,16 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, const bool hasActiveLayer = false; #endif - if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, - hasActiveLayer ? &bounds : NULL)) { + bool status; + if (positions != NULL) { + status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, + positions, hasActiveLayer ? &bounds : NULL); + } else { + // TODO: would it be okay to call renderPosText with null positions? + status = fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, + hasActiveLayer ? &bounds : NULL); + } + if (status) { #if RENDER_LAYERS_AS_REGIONS if (hasActiveLayer) { if (!pureTranslate) { diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 441e9fd6c8d8..378fc8c1e3be 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -138,12 +138,12 @@ public: virtual status_t drawPath(SkPath* path, SkPaint* paint); virtual status_t drawLines(float* points, int count, SkPaint* paint); virtual status_t drawPoints(float* points, int count, SkPaint* paint); - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, - SkPaint* paint, float length = -1.0f); virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); virtual status_t drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); + virtual status_t drawGeneralText(const char* text, int bytesCount, int count, float x, float y, + const float* positions, SkPaint* paint, float length = -1.0f); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); |