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

Commit 9af20d58 authored by Yuqian Li's avatar Yuqian Li Committed by Android (Google) Code Review
Browse files

Merge "More efficient text rendering on path"

parents 3dd05bf6 afc22149
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include "RecordedOp.h"
#include "RenderNode.h"
#include "VectorDrawable.h"
#include "hwui/MinikinUtils.h"

namespace android {
namespace uirenderer {
@@ -541,14 +542,20 @@ void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions,
    drawTextDecorations(x, y, totalAdvance, paint);
}

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);
void RecordingCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
        const SkPaint& paint, const SkPath& path, 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);
        if (PaintUtils::paintWillNotDrawText(paint)) return;
        const uint16_t* tempGlyphs = refBuffer<glyph_t>(glyphs, 1);
        addOp(alloc().create_trivial<TextOnPathOp>(
                *(mState.currentSnapshot()->transform),
                getRecordedClip(),
            refPaint(&paint), glyphs, glyphCount, refPath(&path), hOffset, vOffset));
                refPaint(&paint), tempGlyphs, 1, refPath(&path), x, y));
    }
}

void RecordingCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
+2 −2
Original line number Diff line number Diff line
@@ -196,8 +196,8 @@ protected:
            const SkPaint& paint, float x, float y,
            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
            float totalAdvance) override;
    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
            float hOffset, float vOffset, const SkPaint& paint) override;
    virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
            const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;

private:
    const ClipBase* getRecordedClip() {
+28 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include "CanvasProperty.h"
#include "VectorDrawable.h"
#include "hwui/MinikinUtils.h"

#include <SkDrawable.h>
#include <SkDevice.h>
@@ -25,6 +26,7 @@
#include <SkDrawFilter.h>
#include <SkGraphics.h>
#include <SkImage.h>
#include <SkRSXform.h>
#include <SkShader.h>
#include <SkTemplates.h>

@@ -624,9 +626,32 @@ void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int co
    drawTextDecorations(x, y, totalAdvance, paint);
}

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);
void SkiaCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
        const SkPaint& paint, const SkPath& path, size_t start, size_t end) {
    const int N = end - start;
    SkAutoSMalloc<1024> storage(N * (sizeof(uint16_t) + sizeof(SkRSXform)));
    SkRSXform* xform = (SkRSXform*)storage.get();
    uint16_t* glyphs = (uint16_t*)(xform + N);
    SkPathMeasure meas(path, false);

    for (size_t i = start; i < end; i++) {
        glyphs[i - start] = layout.getGlyphId(i);
        float x = hOffset + layout.getX(i);
        float y = vOffset + layout.getY(i);

        SkPoint pos;
        SkVector tan;
        if (!meas.getPosTan(x, &pos, &tan)) {
            pos.set(x, y);
            tan.set(1, 0);
        }
        xform[i - start].fSCos = tan.x();
        xform[i - start].fSSin = tan.y();
        xform[i - start].fTx   = pos.x() - tan.y() * y;
        xform[i - start].fTy   = pos.y() + tan.x() * y;
    }

    this->asSkCanvas()->drawTextRSXform(glyphs, sizeof(uint16_t) * N, xform, nullptr, paint);
}

// ----------------------------------------------------------------------------
+2 −2
Original line number Diff line number Diff line
@@ -161,8 +161,8 @@ protected:
            const SkPaint& paint, float x, float y,
            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
            float totalAdvance) override;
    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
            float hOffset, float vOffset, const SkPaint& paint) override;
    virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
            const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;

private:
    struct SaveRec {
+19 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <SkPixelRef.h>
#include <SkRect.h>
#include <SkRRect.h>
#include <SkRSXform.h>
#include <SkSurface.h>

#include <memory>
@@ -348,11 +349,26 @@ void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const

void SkiaCanvasProxy::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
        const SkMatrix* matrix, const SkPaint& origPaint) {
    // convert to glyphIDs if necessary
    GlyphIDConverter glyphs(text, byteLength, origPaint);
    mCanvas->drawGlyphsOnPath(glyphs.glyphIDs, glyphs.count, path, 0, 0, glyphs.paint);
    SkDEBUGFAIL("SkiaCanvasProxy::onDrawTextOnPath is not supported");
}

void SkiaCanvasProxy::onDrawTextRSXform(const void* text, size_t byteLength,
        const SkRSXform xform[], const SkRect* cullRect, const SkPaint& paint) {
    GlyphIDConverter glyphs(text, byteLength, paint); // Just get count
    SkMatrix localM, currM, origM;
    mCanvas->getMatrix(&currM);
    origM = currM;
    for (int i = 0; i < glyphs.count; i++) {
        localM.setRSXform(*xform++);
        currM.setConcat(origM, localM);
        mCanvas->setMatrix(currM);
        this->onDrawText((char*)text + (byteLength / glyphs.count * i),
                         byteLength / glyphs.count, 0, 0, paint);
    }
    mCanvas->setMatrix(origM);
}


void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
        const SkPaint& paint) {
    SkDEBUGFAIL("SkiaCanvasProxy::onDrawTextBlob is not supported");
Loading