• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         float             fAdvance,
31                           fAscent;
32         uint32_t          fLineIndex;    // 0-based index for the line this fragment belongs to.
33         bool              fIsWhitespace; // True if the first code point in the corresponding
34                                          // cluster is whitespace.
35     };
36 
37     struct Result {
38         std::vector<Fragment> fFragments;
39         size_t                fMissingGlyphCount = 0;
40 
41         SkRect computeVisualBounds() const;
42     };
43 
44     enum class VAlign : uint8_t {
45         // Align the first line typographical top with the text box top (AE box text).
46         kTop,
47         // Align the first line typographical baseline with the text box top (AE point text).
48         kTopBaseline,
49 
50         // Skottie vertical alignment extensions: these are based on an extent box defined (in Y) as
51         //
52         //   ------------------------------------------------------
53         //   MIN(visual_top_extent   , typographical_top_extent   )
54         //
55         //                         ...
56         //
57         //   MAX(visual_bottom_extent, typographical_bottom_extent)
58         //   ------------------------------------------------------
59 
60         // extent box top -> text box top
61         kVisualTop,
62         // extent box center -> text box center
63         kVisualCenter,
64         // extent box bottom -> text box bottom
65         kVisualBottom,
66     };
67 
68     enum class ResizePolicy : uint8_t {
69         // Use the specified text size.
70         kNone,
71         // Resize the text such that the extent box fits (snuggly) in the text box,
72         // both horizontally and vertically.
73         kScaleToFit,
74         // Same kScaleToFit if the text doesn't fit at the specified font size.
75         // Otherwise, same as kNone.
76         kDownscaleToFit,
77     };
78 
79     enum class LinebreakPolicy : uint8_t {
80         // Break lines such that they fit in a non-empty paragraph box, horizontally.
81         kParagraph,
82         // Only break lines when requested explicitly (\r), regardless of paragraph box dimensions.
83         kExplicit,
84     };
85 
86     // Initial text direction.
87     enum class Direction : uint8_t { kLTR, kRTL };
88 
89     enum class Capitalization {
90         kNone,
91         kUpperCase,
92     };
93 
94     enum Flags : uint32_t {
95         kNone                       = 0x00,
96 
97         // Split out individual glyphs into separate Fragments
98         // (useful when the caller intends to manipulate glyphs independently).
99         kFragmentGlyphs             = 0x01,
100 
101         // Compute the advance and ascent for each fragment.
102         kTrackFragmentAdvanceAscent = 0x02,
103     };
104 
105     struct TextDesc {
106         const sk_sp<SkTypeface>&  fTypeface;
107         SkScalar                  fTextSize,
108                                   fMinTextSize,
109                                   fMaxTextSize,
110                                   fLineHeight,
111                                   fLineShift,
112                                   fAscent;
113         SkTextUtils::Align        fHAlign;
114         VAlign                    fVAlign;
115         ResizePolicy              fResize;
116         LinebreakPolicy           fLinebreak;
117         Direction                 fDirection;
118         Capitalization            fCapitalization;
119         uint32_t                  fFlags;
120     };
121 
122     // Performs text layout along an infinite horizontal line, starting at |textPoint|.
123     // Only explicit line breaks (\r) are observed.
124     static Result Shape(const SkString& text, const TextDesc& desc, const SkPoint& textPoint,
125                         const sk_sp<SkFontMgr>&);
126 
127     // Performs text layout within |textBox|, injecting line breaks as needed to ensure
128     // horizontal fitting.  The result is *not* guaranteed to fit vertically (it may extend
129     // below the box bottom).
130     static Result Shape(const SkString& text, const TextDesc& desc, const SkRect& textBox,
131                         const sk_sp<SkFontMgr>&);
132 
133 private:
134     Shaper() = delete;
135 };
136 
137 } // namespace skottie
138 
139 #endif // SkottieShaper_DEFINED
140