Small changes
Change-Id: Ic9c41a2dd11b4df8ab24037df0109e36536ec6c3 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/257892 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Julia Lavrova <jlavrova@google.com>
This commit is contained in:
parent
3f7c49c96d
commit
90bfd1c1c3
@ -243,15 +243,13 @@ struct Block {
|
||||
Block(size_t start, size_t end, const TextStyle& style) : fRange(start, end), fStyle(style) {}
|
||||
Block(TextRange textRange, const TextStyle& style) : fRange(textRange), fStyle(style) {}
|
||||
|
||||
Block(const Block& other) {
|
||||
fRange = other.fRange;
|
||||
fStyle = other.fStyle;
|
||||
}
|
||||
Block(const Block& other) : fRange(other.fRange), fStyle(other.fStyle) {}
|
||||
|
||||
void add(TextRange tail) {
|
||||
SkASSERT(fRange.end == tail.start);
|
||||
fRange = TextRange(fRange.start, fRange.start + fRange.width() + tail.width());
|
||||
}
|
||||
|
||||
TextRange fRange;
|
||||
TextStyle fStyle;
|
||||
};
|
||||
@ -273,13 +271,12 @@ struct Placeholder {
|
||||
, fBlocksBefore(blocksBefore)
|
||||
, fTextBefore(textBefore) {}
|
||||
|
||||
Placeholder(const Placeholder& other) {
|
||||
fRange = other.fRange;
|
||||
fStyle = other.fStyle;
|
||||
fTextStyle = other.fTextStyle;
|
||||
fBlocksBefore = other.fBlocksBefore;
|
||||
fTextBefore = other.fTextBefore;
|
||||
}
|
||||
Placeholder(const Placeholder& other)
|
||||
: fRange(other.fRange)
|
||||
, fStyle(other.fStyle)
|
||||
, fTextStyle(other.fTextStyle)
|
||||
, fBlocksBefore(other.fBlocksBefore)
|
||||
, fTextBefore(other.fTextBefore) {}
|
||||
|
||||
TextRange fRange;
|
||||
PlaceholderStyle fStyle;
|
||||
|
@ -339,6 +339,7 @@ void OneLineShaper::sortOutGlyphs(std::function<void(GlyphRange)>&& sortOutUnres
|
||||
void OneLineShaper::iterateThroughFontStyles(SkSpan<Block> styleSpan,
|
||||
const ShapeSingleFontVisitor& visitor) {
|
||||
Block combinedBlock;
|
||||
|
||||
for (auto& block : styleSpan) {
|
||||
SkASSERT(combinedBlock.fRange.width() == 0 ||
|
||||
combinedBlock.fRange.end == block.fRange.start);
|
||||
@ -460,11 +461,12 @@ bool OneLineShaper::shape() {
|
||||
}
|
||||
|
||||
iterateThroughFontStyles(styleSpan,
|
||||
[this, &shaper, textDirection, limitlessWidth, &advanceX](Block block) {
|
||||
[this, &shaper, textDirection, limitlessWidth, &advanceX]
|
||||
(Block block) {
|
||||
auto blockSpan = SkSpan<Block>(&block, 1);
|
||||
|
||||
// Start from the beginning (hoping that it's a simple case one block - one run)
|
||||
fHeight = block.fStyle.getHeight();
|
||||
fHeight = block.fStyle.getHeightOverride() ? block.fStyle.getHeight() : 0;
|
||||
fAdvance = SkVector::Make(advanceX, 0);
|
||||
fCurrentText = block.fRange;
|
||||
fUnresolvedBlocks.emplace(RunBlock(block.fRange));
|
||||
@ -495,8 +497,9 @@ bool OneLineShaper::shape() {
|
||||
}
|
||||
|
||||
fCurrentText = unresolvedRange;
|
||||
shaper->shape(unresolvedText.begin(), unresolvedText.size(), fontIter, *bidi,
|
||||
*script, lang, limitlessWidth, this);
|
||||
shaper->shape(unresolvedText.begin(), unresolvedText.size(),
|
||||
fontIter, *bidi,*script, lang,
|
||||
limitlessWidth, this);
|
||||
|
||||
// Take off the queue the block we tried to resolved -
|
||||
// whatever happened, we have now smaller pieces of it to deal with
|
||||
@ -507,7 +510,7 @@ bool OneLineShaper::shape() {
|
||||
return !fUnresolvedBlocks.empty();
|
||||
});
|
||||
|
||||
this->finish(block.fRange, block.fStyle.getHeight(), advanceX);
|
||||
this->finish(block.fRange, fHeight, advanceX);
|
||||
});
|
||||
|
||||
return true;
|
||||
|
@ -887,7 +887,7 @@ PositionWithAffinity ParagraphImpl::getGlyphPositionAtCoordinate(SkScalar dx, Sk
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dx >= context.clip.fRight) {
|
||||
if (dx >= context.clip.fRight + offsetX) {
|
||||
// We have to keep looking but just in case keep the last one as the closes
|
||||
// so far
|
||||
auto index = context.pos + context.size;
|
||||
@ -912,7 +912,7 @@ PositionWithAffinity ParagraphImpl::getGlyphPositionAtCoordinate(SkScalar dx, Sk
|
||||
}
|
||||
found = i;
|
||||
}
|
||||
auto glyphStart = context.run->positionX(found);
|
||||
auto glyphStart = context.run->positionX(found) + context.fTextShift + offsetX;
|
||||
auto glyphWidth = context.run->positionX(found + 1) - context.run->positionX(found);
|
||||
auto clusterIndex8 = context.run->fClusterIndexes[found];
|
||||
|
||||
@ -932,14 +932,11 @@ PositionWithAffinity ParagraphImpl::getGlyphPositionAtCoordinate(SkScalar dx, Sk
|
||||
auto averageCodepoint = glyphWidth / graphemeSize;
|
||||
auto codepointStart = glyphStart + averageCodepoint * (codepointIndex - codepoints.start);
|
||||
auto codepointEnd = codepointStart + averageCodepoint;
|
||||
center = (codepointStart + codepointEnd) / 2 + context.fTextShift;
|
||||
center = (codepointStart + codepointEnd) / 2;
|
||||
} else {
|
||||
SkASSERT(graphemeSize == 1);
|
||||
auto codepointStart = glyphStart;
|
||||
auto codepointEnd = codepointStart + glyphWidth;
|
||||
center = (codepointStart + codepointEnd) / 2 + context.fTextShift;
|
||||
center = glyphStart + glyphWidth / 2;
|
||||
}
|
||||
|
||||
if ((dx < center) == context.run->leftToRight()) {
|
||||
result = { SkToS32(codepointIndex), kDownstream };
|
||||
} else {
|
||||
@ -1092,15 +1089,25 @@ void ParagraphImpl::setState(InternalState state) {
|
||||
}
|
||||
|
||||
void ParagraphImpl::computeEmptyMetrics() {
|
||||
auto defaultTextStyle = paragraphStyle().getTextStyle();
|
||||
auto defaultTextStyle = paragraphStyle().getTextStyle();
|
||||
|
||||
auto typefaces = fontCollection()->findTypefaces(
|
||||
auto typefaces = fontCollection()->findTypefaces(
|
||||
defaultTextStyle.getFontFamilies(), defaultTextStyle.getFontStyle());
|
||||
auto typeface = typefaces.size() ? typefaces.front() : nullptr;
|
||||
auto typeface = typefaces.size() ? typefaces.front() : nullptr;
|
||||
|
||||
SkFont font(typeface, defaultTextStyle.getFontSize());
|
||||
fEmptyMetrics = InternalLineMetrics(font, paragraphStyle().getStrutStyle().getForceStrutHeight());
|
||||
fStrutMetrics.updateLineMetrics(fEmptyMetrics);
|
||||
SkFont font(typeface, defaultTextStyle.getFontSize());
|
||||
|
||||
fEmptyMetrics = InternalLineMetrics(font, paragraphStyle().getStrutStyle().getForceStrutHeight());
|
||||
if (!paragraphStyle().getStrutStyle().getForceStrutHeight() &&
|
||||
defaultTextStyle.getHeightOverride()) {
|
||||
auto multiplier =
|
||||
defaultTextStyle.getHeight() * defaultTextStyle.getFontSize() / fEmptyMetrics.height();
|
||||
fEmptyMetrics = InternalLineMetrics(fEmptyMetrics.ascent() * multiplier,
|
||||
fEmptyMetrics.descent() * multiplier,
|
||||
fEmptyMetrics.leading() * multiplier);
|
||||
}
|
||||
|
||||
fStrutMetrics.updateLineMetrics(fEmptyMetrics);
|
||||
}
|
||||
|
||||
void ParagraphImpl::updateText(size_t from, SkString text) {
|
||||
|
@ -199,6 +199,8 @@ public:
|
||||
InternalLineMetrics getEmptyMetrics() const { return fEmptyMetrics; }
|
||||
InternalLineMetrics getStrutMetrics() const { return fStrutMetrics; }
|
||||
|
||||
BlockRange findAllBlocks(TextRange textRange);
|
||||
|
||||
private:
|
||||
friend class ParagraphBuilder;
|
||||
friend class ParagraphCacheKey;
|
||||
@ -209,7 +211,6 @@ private:
|
||||
friend class OneLineShaper;
|
||||
|
||||
void calculateBoundaries(ClusterRange clusters, SkVector offset, SkVector advance);
|
||||
BlockRange findAllBlocks(TextRange textRange);
|
||||
void extractStyles();
|
||||
|
||||
void markGraphemes16();
|
||||
|
@ -84,8 +84,7 @@ bool TextStyle::equals(const TextStyle& other) const {
|
||||
if (fTextShadows.size() != other.fTextShadows.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < (int32_t)fTextShadows.size(); ++i) {
|
||||
for (size_t i = 0; i < fTextShadows.size(); ++i) {
|
||||
if (fTextShadows[i] != other.fTextShadows[i]) {
|
||||
return false;
|
||||
}
|
||||
@ -134,7 +133,6 @@ bool TextStyle::matchOneAttribute(StyleType styleType, const TextStyle& other) c
|
||||
// TODO: should not we take typefaces in account?
|
||||
return fFontStyle == other.fFontStyle && fFontFamilies == other.fFontFamilies &&
|
||||
fFontSize == other.fFontSize && fHeight == other.fHeight;
|
||||
|
||||
default:
|
||||
SkASSERT(false);
|
||||
return false;
|
||||
|
@ -35,9 +35,7 @@ void TextWrapper::lookAhead(SkScalar maxWidth, Cluster* endOfClusters) {
|
||||
break;
|
||||
}
|
||||
if (cluster->width() > maxWidth) {
|
||||
// Break the cluster into parts by glyph position
|
||||
auto delta = maxWidth - (fWords.width() + fClusters.width());
|
||||
fClip.extend(cluster, cluster->roundPos(delta));
|
||||
fClusters.extend(cluster);
|
||||
fTooLongCluster = true;
|
||||
fTooLongWord = true;
|
||||
break;
|
||||
@ -53,11 +51,9 @@ void TextWrapper::lookAhead(SkScalar maxWidth, Cluster* endOfClusters) {
|
||||
}
|
||||
if (nextWordLength > maxWidth) {
|
||||
// If the word is too long we can break it right now and hope it's enough
|
||||
fMinIntrinsicWidth = SkTMax(fMinIntrinsicWidth, nextWordLength);
|
||||
fTooLongWord = true;
|
||||
}
|
||||
|
||||
// TODO: this is the place when we use hyphenation
|
||||
fMinIntrinsicWidth = SkTMax(fMinIntrinsicWidth, fTooLongWord ? maxWidth : nextWordLength);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -83,8 +79,10 @@ void TextWrapper::moveForward() {
|
||||
} else if (fClusters.width() > 0) {
|
||||
fEndLine.extend(fClusters);
|
||||
fTooLongWord = false;
|
||||
fTooLongCluster = false;
|
||||
} else if (fClip.width() > 0 || (fTooLongWord && fTooLongCluster)) {
|
||||
fEndLine.extend(fClip);
|
||||
// Flutter: forget the clipped cluster but keep the metrics
|
||||
fEndLine.metrics().add(fClip.metrics());
|
||||
fTooLongWord = false;
|
||||
fTooLongCluster = false;
|
||||
} else {
|
||||
@ -159,8 +157,8 @@ void TextWrapper::breakTextIntoLines(ParagraphImpl* parent,
|
||||
SkScalar maxWidth,
|
||||
const AddLineToParagraph& addLine) {
|
||||
fHeight = 0;
|
||||
fMinIntrinsicWidth = 0;
|
||||
fMaxIntrinsicWidth = 0;
|
||||
fMinIntrinsicWidth = std::numeric_limits<SkScalar>::min();
|
||||
fMaxIntrinsicWidth = std::numeric_limits<SkScalar>::min();
|
||||
|
||||
auto span = parent->clusters();
|
||||
if (span.size() == 0) {
|
||||
@ -268,16 +266,35 @@ void TextWrapper::breakTextIntoLines(ParagraphImpl* parent,
|
||||
}
|
||||
|
||||
// We finished formatting the text but we need to scan the rest for some numbers
|
||||
auto cluster = fEndLine.endCluster();
|
||||
while (cluster != end) {
|
||||
fExceededMaxLines = true;
|
||||
if (cluster->isHardBreak()) {
|
||||
softLineMaxIntrinsicWidth = 0;
|
||||
} else {
|
||||
softLineMaxIntrinsicWidth += cluster->width();
|
||||
fMaxIntrinsicWidth = SkTMax(fMaxIntrinsicWidth, softLineMaxIntrinsicWidth);
|
||||
if (fEndLine.breakCluster() != nullptr) {
|
||||
auto lastWordLength = 0.0f;
|
||||
auto cluster = fEndLine.breakCluster();
|
||||
if (cluster != end) {
|
||||
++cluster;
|
||||
}
|
||||
++cluster;
|
||||
while (cluster != end || cluster->endPos() < end->endPos()) {
|
||||
fExceededMaxLines = true;
|
||||
if (cluster->isHardBreak()) {
|
||||
fMaxIntrinsicWidth = SkTMax(fMaxIntrinsicWidth, softLineMaxIntrinsicWidth);
|
||||
softLineMaxIntrinsicWidth = 0;
|
||||
|
||||
fMinIntrinsicWidth = SkTMax(fMinIntrinsicWidth, lastWordLength);
|
||||
lastWordLength = 0;
|
||||
} else if (cluster->isWhitespaces()) {
|
||||
SkASSERT(cluster->isWhitespaces());
|
||||
softLineMaxIntrinsicWidth += cluster->width();
|
||||
fMinIntrinsicWidth = SkTMax(fMinIntrinsicWidth, lastWordLength);
|
||||
lastWordLength = 0;
|
||||
} else {
|
||||
softLineMaxIntrinsicWidth += cluster->width();
|
||||
lastWordLength += cluster->width();
|
||||
}
|
||||
++cluster;
|
||||
}
|
||||
fMinIntrinsicWidth = SkTMax(fMinIntrinsicWidth, lastWordLength);
|
||||
fMaxIntrinsicWidth = SkTMax(fMaxIntrinsicWidth, softLineMaxIntrinsicWidth);
|
||||
// In case we could not place a single cluster on the line
|
||||
fHeight = SkTMax(fHeight, fEndLine.metrics().height());
|
||||
}
|
||||
|
||||
if (fHardLineBreak) {
|
||||
|
@ -1647,15 +1647,13 @@ protected:
|
||||
|
||||
auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
|
||||
|
||||
const char* text = "World domination is such an ugly phrase - I prefer to call it world optimisation";
|
||||
std::u16string text = u"\u0068\u0301\u0350\u0312\u0357\u030C\u0369\u0305\u036C\u0304\u0310\u033F\u0366\u0350\u0343\u0364\u0369\u0311\u0309\u030E\u0365\u031B\u0340\u0337\u0335\u035E\u0334\u0328\u0360\u0360\u0315\u035F\u0340\u0340\u0362\u0360\u0322\u031B\u031B\u0337\u0340\u031E\u031F\u032A\u0331\u0345\u032F\u0332\u032E\u0333\u0353\u0320\u0345\u031C\u031F\u033C\u0325\u0355\u032C\u0325\u033Aa\u0307\u0312\u034B\u0308\u0312\u0346\u0313\u0346\u0304\u0307\u0344\u0305\u0342\u0368\u0346\u036A\u035B\u030F\u0365\u0307\u0340\u0328\u0322\u0361\u0489\u034F\u0328\u0334\u035F\u0335\u0362\u0489\u0360\u0358\u035E\u0360\u035D\u0341\u0337\u0337\u032E\u0326\u032D\u0359\u0318\u033C\u032F\u0333\u035A\u034D\u0319\u031C\u0353\u033C\u0345\u0359\u0331\u033B\u0331\u033C";
|
||||
ParagraphStyle paragraph_style;
|
||||
paragraph_style.setMaxLines(7);
|
||||
paragraph_style.setEllipsis(u"\u2026");
|
||||
ParagraphBuilderImpl builder(paragraph_style, fontCollection);
|
||||
TextStyle text_style;
|
||||
text_style.setColor(SK_ColorBLACK);
|
||||
text_style.setFontFamilies({SkString("Roboto")});
|
||||
text_style.setFontSize(40);
|
||||
text_style.setFontSize(20);
|
||||
builder.pushStyle(text_style);
|
||||
builder.addText(text);
|
||||
auto paragraph = builder.Build();
|
||||
@ -1677,19 +1675,20 @@ protected:
|
||||
|
||||
auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
|
||||
|
||||
const char* text = "";
|
||||
const char* text = "0";
|
||||
ParagraphStyle paragraph_style;
|
||||
paragraph_style.setMaxLines(std::numeric_limits<size_t>::max());
|
||||
//paragraph_style.setEllipsis(u"\u2026");
|
||||
ParagraphBuilderImpl builder(paragraph_style, fontCollection);
|
||||
TextStyle text_style;
|
||||
text_style.setColor(SK_ColorBLACK);
|
||||
text_style.setFontFamilies({SkString("Roboto")});
|
||||
text_style.setFontSize(40);
|
||||
text_style.setFontFamilies({SkString("Google Sans Display")});
|
||||
text_style.setFontSize(160);
|
||||
//text_style.setHeightOverride(true);
|
||||
//text_style.setHeight(1.75);
|
||||
builder.pushStyle(text_style);
|
||||
builder.addText(text);
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->layout(this->width());
|
||||
paragraph->layout(94);
|
||||
|
||||
paragraph->paint(canvas, 0, 0);
|
||||
}
|
||||
|
@ -197,7 +197,6 @@ DEF_TEST(SkParagraph_SimpleParagraph, reporter) {
|
||||
}
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderParagraph.png");
|
||||
@ -297,7 +296,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[6].rect.bottom(), 50, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderBaselineParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderBaselineParagraph.png");
|
||||
@ -354,7 +352,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderBaselineParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 44.694f, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderAboveBaselineParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderAboveBaselineParagraph.png");
|
||||
@ -411,7 +408,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderAboveBaselineParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 56, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderBelowBaselineParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderBelowBaselineParagraph.png");
|
||||
@ -468,7 +464,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderBelowBaselineParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 30.347f, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderBottomParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderBottomParagraph.png");
|
||||
@ -523,7 +518,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderBottomParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderTopParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderTopParagraph.png");
|
||||
@ -578,7 +572,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderTopParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 30.468f, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderMiddleParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderMiddleParagraph.png");
|
||||
@ -633,7 +626,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderMiddleParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 40.234f, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderIdeographicBaselineParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderIdeographicBaselineParagraph.png");
|
||||
@ -687,7 +679,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderIdeographicBaselineParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 42.065f, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderBreakParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderBreakParagraph.png");
|
||||
@ -823,7 +814,6 @@ DEF_TEST(SkParagraph_InlinePlaceholderBreakParagraph, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[17].rect.bottom(), 113.5f, EPSILON100));
|
||||
}
|
||||
|
||||
// Checked: DIFF+ (half of the letter spacing before the text???)
|
||||
DEF_TEST(SkParagraph_InlinePlaceholderGetRectsParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
TestCanvas canvas("SkParagraph_InlinePlaceholderGetRectsParagraph.png");
|
||||
@ -1671,6 +1661,124 @@ DEF_TEST(SkParagraph_JustifyRTL, reporter) {
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 156, EPSILON100));
|
||||
}
|
||||
|
||||
DEF_TEST_DISABLED(SkParagraph_JustifyRTLNewLine, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
|
||||
if (!fontCollection->fontsFound()) return;
|
||||
TestCanvas canvas("SkParagraph_JustifyRTLNewLine.png");
|
||||
const char* text =
|
||||
"אאא בּבּבּבּ אאאא\nבּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
|
||||
"אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
|
||||
"אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ";
|
||||
|
||||
auto icu_text = icu::UnicodeString::fromUTF8(text);
|
||||
std::u16string u16_text(icu_text.getBuffer(), icu_text.getBuffer() + icu_text.length());
|
||||
const size_t len = strlen(text);
|
||||
|
||||
ParagraphStyle paragraph_style;
|
||||
paragraph_style.setMaxLines(14);
|
||||
paragraph_style.setTextAlign(TextAlign::kJustify);
|
||||
paragraph_style.setTextDirection(TextDirection::kRtl);
|
||||
paragraph_style.turnHintingOff();
|
||||
ParagraphBuilderImpl builder(paragraph_style, fontCollection);
|
||||
|
||||
TextStyle text_style;
|
||||
text_style.setFontFamilies({SkString("Ahem")});
|
||||
text_style.setFontSize(26);
|
||||
text_style.setColor(SK_ColorBLACK);
|
||||
builder.pushStyle(text_style);
|
||||
builder.addText(text, len);
|
||||
builder.pop();
|
||||
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->layout(TestCanvasWidth - 100);
|
||||
paragraph->paint(canvas.get(), 0, 0);
|
||||
|
||||
auto impl = static_cast<ParagraphImpl*>(paragraph.get());
|
||||
|
||||
SkPaint paint;
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeWidth(1);
|
||||
|
||||
// Tests for GetRectsForRange()
|
||||
RectHeightStyle rect_height_style = RectHeightStyle::kMax;
|
||||
RectWidthStyle rect_width_style = RectWidthStyle::kTight;
|
||||
paint.setColor(SK_ColorRED);
|
||||
auto boxes = paragraph->getRectsForRange(0, 30, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
canvas.get()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
REPORTER_ASSERT(reporter, boxes.size() == 2ull);
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 562, EPSILON100));
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 900, EPSILON100));
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 26, EPSILON100));
|
||||
|
||||
paint.setColor(SK_ColorBLUE);
|
||||
boxes = paragraph->getRectsForRange(240, 250, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
canvas.get()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
REPORTER_ASSERT(reporter, boxes.size() == 1ull);
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 68, EPSILON100));
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 130, EPSILON100));
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 120, EPSILON100));
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 156, EPSILON100));
|
||||
|
||||
// All lines should be justified to the width of the
|
||||
// paragraph.
|
||||
for (auto& line : impl->lines()) {
|
||||
REPORTER_ASSERT(reporter,
|
||||
SkScalarNearlyEqual(line.width(), TestCanvasWidth - 100, EPSILON100));
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST_DISABLED(SkParagraph_LeadingSpaceRTL, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
|
||||
if (!fontCollection->fontsFound()) return;
|
||||
TestCanvas canvas("SkParagraph_LeadingSpaceRTL.png");
|
||||
|
||||
const char* text = " leading space";
|
||||
|
||||
auto icu_text = icu::UnicodeString::fromUTF8(text);
|
||||
std::u16string u16_text(icu_text.getBuffer(), icu_text.getBuffer() + icu_text.length());
|
||||
const size_t len = strlen(text);
|
||||
|
||||
ParagraphStyle paragraph_style;
|
||||
paragraph_style.setMaxLines(14);
|
||||
paragraph_style.setTextAlign(TextAlign::kJustify);
|
||||
paragraph_style.setTextDirection(TextDirection::kRtl);
|
||||
paragraph_style.turnHintingOff();
|
||||
ParagraphBuilderImpl builder(paragraph_style, fontCollection);
|
||||
|
||||
TextStyle text_style;
|
||||
text_style.setFontFamilies({SkString("Ahem")});
|
||||
text_style.setFontSize(26);
|
||||
text_style.setColor(SK_ColorBLACK);
|
||||
builder.pushStyle(text_style);
|
||||
builder.addText(text, len);
|
||||
builder.pop();
|
||||
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->layout(TestCanvasWidth - 100);
|
||||
paragraph->paint(canvas.get(), 0, 0);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeWidth(1);
|
||||
|
||||
// Tests for GetRectsForRange()
|
||||
RectHeightStyle rect_height_style = RectHeightStyle::kMax;
|
||||
RectWidthStyle rect_width_style = RectWidthStyle::kTight;
|
||||
paint.setColor(SK_ColorRED);
|
||||
auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
canvas.get()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
REPORTER_ASSERT(reporter, boxes.size() == 2ull);
|
||||
}
|
||||
|
||||
// Checked: NO DIFF (some minor decoration differences, probably)
|
||||
DEF_TEST(SkParagraph_DecorationsParagraph, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
@ -1792,7 +1900,7 @@ DEF_TEST(SkParagraph_DecorationsParagraph, reporter) {
|
||||
}
|
||||
|
||||
DEF_TEST(SkParagraph_WavyDecorationParagraph, reporter) {
|
||||
// SkDebugf("TODO: Fix decorations\n");
|
||||
SkDebugf("TODO: Add test for wavy decorations\n");
|
||||
}
|
||||
|
||||
// Checked: NO DIFF
|
||||
@ -4374,11 +4482,6 @@ DEF_TEST(SkParagraph_StrutDefaultParagraph, reporter) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement font features
|
||||
DEF_TEST(SkParagraph_FontFeaturesParagraph, reporter) {
|
||||
// SkDebugf("TODO: Font features\n");
|
||||
}
|
||||
|
||||
// Not in Minikin
|
||||
DEF_TEST(SkParagraph_WhitespacesInMultipleFonts, reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
@ -5040,14 +5143,14 @@ DEF_TEST(SkParagraph_Ellipsis, reporter) {
|
||||
canvas.get()->drawRect(SkRect::MakeXYWH(0, 0, 50, 500), paint);
|
||||
|
||||
relayout(1, false, 50, 10, 950, 950, SK_ColorRED);
|
||||
relayout(3, false, 50, 30, 50, 950, SK_ColorBLUE);
|
||||
relayout(std::numeric_limits<size_t>::max(), false, 50, 200, 50, 950, SK_ColorGREEN);
|
||||
relayout(3, false, 50, 30, 90, 950, SK_ColorBLUE);
|
||||
relayout(std::numeric_limits<size_t>::max(), false, 50, 200, 90, 950, SK_ColorGREEN);
|
||||
|
||||
relayout(1, true, 50, 10, 950, 950, SK_ColorYELLOW);
|
||||
relayout(3, true, 50, 30, 50, 950, SK_ColorMAGENTA);
|
||||
relayout(3, true, 50, 30, 90, 950, SK_ColorMAGENTA);
|
||||
relayout(std::numeric_limits<size_t>::max(), true, 50, 20, 950, 950, SK_ColorCYAN);
|
||||
|
||||
relayout(1, false, 50, 10, 950, 950, SK_ColorRED);
|
||||
relayout(3, false, 50, 30, 50, 950, SK_ColorBLUE);
|
||||
relayout(std::numeric_limits<size_t>::max(), false, 50, 200, 50, 950, SK_ColorGREEN);
|
||||
relayout(3, false, 50, 30, 90, 950, SK_ColorBLUE);
|
||||
relayout(std::numeric_limits<size_t>::max(), false, 50, 200, 90, 950, SK_ColorGREEN);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user