diff options
author | 2023-10-13 18:49:11 +0000 | |
---|---|---|
committer | 2024-01-10 18:47:58 +0000 | |
commit | 47ad8548925da77d012ea48c6807dbbce124d09f (patch) | |
tree | 6947e7de10ee716427fc4c61962400fcdabec180 | |
parent | 2e11589a397c4a64a43f3606d2d33c1d7e19898b (diff) |
fix(high contrast text): draw a solid rectangle background behind text instead of a stroke border
Bug: 186567103
Flag: com.android.graphics.hwui.flags.high_contrast_text_small_text_rect
Test: manual
1. adb shell setenforce 0 && adb shell setprop persist.device_config.aconfig_flags.accessibility.com.android.graphics.hwui.flags.high_contrast_text_small_text_rect true && adb shell stop && adb shell start
2. Settings -> Accessibility -> Display Size and Text
3. Turn on High Contrast Text
Change-Id: Ib2ef3925acc89b01c71addb63194d2a403c99cb6
-rw-r--r-- | libs/hwui/aconfig/hwui_flags.aconfig | 7 | ||||
-rw-r--r-- | libs/hwui/hwui/Canvas.cpp | 9 | ||||
-rw-r--r-- | libs/hwui/hwui/DrawTextFunctor.h | 32 | ||||
-rw-r--r-- | libs/hwui/tests/unit/UnderlineTest.cpp | 3 |
4 files changed, 45 insertions, 6 deletions
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index c156c46a5a9b..72ddeccd26b2 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -22,6 +22,13 @@ flag { } flag { + name: "high_contrast_text_small_text_rect" + namespace: "accessibility" + description: "Draw a solid rectangle background behind text instead of a stroke outline" + bug: "186567103" +} + +flag { name: "hdr_10bit_plus" namespace: "core_graphics" description: "Use 10101010 and FP16 formats for HDR-UI when available" diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp index 80b6c0385fca..e9f4b81c7624 100644 --- a/libs/hwui/hwui/Canvas.cpp +++ b/libs/hwui/hwui/Canvas.cpp @@ -18,6 +18,7 @@ #include <SkFontMetrics.h> #include <SkRRect.h> +#include <minikin/MinikinRect.h> #include "FeatureFlags.h" #include "MinikinUtils.h" @@ -107,7 +108,13 @@ void Canvas::drawText(const uint16_t* text, int textSize, int start, int count, // care of all alignment. paint.setTextAlign(Paint::kLeft_Align); - DrawTextFunctor f(layout, this, paint, x, y, layout.getAdvance()); + minikin::MinikinRect bounds; + // We only need the bounds to draw a rectangular background in high contrast mode. Let's save + // the cycles otherwise. + if (flags::high_contrast_text_small_text_rect() && isHighContrastText()) { + MinikinUtils::getBounds(&paint, bidiFlags, typeface, text, textSize, &bounds); + } + DrawTextFunctor f(layout, this, paint, x, y, layout.getAdvance(), bounds); MinikinUtils::forFontRun(layout, &paint, f); if (text_feature::fix_double_underline()) { diff --git a/libs/hwui/hwui/DrawTextFunctor.h b/libs/hwui/hwui/DrawTextFunctor.h index 8f999904a8ab..ba6543988a7b 100644 --- a/libs/hwui/hwui/DrawTextFunctor.h +++ b/libs/hwui/hwui/DrawTextFunctor.h @@ -33,6 +33,8 @@ namespace flags = com::android::graphics::hwui::flags; namespace android { +inline constexpr int kHighContrastTextBorderWidth = 4; + static inline void drawStroke(SkScalar left, SkScalar right, SkScalar top, SkScalar thickness, const Paint& paint, Canvas* canvas) { const SkScalar strokeWidth = fmax(thickness, 1.0f); @@ -45,15 +47,26 @@ static void simplifyPaint(int color, Paint* paint) { paint->setShader(nullptr); paint->setColorFilter(nullptr); paint->setLooper(nullptr); - paint->setStrokeWidth(4 + 0.04 * paint->getSkFont().getSize()); + paint->setStrokeWidth(kHighContrastTextBorderWidth + 0.04 * paint->getSkFont().getSize()); paint->setStrokeJoin(SkPaint::kRound_Join); paint->setLooper(nullptr); } class DrawTextFunctor { public: + /** + * Creates a Functor to draw the given text layout. + * + * @param layout + * @param canvas + * @param paint + * @param x + * @param y + * @param totalAdvance + * @param bounds bounds of the text. Only required if high contrast text mode is enabled. + */ DrawTextFunctor(const minikin::Layout& layout, Canvas* canvas, const Paint& paint, float x, - float y, float totalAdvance) + float y, float totalAdvance, const minikin::MinikinRect& bounds) : layout(layout) , canvas(canvas) , paint(paint) @@ -61,7 +74,8 @@ public: , y(y) , totalAdvance(totalAdvance) , underlinePosition(0) - , underlineThickness(0) {} + , underlineThickness(0) + , bounds(bounds) {} void operator()(size_t start, size_t end) { auto glyphFunc = [&](uint16_t* text, float* positions) { @@ -91,7 +105,16 @@ public: Paint outlinePaint(paint); simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint); outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style); - canvas->drawGlyphs(glyphFunc, glyphCount, outlinePaint, x, y, totalAdvance); + if (flags::high_contrast_text_small_text_rect()) { + auto bgBounds(bounds); + auto padding = kHighContrastTextBorderWidth + 0.1f * paint.getSkFont().getSize(); + bgBounds.offset(x, y); + canvas->drawRect(bgBounds.mLeft - padding, bgBounds.mTop - padding, + bgBounds.mRight + padding, bgBounds.mBottom + padding, + outlinePaint); + } else { + canvas->drawGlyphs(glyphFunc, glyphCount, outlinePaint, x, y, totalAdvance); + } // inner gDrawTextBlobMode = DrawTextBlobMode::HctInner; @@ -146,6 +169,7 @@ private: float totalAdvance; float underlinePosition; float underlineThickness; + const minikin::MinikinRect& bounds; }; } // namespace android diff --git a/libs/hwui/tests/unit/UnderlineTest.cpp b/libs/hwui/tests/unit/UnderlineTest.cpp index c70a30477ecf..9911bfa70443 100644 --- a/libs/hwui/tests/unit/UnderlineTest.cpp +++ b/libs/hwui/tests/unit/UnderlineTest.cpp @@ -103,8 +103,9 @@ DrawTextFunctor processFunctor(const std::vector<uint16_t>& text, Paint* paint) // Create minikin::Layout std::unique_ptr<Typeface> typeface(makeTypeface()); minikin::Layout layout = doLayout(text, *paint, typeface.get()); + minikin::MinikinRect bounds; - DrawTextFunctor f(layout, &canvas, *paint, 0, 0, layout.getAdvance()); + DrawTextFunctor f(layout, &canvas, *paint, 0, 0, layout.getAdvance(), bounds); MinikinUtils::forFontRun(layout, paint, f); return f; } |