diff options
54 files changed, 449 insertions, 360 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk index c6db0ed6cb69..c685b0c14e2f 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -117,13 +117,10 @@ LOCAL_SRC_FILES:= \ android/graphics/Interpolator.cpp \ android/graphics/MaskFilter.cpp \ android/graphics/Matrix.cpp \ - android/graphics/MinikinSkia.cpp \ - android/graphics/MinikinUtils.cpp \ android/graphics/Movie.cpp \ android/graphics/NinePatch.cpp \ android/graphics/NinePatchPeeker.cpp \ android/graphics/Paint.cpp \ - android/graphics/PaintImpl.cpp \ android/graphics/Path.cpp \ android/graphics/PathMeasure.cpp \ android/graphics/PathEffect.cpp \ @@ -135,7 +132,6 @@ LOCAL_SRC_FILES:= \ android/graphics/Shader.cpp \ android/graphics/SurfaceTexture.cpp \ android/graphics/Typeface.cpp \ - android/graphics/TypefaceImpl.cpp \ android/graphics/Utils.cpp \ android/graphics/Xfermode.cpp \ android/graphics/YuvToJpegEncoder.cpp \ diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index 43e26b332f11..27b98306b72b 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -1,7 +1,6 @@ #define LOG_TAG "Bitmap" #include "Bitmap.h" -#include "Paint.h" #include "SkBitmap.h" #include "SkPixelRef.h" #include "SkImageEncoder.h" @@ -18,6 +17,7 @@ #include "android_nio_utils.h" #include "CreateJavaOutputStreamAdaptor.h" #include <Caches.h> +#include <hwui/Paint.h> #include "core_jni_helpers.h" diff --git a/core/jni/android/graphics/Camera.cpp b/core/jni/android/graphics/Camera.cpp index 6fcf6892d490..76d685149ec4 100644 --- a/core/jni/android/graphics/Camera.cpp +++ b/core/jni/android/graphics/Camera.cpp @@ -3,8 +3,8 @@ #include "SkCamera.h" -#include "Canvas.h" #include "GraphicsJNI.h" +#include <hwui/Canvas.h> static jfieldID gNativeInstanceFieldID; diff --git a/core/jni/android/graphics/CanvasProperty.cpp b/core/jni/android/graphics/CanvasProperty.cpp index 728bc1c3677e..c841d6a5125a 100644 --- a/core/jni/android/graphics/CanvasProperty.cpp +++ b/core/jni/android/graphics/CanvasProperty.cpp @@ -16,9 +16,9 @@ #include "jni.h" #include "GraphicsJNI.h" -#include "Paint.h" #include <core_jni_helpers.h> +#include <hwui/Paint.h> #include <utils/RefBase.h> #include <CanvasProperty.h> diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp index 2e974a3ecaa3..a24af29ea8f2 100644 --- a/core/jni/android/graphics/FontFamily.cpp +++ b/core/jni/android/graphics/FontFamily.cpp @@ -31,9 +31,9 @@ #include <androidfw/AssetManager.h> #include "Utils.h" -#include "TypefaceImpl.h" +#include <hwui/MinikinSkia.h> +#include <hwui/TypefaceImpl.h> #include <minikin/FontFamily.h> -#include "MinikinSkia.h" #include <memory> diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index bd01c73adf80..1ead6188a8aa 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -7,13 +7,13 @@ #include "JNIHelp.h" #include "GraphicsJNI.h" -#include "Canvas.h" #include "SkCanvas.h" #include "SkDevice.h" #include "SkMath.h" #include "SkRegion.h" #include <android_runtime/AndroidRuntime.h> #include <cutils/ashmem.h> +#include <hwui/Canvas.h> #include <Caches.h> #include <TextureCache.h> diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index e99a3ffa2a47..8108e0a08e90 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -11,8 +11,8 @@ #include "SkPoint.h" #include "SkRect.h" #include "SkImageDecoder.h" -#include <Canvas.h> #include <jni.h> +#include <hwui/Canvas.h> class SkBitmapRegionDecoder; class SkCanvas; diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp index 498c5902e5fd..71988f9cf44d 100644 --- a/core/jni/android/graphics/Movie.cpp +++ b/core/jni/android/graphics/Movie.cpp @@ -1,7 +1,5 @@ -#include "Canvas.h" #include "CreateJavaOutputStreamAdaptor.h" #include "GraphicsJNI.h" -#include "Paint.h" #include "ScopedLocalRef.h" #include "SkFrontBufferedStream.h" #include "SkMovie.h" @@ -12,6 +10,8 @@ #include <androidfw/Asset.h> #include <androidfw/ResourceTypes.h> +#include <hwui/Canvas.h> +#include <hwui/Paint.h> #include <jni.h> #include <netinet/in.h> diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp index 3ccbb35cc960..4f2f3897469c 100644 --- a/core/jni/android/graphics/NinePatch.cpp +++ b/core/jni/android/graphics/NinePatch.cpp @@ -19,12 +19,12 @@ #define LOG_NDEBUG 1 #include <androidfw/ResourceTypes.h> +#include <hwui/Canvas.h> +#include <hwui/Paint.h> #include <utils/Log.h> #include <ResourceCache.h> -#include "Paint.h" -#include "Canvas.h" #include "SkCanvas.h" #include "SkRegion.h" #include "GraphicsJNI.h" diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index d00e94ca4fd9..d222a4b4771e 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -37,13 +37,13 @@ #include "unicode/ushape.h" #include "utils/Blur.h" +#include <hwui/MinikinSkia.h> +#include <hwui/MinikinUtils.h> +#include <hwui/Paint.h> +#include <hwui/TypefaceImpl.h> #include <minikin/GraphemeBreak.h> #include <minikin/Measurement.h> #include <unicode/utf16.h> -#include "MinikinSkia.h" -#include "MinikinUtils.h" -#include "Paint.h" -#include "TypefaceImpl.h" #include <cassert> #include <cstring> diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp index 6e83f1b19f5f..07e14a211e64 100644 --- a/core/jni/android/graphics/Picture.cpp +++ b/core/jni/android/graphics/Picture.cpp @@ -14,11 +14,11 @@ * limitations under the License. */ -#include "Canvas.h" #include "Picture.h" #include "SkStream.h" #include <memory> +#include <hwui/Canvas.h> namespace android { diff --git a/core/jni/android/graphics/Rasterizer.cpp b/core/jni/android/graphics/Rasterizer.cpp index a106ecfeb65f..3784f0d8a220 100644 --- a/core/jni/android/graphics/Rasterizer.cpp +++ b/core/jni/android/graphics/Rasterizer.cpp @@ -22,10 +22,11 @@ #include "jni.h" #include "GraphicsJNI.h" -#include "Paint.h" #include "SkLayerRasterizer.h" #include "core_jni_helpers.h" +#include <hwui/Paint.h> + // Rasterizer.java holds a pointer (jlong) to this guy class NativeRasterizer { public: diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp index e97b768dd0cc..8e2572c9b6b9 100644 --- a/core/jni/android/graphics/Typeface.cpp +++ b/core/jni/android/graphics/Typeface.cpp @@ -20,9 +20,9 @@ #include "GraphicsJNI.h" #include "ScopedPrimitiveArray.h" #include "SkTypeface.h" -#include "TypefaceImpl.h" #include <android_runtime/android_util_AssetManager.h> #include <androidfw/AssetManager.h> +#include <hwui/TypefaceImpl.h> using namespace android; @@ -58,7 +58,12 @@ static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) { static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) { ScopedLongArrayRO families(env, familyArray); - return reinterpret_cast<jlong>(TypefaceImpl_createFromFamilies(families.get(), families.size())); + std::vector<FontFamily*> familyVec; + for (size_t i = 0; i < families.size(); i++) { + FontFamily* family = reinterpret_cast<FontFamily*>(families[i]); + familyVec.push_back(family); + } + return reinterpret_cast<jlong>(TypefaceImpl_createFromFamilies(familyVec)); } static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) { diff --git a/core/jni/android/graphics/pdf/PdfDocument.cpp b/core/jni/android/graphics/pdf/PdfDocument.cpp index 5d496e5ccae9..88e37e5545b5 100644 --- a/core/jni/android/graphics/pdf/PdfDocument.cpp +++ b/core/jni/android/graphics/pdf/PdfDocument.cpp @@ -19,7 +19,6 @@ #include "core_jni_helpers.h" #include <vector> -#include "Canvas.h" #include "CreateJavaOutputStreamAdaptor.h" #include "SkDocument.h" @@ -28,6 +27,8 @@ #include "SkStream.h" #include "SkRect.h" +#include <hwui/Canvas.h> + namespace android { struct PageRecord { diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index cf73316d494b..094f3c53d045 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -19,15 +19,14 @@ #include "core_jni_helpers.h" #include <androidfw/ResourceTypes.h> -#include <Canvas.h> +#include <hwui/Canvas.h> +#include <hwui/Paint.h> +#include <hwui/TypefaceImpl.h> +#include <minikin/Layout.h> #include "Bitmap.h" #include "SkDrawFilter.h" #include "SkGraphics.h" -#include "Paint.h" -#include "TypefaceImpl.h" - -#include "MinikinUtils.h" namespace android { @@ -475,111 +474,13 @@ static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jobject jbi vertA.ptr(), colorA.ptr(), paint); } -static void simplifyPaint(int color, SkPaint* paint) { - paint->setColor(color); - paint->setShader(nullptr); - paint->setColorFilter(nullptr); - paint->setLooper(nullptr); - paint->setStrokeWidth(4 + 0.04 * paint->getTextSize()); - paint->setStrokeJoin(SkPaint::kRound_Join); - paint->setLooper(nullptr); -} - -class DrawTextFunctor { -public: - DrawTextFunctor(const Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos, - const SkPaint& paint, float x, float y, MinikinRect& bounds, - float totalAdvance) - : layout(layout), canvas(canvas), glyphs(glyphs), pos(pos), paint(paint), - x(x), y(y), bounds(bounds), totalAdvance(totalAdvance) { } - - void operator()(size_t start, size_t end) { - if (canvas->drawTextAbsolutePos()) { - for (size_t i = start; i < end; i++) { - glyphs[i] = layout.getGlyphId(i); - pos[2 * i] = x + layout.getX(i); - pos[2 * i + 1] = y + layout.getY(i); - } - } else { - for (size_t i = start; i < end; i++) { - glyphs[i] = layout.getGlyphId(i); - pos[2 * i] = layout.getX(i); - pos[2 * i + 1] = layout.getY(i); - } - } - - size_t glyphCount = end - start; - - if (CC_UNLIKELY(canvas->isHighContrastText() && paint.getAlpha() != 0)) { - // high contrast draw path - int color = paint.getColor(); - int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); - bool darken = channelSum < (128 * 3); - - // outline - SkPaint outlinePaint(paint); - simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint); - outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style); - canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, outlinePaint, x, y, - bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance); - - // inner - SkPaint innerPaint(paint); - simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint); - innerPaint.setStyle(SkPaint::kFill_Style); - canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, innerPaint, x, y, - bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance); - } else { - // standard draw path - canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, paint, x, y, - bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, - totalAdvance); - } - } -private: - const Layout& layout; - Canvas* canvas; - uint16_t* glyphs; - float* pos; - const SkPaint& paint; - float x; - float y; - MinikinRect& bounds; - float totalAdvance; -}; - -void drawText(Canvas* canvas, const uint16_t* text, int start, int count, int contextCount, - float x, float y, int bidiFlags, const Paint& origPaint, TypefaceImpl* typeface) { - // minikin may modify the original paint - Paint paint(origPaint); - - Layout layout; - MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, start, count, contextCount); - - size_t nGlyphs = layout.nGlyphs(); - std::unique_ptr<uint16_t[]> glyphs(new uint16_t[nGlyphs]); - std::unique_ptr<float[]> pos(new float[nGlyphs * 2]); - - x += MinikinUtils::xOffsetForTextAlign(&paint, layout); - - MinikinRect bounds; - layout.getBounds(&bounds); - if (!canvas->drawTextAbsolutePos()) { - bounds.offset(x, y); - } - - DrawTextFunctor f(layout, canvas, glyphs.get(), pos.get(), - paint, x, y, bounds, layout.getAdvance()); - MinikinUtils::forFontRun(layout, &paint, f); -} - static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index, jint count, jfloat x, jfloat y, jint bidiFlags, jlong paintHandle, jlong typefaceHandle) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); jchar* jchars = env->GetCharArrayElements(text, NULL); - drawText(get_canvas(canvasHandle), jchars + index, 0, count, count, x, y, + get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y, bidiFlags, *paint, typeface); env->ReleaseCharArrayElements(text, jchars, JNI_ABORT); } @@ -591,7 +492,7 @@ static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring tex TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); const int count = end - start; const jchar* jchars = env->GetStringChars(text, NULL); - drawText(get_canvas(canvasHandle), jchars + start, 0, count, count, x, y, + get_canvas(canvasHandle)->drawText(jchars + start, 0, count, count, x, y, bidiFlags, *paint, typeface); env->ReleaseStringChars(text, jchars); } @@ -604,7 +505,7 @@ static void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArra const int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; jchar* jchars = env->GetCharArrayElements(text, NULL); - drawText(get_canvas(canvasHandle), jchars + contextIndex, index - contextIndex, count, + get_canvas(canvasHandle)->drawText(jchars + contextIndex, index - contextIndex, count, contextCount, x, y, bidiFlags, *paint, typeface); env->ReleaseCharArrayElements(text, jchars, JNI_ABORT); } @@ -620,53 +521,11 @@ static void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstr jint count = end - start; jint contextCount = contextEnd - contextStart; const jchar* jchars = env->GetStringChars(text, NULL); - drawText(get_canvas(canvasHandle), jchars + contextStart, start - contextStart, count, + get_canvas(canvasHandle)->drawText(jchars + contextStart, start - contextStart, count, contextCount, x, y, bidiFlags, *paint, typeface); env->ReleaseStringChars(text, jchars); } -class DrawTextOnPathFunctor { -public: - DrawTextOnPathFunctor(const Layout& layout, Canvas* canvas, float hOffset, - float vOffset, const Paint& paint, const SkPath& path) - : layout(layout), canvas(canvas), hOffset(hOffset), vOffset(vOffset), - paint(paint), path(path) { - } - void operator()(size_t start, size_t end) { - uint16_t glyphs[1]; - for (size_t i = start; i < end; i++) { - glyphs[0] = layout.getGlyphId(i); - float x = hOffset + layout.getX(i); - float y = vOffset + layout.getY(i); - canvas->drawTextOnPath(glyphs, 1, path, x, y, paint); - } - } -private: - const Layout& layout; - Canvas* canvas; - float hOffset; - float vOffset; - const Paint& paint; - const SkPath& path; -}; - -static void drawTextOnPath(Canvas* canvas, const uint16_t* text, int count, int bidiFlags, - const SkPath& path, float hOffset, float vOffset, - const Paint& paint, TypefaceImpl* typeface) { - Paint paintCopy(paint); - Layout layout; - MinikinUtils::doLayout(&layout, &paintCopy, bidiFlags, typeface, text, 0, count, count); - hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path); - - // Set align to left for drawing, as we don't want individual - // glyphs centered or right-aligned; the offset above takes - // care of all alignment. - paintCopy.setTextAlign(Paint::kLeft_Align); - - DrawTextOnPathFunctor f(layout, canvas, hOffset, vOffset, paintCopy, path); - MinikinUtils::forFontRun(layout, &paintCopy, f); -} - static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index, jint count, jlong pathHandle, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintHandle, @@ -677,7 +536,7 @@ static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharA jchar* jchars = env->GetCharArrayElements(text, NULL); - drawTextOnPath(get_canvas(canvasHandle), jchars + index, count, bidiFlags, *path, + get_canvas(canvasHandle)->drawTextOnPath(jchars + index, count, bidiFlags, *path, hOffset, vOffset, *paint, typeface); env->ReleaseCharArrayElements(text, jchars, 0); @@ -693,7 +552,7 @@ static void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstri const jchar* jchars = env->GetStringChars(text, NULL); int count = env->GetStringLength(text); - drawTextOnPath(get_canvas(canvasHandle), jchars, count, bidiFlags, *path, + get_canvas(canvasHandle)->drawTextOnPath(jchars, count, bidiFlags, *path, hOffset, vOffset, *paint, typeface); env->ReleaseStringChars(text, jchars); diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp index e17de17e06cc..a2662f9e81c7 100644 --- a/core/jni/android_graphics_drawable_VectorDrawable.cpp +++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp @@ -19,9 +19,10 @@ #include "core_jni_helpers.h" #include "log/log.h" -#include "Paint.h" #include "VectorDrawable.h" +#include <hwui/Paint.h> + namespace android { using namespace uirenderer; using namespace uirenderer::VectorDrawable; diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp index 83f76eab053d..fddcfa846134 100644 --- a/core/jni/android_text_StaticLayout.cpp +++ b/core/jni/android_text_StaticLayout.cpp @@ -32,10 +32,12 @@ #include "SkPaint.h" #include "SkTypeface.h" -#include "MinikinSkia.h" -#include "MinikinUtils.h" -#include "Paint.h" -#include "minikin/LineBreaker.h" +#include <hwui/MinikinSkia.h> +#include <hwui/MinikinUtils.h> +#include <hwui/Paint.h> +#include <minikin/FontCollection.h> +#include <minikin/LineBreaker.h> +#include <minikin/MinikinFont.h> namespace android { diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp index c87a7701786c..6aac0e4975e8 100644 --- a/core/jni/android_view_DisplayListCanvas.cpp +++ b/core/jni/android_view_DisplayListCanvas.cpp @@ -28,11 +28,11 @@ #include <SkRegion.h> -#include <Canvas.h> #include <Rect.h> #include <RenderNode.h> #include <CanvasProperty.h> -#include <Paint.h> +#include <hwui/Canvas.h> +#include <hwui/Paint.h> #include <renderthread/RenderProxy.h> #include "core_jni_helpers.h" diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp index 3a0ddc9fa825..6b774e8f23e3 100644 --- a/core/jni/android_view_HardwareLayer.cpp +++ b/core/jni/android_view_HardwareLayer.cpp @@ -24,8 +24,8 @@ #include <android_runtime/android_graphics_SurfaceTexture.h> #include <gui/GLConsumer.h> +#include <hwui/Paint.h> -#include <Paint.h> #include <SkBitmap.h> #include <SkCanvas.h> #include <SkMatrix.h> diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index a7ac5b8aae66..79b518fe53ee 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -30,7 +30,7 @@ #include <RenderNode.h> #include <renderthread/CanvasContext.h> #include <TreeInfo.h> -#include <Paint.h> +#include <hwui/Paint.h> #include "core_jni_helpers.h" diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index ca077389b629..26b4c4e875f7 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -12,6 +12,11 @@ HWUI_ENABLE_OPENGL_VALIDATION := true hwui_src_files := \ font/CacheTexture.cpp \ font/Font.cpp \ + hwui/Canvas.cpp \ + hwui/MinikinSkia.cpp \ + hwui/MinikinUtils.cpp \ + hwui/PaintImpl.cpp \ + hwui/TypefaceImpl.cpp \ renderstate/Blend.cpp \ renderstate/MeshState.cpp \ renderstate/OffscreenBufferPool.cpp \ @@ -41,7 +46,6 @@ hwui_src_files := \ AnimatorManager.cpp \ AssetAtlas.cpp \ Caches.cpp \ - Canvas.cpp \ CanvasState.cpp \ ClipArea.cpp \ DamageAccumulator.cpp \ @@ -143,7 +147,9 @@ endef hwui_c_includes += \ external/skia/include/private \ - external/skia/src/core + external/skia/src/core \ + external/harfbuzz_ng/src \ + external/freetype/include ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT)) hwui_cflags += -DANDROID_ENABLE_RENDERSCRIPT diff --git a/libs/hwui/Canvas.cpp b/libs/hwui/Canvas.cpp deleted file mode 100644 index 11ae1a137e2e..000000000000 --- a/libs/hwui/Canvas.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2015 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. - */ - -#include "Canvas.h" - -#include "DisplayListCanvas.h" -#include "RecordingCanvas.h" -#include <SkDrawFilter.h> - -namespace android { - -Canvas* Canvas::create_recording_canvas(int width, int height) { -#if HWUI_NEW_OPS - return new uirenderer::RecordingCanvas(width, height); -#else - return new uirenderer::DisplayListCanvas(width, height); -#endif -} - -void Canvas::drawTextDecorations(float x, float y, float length, const SkPaint& paint) { - uint32_t flags; - SkDrawFilter* drawFilter = getDrawFilter(); - if (drawFilter) { - SkPaint paintCopy(paint); - drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type); - flags = paintCopy.getFlags(); - } else { - flags = paint.getFlags(); - } - if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) { - // Same values used by Skia - const float kStdStrikeThru_Offset = (-6.0f / 21.0f); - const float kStdUnderline_Offset = (1.0f / 9.0f); - const float kStdUnderline_Thickness = (1.0f / 18.0f); - - SkScalar left = x; - SkScalar right = x + length; - float textSize = paint.getTextSize(); - float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f); - if (flags & SkPaint::kUnderlineText_Flag) { - SkScalar top = y + textSize * kStdUnderline_Offset - 0.5f * strokeWidth; - SkScalar bottom = y + textSize * kStdUnderline_Offset + 0.5f * strokeWidth; - drawRect(left, top, right, bottom, paint); - } - if (flags & SkPaint::kStrikeThruText_Flag) { - SkScalar top = y + textSize * kStdStrikeThru_Offset - 0.5f * strokeWidth; - SkScalar bottom = y + textSize * kStdStrikeThru_Offset + 0.5f * strokeWidth; - drawRect(left, top, right, bottom, paint); - } - } -} - -} // namespace android diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp index 43ff33f2b997..e2149d1e4a69 100644 --- a/libs/hwui/CanvasState.cpp +++ b/libs/hwui/CanvasState.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ -#include "Canvas.h" #include "CanvasState.h" +#include "hwui/Canvas.h" #include "utils/MathUtils.h" namespace android { diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp index a14bdc4693e6..2dccf32a7c78 100644 --- a/libs/hwui/DisplayListCanvas.cpp +++ b/libs/hwui/DisplayListCanvas.cpp @@ -418,7 +418,7 @@ void DisplayListCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { addDrawOp(new (alloc()) DrawVectorDrawableOp(tree)); } -void DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count, +void DisplayListCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { if (!glyphs || count <= 0) return; @@ -429,7 +429,7 @@ void DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count, addDrawOp(op); } -void DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions, +void DisplayListCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int count, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) { diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h index a703e227fc8d..d6a5794734d6 100644 --- a/libs/hwui/DisplayListCanvas.h +++ b/libs/hwui/DisplayListCanvas.h @@ -17,12 +17,12 @@ #ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H #define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H -#include "Canvas.h" #include "CanvasState.h" #include "DisplayList.h" #include "RenderNode.h" #include "ResourceCache.h" #include "SkiaCanvasProxy.h" +#include "hwui/Canvas.h" #include "utils/Macros.h" #include <SkDrawFilter.h> @@ -209,10 +209,10 @@ public: virtual void drawVectorDrawable(VectorDrawableRoot* tree) override; // Text - virtual void drawText(const uint16_t* glyphs, const float* positions, int count, + virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) override; - virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path, + virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) override; virtual bool drawTextAbsolutePos() const override { return false; } diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp index fc396825029f..dc967e046f11 100644 --- a/libs/hwui/FrameBuilder.cpp +++ b/libs/hwui/FrameBuilder.cpp @@ -16,11 +16,11 @@ #include "FrameBuilder.h" -#include "Canvas.h" #include "LayerUpdateQueue.h" #include "RenderNode.h" #include "VectorDrawable.h" #include "renderstate/OffscreenBufferPool.h" +#include "hwui/Canvas.h" #include "utils/FatVector.h" #include "utils/PaintUtils.h" #include "utils/TraceUtils.h" diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7693fdcbe817..c0994272c964 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -17,7 +17,6 @@ #include <GpuMemoryTracker.h> #include "OpenGLRenderer.h" -#include "Canvas.h" #include "DeferredDisplayList.h" #include "GammaFontRenderer.h" #include "Glop.h" @@ -32,6 +31,7 @@ #include "SkiaShader.h" #include "Vector.h" #include "VertexBuffer.h" +#include "hwui/Canvas.h" #include "utils/GLUtils.h" #include "utils/PaintUtils.h" #include "utils/TraceUtils.h" diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 1546baf88691..cf78781e8f81 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -514,7 +514,7 @@ void RecordingCanvas::drawNinePatch(const SkBitmap& bitmap, const android::Res_p } // Text -void RecordingCanvas::drawText(const uint16_t* glyphs, const float* positions, int glyphCount, +void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) { if (!glyphs || !positions || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; @@ -530,7 +530,7 @@ void RecordingCanvas::drawText(const uint16_t* glyphs, const float* positions, i drawTextDecorations(x, y, totalAdvance, paint); } -void RecordingCanvas::drawTextOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path, +void RecordingCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { if (!glyphs || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; glyphs = refBuffer<glyph_t>(glyphs, glyphCount); diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index 719872d35169..1eb4fa0b884f 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -17,12 +17,12 @@ #ifndef ANDROID_HWUI_RECORDING_CANVAS_H #define ANDROID_HWUI_RECORDING_CANVAS_H -#include "Canvas.h" #include "CanvasState.h" #include "DisplayList.h" #include "ResourceCache.h" #include "SkiaCanvasProxy.h" #include "Snapshot.h" +#include "hwui/Canvas.h" #include "utils/LinearAllocator.h" #include "utils/Macros.h" #include "utils/NinePatch.h" @@ -191,10 +191,10 @@ public: const SkPaint* paint) override; // Text - virtual void drawText(const uint16_t* glyphs, const float* positions, int glyphCount, + virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) override; - virtual void drawTextOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path, + virtual void drawGlyphsOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) override; virtual bool drawTextAbsolutePos() const override { return false; } diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index 0b0f0fa4f304..f577785110d3 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -23,9 +23,9 @@ #include <SkPath.h> #include <SkPathOps.h> -#include "Canvas.h" #include "Matrix.h" #include "OpenGLRenderer.h" +#include "hwui/Canvas.h" #include "utils/MathUtils.h" namespace android { diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index bd4442dc378d..b1ecb7112207 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -14,10 +14,10 @@ * limitations under the License. */ -#include "Canvas.h" #include "CanvasProperty.h" #include "Layer.h" #include "RenderNode.h" +#include "hwui/Canvas.h" #include <SkCanvas.h> #include <SkClipStack.h> @@ -147,11 +147,11 @@ public: float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) override; - virtual void drawText(const uint16_t* text, const float* positions, int count, + virtual void drawGlyphs(const uint16_t* text, const float* positions, int count, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) override; - virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path, + virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) override; virtual bool drawTextAbsolutePos() const override { return true; } @@ -757,7 +757,7 @@ void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) { // Canvas draw operations: Text // ---------------------------------------------------------------------------- -void SkiaCanvas::drawText(const uint16_t* text, const float* positions, int count, +void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int count, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) { @@ -772,7 +772,7 @@ void SkiaCanvas::drawText(const uint16_t* text, const float* positions, int coun drawTextDecorations(x, y, totalAdvance, paint); } -void SkiaCanvas::drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path, +void SkiaCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { mCanvas->drawTextOnPathHV(glyphs, count << 1, path, hOffset, vOffset, paint); } diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp index 6530d4ed8d50..c6124803eb6a 100644 --- a/libs/hwui/SkiaCanvasProxy.cpp +++ b/libs/hwui/SkiaCanvasProxy.cpp @@ -290,7 +290,7 @@ void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x } static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats"); - mCanvas->drawText(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint, + mCanvas->drawGlyphs(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0); } @@ -326,7 +326,7 @@ void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const S bounds.offset(x, y); static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats"); - mCanvas->drawText(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y, + mCanvas->drawGlyphs(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0); } @@ -344,7 +344,7 @@ void SkiaCanvasProxy::onDrawTextOnPath(const void* text, size_t byteLength, cons const SkMatrix* matrix, const SkPaint& origPaint) { // convert to glyphIDs if necessary GlyphIDConverter glyphs(text, byteLength, origPaint); - mCanvas->drawTextOnPath(glyphs.glyphIDs, glyphs.count, path, 0, 0, glyphs.paint); + mCanvas->drawGlyphsOnPath(glyphs.glyphIDs, glyphs.count, path, 0, 0, glyphs.paint); } void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, diff --git a/libs/hwui/SkiaCanvasProxy.h b/libs/hwui/SkiaCanvasProxy.h index e342d192ea31..973c55fe2236 100644 --- a/libs/hwui/SkiaCanvasProxy.h +++ b/libs/hwui/SkiaCanvasProxy.h @@ -20,7 +20,7 @@ #include <cutils/compiler.h> #include <SkCanvas.h> -#include "Canvas.h" +#include "hwui/Canvas.h" namespace android { namespace uirenderer { diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index cf5e69a1e6ae..d7842801fdd8 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -16,7 +16,7 @@ #include "Snapshot.h" -#include "Canvas.h" +#include "hwui/Canvas.h" namespace android { namespace uirenderer { diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h index 4d2fed096adf..7a45bf5ca8a8 100644 --- a/libs/hwui/VectorDrawable.h +++ b/libs/hwui/VectorDrawable.h @@ -17,7 +17,7 @@ #ifndef ANDROID_HWUI_VPATH_H #define ANDROID_HWUI_VPATH_H -#include "Canvas.h" +#include "hwui/Canvas.h" #include <SkBitmap.h> #include <SkColor.h> diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp new file mode 100644 index 000000000000..04e3af6da7d9 --- /dev/null +++ b/libs/hwui/hwui/Canvas.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2015 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. + */ + +#include "Canvas.h" + +#include "DisplayListCanvas.h" +#include "RecordingCanvas.h" +#include "MinikinUtils.h" +#include "Paint.h" +#include "TypefaceImpl.h" + +#include <SkDrawFilter.h> + +namespace android { + +Canvas* Canvas::create_recording_canvas(int width, int height) { +#if HWUI_NEW_OPS + return new uirenderer::RecordingCanvas(width, height); +#else + return new uirenderer::DisplayListCanvas(width, height); +#endif +} + +void Canvas::drawTextDecorations(float x, float y, float length, const SkPaint& paint) { + uint32_t flags; + SkDrawFilter* drawFilter = getDrawFilter(); + if (drawFilter) { + SkPaint paintCopy(paint); + drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type); + flags = paintCopy.getFlags(); + } else { + flags = paint.getFlags(); + } + if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) { + // Same values used by Skia + const float kStdStrikeThru_Offset = (-6.0f / 21.0f); + const float kStdUnderline_Offset = (1.0f / 9.0f); + const float kStdUnderline_Thickness = (1.0f / 18.0f); + + SkScalar left = x; + SkScalar right = x + length; + float textSize = paint.getTextSize(); + float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f); + if (flags & SkPaint::kUnderlineText_Flag) { + SkScalar top = y + textSize * kStdUnderline_Offset - 0.5f * strokeWidth; + SkScalar bottom = y + textSize * kStdUnderline_Offset + 0.5f * strokeWidth; + drawRect(left, top, right, bottom, paint); + } + if (flags & SkPaint::kStrikeThruText_Flag) { + SkScalar top = y + textSize * kStdStrikeThru_Offset - 0.5f * strokeWidth; + SkScalar bottom = y + textSize * kStdStrikeThru_Offset + 0.5f * strokeWidth; + drawRect(left, top, right, bottom, paint); + } + } +} + +static void simplifyPaint(int color, SkPaint* paint) { + paint->setColor(color); + paint->setShader(nullptr); + paint->setColorFilter(nullptr); + paint->setLooper(nullptr); + paint->setStrokeWidth(4 + 0.04 * paint->getTextSize()); + paint->setStrokeJoin(SkPaint::kRound_Join); + paint->setLooper(nullptr); +} + +class DrawTextFunctor { +public: + DrawTextFunctor(const Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos, + const SkPaint& paint, float x, float y, MinikinRect& bounds, float totalAdvance) + : layout(layout) + , canvas(canvas) + , glyphs(glyphs) + , pos(pos) + , paint(paint) + , x(x) + , y(y) + , bounds(bounds) + , totalAdvance(totalAdvance) { + } + + void operator()(size_t start, size_t end) { + if (canvas->drawTextAbsolutePos()) { + for (size_t i = start; i < end; i++) { + glyphs[i] = layout.getGlyphId(i); + pos[2 * i] = x + layout.getX(i); + pos[2 * i + 1] = y + layout.getY(i); + } + } else { + for (size_t i = start; i < end; i++) { + glyphs[i] = layout.getGlyphId(i); + pos[2 * i] = layout.getX(i); + pos[2 * i + 1] = layout.getY(i); + } + } + + size_t glyphCount = end - start; + + if (CC_UNLIKELY(canvas->isHighContrastText() && paint.getAlpha() != 0)) { + // high contrast draw path + int color = paint.getColor(); + int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); + bool darken = channelSum < (128 * 3); + + // outline + SkPaint outlinePaint(paint); + simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint); + outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style); + canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, outlinePaint, x, y, + bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance); + + // inner + SkPaint innerPaint(paint); + simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint); + innerPaint.setStyle(SkPaint::kFill_Style); + canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, innerPaint, x, y, + bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance); + } else { + // standard draw path + canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, paint, x, y, + bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance); + } + } +private: + const Layout& layout; + Canvas* canvas; + uint16_t* glyphs; + float* pos; + const SkPaint& paint; + float x; + float y; + MinikinRect& bounds; + float totalAdvance; +}; + +void Canvas::drawText(const uint16_t* text, int start, int count, int contextCount, + float x, float y, int bidiFlags, const Paint& origPaint, TypefaceImpl* typeface) { + // minikin may modify the original paint + Paint paint(origPaint); + + Layout layout; + MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, start, count, contextCount); + + size_t nGlyphs = layout.nGlyphs(); + std::unique_ptr<uint16_t[]> glyphs(new uint16_t[nGlyphs]); + std::unique_ptr<float[]> pos(new float[nGlyphs * 2]); + + x += MinikinUtils::xOffsetForTextAlign(&paint, layout); + + MinikinRect bounds; + layout.getBounds(&bounds); + if (!drawTextAbsolutePos()) { + bounds.offset(x, y); + } + + DrawTextFunctor f(layout, this, glyphs.get(), pos.get(), + paint, x, y, bounds, layout.getAdvance()); + MinikinUtils::forFontRun(layout, &paint, f); +} + +class DrawTextOnPathFunctor { +public: + DrawTextOnPathFunctor(const Layout& layout, Canvas* canvas, float hOffset, + float vOffset, const Paint& paint, const SkPath& path) + : layout(layout) + , canvas(canvas) + , hOffset(hOffset) + , vOffset(vOffset) + , paint(paint) + , path(path) { + } + + void operator()(size_t start, size_t end) { + uint16_t glyphs[1]; + for (size_t i = start; i < end; i++) { + glyphs[0] = layout.getGlyphId(i); + float x = hOffset + layout.getX(i); + float y = vOffset + layout.getY(i); + canvas->drawGlyphsOnPath(glyphs, 1, path, x, y, paint); + } + } +private: + const Layout& layout; + Canvas* canvas; + float hOffset; + float vOffset; + const Paint& paint; + const SkPath& path; +}; + +void Canvas::drawTextOnPath(const uint16_t* text, int count, int bidiFlags, const SkPath& path, + float hOffset, float vOffset, const Paint& paint, TypefaceImpl* typeface) { + Paint paintCopy(paint); + Layout layout; + MinikinUtils::doLayout(&layout, &paintCopy, bidiFlags, typeface, text, 0, count, count); + hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path); + + // Set align to left for drawing, as we don't want individual + // glyphs centered or right-aligned; the offset above takes + // care of all alignment. + paintCopy.setTextAlign(Paint::kLeft_Align); + + DrawTextOnPathFunctor f(layout, this, hOffset, vOffset, paintCopy, path); + MinikinUtils::forFontRun(layout, &paintCopy, f); +} + +} // namespace android diff --git a/libs/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index 27facdf652cd..d5f7053479ee 100644 --- a/libs/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -59,6 +59,9 @@ class Tree; }; typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; +class Paint; +struct TypefaceImpl; + class ANDROID_API Canvas { public: virtual ~Canvas() {}; @@ -207,12 +210,12 @@ public: * drawText: count is of glyphs * totalAdvance: used to define width of text decorations (underlines, strikethroughs). */ - virtual void drawText(const uint16_t* glyphs, const float* positions, int count, + virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) = 0; /** drawTextOnPath: count is of glyphs */ - virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path, + virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) = 0; /** @@ -229,6 +232,16 @@ public: */ virtual void drawVectorDrawable(VectorDrawableRoot* tree); + /** + * Converts utf16 text to glyphs, calculating position and boundary, + * and delegating the final draw to virtual drawGlyphs method. + */ + void drawText(const uint16_t* text, int start, int count, int contextCount, + float x, float y, int bidiFlags, const Paint& origPaint, TypefaceImpl* typeface); + + void drawTextOnPath(const uint16_t* text, int count, int bidiFlags, const SkPath& path, + float hOffset, float vOffset, const Paint& paint, TypefaceImpl* typeface); + protected: void drawTextDecorations(float x, float y, float length, const SkPaint& paint); }; diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp index 8ac5d4664687..b9e33589885e 100644 --- a/core/jni/android/graphics/MinikinSkia.cpp +++ b/libs/hwui/hwui/MinikinSkia.cpp @@ -14,14 +14,12 @@ * limitations under the License. */ -#include <SkTypeface.h> -#include <SkPaint.h> +#include "MinikinSkia.h" -#define LOG_TAG "Minikin" +#include <SkPaint.h> +#include <SkTypeface.h> #include <cutils/log.h> -#include "MinikinSkia.h" - namespace android { MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) : diff --git a/core/jni/android/graphics/MinikinSkia.h b/libs/hwui/hwui/MinikinSkia.h index 8f469ba01ddd..1d50168adac0 100644 --- a/core/jni/android/graphics/MinikinSkia.h +++ b/libs/hwui/hwui/MinikinSkia.h @@ -17,11 +17,15 @@ #ifndef _ANDROID_GRAPHICS_MINIKIN_SKIA_H_ #define _ANDROID_GRAPHICS_MINIKIN_SKIA_H_ +#include <cutils/compiler.h> #include <minikin/MinikinFont.h> +class SkPaint; +class SkTypeface; + namespace android { -class MinikinFontSkia : public MinikinFont { +class ANDROID_API MinikinFontSkia : public MinikinFont { public: // Note: this takes ownership of the reference (will unref on dtor) explicit MinikinFontSkia(SkTypeface *typeface); diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp index 309d35b90260..f4feee2dd7d9 100644 --- a/core/jni/android/graphics/MinikinUtils.cpp +++ b/libs/hwui/hwui/MinikinUtils.cpp @@ -13,16 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "MinikinUtils.h" -#define LOG_TAG "Minikin" -#include <cutils/log.h> -#include <string> - -#include "SkPathMeasure.h" #include "Paint.h" +#include "SkPathMeasure.h" #include "TypefaceImpl.h" -#include "MinikinUtils.h" +#include <cutils/log.h> +#include <string> namespace android { diff --git a/core/jni/android/graphics/MinikinUtils.h b/libs/hwui/hwui/MinikinUtils.h index 91525397b2ba..4a49581c4751 100644 --- a/core/jni/android/graphics/MinikinUtils.h +++ b/libs/hwui/hwui/MinikinUtils.h @@ -24,6 +24,7 @@ #ifndef _ANDROID_GRAPHICS_MINIKIN_UTILS_H_ #define _ANDROID_GRAPHICS_MINIKIN_UTILS_H_ +#include <cutils/compiler.h> #include <minikin/Layout.h> #include "Paint.h" #include "MinikinSkia.h" @@ -33,24 +34,24 @@ namespace android { class MinikinUtils { public: - static FontStyle prepareMinikinPaint(MinikinPaint* minikinPaint, FontCollection** pFont, + ANDROID_API static FontStyle prepareMinikinPaint(MinikinPaint* minikinPaint, FontCollection** pFont, const Paint* paint, TypefaceImpl* typeface); - static void doLayout(Layout* layout, const Paint* paint, int bidiFlags, + ANDROID_API static void doLayout(Layout* layout, const Paint* paint, int bidiFlags, TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize); - static float measureText(const Paint* paint, int bidiFlags, TypefaceImpl* typeface, + ANDROID_API static float measureText(const Paint* paint, int bidiFlags, TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize, float *advances); - static bool hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs); + ANDROID_API static bool hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs); - static float xOffsetForTextAlign(Paint* paint, const Layout& layout); + ANDROID_API static float xOffsetForTextAlign(Paint* paint, const Layout& layout); - static float hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path); + ANDROID_API static float hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path); // f is a functor of type void f(size_t start, size_t end); template <typename F> - static void forFontRun(const Layout& layout, Paint* paint, F& f) { + ANDROID_API static void forFontRun(const Layout& layout, Paint* paint, F& f) { float saveSkewX = paint->getTextSkewX(); bool savefakeBold = paint->isFakeBoldText(); MinikinFont* curFont = NULL; diff --git a/core/jni/android/graphics/Paint.h b/libs/hwui/hwui/Paint.h index cb6e622ccced..69c321ca0caa 100644 --- a/core/jni/android/graphics/Paint.h +++ b/libs/hwui/hwui/Paint.h @@ -17,6 +17,8 @@ #ifndef ANDROID_GRAPHICS_PAINT_H_ #define ANDROID_GRAPHICS_PAINT_H_ +#include <cutils/compiler.h> + #include <SkPaint.h> #include <string> @@ -24,7 +26,7 @@ namespace android { -class Paint : public SkPaint { +class ANDROID_API Paint : public SkPaint { public: Paint(); Paint(const Paint& paint); @@ -45,7 +47,7 @@ public: return mLetterSpacing; } - void setFontFeatureSettings(const std::string &fontFeatureSettings) { + void setFontFeatureSettings(const std::string& fontFeatureSettings) { mFontFeatureSettings = fontFeatureSettings; } diff --git a/core/jni/android/graphics/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp index bd513ae60823..1172a0e044b1 100644 --- a/core/jni/android/graphics/PaintImpl.cpp +++ b/libs/hwui/hwui/PaintImpl.cpp @@ -15,10 +15,6 @@ */ #include "Paint.h" -#include <SkPaint.h> - -#define LOG_TAG "Paint" -#include <cutils/log.h> namespace android { diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/libs/hwui/hwui/TypefaceImpl.cpp index da56290c94f9..f14381b346c0 100644 --- a/core/jni/android/graphics/TypefaceImpl.cpp +++ b/libs/hwui/hwui/TypefaceImpl.cpp @@ -20,21 +20,16 @@ * being, that choice is hidden under the USE_MINIKIN compile-time flag. */ -#define LOG_TAG "TypefaceImpl" - -#include "jni.h" // for jlong, remove when being passed proper type +#include "TypefaceImpl.h" +#include "MinikinSkia.h" #include "SkTypeface.h" +#include "SkPaint.h" -#include <vector> #include <minikin/FontCollection.h> #include <minikin/FontFamily.h> #include <minikin/Layout.h> -#include "SkPaint.h" -#include "MinikinSkia.h" - -#include "TypefaceImpl.h" -#include "Utils.h" +#include <utils/Log.h> namespace android { @@ -133,15 +128,10 @@ TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int weight) { return result; } -TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) { - std::vector<FontFamily *>familyVec; - for (size_t i = 0; i < size; i++) { - FontFamily* family = reinterpret_cast<FontFamily*>(families[i]); - familyVec.push_back(family); - } +TypefaceImpl* TypefaceImpl_createFromFamilies(const std::vector<FontFamily*>& families) { TypefaceImpl* result = new TypefaceImpl; - result->fFontCollection = new FontCollection(familyVec); - if (size == 0) { + result->fFontCollection = new FontCollection(families); + if (families.empty()) { ALOGW("createFromFamilies creating empty collection"); result->fSkiaStyle = SkTypeface::kNormal; } else { diff --git a/core/jni/android/graphics/TypefaceImpl.h b/libs/hwui/hwui/TypefaceImpl.h index 4b14917eaaf2..01f1e83f9572 100644 --- a/core/jni/android/graphics/TypefaceImpl.h +++ b/libs/hwui/hwui/TypefaceImpl.h @@ -18,15 +18,15 @@ #ifndef _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_ #define _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_ -#include "jni.h" // for jlong, eventually remove #include "SkTypeface.h" -#include <androidfw/AssetManager.h> +#include <cutils/compiler.h> #include <minikin/FontCollection.h> +#include <vector> namespace android { -struct TypefaceImpl { +struct ANDROID_API TypefaceImpl { FontCollection *fFontCollection; // style used for constructing and querying Typeface objects @@ -44,21 +44,19 @@ struct TypefaceImpl { // is just a pointer to SkTypeface, in the non-USE_MINIKIN case. // TODO: when #ifdef USE_MINIKIN is removed, move to member functions. -TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src); +ANDROID_API TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src); -TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style); +ANDROID_API TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style); -TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int baseweight); +ANDROID_API TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int baseweight); -// When we remove the USE_MINIKIN ifdef, probably a good idea to move the casting -// (from jlong to FontFamily*) to the caller in Typeface.cpp. -TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size); +ANDROID_API TypefaceImpl* TypefaceImpl_createFromFamilies(const std::vector<FontFamily*>& families); -void TypefaceImpl_unref(TypefaceImpl* face); +ANDROID_API void TypefaceImpl_unref(TypefaceImpl* face); -int TypefaceImpl_getStyle(TypefaceImpl* face); +ANDROID_API int TypefaceImpl_getStyle(TypefaceImpl* face); -void TypefaceImpl_setDefault(TypefaceImpl* face); +ANDROID_API void TypefaceImpl_setDefault(TypefaceImpl* face); } diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk index 7d4ef0f1f31e..299095217a8d 100644 --- a/libs/hwui/hwui_static_deps.mk +++ b/libs/hwui/hwui_static_deps.mk @@ -21,8 +21,11 @@ LOCAL_SHARED_LIBRARIES += \ libskia \ libui \ libgui \ - libprotobuf-cpp-lite + libprotobuf-cpp-lite \ + libharfbuzz_ng \ + libft2 \ + libminikin ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT)) LOCAL_SHARED_LIBRARIES += libRS libRScpp -endif
\ No newline at end of file +endif diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index c539d63daed3..31eec8cf3173 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -19,7 +19,6 @@ #include "AnimationContext.h" #include "Caches.h" -#include "Canvas.h" #include "DeferredLayerUpdater.h" #include "EglManager.h" #include "LayerUpdateQueue.h" @@ -27,6 +26,7 @@ #include "OpenGLRenderer.h" #include "Properties.h" #include "RenderThread.h" +#include "hwui/Canvas.h" #include "renderstate/RenderState.h" #include "renderstate/Stencil.h" #include "protos/hwui.pb.h" diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index c809ff4f85e8..a4aee61a7b11 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -87,7 +87,7 @@ void TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text, *outTotalAdvance = totalAdvance; } -void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text, +void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text, const SkPaint& paint, float x, float y) { // drawing text requires GlyphID TextEncoding (which JNI layer would have done) LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding, @@ -113,11 +113,11 @@ void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text, // Force left alignment, since alignment offset is already baked in SkPaint alignPaintCopy(paint); alignPaintCopy.setTextAlign(SkPaint::kLeft_Align); - canvas->drawText(glyphs.data(), positions.data(), glyphs.size(), alignPaintCopy, x, y, + canvas->drawGlyphs(glyphs.data(), positions.data(), glyphs.size(), alignPaintCopy, x, y, bounds.left, bounds.top, bounds.right, bounds.bottom, totalAdvance); } -void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text, +void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text, const SkPaint& paint, const SkPath& path) { // drawing text requires GlyphID TextEncoding (which JNI layer would have done) LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding, @@ -130,7 +130,7 @@ void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text, SkUnichar unichar = SkUTF8_NextUnichar(&text); glyphs.push_back(autoCache.getCache()->unicharToGlyph(unichar)); } - canvas->drawTextOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint); + canvas->drawGlyphsOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint); } void TestUtils::TestTask::run() { @@ -143,5 +143,13 @@ void TestUtils::TestTask::run() { renderState.onGLContextDestroyed(); } +std::unique_ptr<uint16_t[]> TestUtils::utf8ToUtf16(const char* str) { + const size_t strLen = strlen(str); + const ssize_t utf16Len = utf8_to_utf16_length((uint8_t*) str, strLen); + std::unique_ptr<uint16_t[]> dst(new uint16_t[utf16Len + 1]); + utf8_to_utf16((uint8_t*) str, strLen, (char16_t*) dst.get()); + return dst; +} + } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index 28ac1166fc5c..a5e7a5fb808c 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -207,12 +207,14 @@ public: std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions, float* outTotalAdvance, Rect* outBounds); - static void drawTextToCanvas(TestCanvas* canvas, const char* text, + static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text, const SkPaint& paint, float x, float y); - static void drawTextToCanvas(TestCanvas* canvas, const char* text, + static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text, const SkPaint& paint, const SkPath& path); + static std::unique_ptr<uint16_t[]> utf8ToUtf16(const char* str); + private: static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) { node->syncProperties(); diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp index 43e247e68bc0..ab368c059de0 100644 --- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp +++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp @@ -136,9 +136,9 @@ private: textPaint.setAntiAlias(true); char buf[256]; snprintf(buf, sizeof(buf), "This card is #%d", cardId); - TestUtils::drawTextToCanvas(&canvas, buf, textPaint, cardHeight, dp(25)); + TestUtils::drawUtf8ToCanvas(&canvas, buf, textPaint, cardHeight, dp(25)); textPaint.setTextSize(dp(15)); - TestUtils::drawTextToCanvas(&canvas, "This is some more text on the card", textPaint, + TestUtils::drawUtf8ToCanvas(&canvas, "This is some more text on the card", textPaint, cardHeight, dp(45)); canvas.drawBitmap(createRandomCharIcon(), dp(10), dp(10), nullptr); diff --git a/libs/hwui/tests/common/scenes/TextAnimation.cpp b/libs/hwui/tests/common/scenes/TextAnimation.cpp index 1823db2940aa..be8f48b9fd17 100644 --- a/libs/hwui/tests/common/scenes/TextAnimation.cpp +++ b/libs/hwui/tests/common/scenes/TextAnimation.cpp @@ -39,14 +39,14 @@ public: paint.setColor(Color::Black); for (int i = 0; i < 10; i++) { - TestUtils::drawTextToCanvas(&canvas, "Test string", paint, 400, i * 100); + TestUtils::drawUtf8ToCanvas(&canvas, "Test string", paint, 400, i * 100); } SkPath path; path.addOval(SkRect::MakeLTRB(100, 100, 300, 300)); paint.setColor(Color::Blue_500); - TestUtils::drawTextToCanvas(&canvas, "This is a neat circle of text!", paint, path); + TestUtils::drawUtf8ToCanvas(&canvas, "This is a neat circle of text!", paint, path); }); canvas.drawRenderNode(card.get()); } diff --git a/libs/hwui/tests/unit/CanvasStateTests.cpp b/libs/hwui/tests/unit/CanvasStateTests.cpp index 68d74ee1e91d..0afabd83f5cc 100644 --- a/libs/hwui/tests/unit/CanvasStateTests.cpp +++ b/libs/hwui/tests/unit/CanvasStateTests.cpp @@ -16,9 +16,9 @@ #include "CanvasState.h" -#include "Canvas.h" #include "Matrix.h" #include "Rect.h" +#include "hwui/Canvas.h" #include "utils/LinearAllocator.h" #include <gtest/gtest.h> diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp index 31555f2f86ec..a467b5c15560 100644 --- a/libs/hwui/tests/unit/FrameBuilderTests.cpp +++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp @@ -274,8 +274,8 @@ TEST(FrameBuilder, textMerging) { paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); paint.setAntiAlias(true); paint.setTextSize(50); - TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 0); // will be top clipped - TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 100); // not clipped + TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 0); // will be top clipped + TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100); // not clipped }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400, TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); @@ -305,7 +305,7 @@ TEST(FrameBuilder, textStrikethrough) { textPaint.setStrikeThruText(true); textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); for (int i = 0; i < LOOPS; i++) { - TestUtils::drawTextToCanvas(&canvas, "test text", textPaint, 10, 100 * (i + 1)); + TestUtils::drawUtf8ToCanvas(&canvas, "test text", textPaint, 10, 100 * (i + 1)); } }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 2000), 200, 2000, @@ -361,7 +361,7 @@ TEST(FrameBuilder, textStyle) { // They'll get merged, but with for (auto style : styles) { paint.setStyle(style); - TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 100); + TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100); } }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400, diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp index e6d84c6681f1..6ab5110aaa9a 100644 --- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp +++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp @@ -18,6 +18,8 @@ #include <RecordedOp.h> #include <RecordingCanvas.h> +#include <hwui/Paint.h> +#include <minikin/Layout.h> #include <tests/common/TestUtils.h> #include <utils/Color.h> @@ -131,13 +133,13 @@ TEST(RecordingCanvas, drawRoundRect) { << "Non-rounded rects should be converted"; } -TEST(RecordingCanvas, drawText) { +TEST(RecordingCanvas, drawGlyphs) { auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(20); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25); + TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); }); int count = 0; @@ -152,7 +154,7 @@ TEST(RecordingCanvas, drawText) { ASSERT_EQ(1, count); } -TEST(RecordingCanvas, drawText_strikeThruAndUnderline) { +TEST(RecordingCanvas, drawGlyphs_strikeThruAndUnderline) { auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { SkPaint paint; paint.setAntiAlias(true); @@ -162,7 +164,7 @@ TEST(RecordingCanvas, drawText_strikeThruAndUnderline) { for (int j = 0; j < 2; j++) { paint.setUnderlineText(i != 0); paint.setStrikeThruText(j != 0); - TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25); + TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); } } }); @@ -184,18 +186,18 @@ TEST(RecordingCanvas, drawText_strikeThruAndUnderline) { EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId); // strikethrough } -TEST(RecordingCanvas, drawText_forceAlignLeft) { +TEST(RecordingCanvas, drawGlyphs_forceAlignLeft) { auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(20); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); paint.setTextAlign(SkPaint::kLeft_Align); - TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25); + TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); paint.setTextAlign(SkPaint::kCenter_Align); - TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25); + TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); paint.setTextAlign(SkPaint::kRight_Align); - TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25); + TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); }); int count = 0; @@ -576,7 +578,7 @@ TEST(RecordingCanvas, refPaint) { canvas.drawRect(0, 0, 200, 10, paint); SkPaint paintCopy(paint); canvas.drawRect(0, 10, 200, 20, paintCopy); - TestUtils::drawTextToCanvas(&canvas, "helloworld", paint, 50, 25); + TestUtils::drawUtf8ToCanvas(&canvas, "helloworld", paint, 50, 25); // only here do we use different paint ptr paint.setColor(SK_ColorRED); @@ -597,5 +599,54 @@ TEST(RecordingCanvas, refPaint) { EXPECT_NE(&paint, ops[3]->paint); } +TEST(RecordingCanvas, drawText) { + auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { + Paint paint; + paint.setAntiAlias(true); + paint.setTextSize(20); + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO"); + canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL); + }); + + int count = 0; + playbackOps(*dl, [&count](const RecordedOp& op) { + count++; + ASSERT_EQ(RecordedOpId::TextOp, op.opId); + EXPECT_EQ(nullptr, op.localClip); + EXPECT_TRUE(op.localMatrix.isIdentity()); + EXPECT_TRUE(op.unmappedBounds.getHeight() >= 10); + EXPECT_TRUE(op.unmappedBounds.getWidth() >= 25); + }); + ASSERT_EQ(1, count); +} + +TEST(RecordingCanvas, drawTextInHighContrast) { + auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { + canvas.setHighContrastText(true); + Paint paint; + paint.setColor(SK_ColorWHITE); + paint.setAntiAlias(true); + paint.setTextSize(20); + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO"); + canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL); + }); + + int count = 0; + playbackOps(*dl, [&count](const RecordedOp& op) { + ASSERT_EQ(RecordedOpId::TextOp, op.opId); + if (count++ == 0) { + EXPECT_EQ(SK_ColorBLACK, op.paint->getColor()); + EXPECT_EQ(SkPaint::kStrokeAndFill_Style, op.paint->getStyle()); + } else { + EXPECT_EQ(SK_ColorWHITE, op.paint->getColor()); + EXPECT_EQ(SkPaint::kFill_Style, op.paint->getStyle()); + } + + }); + ASSERT_EQ(2, count); +} + } // namespace uirenderer } // namespace android |