SkFont::breakText and SkTextUtils::GetPosPath replacement

76 views
Skip to first unread message

Clark Kent

unread,
Sep 8, 2022, 7:50:58 AM9/8/22
to skia-discuss
SkFont::breakText has been silently removed and is not documented in the release notes

SkTextUtils::GetPosPath has been silently removed and is not documented in the release notes

what can these API's be replaced with?

Clark Kent

unread,
Sep 8, 2022, 8:25:57 AM9/8/22
to skia-discuss
breakText can be "revived" via



    const SkFont* skfont = AsFont(font);
    SkTextEncoding skencoding = (SkTextEncoding)encoding;
    const SkPaint* skpaint = AsPaint(paint);

    if (0 == byteLength || 0 >= maxWidth) {
        if (measuredWidth) {
            *measuredWidth = 0;
        }
        return 0;
    }
    if (0 == skfont->getSize()) {
        if (measuredWidth) {
            *measuredWidth = 0;
        }
        return byteLength;
    }

    SkASSERT(text != nullptr);

    auto [strikeSpec, scale] = SkStrikeSpec::MakeCanonicalized(*skfont, skpaint);

    SkBulkGlyphMetrics metrics{ strikeSpec };

    // adjust max instead of each glyph
    if (scale) {
        maxWidth /= scale;
    }

    SkScalar width = 0;

    const char* start = (const char*)text;
    const char* stop = start + byteLength;
    while (start < stop) {
        const char* curr = start;

        // read the glyph and move the pointer
        SkGlyphID glyphID;
        if (skencoding == SkTextEncoding::kGlyphID) {
            auto glyphs = (const uint16_t*)start;
            glyphID = *glyphs;
            glyphs++;
            start = (const char*)glyphs;
        }
        else {
            auto t = (const void*)start;
            auto unichar = SkUTFN_Next(skencoding, &t, stop);
            start = (const char*)t;
            glyphID = skfont->getTypefaceOrDefault()->unicharToGlyph(unichar);
        }

        auto glyph = metrics.glyph(glyphID);

        SkScalar x = glyph->advanceX();
        if ((width += x) > maxWidth) {
            width -= x;
            start = curr;
            break;
        }
    }

    if (measuredWidth) {
        if (scale) {
            width *= scale;
        }
        *measuredWidth = width;
    }

    // return the number of bytes measured
    return start - stop + byteLength;

Clark Kent

unread,
Sep 8, 2022, 8:28:14 AM9/8/22
to skia-discuss
and GetPosPath can be "revived" via



void GetPosPath(const void* text, size_t length, SkTextEncoding encoding,
    const SkPoint pos[], const SkFont& font, SkPath* path) {
    SkAutoToGlyphs ag(font, text, length, encoding);

    struct Rec {
        SkPath* fDst;
        const SkPoint* fPos;
    } rec = { path, pos };

    path->reset();
    font.getPaths(ag.glyphs(), ag.count(), [](const SkPath* src, const SkMatrix& mx, void* ctx) {
        Rec* rec = (Rec*)ctx;
        if (src) {
            SkMatrix m(mx);
            m.postTranslate(rec->fPos->fX, rec->fPos->fY);
            rec->fDst->addPath(*src, m);
        }
        rec->fPos += 1;
        }, &rec);
Reply all
Reply to author
Forward
0 new messages