void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
                                                       const SkScalar pos[], int scalarsPerPosition,
                                                       const SkPoint& offset) {
    SkASSERT(byteLength == 0 || text != nullptr);
    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);

    SkGlyphCache* glyphCache = this->getGlyphCache();
    SkPaint::GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(fFont.getTextEncoding(),
                                                                        fFont.isDevKernText(),
                                                                        true);

    fTotalGlyphCount = fFont.countText(text, byteLength);
    fInstanceData.reset(InstanceData::Alloc(GrPathRendering::kTranslate_PathTransformType,
                                            fTotalGlyphCount));

    const char* stop = text + byteLength;

    SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
    SkTextAlignProc alignProc(fFont.getTextAlign());
    FallbackBlobBuilder fallback;
    while (text < stop) {
        const SkGlyph& glyph = glyphCacheProc(glyphCache, &text);
        if (glyph.fWidth) {
            SkPoint tmsLoc;
            tmsProc(pos, &tmsLoc);
            SkPoint loc;
            alignProc(tmsLoc, glyph, &loc);

            this->appendGlyph(glyph, loc, &fallback);
        }
        pos += scalarsPerPosition;
    }

    fFallbackTextBlob = fallback.makeIfNeeded(&fFallbackGlyphCount);
}
Exemple #2
0
void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
                                                       const SkScalar pos[], int scalarsPerPosition,
                                                       const SkPoint& offset) {
    SkASSERT(byteLength == 0 || text != nullptr);
    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);

    SkGlyphCache* glyphCache = this->getGlyphCache();
    SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();

    fDraw.reset(GrPathRangeDraw::Create(GrPathRendering::kTranslate_PathTransformType,
                                        fTotalGlyphCount = fFont.countText(text, byteLength)));

    const char* stop = text + byteLength;

    SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
    SkTextAlignProc alignProc(fFont.getTextAlign());
    FallbackBlobBuilder fallback;
    while (text < stop) {
        const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
        if (glyph.fWidth) {
            SkPoint tmsLoc;
            tmsProc(pos, &tmsLoc);
            SkPoint loc;
            alignProc(tmsLoc, glyph, &loc);

            this->appendGlyph(glyph, loc, &fallback);
        }
        pos += scalarsPerPosition;
    }

    fFallbackTextBlob.reset(fallback.buildIfInitialized());
}
void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t byteLength,
                                                    SkScalar x, SkScalar y) {
    SkASSERT(byteLength == 0 || text != nullptr);

    SkGlyphCache* glyphCache = this->getGlyphCache();
    SkPaint::GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(fFont.getTextEncoding(),
                                                                        fFont.isDevKernText(),
                                                                        true);

    fTotalGlyphCount = fFont.countText(text, byteLength);
    fInstanceData.reset(InstanceData::Alloc(GrPathRendering::kTranslate_PathTransformType,
                                            fTotalGlyphCount));

    const char* stop = text + byteLength;

    // Measure first if needed.
    if (fFont.getTextAlign() != SkPaint::kLeft_Align) {
        SkScalar   stopX = 0;
        SkScalar   stopY = 0;

        const char* textPtr = text;
        while (textPtr < stop) {
            // We don't need x, y here, since all subpixel variants will have the
            // same advance.
            const SkGlyph& glyph = glyphCacheProc(glyphCache, &textPtr);

            stopX += SkFloatToScalar(glyph.fAdvanceX);
            stopY += SkFloatToScalar(glyph.fAdvanceY);
        }
        SkASSERT(textPtr == stop);

        SkScalar alignX = stopX * fTextRatio;
        SkScalar alignY = stopY * fTextRatio;

        if (fFont.getTextAlign() == SkPaint::kCenter_Align) {
            alignX = SkScalarHalf(alignX);
            alignY = SkScalarHalf(alignY);
        }

        x -= alignX;
        y -= alignY;
    }

    SkAutoKern autokern;

    FallbackBlobBuilder fallback;
    while (text < stop) {
        const SkGlyph& glyph = glyphCacheProc(glyphCache, &text);
        x += autokern.adjust(glyph) * fTextRatio;
        if (glyph.fWidth) {
            this->appendGlyph(glyph, SkPoint::Make(x, y), &fallback);
        }

        x += SkFloatToScalar(glyph.fAdvanceX) * fTextRatio;
        y += SkFloatToScalar(glyph.fAdvanceY) * fTextRatio;
    }

    fFallbackTextBlob = fallback.makeIfNeeded(&fFallbackGlyphCount);
}
void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t byteLength,
        SkScalar x, SkScalar y) {
    SkASSERT(byteLength == 0 || text != nullptr);

    SkGlyphCache* glyphCache = this->getGlyphCache();
    SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();

    fTotalGlyphCount = fFont.countText(text, byteLength);
    fInstanceData.reset(InstanceData::Alloc(GrPathRendering::kTranslate_PathTransformType,
                                            fTotalGlyphCount));

    const char* stop = text + byteLength;

    // Measure first if needed.
    if (fFont.getTextAlign() != SkPaint::kLeft_Align) {
        SkFixed    stopX = 0;
        SkFixed    stopY = 0;

        const char* textPtr = text;
        while (textPtr < stop) {
            // We don't need x, y here, since all subpixel variants will have the
            // same advance.
            const SkGlyph& glyph = glyphCacheProc(glyphCache, &textPtr, 0, 0);

            stopX += glyph.fAdvanceX;
            stopY += glyph.fAdvanceY;
        }
        SkASSERT(textPtr == stop);

        SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio;
        SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio;

        if (fFont.getTextAlign() == SkPaint::kCenter_Align) {
            alignX = SkScalarHalf(alignX);
            alignY = SkScalarHalf(alignY);
        }

        x -= alignX;
        y -= alignY;
    }

    SkAutoKern autokern;

    SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio);

    SkFixed fx = SkScalarToFixed(x);
    SkFixed fy = SkScalarToFixed(y);
    FallbackBlobBuilder fallback;
    while (text < stop) {
        const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
        fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio);
        if (glyph.fWidth) {
            this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedToScalar(fy)),
                              &fallback);
        }

        fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio);
        fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
    }

    fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount));
}