TextHeightBehavior implemented
Bug: skia:10201 Change-Id: I5398836d2068164282bab77fe8448654a72050d7 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/286456 Commit-Queue: Julia Lavrova <jlavrova@google.com> Reviewed-by: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
1ff415d5a1
commit
9588a643d9
@ -126,6 +126,13 @@ enum class TextBaseline {
|
||||
kIdeographic,
|
||||
};
|
||||
|
||||
enum TextHeightBehavior {
|
||||
kAll = 0x0,
|
||||
kDisableFirstAscent = 0x1,
|
||||
kDisableLastDescent = 0x2,
|
||||
kDisableAll = 0x1 | 0x2,
|
||||
};
|
||||
|
||||
} // namespace textlayout
|
||||
} // namespace skia
|
||||
|
||||
|
@ -91,6 +91,10 @@ struct ParagraphStyle {
|
||||
SkScalar getHeight() const { return fHeight; }
|
||||
void setHeight(SkScalar height) { fHeight = height; }
|
||||
|
||||
|
||||
TextHeightBehavior getTextHeightBehavior() const { return fTextHeightBehavior; }
|
||||
void setTextHeightBehavior(TextHeightBehavior v) { fTextHeightBehavior = v; }
|
||||
|
||||
bool unlimited_lines() const {
|
||||
return fLinesLimit == std::numeric_limits<size_t>::max();
|
||||
}
|
||||
@ -107,6 +111,7 @@ private:
|
||||
size_t fLinesLimit;
|
||||
SkString fEllipsis;
|
||||
SkScalar fHeight;
|
||||
TextHeightBehavior fTextHeightBehavior;
|
||||
bool fHintingIsOn;
|
||||
};
|
||||
} // namespace textlayout
|
||||
|
@ -430,6 +430,7 @@ void ParagraphImpl::breakShapedTextIntoLines(SkScalar maxWidth) {
|
||||
|
||||
fLongestLine = std::max(fLongestLine, nearlyZero(advance.fX) ? widthWithSpaces : advance.fX);
|
||||
});
|
||||
|
||||
fHeight = textWrapper.height();
|
||||
fWidth = maxWidth;
|
||||
fMaxIntrinsicWidth = textWrapper.maxIntrinsicWidth();
|
||||
@ -437,6 +438,26 @@ void ParagraphImpl::breakShapedTextIntoLines(SkScalar maxWidth) {
|
||||
fAlphabeticBaseline = fLines.empty() ? fEmptyMetrics.alphabeticBaseline() : fLines.front().alphabeticBaseline();
|
||||
fIdeographicBaseline = fLines.empty() ? fEmptyMetrics.ideographicBaseline() : fLines.front().ideographicBaseline();
|
||||
fExceededMaxLines = textWrapper.exceededMaxLines();
|
||||
|
||||
// Correct the first and the last line ascents/descents if required
|
||||
if ((fParagraphStyle.getTextHeightBehavior() & TextHeightBehavior::kDisableFirstAscent) != 0) {
|
||||
auto& firstLine = fLines.front();
|
||||
auto delta = firstLine.metricsWithoutMultiplier(TextHeightBehavior::kDisableFirstAscent);
|
||||
if (!SkScalarNearlyZero(delta)) {
|
||||
fHeight += delta;
|
||||
// Shift all the lines up
|
||||
for (auto& line : fLines) {
|
||||
line.shiftVertically(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((fParagraphStyle.getTextHeightBehavior() & TextHeightBehavior::kDisableLastDescent) != 0) {
|
||||
auto& lastLine = fLines.back();
|
||||
auto delta = lastLine.metricsWithoutMultiplier(TextHeightBehavior::kDisableLastDescent);
|
||||
// It's the last line. There is nothing below to shift
|
||||
fHeight += delta;
|
||||
}
|
||||
}
|
||||
|
||||
void ParagraphImpl::formatLines(SkScalar maxWidth) {
|
||||
|
@ -21,6 +21,7 @@ ParagraphStyle::ParagraphStyle() {
|
||||
fTextDirection = TextDirection::kLtr;
|
||||
fLinesLimit = std::numeric_limits<size_t>::max();
|
||||
fHeight = 1;
|
||||
fTextHeightBehavior = TextHeightBehavior::kAll;
|
||||
fHintingIsOn = true;
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,8 @@ public:
|
||||
}
|
||||
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) {
|
||||
@ -417,6 +419,7 @@ public:
|
||||
SkScalar descent() const { return fDescent; }
|
||||
SkScalar leading() const { return fLeading; }
|
||||
void setForceStrut(bool value) { fForceStrut = value; }
|
||||
bool getForceStrut() const { return fForceStrut; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -305,6 +305,29 @@ SkRect TextLine::extendHeight(const ClipContext& context) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
SkScalar TextLine::metricsWithoutMultiplier(TextHeightBehavior correction) {
|
||||
|
||||
if (this->fSizes.getForceStrut()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
InternalLineMetrics result;
|
||||
this->iterateThroughVisualRuns(true,
|
||||
[&result](const Run* run, SkScalar runOffset, TextRange textRange, SkScalar* width) {
|
||||
InternalLineMetrics runMetrics(run->ascent(), run->descent(), run->leading());
|
||||
result.add(runMetrics);
|
||||
return true;
|
||||
});
|
||||
SkScalar delta = 0;
|
||||
if (correction == TextHeightBehavior::kDisableFirstAscent) {
|
||||
delta += (this->fSizes.ascent() - result.ascent());
|
||||
} else if (correction == TextHeightBehavior::kDisableLastDescent) {
|
||||
delta -= (this->fSizes.descent() - result.descent());
|
||||
}
|
||||
fAdvance.fY += delta;
|
||||
return delta;
|
||||
}
|
||||
|
||||
void TextLine::paintText(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const {
|
||||
|
||||
if (context.run->placeholderStyle() != nullptr) {
|
||||
|
@ -103,6 +103,9 @@ public:
|
||||
|
||||
SkRect extendHeight(const ClipContext& context) const;
|
||||
|
||||
SkScalar metricsWithoutMultiplier(TextHeightBehavior correction);
|
||||
void shiftVertically(SkScalar shift) { fOffset.fY += shift; }
|
||||
|
||||
private:
|
||||
|
||||
Run* shapeEllipsis(const SkString& ellipsis, Run* run);
|
||||
|
Loading…
Reference in New Issue
Block a user