Full support for Canvas.drawPosText
This also introduces a small optimization when rendering text.
Change-Id: Iff620ac97bf878eaac406bccc6daa07052c93890
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 6ec87f3..786a4f1 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2084,23 +2084,81 @@
void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint) {
- if (text == NULL || count == 0) {
+ if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
+ (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
return;
}
- if (mSnapshot->isIgnored()) return;
- // TODO: implement properly
- drawText(text, bytesCount, count, 0, 0, paint);
+ // NOTE: Skia does not support perspective transform on drawPosText yet
+ if (!mSnapshot->transform->isSimple()) {
+ return;
+ }
+
+ float x = 0.0f;
+ float y = 0.0f;
+ const bool pureTranslate = mSnapshot->transform->isPureTranslate();
+ if (pureTranslate) {
+ x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
+ y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
+ }
+
+ FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
+ fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
+ paint->getTextSize());
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ // Pick the appropriate texture filtering
+ bool linearFilter = mSnapshot->transform->changesBounds();
+ if (pureTranslate && !linearFilter) {
+ linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
+ }
+
+ mCaches.activeTexture(0);
+ setupDraw();
+ setupDrawDirtyRegionsDisabled();
+ setupDrawWithTexture(true);
+ setupDrawAlpha8Color(paint->getColor(), alpha);
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(true, mode);
+ setupDrawProgram();
+ setupDrawModelView(x, y, x, y, pureTranslate, true);
+ setupDrawTexture(fontRenderer.getTexture(linearFilter));
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawShaderUniforms(pureTranslate);
+
+ const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
+ Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
+
+#if RENDER_LAYERS_AS_REGIONS
+ bool hasActiveLayer = hasLayer();
+#else
+ bool hasActiveLayer = false;
+#endif
+
+ if (fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
+ positions, hasActiveLayer ? &bounds : NULL)) {
+#if RENDER_LAYERS_AS_REGIONS
+ if (hasActiveLayer) {
+ if (!pureTranslate) {
+ mSnapshot->transform->mapRect(bounds);
+ }
+ dirtyLayerUnchecked(bounds, getRegion());
+ }
+#endif
+ }
}
void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint, float length) {
- if (text == NULL || count == 0) {
+ if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
+ (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
return;
}
- if (mSnapshot->isIgnored()) return;
-
- // NOTE: AA and glyph id encoding are set in DisplayListRenderer.cpp
switch (paint->getTextAlign()) {
case SkPaint::kCenter_Align:
@@ -2177,10 +2235,6 @@
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
}
- if (paint->getAlpha() == 0 && paint->getXfermode() == NULL) {
- return;
- }
-
// Pick the appropriate texture filtering
bool linearFilter = mSnapshot->transform->changesBounds();
if (pureTranslate && !linearFilter) {