Merge "First pass at implementing Canvas.drawPosText() in GL"
This commit is contained in:
@@ -945,14 +945,38 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
@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);
|
||||
|
||||
@@ -567,6 +567,54 @@ static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -830,6 +878,10 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "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 },
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ const char* DisplayList::OP_NAMES[] = {
|
||||
"DrawLines",
|
||||
"DrawPoints",
|
||||
"DrawText",
|
||||
"DrawPosText",
|
||||
"ResetShader",
|
||||
"SetupShader",
|
||||
"ResetColorFilter",
|
||||
@@ -482,6 +483,15 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
|
||||
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]);
|
||||
}
|
||||
@@ -844,6 +854,17 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
|
||||
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();
|
||||
@@ -1216,6 +1237,17 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
DrawLines,
|
||||
DrawPoints,
|
||||
DrawText,
|
||||
DrawPosText,
|
||||
ResetShader,
|
||||
SetupShader,
|
||||
ResetColorFilter,
|
||||
@@ -291,6 +292,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 drawPosText(const char* text, int bytesCount, int count, const float* positions,
|
||||
SkPaint* paint);
|
||||
|
||||
virtual void resetShader();
|
||||
virtual void setupShader(SkiaShader* shader);
|
||||
|
||||
@@ -2082,6 +2082,17 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -2120,10 +2131,11 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
|
||||
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());
|
||||
|
||||
|
||||
@@ -124,6 +124,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 drawPosText(const char* text, int bytesCount, int count, const float* positions,
|
||||
SkPaint* paint);
|
||||
|
||||
virtual void resetShader();
|
||||
virtual void setupShader(SkiaShader* shader);
|
||||
|
||||
Reference in New Issue
Block a user