Skip to content

Commit

Permalink
Small changes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Rusino authored and Skia Commit-Bot committed Dec 9, 2019
1 parent 3f7c49c commit 90bfd1c
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 81 deletions.
19 changes: 8 additions & 11 deletions modules/skparagraph/include/TextStyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -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;
Expand Down
13 changes: 8 additions & 5 deletions modules/skparagraph/src/OneLineShaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down
33 changes: 20 additions & 13 deletions modules/skparagraph/src/ParagraphImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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];

Expand All @@ -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 {
Expand Down Expand Up @@ -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());
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);
}

SkFont font(typeface, defaultTextStyle.getFontSize());
fEmptyMetrics = InternalLineMetrics(font, paragraphStyle().getStrutStyle().getForceStrutHeight());
fStrutMetrics.updateLineMetrics(fEmptyMetrics);
fStrutMetrics.updateLineMetrics(fEmptyMetrics);
}

void ParagraphImpl::updateText(size_t from, SkString text) {
Expand Down
3 changes: 2 additions & 1 deletion modules/skparagraph/src/ParagraphImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ class ParagraphImpl final : public Paragraph {
InternalLineMetrics getEmptyMetrics() const { return fEmptyMetrics; }
InternalLineMetrics getStrutMetrics() const { return fStrutMetrics; }

BlockRange findAllBlocks(TextRange textRange);

private:
friend class ParagraphBuilder;
friend class ParagraphCacheKey;
Expand All @@ -209,7 +211,6 @@ class ParagraphImpl final : public Paragraph {
friend class OneLineShaper;

void calculateBoundaries(ClusterRange clusters, SkVector offset, SkVector advance);
BlockRange findAllBlocks(TextRange textRange);
void extractStyles();

void markGraphemes16();
Expand Down
4 changes: 1 addition & 3 deletions modules/skparagraph/src/TextStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
53 changes: 35 additions & 18 deletions modules/skparagraph/src/TextWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand All @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 8 additions & 9 deletions samplecode/SampleParagraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1647,15 +1647,13 @@ class ParagraphView19 : public ParagraphView_Base {

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();
Expand All @@ -1677,19 +1675,20 @@ class ParagraphView20 : public ParagraphView_Base {

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);
}
Expand Down
Loading

0 comments on commit 90bfd1c

Please sign in to comment.