summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/GLES20Canvas.java28
-rw-r--r--core/jni/android/graphics/TextLayout.cpp5
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp36
-rw-r--r--libs/hwui/DisplayListRenderer.cpp40
-rw-r--r--libs/hwui/DisplayListRenderer.h3
-rw-r--r--libs/hwui/OpenGLRenderer.cpp5
-rw-r--r--libs/hwui/OpenGLRenderer.h6
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml9
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java84
9 files changed, 206 insertions, 10 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index f5fc708..36582af 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -1208,14 +1208,38 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
float vOffset, Paint paint) {
- // TODO: Implement
+ if (index < 0 || index + count > text.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ int modifiers = setupModifiers(paint);
+ try {
+ nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset,
+ paint.mBidiFlags, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
+ private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count,
+ int path, float hOffset, float vOffset, int bidiFlags, int nativePaint);
+
@Override
public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
- // TODO: Implement
+ if (text.length() == 0) return;
+
+ int modifiers = setupModifiers(paint);
+ try {
+ nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset,
+ paint.mBidiFlags, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
+ private static native void nDrawTextOnPath(int renderer, String text, int start, int end,
+ int path, float hOffset, float vOffset, int bidiFlags, int nativePaint);
+
@Override
public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
float x, float y, int dir, Paint paint) {
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index 2241f60..2beedad 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -101,11 +101,6 @@ void TextLayout::drawTextOnPath(SkPaint* paint, const jchar* text, int count,
SkScalar h_ = SkFloatToScalar(hOffset);
SkScalar v_ = SkFloatToScalar(vOffset);
- if (!needsLayout(text, count, bidiFlags)) {
- canvas->drawTextOnPathHV(text, count << 1, *path, h_, v_, *paint);
- return;
- }
-
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
text, 0, count, count, bidiFlags);
if (value == NULL) {
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index cdce4f9..f0560c1 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -521,6 +521,20 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
}
+static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
+ SkPath* path, jfloat hOffset, jfloat vOffset, int flags, SkPaint* paint) {
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, 0, count, count, flags);
+ if (value == NULL) {
+ return;
+ }
+ const jchar* glyphs = value->getGlyphs();
+ size_t glyphsCount = value->getGlyphsCount();
+ int bytesCount = glyphsCount * sizeof(jchar);
+ renderer->drawTextOnPath((const char*) glyphs, bytesCount, glyphsCount, path,
+ hOffset, vOffset, paint);
+}
+
static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
jint start, jint count, jint contextCount, jfloat x, jfloat y,
int flags, SkPaint* paint) {
@@ -551,6 +565,24 @@ static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
env->ReleaseStringChars(text, textArray);
}
+static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
+ SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) {
+ jchar* textArray = env->GetCharArrayElements(text, NULL);
+ renderTextOnPath(renderer, textArray + index, count, path,
+ hOffset, vOffset, flags, paint);
+ env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
+}
+
+static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jstring text, jint start, jint end,
+ SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) {
+ const jchar* textArray = env->GetStringChars(text, NULL);
+ renderTextOnPath(renderer, textArray + start, end - start, path,
+ hOffset, vOffset, flags, paint);
+ env->ReleaseStringChars(text, textArray);
+}
+
static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
@@ -885,6 +917,10 @@ static JNINativeMethod gMethods[] = {
{ "nDrawText", "(ILjava/lang/String;IIFFII)V",
(void*) android_view_GLES20Canvas_drawText },
+ { "nDrawTextOnPath", "(I[CIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath },
+ { "nDrawTextOnPath", "(ILjava/lang/String;IIIFFII)V",
+ (void*) android_view_GLES20Canvas_drawTextOnPath },
+
{ "nDrawTextRun", "(I[CIIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
{ "nDrawTextRun", "(ILjava/lang/String;IIIIFFII)V",
(void*) android_view_GLES20Canvas_drawTextRun },
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f9088ac..8153823 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -61,6 +61,7 @@ const char* DisplayList::OP_NAMES[] = {
"DrawLines",
"DrawPoints",
"DrawText",
+ "DrawTextOnPath",
"DrawPosText",
"ResetShader",
"SetupShader",
@@ -483,7 +484,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
break;
case DrawText: {
getText(&text);
- int count = getInt();
+ int32_t count = getInt();
float x = getFloat();
float y = getFloat();
SkPaint* paint = getPaint(renderer);
@@ -492,6 +493,17 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
text.text(), text.length(), count, x, y, paint, length);
}
break;
+ case DrawTextOnPath: {
+ getText(&text);
+ int32_t count = getInt();
+ SkPath* path = getPath();
+ float hOffset = getFloat();
+ float vOffset = getFloat();
+ SkPaint* paint = getPaint(renderer);
+ ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
+ text.text(), text.length(), count, paint);
+ }
+ break;
case DrawPosText: {
getText(&text);
int count = getInt();
@@ -890,6 +902,19 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
}
break;
+ case DrawTextOnPath: {
+ getText(&text);
+ int32_t count = getInt();
+ SkPath* path = getPath();
+ float hOffset = getFloat();
+ float vOffset = getFloat();
+ SkPaint* paint = getPaint(renderer);
+ DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
+ text.text(), text.length(), count, paint);
+ renderer.drawTextOnPath(text.text(), text.length(), count, path,
+ hOffset, vOffset, paint);
+ }
+ break;
case DrawPosText: {
getText(&text);
int32_t count = getInt();
@@ -1331,6 +1356,19 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
addSkip(location);
}
+void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+ SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
+ if (!text || count <= 0) return;
+ addOp(DisplayList::DrawTextOnPath);
+ addText(text, bytesCount);
+ addInt(count);
+ addPath(path);
+ addFloat(hOffset);
+ addFloat(vOffset);
+ paint->setAntiAlias(true);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint) {
if (!text || count <= 0) return;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 4a299c6..5d1b460 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -99,6 +99,7 @@ public:
DrawLines,
DrawPoints,
DrawText,
+ DrawTextOnPath,
DrawPosText,
ResetShader,
SetupShader,
@@ -310,6 +311,8 @@ public:
virtual void drawPoints(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint, float length = 1.0f);
+ virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ float hOffset, float vOffset, SkPaint* paint);
virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
SkPaint* paint);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 55e2ca5..6f0f836 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2292,6 +2292,11 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
}
+void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ float hOffset, float vOffset, SkPaint* paint) {
+ // TODO: Implement
+}
+
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 3f63c3fe..4d7a491 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -124,8 +124,10 @@ public:
virtual void drawPoints(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint, float length = -1.0f);
- virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
- SkPaint* paint);
+ virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ float hOffset, float vOffset, SkPaint* paint);
+ virtual void drawPosText(const char* text, int bytesCount, int count,
+ const float* positions, SkPaint* paint);
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index ed78daa3..b310d93 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -568,6 +568,15 @@
</activity>
<activity
+ android:name="TextOnPathActivity"
+ android:label="_TextOnPath">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="PathsCacheActivity"
android:label="_PathsCache">
<intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java
new file mode 100644
index 0000000..439d029
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class TextOnPathActivity extends Activity {
+ private Path mPath;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mPath = makePath();
+
+ final TextOnPathView view = new TextOnPathView(this);
+ setContentView(view);
+ }
+
+ private Path makePath() {
+ Path path = new Path();
+ buildPath(path);
+ return path;
+ }
+
+ private void buildPath(Path path) {
+ path.moveTo(0.0f, 0.0f);
+ path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f);
+ path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f);
+ path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f);
+ }
+
+ public class TextOnPathView extends View {
+ private static final String TEST_STRING = "Hello OpenGL renderer, text on path! ";
+
+ private final Paint mPaint;
+ private final String mText;
+
+ public TextOnPathView(Context c) {
+ super(c);
+
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(0xff000000);
+
+ StringBuilder builder = new StringBuilder(TEST_STRING.length() * 5);
+ for (int i = 0; i < 5; i++) {
+ builder.append(TEST_STRING);
+ }
+ mText = builder.toString();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.drawARGB(255, 255, 255, 255);
+
+ canvas.translate(550.0f, 60.0f);
+ canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint);
+ }
+ }
+}