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