diff --git a/modules/skparagraph/src/Decorations.cpp b/modules/skparagraph/src/Decorations.cpp index 1a48dd1751..18a56f0cd9 100644 --- a/modules/skparagraph/src/Decorations.cpp +++ b/modules/skparagraph/src/Decorations.cpp @@ -55,9 +55,9 @@ void Decorations::paint(SkCanvas* canvas, const TextStyle& textStyle, const Text if (drawGaps) { SkScalar left = x - context.fTextShift; canvas->translate(context.fTextShift, 0); - calculateGaps(context, left, left + width, y, y + fThickness, baseline, fThickness); + calculateGaps(context, SkRect::MakeXYWH(left, y, width, fThickness), baseline, fThickness); canvas->drawPath(fPath, fPaint); - calculateGaps(context, left, left + width, bottom, bottom + fThickness, baseline, fThickness); + calculateGaps(context, SkRect::MakeXYWH(left, bottom, width, fThickness), baseline, fThickness); canvas->drawPath(fPath, fPaint); } else { draw_line_as_rect(canvas, x, y, width, fPaint); @@ -70,7 +70,7 @@ void Decorations::paint(SkCanvas* canvas, const TextStyle& textStyle, const Text if (drawGaps) { SkScalar left = x - context.fTextShift; canvas->translate(context.fTextShift, 0); - calculateGaps(context, left, left + width, y, y + fThickness, baseline, 0); + calculateGaps(context, SkRect::MakeXYWH(left, y, width, fThickness), baseline, 0); canvas->drawPath(fPath, fPaint); } else { canvas->drawLine(x, y, x + width, y, fPaint); @@ -80,7 +80,7 @@ void Decorations::paint(SkCanvas* canvas, const TextStyle& textStyle, const Text if (drawGaps) { SkScalar left = x - context.fTextShift; canvas->translate(context.fTextShift, 0); - calculateGaps(context, left, left + width, y, y + fThickness, baseline, fThickness); + calculateGaps(context, SkRect::MakeXYWH(left, y, width, fThickness), baseline, fThickness); canvas->drawPath(fPath, fPaint); } else { draw_line_as_rect(canvas, x, y, width, fPaint); @@ -91,7 +91,7 @@ void Decorations::paint(SkCanvas* canvas, const TextStyle& textStyle, const Text } } -void Decorations::calculateGaps(const TextLine::ClipContext& context, SkScalar x0, SkScalar x1, SkScalar y0, SkScalar y1, SkScalar baseline, SkScalar halo) { +void Decorations::calculateGaps(const TextLine::ClipContext& context, const SkRect& rect, SkScalar baseline, SkScalar halo) { fPath.reset(); @@ -99,27 +99,30 @@ void Decorations::calculateGaps(const TextLine::ClipContext& context, SkScalar x SkTextBlobBuilder builder; context.run->copyTo(builder, SkToU32(context.pos), - context.size, - SkVector::Make(0, baseline)); + context.size); auto blob = builder.make(); - const SkScalar bounds[2] = {y0, y1}; + // Since we do not shift down the text by {baseline} + // (it now happens on drawTextBlob but we do not draw text here) + // we have to shift up the bounds to compensate + // This baseline thing ends with getIntercepts + const SkScalar bounds[2] = {rect.fTop - baseline, rect.fBottom - baseline}; auto count = blob->getIntercepts(bounds, nullptr, &fPaint); SkTArray intersections(count); intersections.resize(count); blob->getIntercepts(bounds, intersections.data(), &fPaint); - auto start = x0; - fPath.moveTo({x0, y0}); + auto start = rect.fLeft; + fPath.moveTo(rect.fLeft, rect.fTop); for (int i = 0; i < intersections.count(); i += 2) { auto end = intersections[i] - halo; if (end - start >= halo) { start = intersections[i + 1] + halo; - fPath.lineTo(end, y0).moveTo(start, y0); + fPath.lineTo(end, rect.fTop).moveTo(start, rect.fTop); } } - if (!intersections.empty() && (x1 - start > halo)) { - fPath.lineTo(x1, y0); + if (!intersections.empty() && (rect.fRight - start > halo)) { + fPath.lineTo(rect.fRight, rect.fTop); } } diff --git a/modules/skparagraph/src/Decorations.h b/modules/skparagraph/src/Decorations.h index c7cbc6fbce..959c409822 100644 --- a/modules/skparagraph/src/Decorations.h +++ b/modules/skparagraph/src/Decorations.h @@ -20,7 +20,7 @@ class Decorations { void calculatePosition(TextDecoration decoration, SkScalar ascent); void calculatePaint(const TextStyle& textStyle); void calculateWaves(const TextStyle& textStyle, SkRect clip); - void calculateGaps(const TextLine::ClipContext& context, SkScalar x0, SkScalar x1, SkScalar y0, SkScalar y1, SkScalar baseline, SkScalar halo); + void calculateGaps(const TextLine::ClipContext& context, const SkRect& rect, SkScalar baseline, SkScalar halo); SkScalar fThickness; SkScalar fPosition; diff --git a/modules/skparagraph/src/OneLineShaper.cpp b/modules/skparagraph/src/OneLineShaper.cpp index 1c37c1e148..9f00fd2498 100644 --- a/modules/skparagraph/src/OneLineShaper.cpp +++ b/modules/skparagraph/src/OneLineShaper.cpp @@ -222,7 +222,6 @@ void OneLineShaper::finish(TextRange blockText, SkScalar height, SkScalar& advan piece->fBounds[index] = run->fBounds[i]; } piece->fClusterIndexes[index] = run->fClusterIndexes[i]; - piece->fOffsets[index] = run->fOffsets[i]; piece->fPositions[index] = run->fPositions[i] - zero; piece->addX(index, advanceX); } @@ -534,7 +533,6 @@ bool OneLineShaper::iterateThroughShapingRegions(const ShapeVisitor& shape) { advanceX); run.fPositions[0] = { advanceX, 0 }; - run.fOffsets[0] = {0, 0}; run.fClusterIndexes[0] = 0; run.fPlaceholderIndex = &placeholder - fParagraph->fPlaceholders.begin(); advanceX += placeholder.fStyle.fWidth; diff --git a/modules/skparagraph/src/Run.cpp b/modules/skparagraph/src/Run.cpp index 28c4017fb7..daedb23373 100644 --- a/modules/skparagraph/src/Run.cpp +++ b/modules/skparagraph/src/Run.cpp @@ -35,21 +35,19 @@ Run::Run(ParagraphImpl* master, fGlyphs.push_back_n(info.glyphCount); fBounds.push_back_n(info.glyphCount); fPositions.push_back_n(info.glyphCount + 1); - fOffsets.push_back_n(info.glyphCount + 1); fClusterIndexes.push_back_n(info.glyphCount + 1); fShifts.push_back_n(info.glyphCount + 1, 0.0); info.fFont.getMetrics(&fFontMetrics); fSpaced = false; // To make edge cases easier: fPositions[info.glyphCount] = fOffset + fAdvance; - fOffsets[info.glyphCount] = { 0, 0}; fClusterIndexes[info.glyphCount] = this->leftToRight() ? info.utf8Range.end() : info.utf8Range.begin(); fEllipsis = false; fPlaceholderIndex = std::numeric_limits::max(); } SkShaper::RunHandler::Buffer Run::newRunBuffer() { - return {fGlyphs.data(), fPositions.data(), fOffsets.data(), fClusterIndexes.data(), fOffset}; + return {fGlyphs.data(), fPositions.data(), nullptr, fClusterIndexes.data(), fOffset}; } void Run::commit() { @@ -71,21 +69,24 @@ SkScalar Run::calculateWidth(size_t start, size_t end, bool clip) const { return posX(end) - posX(start) + shift + correction; } -void Run::copyTo(SkTextBlobBuilder& builder, size_t pos, size_t size, SkVector runOffset) const { +void Run::copyTo(SkTextBlobBuilder& builder, size_t pos, size_t size) const { SkASSERT(pos + size <= this->size()); const auto& blobBuffer = builder.allocRunPos(fFont, SkToInt(size)); sk_careful_memcpy(blobBuffer.glyphs, fGlyphs.data() + pos, size * sizeof(SkGlyphID)); - for (size_t i = 0; i < size; ++i) { - auto point = fPositions[i + pos]; - auto offset = fOffsets[i + pos]; - point.offset(offset.fX, offset.fY); - if (fSpaced) { - point.fX += fShifts[i + pos]; + + if (!fSpaced && fJustificationShifts.empty()) { + sk_careful_memcpy(blobBuffer.points(), fPositions.data() + pos, size * sizeof(SkPoint)); + } else { + for (size_t i = 0; i < size; ++i) { + auto point = fPositions[i + pos]; + if (fSpaced) { + point.fX += fShifts[i + pos]; + } + if (!fJustificationShifts.empty()) { + point.fX += fJustificationShifts[i + pos].fX; + } + blobBuffer.points()[i] = point; } - if (!fJustificationShifts.empty()) { - point.fX += fJustificationShifts[i + pos].fX; - } - blobBuffer.points()[i] = point + runOffset; } } diff --git a/modules/skparagraph/src/Run.h b/modules/skparagraph/src/Run.h index b5042bf76a..48068a501f 100644 --- a/modules/skparagraph/src/Run.h +++ b/modules/skparagraph/src/Run.h @@ -73,15 +73,9 @@ public: SkShaper::RunHandler::Buffer newRunBuffer(); - SkScalar posX(size_t index) const { - return fPositions[index].fX + fOffsets[index].fX; - } - void addX(size_t index, SkScalar shift) { - fPositions[index].fX += shift; - } - SkScalar posY(size_t index) const { - return fPositions[index].fY + fOffsets[index].fY; - } + SkScalar posX(size_t index) const { return fPositions[index].fX; } + void addX(size_t index, SkScalar shift) { fPositions[index].fX += shift; } + SkScalar posY(size_t index) const { return fPositions[index].fY; } size_t size() const { return fGlyphs.size(); } void setWidth(SkScalar width) { fAdvance.fX = width; } void setHeight(SkScalar height) { fAdvance.fY = height; } @@ -158,7 +152,7 @@ public: } SkScalar calculateWidth(size_t start, size_t end, bool clip) const; - void copyTo(SkTextBlobBuilder& builder, size_t pos, size_t size, SkVector offset) const; + void copyTo(SkTextBlobBuilder& builder, size_t pos, size_t size) const; using ClusterTextVisitor = std::function positions() const { return SkSpan(fPositions.begin(), fPositions.size()); } - SkSpan offsets() const { - return SkSpan(fOffsets.begin(), fOffsets.size()); - } SkSpan clusterIndexes() const { return SkSpan(fClusterIndexes.begin(), fClusterIndexes.size()); } @@ -219,7 +210,6 @@ private: SkSTArray<128, SkGlyphID, true> fGlyphs; SkSTArray<128, SkPoint, true> fPositions; SkSTArray<128, SkPoint, true> fJustificationShifts; // For justification (current and prev shifts) - SkSTArray<128, SkPoint, true> fOffsets; SkSTArray<128, uint32_t, true> fClusterIndexes; SkSTArray<128, SkRect, true> fBounds; diff --git a/modules/skparagraph/src/TextLine.cpp b/modules/skparagraph/src/TextLine.cpp index c087c4c419..e225a335aa 100644 --- a/modules/skparagraph/src/TextLine.cpp +++ b/modules/skparagraph/src/TextLine.cpp @@ -368,15 +368,16 @@ void TextLine::paintText(SkCanvas* canvas, TextRange textRange, const TextStyle& } // TODO: This is the change for flutter, must be removed later - SkScalar correctedBaseline = SkScalarFloorToScalar(this->baseline() + 0.5); SkTextBlobBuilder builder; - context.run->copyTo(builder, SkToU32(context.pos), context.size, SkVector::Make(context.fTextShift, correctedBaseline)); + context.run->copyTo(builder, SkToU32(context.pos), context.size); if (context.clippingNeeded) { canvas->save(); canvas->clipRect(extendHeight(context).makeOffset(this->offset())); } - canvas->drawTextBlob(builder.make(), this->offset().fX, this->offset().fY, paint); + SkScalar correctedBaseline = SkScalarFloorToScalar(this->baseline() + 0.5); + canvas->drawTextBlob(builder.make(), + this->offset().fX + context.fTextShift, this->offset().fY + correctedBaseline, paint); if (context.clippingNeeded) { canvas->restore(); @@ -403,7 +404,7 @@ void TextLine::paintShadow(SkCanvas* canvas, TextRange textRange, const TextStyl } SkTextBlobBuilder builder; - context.run->copyTo(builder, context.pos, context.size, SkVector::Make(context.fTextShift, shiftDown)); + context.run->copyTo(builder, context.pos, context.size); if (context.clippingNeeded) { canvas->save(); @@ -411,7 +412,10 @@ void TextLine::paintShadow(SkCanvas* canvas, TextRange textRange, const TextStyl clip.offset(this->offset()); canvas->clipRect(clip); } - canvas->drawTextBlob(builder.make(), this->offset().fX + shadow.fOffset.x(), this->offset().fY + shadow.fOffset.y(), paint); + canvas->drawTextBlob(builder.make(), + this->offset().fX + shadow.fOffset.x() + context.fTextShift, + this->offset().fY + shadow.fOffset.y() + shiftDown, + paint); if (context.clippingNeeded) { canvas->restore();