Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf10ff6a authored by Tyler Freeman's avatar Tyler Freeman Committed by Android (Google) Code Review
Browse files

Merge "fix(high contrast text): fix solid rectangle background obscuring other...

Merge "fix(high contrast text): fix solid rectangle background obscuring other text in the same layout pass" into main
parents 3dfbebd5 73566bbb
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@

#include <SkFontMetrics.h>
#include <SkRRect.h>
#include <minikin/MinikinRect.h>

#include "FeatureFlags.h"
#include "MinikinUtils.h"
@@ -108,13 +107,7 @@ void Canvas::drawText(const uint16_t* text, int textSize, int start, int count,
    // care of all alignment.
    paint.setTextAlign(Paint::kLeft_Align);

    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);
    DrawTextFunctor f(layout, this, paint, x, y, layout.getAdvance());
    MinikinUtils::forFontRun(layout, &paint, f);

    if (text_feature::fix_double_underline()) {
+29 −10
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include <SkFontMetrics.h>
#include <SkRRect.h>
#include <SkTextBlob.h>
#include <com_android_graphics_hwui_flags.h>

#include "../utils/Color.h"
@@ -66,7 +67,7 @@ public:
     * @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, const minikin::MinikinRect& bounds)
                    float y, float totalAdvance)
            : layout(layout)
            , canvas(canvas)
            , paint(paint)
@@ -74,8 +75,7 @@ public:
            , y(y)
            , totalAdvance(totalAdvance)
            , underlinePosition(0)
            , underlineThickness(0)
            , bounds(bounds) {}
            , underlineThickness(0) {}

    void operator()(size_t start, size_t end) {
        auto glyphFunc = [&](uint16_t* text, float* positions) {
@@ -106,12 +106,32 @@ public:
            simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint);
            outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style);
            if (flags::high_contrast_text_small_text_rect()) {
                auto bgBounds(bounds);
                auto padding = kHighContrastTextBorderWidth + 0.1f * paint.getSkFont().getSize();
                const SkFont& font = paint.getSkFont();
                auto padding = kHighContrastTextBorderWidth + 0.1f * font.getSize();

                // Draw the background only behind each glyph's bounds. We do this instead of using
                // the bounds of the entire layout, because the layout includes alignment whitespace
                // etc which can obscure other text from separate passes (e.g. emojis).
                // Merge all the glyph bounds into one rect for this line, since drawing a rect for
                // each glyph is expensive.
                SkRect glyphBounds;
                SkRect bgBounds;
                for (size_t i = start; i < end; i++) {
                    auto glyph = layout.getGlyphId(i);

                    font.getBounds(reinterpret_cast<const SkGlyphID*>(&glyph), 1, &glyphBounds,
                                   &paint);
                    glyphBounds.offset(layout.getX(i), layout.getY(i));

                    bgBounds.join(glyphBounds);
                }

                if (!bgBounds.isEmpty()) {
                    bgBounds.offset(x, y);
                canvas->drawRect(bgBounds.mLeft - padding, bgBounds.mTop - padding,
                                 bgBounds.mRight + padding, bgBounds.mBottom + padding,
                                 outlinePaint);
                    bgBounds.outset(padding, padding);
                    canvas->drawRect(bgBounds.fLeft, bgBounds.fTop, bgBounds.fRight,
                                     bgBounds.fBottom, outlinePaint);
                }
            } else {
                canvas->drawGlyphs(glyphFunc, glyphCount, outlinePaint, x, y, totalAdvance);
            }
@@ -169,7 +189,6 @@ private:
    float totalAdvance;
    float underlinePosition;
    float underlineThickness;
    const minikin::MinikinRect& bounds;
};

}  // namespace android
+1 −2
Original line number Diff line number Diff line
@@ -103,9 +103,8 @@ 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(), bounds);
    DrawTextFunctor f(layout, &canvas, *paint, 0, 0, layout.getAdvance());
    MinikinUtils::forFontRun(layout, paint, f);
    return f;
}