Bug fixes
Change-Id: I2b4b210301584c23a3b9325ebfdfdd9e6c4712d1
Bug: skia:9881, skia:9882
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271865
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
diff --git a/modules/skparagraph/src/ParagraphCache.cpp b/modules/skparagraph/src/ParagraphCache.cpp
index e3a1e3f..3ee287c 100644
--- a/modules/skparagraph/src/ParagraphCache.cpp
+++ b/modules/skparagraph/src/ParagraphCache.cpp
@@ -35,15 +35,13 @@
public:
ParagraphCacheValue(const ParagraphImpl* paragraph)
: fKey(ParagraphCacheKey(paragraph))
- , fRuns(paragraph->fRuns)
- , fClusters(paragraph->fClusters) { }
+ , fRuns(paragraph->fRuns) { }
// Input == key
ParagraphCacheKey fKey;
// Shaped results
SkTArray<Run, false> fRuns;
- SkTArray<Cluster, true> fClusters;
};
uint32_t ParagraphCache::KeyHash::mix(uint32_t hash, uint32_t data) const {
@@ -208,14 +206,6 @@
for (auto& run : paragraph->fRuns) {
run.setMaster(paragraph);
}
-
- paragraph->fClusters.reset();
- paragraph->fClusters = entry->fValue->fClusters;
- for (auto& cluster : paragraph->fClusters) {
- cluster.setMaster(paragraph);
- }
-
- paragraph->fState = kMarked;
}
void ParagraphCache::printStatistics() {
diff --git a/modules/skparagraph/src/ParagraphImpl.cpp b/modules/skparagraph/src/ParagraphImpl.cpp
index ee1a386..45c7bd4 100644
--- a/modules/skparagraph/src/ParagraphImpl.cpp
+++ b/modules/skparagraph/src/ParagraphImpl.cpp
@@ -133,19 +133,12 @@
} else if (fState >= kLineBroken && (fOldWidth != floorWidth || fOldHeight != fHeight)) {
// We can use the results from SkShaper but have to do EVERYTHING ELSE again
this->fClusters.reset();
- this->fRunShifts.reset();
this->resetRunShifts();
fState = kShaped;
-
- this->buildClusterTable();
- fState = kClusterized;
-
- this->markLineBreaks(); // Just because it's on cluster table
- fState = kMarked;
}
if (fState < kShaped) {
- fClusters.reset();
+
fGraphemes.reset();
this->markGraphemes();
@@ -173,23 +166,18 @@
return;
}
- if (fState < kShaped) {
- this->resetRunShifts();
- fState = kShaped;
- } else {
- layout(floorWidth);
- return;
- }
- if (fState < kMarked) {
- this->buildClusterTable();
- fState = kClusterized;
- this->markLineBreaks();
- fState = kMarked;
+ this->fClusters.reset();
+ this->resetRunShifts();
+ fState = kShaped;
+ }
- // Add the paragraph to the cache
- fFontCollection->getParagraphCache()->updateParagraph(this);
- }
+ if (fState < kMarked) {
+ this->buildClusterTable();
+ fState = kClusterized;
+
+ this->markLineBreaks();
+ fState = kMarked;
}
if (fState >= kLineBroken) {
@@ -377,7 +365,6 @@
// Check the font-resolved text against the cache
if (fFontCollection->getParagraphCache()->findParagraph(this)) {
- this->fRunShifts.reset();
return true;
}
@@ -390,7 +377,8 @@
if (!result) {
return false;
} else {
- this->fRunShifts.reset();
+ // Add the paragraph to the cache
+ fFontCollection->getParagraphCache()->updateParagraph(this);
return true;
}
}
@@ -1275,5 +1263,27 @@
return true;
}
+void ParagraphImpl::shiftCluster(ClusterIndex index, SkScalar shift, SkScalar lastShift) {
+ auto& cluster = fClusters[index];
+ auto& runShift = fRunShifts[cluster.runIndex()];
+ auto& run = fRuns[cluster.runIndex()];
+ auto start = cluster.startPos();
+ auto end = cluster.endPos();
+ if (!run.leftToRight()) {
+ runShift.fShifts[start] = lastShift;
+ ++start;
+ ++end;
+ }
+
+ if (end == runShift.fShifts.size() - 1) {
+ // Set the same shift for the fake last glyph (to avoid all extra checks)
+ ++end;
+ }
+
+ for (size_t pos = start; pos < end; ++pos) {
+ runShift.fShifts[pos] = shift;
+ }
+}
+
} // namespace textlayout
} // namespace skia
diff --git a/modules/skparagraph/src/ParagraphImpl.h b/modules/skparagraph/src/ParagraphImpl.h
index 2f4d2cd..960922a 100644
--- a/modules/skparagraph/src/ParagraphImpl.h
+++ b/modules/skparagraph/src/ParagraphImpl.h
@@ -144,21 +144,7 @@
sk_sp<FontCollection> fontCollection() const { return fFontCollection; }
void formatLines(SkScalar maxWidth);
- void shiftCluster(ClusterIndex index, SkScalar shift, SkScalar lastShift) {
- auto& cluster = fClusters[index];
- auto& runShift = fRunShifts[cluster.runIndex()];
- auto& run = fRuns[cluster.runIndex()];
- auto start = cluster.startPos();
- auto end = cluster.endPos();
- if (!run.leftToRight()) {
- runShift.fShifts[start] = lastShift;
- ++start;
- ++end;
- }
- for (size_t pos = start; pos < end; ++pos) {
- runShift.fShifts[pos] = shift;
- }
- }
+ void shiftCluster(ClusterIndex index, SkScalar shift, SkScalar lastShift);
SkScalar posShift(RunIndex index, size_t pos) const {
if (fRunShifts.count() == 0) return 0.0;
diff --git a/modules/skparagraph/src/TextLine.cpp b/modules/skparagraph/src/TextLine.cpp
index 4cf587b..5924c92 100644
--- a/modules/skparagraph/src/TextLine.cpp
+++ b/modules/skparagraph/src/TextLine.cpp
@@ -123,7 +123,7 @@
SkRect TextLine::calculateBoundaries() {
- auto boundaries = SkRect::MakeEmpty();
+ auto boundaries = SkRect::MakeIWH(fAdvance.fX, fAdvance.fY);
auto clusters = fMaster->clusters(fClusterRange);
Run* run = nullptr;
auto runShift = 0.0f;
diff --git a/samplecode/SampleParagraph.cpp b/samplecode/SampleParagraph.cpp
index 2dcc11e..6391670 100644
--- a/samplecode/SampleParagraph.cpp
+++ b/samplecode/SampleParagraph.cpp
@@ -2177,32 +2177,48 @@
void onDrawContent(SkCanvas* canvas) override {
- const char* text = "test text with space at end ";
+ /*
+ * text: TextSpan(
+ text: 'aaaa bbbb ',
+ style: TextStyle(fontSize: 48.0),
+ children: <TextSpan>[
+ TextSpan(text: 'cc dd', style:TextStyle(fontFamily: 'serif', fontSize: 64.0)),
+ ],
+ ),
+ textDirection: TextDirection.ltr,
+ textAlign: TextAlign.justify,
+
+ */
+
+ const char* text1 = "aaaa bbbb ";
+ const char* text2 = "cc dd";
+
canvas->drawColor(SK_ColorWHITE);
ParagraphStyle paragraph_style;
- paragraph_style.setTextAlign(TextAlign::kCenter);
+ paragraph_style.setTextAlign(TextAlign::kJustify);
auto collection = getFontCollection();
+ SkPaint red;
+ red.setColor(SK_ColorRED);
TextStyle text_style;
text_style.setColor(SK_ColorBLACK);
- text_style.setFontFamilies({SkString("Roboto")});
- text_style.setFontSize(48);
ParagraphBuilderImpl builder(paragraph_style, collection);
+
+ text_style.setFontFamilies({SkString("Roboto")});
+ text_style.setFontSize(48);
builder.pushStyle(text_style);
- builder.addText(text);
+ builder.addText(text1);
+
+ text_style.setFontFamilies({SkString("Google Sans")});
+ text_style.setFontSize(64);
+ builder.pushStyle(text_style);
+ builder.addText(text2);
+
auto paragraph = builder.Build();
- auto width = this->width();
- paragraph->layout(width);
- SkDebugf("%f: %f %f\n", width, paragraph->getMinIntrinsicWidth(), paragraph->getMaxIntrinsicWidth());
+ paragraph->layout(310);
paragraph->paint(canvas, 0, 0);
- auto boxes = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight, RectWidthStyle::kTight);
- for (auto& b : boxes) {
- SkDebugf("box[%f:%f * %f:%f] %s\n",
- b.rect.fLeft, b.rect.fRight, b.rect.fTop, b.rect.fBottom,
- b.direction == TextDirection::kRtl ? "rtl" : "ltr");
- }
}
private: