1*c8dee2aaSAndroid Build Coastguard Worker // Copyright 2019 Google LLC. 2*c8dee2aaSAndroid Build Coastguard Worker #ifndef ParagraphImpl_DEFINED 3*c8dee2aaSAndroid Build Coastguard Worker #define ParagraphImpl_DEFINED 4*c8dee2aaSAndroid Build Coastguard Worker 5*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h" 6*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 7*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPicture.h" 8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkOnce.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/DartTypes.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/FontCollection.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/Paragraph.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/ParagraphCache.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/ParagraphStyle.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TextShadow.h" 24*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TextStyle.h" 25*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/Run.h" 26*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/TextLine.h" 27*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode.h" 28*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkBitmaskEnum.h" 29*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTHash.h" 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 32*c8dee2aaSAndroid Build Coastguard Worker #include <string> 33*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker class SkCanvas; 36*c8dee2aaSAndroid Build Coastguard Worker 37*c8dee2aaSAndroid Build Coastguard Worker namespace skia { 38*c8dee2aaSAndroid Build Coastguard Worker namespace textlayout { 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker class LineMetrics; 41*c8dee2aaSAndroid Build Coastguard Worker class TextLine; 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker template <typename T> bool operator==(const SkSpan<T>& a, const SkSpan<T>& b) { 44*c8dee2aaSAndroid Build Coastguard Worker return a.size() == b.size() && a.begin() == b.begin(); 45*c8dee2aaSAndroid Build Coastguard Worker } 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker template <typename T> bool operator<=(const SkSpan<T>& a, const SkSpan<T>& b) { 48*c8dee2aaSAndroid Build Coastguard Worker return a.begin() >= b.begin() && a.end() <= b.end(); 49*c8dee2aaSAndroid Build Coastguard Worker } 50*c8dee2aaSAndroid Build Coastguard Worker 51*c8dee2aaSAndroid Build Coastguard Worker template <typename TStyle> 52*c8dee2aaSAndroid Build Coastguard Worker struct StyleBlock { StyleBlockStyleBlock53*c8dee2aaSAndroid Build Coastguard Worker StyleBlock() : fRange(EMPTY_RANGE), fStyle() { } StyleBlockStyleBlock54*c8dee2aaSAndroid Build Coastguard Worker StyleBlock(size_t start, size_t end, const TStyle& style) : fRange(start, end), fStyle(style) {} StyleBlockStyleBlock55*c8dee2aaSAndroid Build Coastguard Worker StyleBlock(TextRange textRange, const TStyle& style) : fRange(textRange), fStyle(style) {} addStyleBlock56*c8dee2aaSAndroid Build Coastguard Worker void add(TextRange tail) { 57*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fRange.end == tail.start); 58*c8dee2aaSAndroid Build Coastguard Worker fRange = TextRange(fRange.start, fRange.start + fRange.width() + tail.width()); 59*c8dee2aaSAndroid Build Coastguard Worker } 60*c8dee2aaSAndroid Build Coastguard Worker TextRange fRange; 61*c8dee2aaSAndroid Build Coastguard Worker TStyle fStyle; 62*c8dee2aaSAndroid Build Coastguard Worker }; 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker struct ResolvedFontDescriptor { ResolvedFontDescriptorResolvedFontDescriptor65*c8dee2aaSAndroid Build Coastguard Worker ResolvedFontDescriptor(TextIndex index, SkFont font) 66*c8dee2aaSAndroid Build Coastguard Worker : fFont(std::move(font)), fTextStart(index) {} 67*c8dee2aaSAndroid Build Coastguard Worker SkFont fFont; 68*c8dee2aaSAndroid Build Coastguard Worker TextIndex fTextStart; 69*c8dee2aaSAndroid Build Coastguard Worker }; 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker enum InternalState { 72*c8dee2aaSAndroid Build Coastguard Worker kUnknown = 0, 73*c8dee2aaSAndroid Build Coastguard Worker kIndexed = 1, // Text is indexed 74*c8dee2aaSAndroid Build Coastguard Worker kShaped = 2, // Text is shaped 75*c8dee2aaSAndroid Build Coastguard Worker kLineBroken = 5, 76*c8dee2aaSAndroid Build Coastguard Worker kFormatted = 6, 77*c8dee2aaSAndroid Build Coastguard Worker kDrawn = 7 78*c8dee2aaSAndroid Build Coastguard Worker }; 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker /* 81*c8dee2aaSAndroid Build Coastguard Worker struct BidiRegion { 82*c8dee2aaSAndroid Build Coastguard Worker BidiRegion(size_t start, size_t end, uint8_t dir) 83*c8dee2aaSAndroid Build Coastguard Worker : text(start, end), direction(dir) { } 84*c8dee2aaSAndroid Build Coastguard Worker TextRange text; 85*c8dee2aaSAndroid Build Coastguard Worker uint8_t direction; 86*c8dee2aaSAndroid Build Coastguard Worker }; 87*c8dee2aaSAndroid Build Coastguard Worker */ 88*c8dee2aaSAndroid Build Coastguard Worker class ParagraphImpl final : public Paragraph { 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker public: 91*c8dee2aaSAndroid Build Coastguard Worker 92*c8dee2aaSAndroid Build Coastguard Worker ParagraphImpl(const SkString& text, 93*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle style, 94*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Block, true> blocks, 95*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Placeholder, true> placeholders, 96*c8dee2aaSAndroid Build Coastguard Worker sk_sp<FontCollection> fonts, 97*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkUnicode> unicode); 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker ParagraphImpl(const std::u16string& utf16text, 100*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle style, 101*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Block, true> blocks, 102*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Placeholder, true> placeholders, 103*c8dee2aaSAndroid Build Coastguard Worker sk_sp<FontCollection> fonts, 104*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkUnicode> unicode); 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker ~ParagraphImpl() override; 107*c8dee2aaSAndroid Build Coastguard Worker 108*c8dee2aaSAndroid Build Coastguard Worker void layout(SkScalar width) override; 109*c8dee2aaSAndroid Build Coastguard Worker void paint(SkCanvas* canvas, SkScalar x, SkScalar y) override; 110*c8dee2aaSAndroid Build Coastguard Worker void paint(ParagraphPainter* canvas, SkScalar x, SkScalar y) override; 111*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> getRectsForRange(unsigned start, 112*c8dee2aaSAndroid Build Coastguard Worker unsigned end, 113*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rectHeightStyle, 114*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rectWidthStyle) override; 115*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> getRectsForPlaceholders() override; 116*c8dee2aaSAndroid Build Coastguard Worker void getLineMetrics(std::vector<LineMetrics>&) override; 117*c8dee2aaSAndroid Build Coastguard Worker PositionWithAffinity getGlyphPositionAtCoordinate(SkScalar dx, SkScalar dy) override; 118*c8dee2aaSAndroid Build Coastguard Worker SkRange<size_t> getWordBoundary(unsigned offset) override; 119*c8dee2aaSAndroid Build Coastguard Worker getApplyRoundingHack()120*c8dee2aaSAndroid Build Coastguard Worker bool getApplyRoundingHack() const { return fParagraphStyle.getApplyRoundingHack(); } 121*c8dee2aaSAndroid Build Coastguard Worker lineNumber()122*c8dee2aaSAndroid Build Coastguard Worker size_t lineNumber() override { return fLines.size(); } 123*c8dee2aaSAndroid Build Coastguard Worker 124*c8dee2aaSAndroid Build Coastguard Worker TextLine& addLine(SkVector offset, SkVector advance, 125*c8dee2aaSAndroid Build Coastguard Worker TextRange textExcludingSpaces, TextRange text, TextRange textIncludingNewlines, 126*c8dee2aaSAndroid Build Coastguard Worker ClusterRange clusters, ClusterRange clustersWithGhosts, SkScalar widthWithSpaces, 127*c8dee2aaSAndroid Build Coastguard Worker InternalLineMetrics sizes); 128*c8dee2aaSAndroid Build Coastguard Worker text()129*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const char> text() const { return SkSpan<const char>(fText.c_str(), fText.size()); } state()130*c8dee2aaSAndroid Build Coastguard Worker InternalState state() const { return fState; } runs()131*c8dee2aaSAndroid Build Coastguard Worker SkSpan<Run> runs() { return SkSpan<Run>(fRuns.data(), fRuns.size()); } styles()132*c8dee2aaSAndroid Build Coastguard Worker SkSpan<Block> styles() { 133*c8dee2aaSAndroid Build Coastguard Worker return SkSpan<Block>(fTextStyles.data(), fTextStyles.size()); 134*c8dee2aaSAndroid Build Coastguard Worker } placeholders()135*c8dee2aaSAndroid Build Coastguard Worker SkSpan<Placeholder> placeholders() { 136*c8dee2aaSAndroid Build Coastguard Worker return SkSpan<Placeholder>(fPlaceholders.data(), fPlaceholders.size()); 137*c8dee2aaSAndroid Build Coastguard Worker } lines()138*c8dee2aaSAndroid Build Coastguard Worker SkSpan<TextLine> lines() { return SkSpan<TextLine>(fLines.data(), fLines.size()); } paragraphStyle()139*c8dee2aaSAndroid Build Coastguard Worker const ParagraphStyle& paragraphStyle() const { return fParagraphStyle; } clusters()140*c8dee2aaSAndroid Build Coastguard Worker SkSpan<Cluster> clusters() { return SkSpan<Cluster>(fClusters.begin(), fClusters.size()); } fontCollection()141*c8dee2aaSAndroid Build Coastguard Worker sk_sp<FontCollection> fontCollection() const { return fFontCollection; } 142*c8dee2aaSAndroid Build Coastguard Worker void formatLines(SkScalar maxWidth); 143*c8dee2aaSAndroid Build Coastguard Worker void ensureUTF16Mapping(); 144*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<TextIndex> countSurroundingGraphemes(TextRange textRange) const; 145*c8dee2aaSAndroid Build Coastguard Worker TextIndex findNextGraphemeBoundary(TextIndex utf8) const; 146*c8dee2aaSAndroid Build Coastguard Worker TextIndex findPreviousGraphemeBoundary(TextIndex utf8) const; 147*c8dee2aaSAndroid Build Coastguard Worker TextIndex findNextGlyphClusterBoundary(TextIndex utf8) const; 148*c8dee2aaSAndroid Build Coastguard Worker TextIndex findPreviousGlyphClusterBoundary(TextIndex utf8) const; getUTF16Index(TextIndex index)149*c8dee2aaSAndroid Build Coastguard Worker size_t getUTF16Index(TextIndex index) const { 150*c8dee2aaSAndroid Build Coastguard Worker return fUTF16IndexForUTF8Index[index]; 151*c8dee2aaSAndroid Build Coastguard Worker } 152*c8dee2aaSAndroid Build Coastguard Worker strutEnabled()153*c8dee2aaSAndroid Build Coastguard Worker bool strutEnabled() const { return paragraphStyle().getStrutStyle().getStrutEnabled(); } strutForceHeight()154*c8dee2aaSAndroid Build Coastguard Worker bool strutForceHeight() const { 155*c8dee2aaSAndroid Build Coastguard Worker return paragraphStyle().getStrutStyle().getForceStrutHeight(); 156*c8dee2aaSAndroid Build Coastguard Worker } strutHeightOverride()157*c8dee2aaSAndroid Build Coastguard Worker bool strutHeightOverride() const { 158*c8dee2aaSAndroid Build Coastguard Worker return paragraphStyle().getStrutStyle().getHeightOverride(); 159*c8dee2aaSAndroid Build Coastguard Worker } strutMetrics()160*c8dee2aaSAndroid Build Coastguard Worker InternalLineMetrics strutMetrics() const { return fStrutMetrics; } 161*c8dee2aaSAndroid Build Coastguard Worker 162*c8dee2aaSAndroid Build Coastguard Worker SkString getEllipsis() const; 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const char> text(TextRange textRange); 165*c8dee2aaSAndroid Build Coastguard Worker SkSpan<Cluster> clusters(ClusterRange clusterRange); 166*c8dee2aaSAndroid Build Coastguard Worker Cluster& cluster(ClusterIndex clusterIndex); clusterIndex(TextIndex textIndex)167*c8dee2aaSAndroid Build Coastguard Worker ClusterIndex clusterIndex(TextIndex textIndex) { 168*c8dee2aaSAndroid Build Coastguard Worker auto clusterIndex = this->fClustersIndexFromCodeUnit[textIndex]; 169*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(clusterIndex != EMPTY_INDEX); 170*c8dee2aaSAndroid Build Coastguard Worker return clusterIndex; 171*c8dee2aaSAndroid Build Coastguard Worker } run(RunIndex runIndex)172*c8dee2aaSAndroid Build Coastguard Worker Run& run(RunIndex runIndex) { 173*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(runIndex < SkToSizeT(fRuns.size())); 174*c8dee2aaSAndroid Build Coastguard Worker return fRuns[runIndex]; 175*c8dee2aaSAndroid Build Coastguard Worker } 176*c8dee2aaSAndroid Build Coastguard Worker 177*c8dee2aaSAndroid Build Coastguard Worker Run& runByCluster(ClusterIndex clusterIndex); 178*c8dee2aaSAndroid Build Coastguard Worker SkSpan<Block> blocks(BlockRange blockRange); 179*c8dee2aaSAndroid Build Coastguard Worker Block& block(BlockIndex blockIndex); resolvedFonts()180*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<ResolvedFontDescriptor> resolvedFonts() const { return fFontSwitches; } 181*c8dee2aaSAndroid Build Coastguard Worker markDirty()182*c8dee2aaSAndroid Build Coastguard Worker void markDirty() override { 183*c8dee2aaSAndroid Build Coastguard Worker if (fState > kIndexed) { 184*c8dee2aaSAndroid Build Coastguard Worker fState = kIndexed; 185*c8dee2aaSAndroid Build Coastguard Worker } 186*c8dee2aaSAndroid Build Coastguard Worker } 187*c8dee2aaSAndroid Build Coastguard Worker 188*c8dee2aaSAndroid Build Coastguard Worker int32_t unresolvedGlyphs() override; 189*c8dee2aaSAndroid Build Coastguard Worker std::unordered_set<SkUnichar> unresolvedCodepoints() override; 190*c8dee2aaSAndroid Build Coastguard Worker void addUnresolvedCodepoints(TextRange textRange); 191*c8dee2aaSAndroid Build Coastguard Worker 192*c8dee2aaSAndroid Build Coastguard Worker void setState(InternalState state); getPicture()193*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> getPicture() { return fPicture; } 194*c8dee2aaSAndroid Build Coastguard Worker widthWithTrailingSpaces()195*c8dee2aaSAndroid Build Coastguard Worker SkScalar widthWithTrailingSpaces() { return fMaxWidthWithTrailingSpaces; } 196*c8dee2aaSAndroid Build Coastguard Worker 197*c8dee2aaSAndroid Build Coastguard Worker void resetContext(); 198*c8dee2aaSAndroid Build Coastguard Worker void resolveStrut(); 199*c8dee2aaSAndroid Build Coastguard Worker 200*c8dee2aaSAndroid Build Coastguard Worker bool computeCodeUnitProperties(); 201*c8dee2aaSAndroid Build Coastguard Worker void applySpacingAndBuildClusterTable(); 202*c8dee2aaSAndroid Build Coastguard Worker void buildClusterTable(); 203*c8dee2aaSAndroid Build Coastguard Worker bool shapeTextIntoEndlessLine(); 204*c8dee2aaSAndroid Build Coastguard Worker void breakShapedTextIntoLines(SkScalar maxWidth); 205*c8dee2aaSAndroid Build Coastguard Worker 206*c8dee2aaSAndroid Build Coastguard Worker void updateTextAlign(TextAlign textAlign) override; 207*c8dee2aaSAndroid Build Coastguard Worker void updateFontSize(size_t from, size_t to, SkScalar fontSize) override; 208*c8dee2aaSAndroid Build Coastguard Worker void updateForegroundPaint(size_t from, size_t to, SkPaint paint) override; 209*c8dee2aaSAndroid Build Coastguard Worker void updateBackgroundPaint(size_t from, size_t to, SkPaint paint) override; 210*c8dee2aaSAndroid Build Coastguard Worker 211*c8dee2aaSAndroid Build Coastguard Worker void visit(const Visitor&) override; 212*c8dee2aaSAndroid Build Coastguard Worker void extendedVisit(const ExtendedVisitor&) override; 213*c8dee2aaSAndroid Build Coastguard Worker int getPath(int lineNumber, SkPath* dest) override; 214*c8dee2aaSAndroid Build Coastguard Worker bool containsColorFontOrBitmap(SkTextBlob* textBlob) override; 215*c8dee2aaSAndroid Build Coastguard Worker bool containsEmoji(SkTextBlob* textBlob) override; 216*c8dee2aaSAndroid Build Coastguard Worker 217*c8dee2aaSAndroid Build Coastguard Worker int getLineNumberAt(TextIndex codeUnitIndex) const override; 218*c8dee2aaSAndroid Build Coastguard Worker int getLineNumberAtUTF16Offset(size_t codeUnitIndex) override; 219*c8dee2aaSAndroid Build Coastguard Worker bool getLineMetricsAt(int lineNumber, LineMetrics* lineMetrics) const override; 220*c8dee2aaSAndroid Build Coastguard Worker TextRange getActualTextRange(int lineNumber, bool includeSpaces) const override; 221*c8dee2aaSAndroid Build Coastguard Worker bool getGlyphClusterAt(TextIndex codeUnitIndex, GlyphClusterInfo* glyphInfo) override; 222*c8dee2aaSAndroid Build Coastguard Worker bool getClosestGlyphClusterAt(SkScalar dx, 223*c8dee2aaSAndroid Build Coastguard Worker SkScalar dy, 224*c8dee2aaSAndroid Build Coastguard Worker GlyphClusterInfo* glyphInfo) override; 225*c8dee2aaSAndroid Build Coastguard Worker 226*c8dee2aaSAndroid Build Coastguard Worker bool getGlyphInfoAtUTF16Offset(size_t codeUnitIndex, GlyphInfo* graphemeInfo) override; 227*c8dee2aaSAndroid Build Coastguard Worker bool getClosestUTF16GlyphInfoAt(SkScalar dx, SkScalar dy, GlyphInfo* graphemeInfo) override; 228*c8dee2aaSAndroid Build Coastguard Worker SkFont getFontAt(TextIndex codeUnitIndex) const override; 229*c8dee2aaSAndroid Build Coastguard Worker SkFont getFontAtUTF16Offset(size_t codeUnitIndex) override; 230*c8dee2aaSAndroid Build Coastguard Worker std::vector<FontInfo> getFonts() const override; 231*c8dee2aaSAndroid Build Coastguard Worker getEmptyMetrics()232*c8dee2aaSAndroid Build Coastguard Worker InternalLineMetrics getEmptyMetrics() const { return fEmptyMetrics; } getStrutMetrics()233*c8dee2aaSAndroid Build Coastguard Worker InternalLineMetrics getStrutMetrics() const { return fStrutMetrics; } 234*c8dee2aaSAndroid Build Coastguard Worker 235*c8dee2aaSAndroid Build Coastguard Worker BlockRange findAllBlocks(TextRange textRange); 236*c8dee2aaSAndroid Build Coastguard Worker resetShifts()237*c8dee2aaSAndroid Build Coastguard Worker void resetShifts() { 238*c8dee2aaSAndroid Build Coastguard Worker for (auto& run : fRuns) { 239*c8dee2aaSAndroid Build Coastguard Worker run.resetJustificationShifts(); 240*c8dee2aaSAndroid Build Coastguard Worker } 241*c8dee2aaSAndroid Build Coastguard Worker } 242*c8dee2aaSAndroid Build Coastguard Worker codeUnitHasProperty(size_t index,SkUnicode::CodeUnitFlags property)243*c8dee2aaSAndroid Build Coastguard Worker bool codeUnitHasProperty(size_t index, SkUnicode::CodeUnitFlags property) const { 244*c8dee2aaSAndroid Build Coastguard Worker return (fCodeUnitProperties[index] & property) == property; 245*c8dee2aaSAndroid Build Coastguard Worker } 246*c8dee2aaSAndroid Build Coastguard Worker getUnicode()247*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkUnicode> getUnicode() { return fUnicode; } 248*c8dee2aaSAndroid Build Coastguard Worker 249*c8dee2aaSAndroid Build Coastguard Worker private: 250*c8dee2aaSAndroid Build Coastguard Worker friend class ParagraphBuilder; 251*c8dee2aaSAndroid Build Coastguard Worker friend class ParagraphCacheKey; 252*c8dee2aaSAndroid Build Coastguard Worker friend class ParagraphCacheValue; 253*c8dee2aaSAndroid Build Coastguard Worker friend class ParagraphCache; 254*c8dee2aaSAndroid Build Coastguard Worker 255*c8dee2aaSAndroid Build Coastguard Worker friend class TextWrapper; 256*c8dee2aaSAndroid Build Coastguard Worker friend class OneLineShaper; 257*c8dee2aaSAndroid Build Coastguard Worker 258*c8dee2aaSAndroid Build Coastguard Worker void computeEmptyMetrics(); 259*c8dee2aaSAndroid Build Coastguard Worker 260*c8dee2aaSAndroid Build Coastguard Worker // Input 261*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<StyleBlock<SkScalar>> fLetterSpaceStyles; 262*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<StyleBlock<SkScalar>> fWordSpaceStyles; 263*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<StyleBlock<SkPaint>> fBackgroundStyles; 264*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<StyleBlock<SkPaint>> fForegroundStyles; 265*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<StyleBlock<std::vector<TextShadow>>> fShadowStyles; 266*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<StyleBlock<Decoration>> fDecorationStyles; 267*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Block, true> fTextStyles; // TODO: take out only the font stuff 268*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Placeholder, true> fPlaceholders; 269*c8dee2aaSAndroid Build Coastguard Worker SkString fText; 270*c8dee2aaSAndroid Build Coastguard Worker 271*c8dee2aaSAndroid Build Coastguard Worker // Internal structures 272*c8dee2aaSAndroid Build Coastguard Worker InternalState fState; 273*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Run, false> fRuns; // kShaped 274*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<Cluster, true> fClusters; // kClusterized (cached: text, word spacing, letter spacing, resolved fonts) 275*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<SkUnicode::CodeUnitFlags, true> fCodeUnitProperties; 276*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<size_t, true> fClustersIndexFromCodeUnit; 277*c8dee2aaSAndroid Build Coastguard Worker std::vector<size_t> fWords; 278*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::BidiRegion> fBidiRegions; 279*c8dee2aaSAndroid Build Coastguard Worker // These two arrays are used in measuring methods (getRectsForRange, getGlyphPositionAtCoordinate) 280*c8dee2aaSAndroid Build Coastguard Worker // They are filled lazily whenever they need and cached 281*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<TextIndex, true> fUTF8IndexForUTF16Index; 282*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<size_t, true> fUTF16IndexForUTF8Index; 283*c8dee2aaSAndroid Build Coastguard Worker SkOnce fillUTF16MappingOnce; 284*c8dee2aaSAndroid Build Coastguard Worker size_t fUnresolvedGlyphs; 285*c8dee2aaSAndroid Build Coastguard Worker std::unordered_set<SkUnichar> fUnresolvedCodepoints; 286*c8dee2aaSAndroid Build Coastguard Worker 287*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<TextLine, false> fLines; // kFormatted (cached: width, max lines, ellipsis, text align) 288*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> fPicture; // kRecorded (cached: text styles) 289*c8dee2aaSAndroid Build Coastguard Worker 290*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<ResolvedFontDescriptor> fFontSwitches; 291*c8dee2aaSAndroid Build Coastguard Worker 292*c8dee2aaSAndroid Build Coastguard Worker InternalLineMetrics fEmptyMetrics; 293*c8dee2aaSAndroid Build Coastguard Worker InternalLineMetrics fStrutMetrics; 294*c8dee2aaSAndroid Build Coastguard Worker 295*c8dee2aaSAndroid Build Coastguard Worker SkScalar fOldWidth; 296*c8dee2aaSAndroid Build Coastguard Worker SkScalar fOldHeight; 297*c8dee2aaSAndroid Build Coastguard Worker SkScalar fMaxWidthWithTrailingSpaces; 298*c8dee2aaSAndroid Build Coastguard Worker 299*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkUnicode> fUnicode; 300*c8dee2aaSAndroid Build Coastguard Worker bool fHasLineBreaks; 301*c8dee2aaSAndroid Build Coastguard Worker bool fHasWhitespacesInside; 302*c8dee2aaSAndroid Build Coastguard Worker TextIndex fTrailingSpaces; 303*c8dee2aaSAndroid Build Coastguard Worker }; 304*c8dee2aaSAndroid Build Coastguard Worker } // namespace textlayout 305*c8dee2aaSAndroid Build Coastguard Worker } // namespace skia 306*c8dee2aaSAndroid Build Coastguard Worker 307*c8dee2aaSAndroid Build Coastguard Worker 308*c8dee2aaSAndroid Build Coastguard Worker #endif // ParagraphImpl_DEFINED 309