1 /* 2 * Copyright 2019 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkottieShaper_DEFINED 9 #define SkottieShaper_DEFINED 10 11 #include "include/core/SkPoint.h" 12 #include "include/utils/SkTextUtils.h" 13 14 #include <vector> 15 16 class SkFontMgr; 17 class SkTextBlob; 18 19 namespace skottie { 20 21 // Helper implementing After Effects text shaping semantics on top of SkShaper. 22 23 class Shaper final { 24 public: 25 struct Fragment { 26 sk_sp<SkTextBlob> fBlob; 27 SkPoint fPos; 28 29 // Only valid for kFragmentGlyphs 30 uint32_t fLineIndex; // 0-based index for the line this fragment belongs to. 31 bool fIsWhitespace; // True if the first code point in the corresponding 32 // cluster is whitespace. 33 }; 34 35 struct Result { 36 std::vector<Fragment> fFragments; 37 size_t fMissingGlyphCount = 0; 38 39 SkRect computeVisualBounds() const; 40 }; 41 42 enum class VAlign : uint8_t { 43 // Align the first line typographical top with the text box top (AE box text). 44 kTop, 45 // Align the first line typographical baseline with the text box top (AE point text). 46 kTopBaseline, 47 48 // Skottie vertical alignment extensions: these are based on an extent box defined (in Y) as 49 // 50 // ------------------------------------------------------ 51 // MIN(visual_top_extent , typographical_top_extent ) 52 // 53 // ... 54 // 55 // MAX(visual_bottom_extent, typographical_bottom_extent) 56 // ------------------------------------------------------ 57 58 // extent box top -> text box top 59 kVisualTop, 60 // extent box center -> text box center 61 kVisualCenter, 62 // extent box bottom -> text box bottom 63 kVisualBottom, 64 }; 65 66 enum class ResizePolicy : uint8_t { 67 // Use the specified text size. 68 kNone, 69 // Resize the text such that the extent box fits (snuggly) in the text box, 70 // both horizontally and vertically. 71 kScaleToFit, 72 // Same kScaleToFit if the text doesn't fit at the specified font size. 73 // Otherwise, same as kNone. 74 kDownscaleToFit, 75 }; 76 77 enum Flags : uint32_t { 78 kNone = 0x00, 79 80 // Split out individual glyphs into separate Fragments 81 // (useful when the caller intends to manipulate glyphs independently). 82 kFragmentGlyphs = 0x01, 83 }; 84 85 struct TextDesc { 86 const sk_sp<SkTypeface>& fTypeface; 87 SkScalar fTextSize, 88 fLineHeight, 89 fAscent; 90 SkTextUtils::Align fHAlign; 91 VAlign fVAlign; 92 ResizePolicy fResize; 93 uint32_t fFlags; 94 }; 95 96 // Performs text layout along an infinite horizontal line, starting at |textPoint|. 97 // Only explicit line breaks (\r) are observed. 98 static Result Shape(const SkString& text, const TextDesc& desc, const SkPoint& textPoint, 99 const sk_sp<SkFontMgr>&); 100 101 // Performs text layout within |textBox|, injecting line breaks as needed to ensure 102 // horizontal fitting. The result is *not* guaranteed to fit vertically (it may extend 103 // below the box bottom). 104 static Result Shape(const SkString& text, const TextDesc& desc, const SkRect& textBox, 105 const sk_sp<SkFontMgr>&); 106 107 private: 108 Shaper() = delete; 109 }; 110 111 } // namespace skottie 112 113 #endif // SkottieShaper_DEFINED 114