1 // Copyright 2019 Google LLC. 2 #ifndef ParagraphBuilderImpl_DEFINED 3 #define ParagraphBuilderImpl_DEFINED 4 5 #include <memory> 6 #include <stack> 7 #include <string> 8 #include <tuple> 9 #include "include/private/SkOnce.h" 10 #include "include/private/SkTArray.h" 11 #include "modules/skparagraph/include/FontCollection.h" 12 #include "modules/skparagraph/include/Paragraph.h" 13 #include "modules/skparagraph/include/ParagraphBuilder.h" 14 #include "modules/skparagraph/include/ParagraphStyle.h" 15 #include "modules/skparagraph/include/TextStyle.h" 16 17 namespace skia { 18 namespace textlayout { 19 20 class ParagraphBuilderImpl : public ParagraphBuilder { 21 public: 22 ParagraphBuilderImpl(const ParagraphStyle& style, 23 sk_sp<FontCollection> fontCollection, 24 std::unique_ptr<SkUnicode> unicode); 25 26 // Just until we fix all the code; calls icu::make inside 27 ParagraphBuilderImpl(const ParagraphStyle& style, sk_sp<FontCollection> fontCollection); 28 29 ~ParagraphBuilderImpl() override; 30 31 // Push a style to the stack. The corresponding text added with AddText will 32 // use the top-most style. 33 void pushStyle(const TextStyle& style) override; 34 35 // Remove a style from the stack. Useful to apply different styles to chunks 36 // of text such as bolding. 37 // Example: 38 // builder.PushStyle(normal_style); 39 // builder.AddText("Hello this is normal. "); 40 // 41 // builder.PushStyle(bold_style); 42 // builder.AddText("And this is BOLD. "); 43 // 44 // builder.Pop(); 45 // builder.AddText(" Back to normal again."); 46 void pop() override; 47 48 TextStyle peekStyle() override; 49 50 // Adds text to the builder. Forms the proper runs to use the upper-most style 51 // on the style_stack. 52 void addText(const std::u16string& text) override; 53 54 // Adds text to the builder, using the top-most style on on the style_stack. 55 void addText(const char* text) override; // Don't use this one - going away soon 56 void addText(const char* text, size_t len) override; 57 58 void addPlaceholder(const PlaceholderStyle& placeholderStyle) override; 59 60 // Constructs a SkParagraph object that can be used to layout and paint the text to a SkCanvas. 61 std::unique_ptr<Paragraph> Build() override; 62 63 // Support for "Client" unicode 64 SkSpan<char> getText() override; 65 const ParagraphStyle& getParagraphStyle() const override; 66 67 void setWordsUtf8(std::vector<SkUnicode::Position> wordsUtf8) override; 68 void setWordsUtf16(std::vector<SkUnicode::Position> wordsUtf16) override; 69 70 void setGraphemeBreaksUtf8(std::vector<SkUnicode::Position> graphemesUtf8) override; 71 void setGraphemeBreaksUtf16(std::vector<SkUnicode::Position> graphemesUtf16) override; 72 73 void setLineBreaksUtf8(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf8) override; 74 void setLineBreaksUtf16(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf16) override; 75 SetUnicode(std::unique_ptr<SkUnicode> unicode)76 void SetUnicode(std::unique_ptr<SkUnicode> unicode) override { 77 fUnicode = std::move(unicode); 78 } 79 // Support for Flutter optimization 80 void Reset() override; 81 82 static std::unique_ptr<ParagraphBuilder> make(const ParagraphStyle& style, 83 sk_sp<FontCollection> fontCollection, 84 std::unique_ptr<SkUnicode> unicode); 85 86 // Just until we fix all the code; calls icu::make inside 87 static std::unique_ptr<ParagraphBuilder> make(const ParagraphStyle& style, 88 sk_sp<FontCollection> fontCollection); 89 90 static bool RequiresClientICU(); 91 protected: 92 void startStyledBlock(); 93 void endRunIfNeeded(); 94 const TextStyle& internalPeekStyle(); 95 void addPlaceholder(const PlaceholderStyle& placeholderStyle, bool lastOne); 96 void finalize(); 97 98 SkString fUtf8; 99 SkSTArray<4, TextStyle, true> fTextStyles; 100 SkSTArray<4, Block, true> fStyledBlocks; 101 SkSTArray<4, Placeholder, true> fPlaceholders; 102 sk_sp<FontCollection> fFontCollection; 103 ParagraphStyle fParagraphStyle; 104 105 std::shared_ptr<SkUnicode> fUnicode; 106 private: 107 SkOnce fillUTF16MappingOnce; 108 void ensureUTF16Mapping(); 109 SkTArray<TextIndex, true> fUTF8IndexForUTF16Index; 110 SkTArray<TextIndex, true> fUTF16IndexForUTF8Index; 111 #if defined(SK_UNICODE_CLIENT_IMPLEMENTATION) 112 bool fTextIsFinalized; 113 bool fUsingClientInfo; 114 std::vector<SkUnicode::Position> fWordsUtf16; 115 std::vector<SkUnicode::Position> fGraphemeBreaksUtf8; 116 std::vector<SkUnicode::LineBreakBefore> fLineBreaksUtf8; 117 #endif 118 }; 119 } // namespace textlayout 120 } // namespace skia 121 122 #endif // ParagraphBuilderImpl_DEFINED 123