1 // Copyright 2021 Google LLC. 2 #ifndef Painter_DEFINED 3 #define Painter_DEFINED 4 #include "experimental/sktext/include/Text.h" 5 #include "experimental/sktext/include/Types.h" 6 #include "include/core/SkCanvas.h" 7 8 namespace skia { 9 namespace text { 10 11 struct DecoratedBlock { DecoratedBlockDecoratedBlock12 DecoratedBlock(uint32_t count, SkPaint fg, SkPaint bg) 13 : charCount(count) 14 , foregroundPaint(std::move(fg)) 15 , backgroundPaint(std::move(bg)) { } 16 uint32_t charCount; 17 SkPaint foregroundPaint; 18 SkPaint backgroundPaint; 19 }; 20 21 class TrivialFontChain : public FontChain { 22 public: TrivialFontChain(const char * ff,SkScalar size,SkFontStyle fontStyle)23 TrivialFontChain(const char* ff, SkScalar size, SkFontStyle fontStyle) 24 : fTypeface(sk_sp<SkTypeface>(SkFontMgr::RefDefault()->matchFamilyStyle(ff, SkFontStyle::Normal()))) 25 , fSize(size) 26 , fFontStyle(fontStyle) { } count()27 size_t count() const override { return (size_t)1; } 28 sk_sp<SkTypeface> operator[](size_t index) const override { 29 SkASSERT(index == 0); 30 return fTypeface; 31 } fontSize()32 float fontSize() const override { return fSize; } locale()33 SkString locale() const override { return SkString("en"); } getTypeface()34 sk_sp<SkTypeface> getTypeface() const { return fTypeface; } empty()35 bool empty() const { return fTypeface == nullptr; } 36 37 private: 38 sk_sp<SkTypeface> fTypeface; 39 SkScalar fSize; 40 SkFontStyle fFontStyle; 41 }; 42 43 class MultipleFontChain : public FontChain { 44 public: MultipleFontChain(std::vector<const char * > ffs,SkScalar size,SkFontStyle fontStyle)45 MultipleFontChain(std::vector<const char*> ffs, SkScalar size, SkFontStyle fontStyle) 46 : fSize(size) 47 , fFontStyle(fontStyle) { 48 for (auto& ff : ffs) { 49 auto typeface = SkFontMgr::RefDefault()->matchFamilyStyle(ff, SkFontStyle::Normal()); 50 if (typeface != nullptr) { 51 fTypefaces.emplace_back(typeface); 52 } 53 } 54 } count()55 size_t count() const override { return fTypefaces.size(); } 56 sk_sp<SkTypeface> operator[](size_t index) const override { 57 SkASSERT(index < fTypefaces.size()); 58 return fTypefaces[index]; 59 } fontSize()60 float fontSize() const override { return fSize; } locale()61 SkString locale() const override { return SkString("en"); } empty()62 bool empty() const { return fTypefaces.empty(); } 63 64 private: 65 std::vector<sk_sp<SkTypeface>> fTypefaces; 66 SkScalar fSize; 67 SkFontStyle fFontStyle; 68 }; 69 70 class Paint : public Visitor { 71 public: 72 void paint(SkCanvas* canvas, SkPoint xy, UnicodeText* unicodeText, WrappedText* wrappedText, SkSpan<DecoratedBlock> decoratedBlocks); 73 // Simplification (using default font manager, default font family and default everything possible) 74 static bool drawText(std::u16string text, SkCanvas* canvas, SkScalar x, SkScalar y); 75 static bool drawText(std::u16string text, SkCanvas* canvas, SkScalar width); 76 static bool drawText(std::u16string text, SkCanvas* canvas, 77 TextDirection textDirection, TextAlign textAlign, 78 SkPaint foreground, SkPaint background, 79 const SkString& fontFamily, SkScalar fontSize, SkFontStyle fontStyle, 80 SkScalar x, SkScalar y); 81 static bool drawText(std::u16string text, SkCanvas* canvas, 82 TextDirection textDirection, TextAlign textAlign, 83 SkPaint foreground, SkPaint background, 84 const SkString& fontFamily, SkScalar fontSize, SkFontStyle fontStyle, 85 SkSize reqSize, SkScalar x, SkScalar y); 86 87 private: 88 static std::unique_ptr<WrappedText> layout(std::u16string text, 89 TextDirection textDirection, TextAlign textAlign, 90 SkSize reqSize, 91 SkSpan<FontBlock> fontBlocks); 92 93 void onGlyphRun(const SkFont& font, 94 DirTextRange dirTextRange, 95 SkRect bounds, 96 TextIndex trailingSpaces, 97 size_t glyphCount, 98 const uint16_t glyphs[], 99 const SkPoint positions[], 100 const TextIndex clusters[]) override; 101 102 // We guarantee that the text range will be inside one of the decorated blocks 103 DecoratedBlock findDecoratedBlock(TextRange textRange); 104 105 SkCanvas* fCanvas; 106 SkPoint fXY; 107 SkSpan<FontBlock> fFontBlocks; 108 SkSpan<DecoratedBlock> fDecoratedBlocks; 109 }; 110 } // namespace text 111 } // namespace skia 112 #endif // Painter_DEFINED 113