Removing fOffsets array from Run; optimizing copyTo
Change-Id: I4df661f800436ddb2b2bdb0cf19017e651332971 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295236 Commit-Queue: Julia Lavrova <jlavrova@google.com> Reviewed-by: Ben Wagner <bungeman@google.com> Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
parent
990a04ecd5
commit
73905c3db2
@ -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<SkScalar> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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<size_t>::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));
|
||||
|
||||
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];
|
||||
auto offset = fOffsets[i + pos];
|
||||
point.offset(offset.fX, offset.fY);
|
||||
if (fSpaced) {
|
||||
point.fX += fShifts[i + pos];
|
||||
}
|
||||
if (!fJustificationShifts.empty()) {
|
||||
point.fX += fJustificationShifts[i + pos].fX;
|
||||
}
|
||||
blobBuffer.points()[i] = point + runOffset;
|
||||
blobBuffer.points()[i] = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<void(size_t glyphStart,
|
||||
size_t glyphEnd,
|
||||
@ -178,9 +172,6 @@ public:
|
||||
SkSpan<const SkPoint> positions() const {
|
||||
return SkSpan<const SkPoint>(fPositions.begin(), fPositions.size());
|
||||
}
|
||||
SkSpan<const SkPoint> offsets() const {
|
||||
return SkSpan<const SkPoint>(fOffsets.begin(), fOffsets.size());
|
||||
}
|
||||
SkSpan<const uint32_t> clusterIndexes() const {
|
||||
return SkSpan<const uint32_t>(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;
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user