summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Stan Iliev <stani@google.com> 2018-02-05 18:04:11 -0500
committer Stan Iliev <stani@google.com> 2018-02-08 23:04:47 +0000
commit7717e22c85fd2eaba39f1dc38c65fb7f723882f4 (patch)
tree36a98afb1180490da3e2db3e0e54344ed4a39b86
parentfcd3c57e194ba0fafa2de673f2d4fae6a05ef91e (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.java1
-rw-r--r--core/jni/android_graphics_Canvas.cpp6
-rw-r--r--graphics/java/android/graphics/Canvas.java4
-rw-r--r--libs/hwui/SkiaCanvas.cpp6
-rw-r--r--libs/hwui/hwui/Canvas.cpp6
-rw-r--r--libs/hwui/hwui/Canvas.h10
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;