Loading core/jni/android/graphics/TextLayout.cpp +30 −21 Original line number Diff line number Diff line Loading @@ -150,26 +150,22 @@ jint TextLayout::layoutLine(const jchar* text, jint len, jint flags, int &dir, j return result; } // Draws or gets the path of a paragraph of text on a single line, running bidi and shaping. // This will draw if canvas is not null, otherwise path must be non-null and it will create // a path representing the text that would have been drawn. void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, jfloat x, jfloat y,SkCanvas *canvas, SkPath *path) { bool TextLayout::prepareText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, const jchar** outText, int32_t* outBytes) { const jchar *workText = text; jchar *buffer = NULL; int dir = kDirection_LTR; if (needsLayout(text, len, bidiFlags)) { buffer =(jchar *) malloc(len * sizeof(jchar)); if (!buffer) { return; return false; } UErrorCode status = U_ZERO_ERROR; len = layoutLine(text, len, bidiFlags, dir, buffer, status); // might change len, dir if (!U_SUCCESS(status)) { LOG(LOG_WARN, "LAYOUT", "drawText error %d\n", status); free(buffer); return; // can't render return false; // can't render } workText = buffer; // use the shaped text Loading Loading @@ -198,7 +194,21 @@ void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, } } int32_t workBytes = (workLimit - workText) << 1; *outBytes = (workLimit - workText) << 1; *outText = workText; free(buffer); return true; } // Draws or gets the path of a paragraph of text on a single line, running bidi and shaping. // This will draw if canvas is not null, otherwise path must be non-null and it will create // a path representing the text that would have been drawn. void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, jfloat x, jfloat y,SkCanvas *canvas, SkPath *path) { const jchar *workText; int32_t workBytes; if (prepareText(paint, text, len, bidiFlags, &workText, &workBytes)) { SkScalar x_ = SkFloatToScalar(x); SkScalar y_ = SkFloatToScalar(y); if (canvas) { Loading @@ -206,8 +216,7 @@ void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, } else { paint->getTextPath(workText, workBytes, x_, y_, path); } free(buffer); } } void TextLayout::drawTextRun(SkPaint* paint, const jchar* chars, Loading core/jni/android/graphics/TextLayout.h +3 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public: int bidiFlags, jfloat hOffset, jfloat vOffset, SkPath* path, SkCanvas* canvas); static bool prepareText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, const jchar** outText, int32_t* outBytes); private: static bool needsLayout(const jchar* text, jint len, jint bidiFlags); static int shapeRtlText(const jchar* context, jsize start, jsize count, jsize contextCount, Loading core/jni/android_view_GLES20Canvas.cpp +13 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <Rect.h> #include <ui/Rect.h> #include "TextLayout.h" namespace android { using namespace uirenderer; Loading Loading @@ -251,12 +253,20 @@ static void android_view_GLES20Canvas_setupLinearShader(JNIEnv* env, jobject can // Text // ---------------------------------------------------------------------------- static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { const jchar *workText; int32_t workBytes; if (TextLayout::prepareText(paint, text, count, flags, &workText, &workBytes)) { renderer->drawText((const char*) workText, workBytes, count, x, y, paint); } } static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jcharArray text, int index, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { jchar* textArray = env->GetCharArrayElements(text, NULL); // TODO: Prepare the text for RTL renderer->drawText((const char*) (textArray + index), count, x, y, paint); renderText(renderer, textArray + index, count, x, y, flags, paint); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); } Loading @@ -264,8 +274,7 @@ static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jstring text, int start, int end, jfloat x, jfloat y, int flags, SkPaint* paint) { const jchar* textArray = env->GetStringChars(text, NULL); // TODO: Prepare the text for RTL renderer->drawText((const char*) (textArray + start), end - start, x, y, paint); renderText(renderer, textArray + start, end - start, x, y, flags, paint); env->ReleaseStringChars(text, textArray); } Loading libs/hwui/OpenGLRenderer.cpp +21 −2 Original line number Diff line number Diff line Loading @@ -525,7 +525,26 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, drawColorRect(left, top, right, bottom, color, mode); } void OpenGLRenderer::drawText(const char* text, int count, float x, float y, SkPaint* paint) { void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint) { if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { return; } float length; switch (paint->getTextAlign()) { case SkPaint::kCenter_Align: length = paint->measureText(text, bytesCount); x -= length / 2.0f; break; case SkPaint::kRight_Align: length = paint->measureText(text, bytesCount); x -= length; break; default: break; } int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); Loading @@ -551,7 +570,7 @@ void OpenGLRenderer::drawText(const char* text, int count, float x, float y, SkP const Rect& clip = mSnapshot->getLocalClip(); mFontRenderer.setFont(SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize()); mFontRenderer.renderText(paint, &clip, text, 0, count, count, x, y); mFontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } Loading libs/hwui/OpenGLRenderer.h +1 −1 Original line number Diff line number Diff line Loading @@ -110,7 +110,7 @@ public: float* positions, int count, SkShader::TileMode tileMode, SkMatrix* matrix, bool hasAlpha); void drawText(const char* text, int count, float x, float y, SkPaint* paint); void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); private: /** Loading Loading
core/jni/android/graphics/TextLayout.cpp +30 −21 Original line number Diff line number Diff line Loading @@ -150,26 +150,22 @@ jint TextLayout::layoutLine(const jchar* text, jint len, jint flags, int &dir, j return result; } // Draws or gets the path of a paragraph of text on a single line, running bidi and shaping. // This will draw if canvas is not null, otherwise path must be non-null and it will create // a path representing the text that would have been drawn. void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, jfloat x, jfloat y,SkCanvas *canvas, SkPath *path) { bool TextLayout::prepareText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, const jchar** outText, int32_t* outBytes) { const jchar *workText = text; jchar *buffer = NULL; int dir = kDirection_LTR; if (needsLayout(text, len, bidiFlags)) { buffer =(jchar *) malloc(len * sizeof(jchar)); if (!buffer) { return; return false; } UErrorCode status = U_ZERO_ERROR; len = layoutLine(text, len, bidiFlags, dir, buffer, status); // might change len, dir if (!U_SUCCESS(status)) { LOG(LOG_WARN, "LAYOUT", "drawText error %d\n", status); free(buffer); return; // can't render return false; // can't render } workText = buffer; // use the shaped text Loading Loading @@ -198,7 +194,21 @@ void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, } } int32_t workBytes = (workLimit - workText) << 1; *outBytes = (workLimit - workText) << 1; *outText = workText; free(buffer); return true; } // Draws or gets the path of a paragraph of text on a single line, running bidi and shaping. // This will draw if canvas is not null, otherwise path must be non-null and it will create // a path representing the text that would have been drawn. void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, jfloat x, jfloat y,SkCanvas *canvas, SkPath *path) { const jchar *workText; int32_t workBytes; if (prepareText(paint, text, len, bidiFlags, &workText, &workBytes)) { SkScalar x_ = SkFloatToScalar(x); SkScalar y_ = SkFloatToScalar(y); if (canvas) { Loading @@ -206,8 +216,7 @@ void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, } else { paint->getTextPath(workText, workBytes, x_, y_, path); } free(buffer); } } void TextLayout::drawTextRun(SkPaint* paint, const jchar* chars, Loading
core/jni/android/graphics/TextLayout.h +3 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public: int bidiFlags, jfloat hOffset, jfloat vOffset, SkPath* path, SkCanvas* canvas); static bool prepareText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, const jchar** outText, int32_t* outBytes); private: static bool needsLayout(const jchar* text, jint len, jint bidiFlags); static int shapeRtlText(const jchar* context, jsize start, jsize count, jsize contextCount, Loading
core/jni/android_view_GLES20Canvas.cpp +13 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <Rect.h> #include <ui/Rect.h> #include "TextLayout.h" namespace android { using namespace uirenderer; Loading Loading @@ -251,12 +253,20 @@ static void android_view_GLES20Canvas_setupLinearShader(JNIEnv* env, jobject can // Text // ---------------------------------------------------------------------------- static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { const jchar *workText; int32_t workBytes; if (TextLayout::prepareText(paint, text, count, flags, &workText, &workBytes)) { renderer->drawText((const char*) workText, workBytes, count, x, y, paint); } } static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jcharArray text, int index, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { jchar* textArray = env->GetCharArrayElements(text, NULL); // TODO: Prepare the text for RTL renderer->drawText((const char*) (textArray + index), count, x, y, paint); renderText(renderer, textArray + index, count, x, y, flags, paint); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); } Loading @@ -264,8 +274,7 @@ static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jstring text, int start, int end, jfloat x, jfloat y, int flags, SkPaint* paint) { const jchar* textArray = env->GetStringChars(text, NULL); // TODO: Prepare the text for RTL renderer->drawText((const char*) (textArray + start), end - start, x, y, paint); renderText(renderer, textArray + start, end - start, x, y, flags, paint); env->ReleaseStringChars(text, textArray); } Loading
libs/hwui/OpenGLRenderer.cpp +21 −2 Original line number Diff line number Diff line Loading @@ -525,7 +525,26 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, drawColorRect(left, top, right, bottom, color, mode); } void OpenGLRenderer::drawText(const char* text, int count, float x, float y, SkPaint* paint) { void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint) { if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { return; } float length; switch (paint->getTextAlign()) { case SkPaint::kCenter_Align: length = paint->measureText(text, bytesCount); x -= length / 2.0f; break; case SkPaint::kRight_Align: length = paint->measureText(text, bytesCount); x -= length; break; default: break; } int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); Loading @@ -551,7 +570,7 @@ void OpenGLRenderer::drawText(const char* text, int count, float x, float y, SkP const Rect& clip = mSnapshot->getLocalClip(); mFontRenderer.setFont(SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize()); mFontRenderer.renderText(paint, &clip, text, 0, count, count, x, y); mFontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } Loading
libs/hwui/OpenGLRenderer.h +1 −1 Original line number Diff line number Diff line Loading @@ -110,7 +110,7 @@ public: float* positions, int count, SkShader::TileMode tileMode, SkMatrix* matrix, bool hasAlpha); void drawText(const char* text, int count, float x, float y, SkPaint* paint); void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); private: /** Loading