@Override
public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
- // TODO: Implement
+ if (index < 0 || index + count > text.length || count * 2 > pos.length) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ int modifiers = setupModifiers(paint);
+ try {
+ nDrawPosText(mRenderer, text, index, count, pos, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
+ private static native void nDrawPosText(int renderer, char[] text, int index, int count,
+ float[] pos, int paint);
+
@Override
public void drawPosText(String text, float[] pos, Paint paint) {
- // TODO: Implement
+ if (text.length() * 2 > pos.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ int modifiers = setupModifiers(paint);
+ try {
+ nDrawPosText(mRenderer, text, 0, text.length(), pos, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
+ private static native void nDrawPosText(int renderer, String text, int start, int end,
+ float[] pos, int paint);
+
@Override
public void drawRect(float left, float top, float right, float bottom, Paint paint) {
int modifiers = setupModifiers(paint);
env->ReleaseStringChars(text, textArray);
}
+static void renderPosText(OpenGLRenderer* renderer, const jchar* text, int count,
+ const jfloat* positions, jint dirFlags, SkPaint* paint) {
+ sp<TextLayoutCacheValue> value;
+#if USE_TEXT_LAYOUT_CACHE
+ value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, dirFlags);
+ if (value == NULL) {
+ ALOGE("Cannot get TextLayoutCache value for text = '%s'",
+ String8(text, count).string());
+ return;
+ }
+#else
+ value = new TextLayoutCacheValue(count);
+ TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+ text, 0, count, count, dirFlags);
+#endif
+
+ const jchar* glyphs = value->getGlyphs();
+ size_t glyphsCount = value->getGlyphsCount();
+ int bytesCount = glyphsCount * sizeof(jchar);
+
+ renderer->drawPosText((const char*) glyphs, bytesCount,
+ count < int(glyphsCount) ? count : glyphsCount, positions, paint);
+}
+
+static void android_view_GLES20Canvas_drawPosTextArray(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
+ jfloatArray pos, SkPaint* paint) {
+ jchar* textArray = env->GetCharArrayElements(text, NULL);
+ jfloat* positions = env->GetFloatArrayElements(pos, NULL);
+
+ renderPosText(renderer, textArray + index, count, positions, kBidi_LTR, paint);
+
+ env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT);
+ env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
+}
+
+static void android_view_GLES20Canvas_drawPosText(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jstring text, jint start, jint end,
+ jfloatArray pos, SkPaint* paint) {
+ const jchar* textArray = env->GetStringChars(text, NULL);
+ jfloat* positions = env->GetFloatArrayElements(pos, NULL);
+
+ renderPosText(renderer, textArray + start, end - start, positions, kBidi_LTR, paint);
+
+ env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT);
+ env->ReleaseStringChars(text, textArray);
+}
+
// ----------------------------------------------------------------------------
// Display lists
// ----------------------------------------------------------------------------
{ "nDrawTextRun", "(ILjava/lang/String;IIIIFFII)V",
(void*) android_view_GLES20Canvas_drawTextRun },
+ { "nDrawPosText", "(I[CII[FI)V", (void*) android_view_GLES20Canvas_drawPosTextArray },
+ { "nDrawPosText", "(ILjava/lang/String;II[FI)V",
+ (void*) android_view_GLES20Canvas_drawPosText },
+
{ "nGetClipBounds", "(ILandroid/graphics/Rect;)Z",
(void*) android_view_GLES20Canvas_getClipBounds },
"DrawLines",
"DrawPoints",
"DrawText",
+ "DrawPosText",
"ResetShader",
"SetupShader",
"ResetColorFilter",
text.text(), text.length(), count, x, y, paint, length);
}
break;
+ case DrawPosText: {
+ getText(&text);
+ int count = getInt();
+ int positionsCount = 0;
+ float* positions = getFloats(positionsCount);
+ SkPaint* paint = getPaint();
+ ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
+ text.text(), text.length(), count, paint);
+ }
case ResetShader: {
ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
}
renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
}
break;
+ case DrawPosText: {
+ getText(&text);
+ int count = getInt();
+ int positionsCount = 0;
+ float* positions = getFloats(positionsCount);
+ SkPaint* paint = getPaint();
+ DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
+ OP_NAMES[op], text.text(), text.length(), count, paint);
+ renderer.drawPosText(text.text(), text.length(), count, positions, paint);
+ }
+ break;
case ResetShader: {
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.resetShader();
addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length);
}
+void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
+ const float* positions, SkPaint* paint) {
+ if (count <= 0) return;
+ addOp(DisplayList::DrawPosText);
+ addText(text, bytesCount);
+ addInt(count);
+ addFloats(positions, count * 2);
+ paint->setAntiAlias(true);
+ addPaint(paint);
+}
+
void DisplayListRenderer::resetShader() {
addOp(DisplayList::ResetShader);
}
DrawLines,
DrawPoints,
DrawText,
+ DrawPosText,
ResetShader,
SetupShader,
ResetColorFilter,
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 resetShader();
virtual void setupShader(SkiaShader* shader);
}
}
+void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
+ const float* positions, SkPaint* paint) {
+ if (text == NULL || count == 0) {
+ return;
+ }
+ if (mSnapshot->isIgnored()) return;
+
+ // TODO: implement properly
+ drawText(text, bytesCount, count, 0, 0, paint);
+}
+
void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint, float length) {
if (text == NULL || count == 0) {
y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
}
- FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
#if DEBUG_GLYPHS
ALOGD("OpenGLRenderer drawText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface()));
#endif
+
+ FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
paint->getTextSize());
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 resetShader();
virtual void setupShader(SkiaShader* shader);