2#ifndef TextWrapper_DEFINED
3#define TextWrapper_DEFINED
17 ClusterPos() : fCluster(
nullptr), fPos(0) {}
18 ClusterPos(
Cluster* cluster,
size_t pos) : fCluster(cluster), fPos(
pos) {}
19 inline Cluster* cluster()
const {
return fCluster; }
20 inline size_t position()
const {
return fPos; }
21 inline void setPosition(
size_t pos) { fPos =
pos; }
27 fCluster += up ? 1 : -1;
28 fPos = up ? 0 : fCluster->endPos();
37 TextStretch() : fStart(), fEnd(), fWidth(0), fWidthWithGhostSpaces(0) {}
39 : fStart(
s, 0), fEnd(
e,
e->endPos()), fMetrics(forceStrut), fWidth(0), fWidthWithGhostSpaces(0) {
40 for (
auto c =
s; c <=
e; ++c) {
41 if (
auto r = c->runOrNull()) {
48 fWidthWithGhostSpaces = fWidth;
52 SkScalar widthWithGhostSpaces()
const {
return fWidthWithGhostSpaces; }
53 inline Cluster* startCluster()
const {
return fStart.cluster(); }
54 inline Cluster* endCluster()
const {
return fEnd.cluster(); }
55 inline Cluster* breakCluster()
const {
return fBreak.cluster(); }
57 inline size_t startPos()
const {
return fStart.position(); }
58 inline size_t endPos()
const {
return fEnd.position(); }
59 bool endOfCluster() {
return fEnd.position() == fEnd.cluster()->endPos(); }
61 return endOfCluster() &&
62 (fEnd.cluster()->isHardBreak() || fEnd.cluster()->isSoftBreak());
65 void extend(TextStretch& stretch) {
66 fMetrics.add(stretch.fMetrics);
68 fWidth += stretch.fWidth;
72 bool empty() {
return fStart.cluster() == fEnd.cluster() &&
73 fStart.position() == fEnd.position(); }
78 if (fStart.cluster() ==
nullptr) {
79 fStart = ClusterPos(cluster, cluster->
startPos());
81 fEnd = ClusterPos(cluster, cluster->
endPos());
83 auto& r = cluster->
run();
84 if (!cluster->
isHardBreak() && !r.isPlaceholder()) {
88 fWidth += cluster->
width();
92 fEnd = ClusterPos(cluster,
pos);
99 fStart = ClusterPos(cluster,
pos);
100 fEnd = ClusterPos(cluster,
pos);
104 if (!r->isPlaceholder()) {
112 fWidthWithGhostSpaces = fWidth;
116 void restoreBreak() {
117 fWidth = fWidthWithGhostSpaces;
127 if (fEnd.cluster() !=
nullptr &&
128 fEnd.cluster()->owner() !=
nullptr &&
129 fEnd.cluster()->runOrNull() !=
nullptr &&
130 fEnd.cluster()->run().placeholderStyle() ==
nullptr &&
132 fWidth -= (fEnd.cluster()->width() - fEnd.cluster()->trimmedWidth(fEnd.position()));
137 SkASSERT(fEnd.cluster() == cluster);
138 if (fEnd.cluster() > fStart.cluster()) {
140 fWidth -= cluster->
width();
142 fEnd.setPosition(fStart.position());
166 fHardLineBreak =
false;
167 fExceededMaxLines =
false;
193 TextStretch fClusters;
195 TextStretch fEndLine;
198 bool fTooLongCluster;
201 bool fExceededMaxLines;
211 fTooLongCluster =
false;
212 fTooLongWord =
false;
213 fHardLineBreak =
false;
216 void lookAhead(
SkScalar maxWidth, Cluster* endOfClusters,
bool applyRoundingHack);
217 void moveForward(
bool hasEllipsis);
219 std::tuple<Cluster*, size_t, SkScalar> trimStartSpaces(Cluster* endOfClusters);
static SkCanvas * trim(SkCanvas *canvas, SkScalar width, SkScalar height, const SkRect *content)
std::function< void(TextRange textExcludingSpaces, TextRange text, TextRange textIncludingNewlines, ClusterRange clusters, ClusterRange clustersWithGhosts, SkScalar AddLineToParagraph, size_t startClip, size_t endClip, SkVector offset, SkVector advance, InternalLineMetrics metrics, bool addEllipsis)> AddLineToParagraph
SkScalar minIntrinsicWidth() const
void breakTextIntoLines(ParagraphImpl *parent, SkScalar maxWidth, const AddLineToParagraph &addLine)
bool exceededMaxLines() const
SkScalar maxIntrinsicWidth() const
EMSCRIPTEN_KEEPALIVE void empty()
Dart_NativeFunction function