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