diff options
author | 2018-02-05 18:04:11 -0500 | |
---|---|---|
committer | 2018-02-08 23:04:47 +0000 | |
commit | 7717e22c85fd2eaba39f1dc38c65fb7f723882f4 (patch) | |
tree | 36a98afb1180490da3e2db3e0e54344ed4a39b86 | |
parent | fcd3c57e194ba0fafa2de673f2d4fae6a05ef91e (diff) |
Draw text with a hairline stroke as if it is fill style
Dew to a side effect of HWUI opengl pipeline, the hairline stroke
is not respected, but it is drawn as a fill style. Implement the
same behaviour for skiagl pipeline with SDK API 27 and older.
On SDK released with Android P, the hairline stroke is respected.
Bug: 72494357
Test: Ran duolingo app
Change-Id: I48bdcf3ddec4bf65b5e93e01c5002177c4e3da90
-rw-r--r-- | core/java/android/view/View.java | 1 | ||||
-rw-r--r-- | core/jni/android_graphics_Canvas.cpp | 6 | ||||
-rw-r--r-- | graphics/java/android/graphics/Canvas.java | 4 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/hwui/Canvas.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/hwui/Canvas.h | 10 |
6 files changed, 33 insertions, 0 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 0910c117c17c..5de25bae6a3e 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4806,6 +4806,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Canvas.sCompatibilityRestore = targetSdkVersion < Build.VERSION_CODES.M; Canvas.sCompatibilitySetBitmap = targetSdkVersion < Build.VERSION_CODES.O; + Canvas.setCompatibilityVersion(targetSdkVersion); // In M and newer, our widgets can pass a "hint" value in the size // for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index 6b961f54cf88..06de5daab7d2 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -573,6 +573,11 @@ static void freeTextLayoutCaches(JNIEnv* env, jobject) { minikin::Layout::purgeCaches(); } +static void setCompatibilityVersion(JNIEnv* env, jobject, jint apiLevel) { + Canvas::setCompatibilityVersion(apiLevel); +} + + }; // namespace CanvasJNI static const JNINativeMethod gMethods[] = { @@ -580,6 +585,7 @@ static const JNINativeMethod gMethods[] = { {"nInitRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster}, {"nFreeCaches", "()V", (void*) CanvasJNI::freeCaches}, {"nFreeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches}, + {"nSetCompatibilityVersion", "(I)V", (void*) CanvasJNI::setCompatibilityVersion}, // ------------ @FastNative ---------------- {"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap}, diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index f5e863305766..d925441e3657 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1219,10 +1219,14 @@ public class Canvas extends BaseCanvas { nFreeTextLayoutCaches(); } + /** @hide */ + public static void setCompatibilityVersion(int apiLevel) { nSetCompatibilityVersion(apiLevel); } + private static native void nFreeCaches(); private static native void nFreeTextLayoutCaches(); private static native long nInitRaster(Bitmap bitmap); private static native long nGetNativeFinalizer(); + private static native void nSetCompatibilityVersion(int apiLevel); // ---------------- @FastNative ------------------- diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 9e0d10d07892..2b0b22df7edf 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -742,6 +742,12 @@ void SkiaCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& p SkPaint paintCopy(paint); paintCopy.setTextAlign(SkPaint::kLeft_Align); SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding); + // Stroke with a hairline is drawn on HW with a fill style for compatibility with Android O and + // older. + if (!mCanvasOwned && sApiLevel <= 27 && paintCopy.getStrokeWidth() <= 0 + && paintCopy.getStyle() == SkPaint::kStroke_Style) { + paintCopy.setStyle(SkPaint::kFill_Style); + } SkRect bounds = SkRect::MakeLTRB(boundsLeft + x, boundsTop + y, boundsRight + x, boundsBottom + y); diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp index 284fd836745c..ad4c8be74d75 100644 --- a/libs/hwui/hwui/Canvas.cpp +++ b/libs/hwui/hwui/Canvas.cpp @@ -225,4 +225,10 @@ void Canvas::drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiF MinikinUtils::forFontRun(layout, &paintCopy, f); } +int Canvas::sApiLevel = 1; + +void Canvas::setCompatibilityVersion(int apiLevel) { + sApiLevel = apiLevel; +} + } // namespace android diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index 3ddf1c48b83f..fabb8d2e4549 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -116,6 +116,14 @@ public: static Canvas* create_canvas(SkCanvas* skiaCanvas); /** + * Sets the target SDK version used to build the app. + * + * @param apiLevel API level + * + */ + static void setCompatibilityVersion(int apiLevel); + + /** * Provides a Skia SkCanvas interface that acts as a proxy to this Canvas. * It is useful for testing and clients (e.g. Picture/Movie) that expect to * draw their contents into an SkCanvas. @@ -282,6 +290,8 @@ protected: virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset, const SkPaint& paint, const SkPath& path, size_t start, size_t end) = 0; + static int sApiLevel; + friend class DrawTextFunctor; friend class DrawTextOnPathFunctor; friend class uirenderer::SkiaCanvasProxy; |