Keeping run metrics rather than calculating them every time

Change-Id: Ic0257859317cf46dbb90277573f184d565fdb58d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295322
Reviewed-by: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
This commit is contained in:
Julia Lavrova 2020-06-09 15:04:52 -04:00 committed by Skia Commit-Bot
parent fb5ede576d
commit f7005498d4
4 changed files with 30 additions and 29 deletions

View File

@ -540,7 +540,7 @@ void ParagraphImpl::buildClusterTable() {
run.setClusterRange(runStart, fClusters.size());
fMaxIntrinsicWidth += run.advance().fX;
}
fClustersIndexFromCodeUnit[fText.size()] = fClusters.size();
fClustersIndexFromCodeUnit[fText.size()] = fClusters.size();
fClusters.emplace_back(this, EMPTY_RUN, 0, 0, this->text({fText.size(), fText.size()}), 0, 0);
}

View File

@ -17,7 +17,7 @@ namespace textlayout {
Run::Run(ParagraphImpl* master,
const SkShaper::RunHandler::RunInfo& info,
size_t firstChar,
SkScalar lineHeight,
SkScalar heightMultiplier,
size_t index,
SkScalar offsetX)
: fMaster(master)
@ -25,7 +25,7 @@ Run::Run(ParagraphImpl* master,
, fClusterRange(EMPTY_CLUSTERS)
, fFont(info.fFont)
, fClusterStart(firstChar)
, fHeightMultiplier(lineHeight)
, fHeightMultiplier(heightMultiplier)
{
fBidiLevel = info.fBidiLevel;
fAdvance = info.fAdvance;
@ -38,6 +38,9 @@ Run::Run(ParagraphImpl* master,
fClusterIndexes.push_back_n(info.glyphCount + 1);
fShifts.push_back_n(info.glyphCount + 1, 0.0);
info.fFont.getMetrics(&fFontMetrics);
this->calculateMetrics();
fSpaced = false;
// To make edge cases easier:
fPositions[info.glyphCount] = fOffset + fAdvance;
@ -46,6 +49,18 @@ Run::Run(ParagraphImpl* master,
fPlaceholderIndex = std::numeric_limits<size_t>::max();
}
void Run::calculateMetrics() {
fCorrectAscent = fFontMetrics.fAscent - fFontMetrics.fLeading * 0.5;
fCorrectDescent = fFontMetrics.fDescent + fFontMetrics.fLeading * 0.5;
fCorrectLeading = 0;
if (!SkScalarNearlyZero(fHeightMultiplier)) {
auto multiplier = fHeightMultiplier * fFont.getSize() /
(fFontMetrics.fDescent - fFontMetrics.fAscent + fFontMetrics.fLeading);
fCorrectAscent *= multiplier;
fCorrectDescent *= multiplier;
}
}
SkShaper::RunHandler::Buffer Run::newRunBuffer() {
return {fGlyphs.data(), fPositions.data(), nullptr, fClusterIndexes.data(), fOffset};
}
@ -267,6 +282,8 @@ void Run::updateMetrics(InternalLineMetrics* endlineMetrics) {
break;
}
this->calculateMetrics();
// Make sure the placeholder can fit the line
endlineMetrics->add(this);
}

View File

@ -60,7 +60,7 @@ public:
Run(ParagraphImpl* master,
const SkShaper::RunHandler::RunInfo& info,
size_t firstChar,
SkScalar lineHeight,
SkScalar heightMultiplier,
size_t index,
SkScalar shiftX);
Run(const Run&) = default;
@ -84,36 +84,15 @@ public:
fOffset.fY += shiftY;
}
SkVector advance() const {
return SkVector::Make(fAdvance.fX, fFontMetrics.fDescent - fFontMetrics.fAscent);
return SkVector::Make(fAdvance.fX, fFontMetrics.fDescent - fFontMetrics.fAscent + fFontMetrics.fLeading);
}
SkVector offset() const { return fOffset; }
SkScalar ascent() const { return fFontMetrics.fAscent; }
SkScalar descent() const { return fFontMetrics.fDescent; }
SkScalar leading() const { return fFontMetrics.fLeading; }
SkScalar correctAscent() const {
if (fHeightMultiplier == 0) {
return fFontMetrics.fAscent - fFontMetrics.fLeading / 2;
}
return fFontMetrics.fAscent * fHeightMultiplier * fFont.getSize() /
(fFontMetrics.fDescent - fFontMetrics.fAscent + fFontMetrics.fLeading / 2);
}
SkScalar correctDescent() const {
if (fHeightMultiplier == 0) {
return fFontMetrics.fDescent + fFontMetrics.fLeading / 2;
}
return fFontMetrics.fDescent * fHeightMultiplier * fFont.getSize() /
(fFontMetrics.fDescent - fFontMetrics.fAscent + fFontMetrics.fLeading / 2);
}
SkScalar correctLeading() const {
if (fHeightMultiplier == 0) {
return fFontMetrics.fAscent;
}
return fFontMetrics.fLeading * fHeightMultiplier * fFont.getSize() /
(fFontMetrics.fDescent - fFontMetrics.fAscent + fFontMetrics.fLeading);
}
SkScalar correctAscent() const { return fCorrectAscent; }
SkScalar correctDescent() const { return fCorrectDescent; }
SkScalar correctLeading() const { return fCorrectLeading; }
const SkFont& font() const { return fFont; }
bool leftToRight() const { return fBidiLevel % 2 == 0; }
TextDirection getTextDirection() const { return leftToRight() ? TextDirection::kLtr : TextDirection::kRtl; }
@ -132,6 +111,7 @@ public:
bool isEllipsis() const { return fEllipsis; }
void calculateMetrics();
void updateMetrics(InternalLineMetrics* endlineMetrics);
void setClusterRange(size_t from, size_t to) { fClusterRange = ClusterRange(from, to); }
@ -217,6 +197,9 @@ private:
SkFontMetrics fFontMetrics;
const SkScalar fHeightMultiplier;
SkScalar fCorrectAscent;
SkScalar fCorrectDescent;
SkScalar fCorrectLeading;
bool fSpaced;
bool fEllipsis;

View File

@ -75,6 +75,7 @@ class TextWrapper {
fStart = ClusterPos(cluster, cluster->startPos());
}
fEnd = ClusterPos(cluster, cluster->endPos());
// TODO: Make sure all the checks are correct and there are no unnecessary checks
if (!cluster->run()->isPlaceholder()) {
fMetrics.add(cluster->run());
}