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:
Julia Lavrova 2020-06-09 10:58:02 -04:00 committed by Skia Commit-Bot
parent 990a04ecd5
commit 73905c3db2
6 changed files with 45 additions and 49 deletions

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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));
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;
}
}

View File

@ -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;

View File

@ -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();