OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2014 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 SkTextBlob_DEFINED | |
9 #define SkTextBlob_DEFINED | |
10 | |
11 #include "SkPaint.h" | |
12 #include "SkRefCnt.h" | |
13 #include "SkTArray.h" | |
14 #include "SkTDArray.h" | |
15 | |
16 /** \class SkTextBlob | |
17 | |
18 SkTextBlob combines multiple text runs into an immutable, ref-counted struct ure. | |
19 */ | |
20 class SkTextBlob : public SkRefCnt { | |
21 public: | |
22 virtual ~SkTextBlob(); | |
23 | |
24 /** Specifies the glyph positioning mode. | |
25 */ | |
26 enum Positioning { | |
27 kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. | |
28 kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar p er glyph. | |
29 kFull_Positioning = 2 // Point positioning -- two scalars per g lyph. | |
30 }; | |
31 | |
32 /** \struct RunInfo | |
33 | |
34 A run is a sequence of (optionally positioned) glyphs sharing the same f ont metrics | |
35 and positioning mode. | |
36 */ | |
37 struct RunInfo { | |
38 uint32_t glyphCount; | |
39 Positioning positioning; | |
40 const uint16_t* glyphs; | |
41 const SkScalar* pos; | |
42 const SkPaint* font; | |
jbroman
2014/08/19 17:39:16
nit: Why not "const SkPaint&"? Is this a sign that
f(malita)
2014/08/20 01:21:57
Good point -- done.
| |
43 | |
44 RunInfo(uint32_t c, Positioning m, const uint16_t* g, const SkScalar* p, const SkPaint *f) | |
45 : glyphCount(c), positioning(m), glyphs(g), pos(p), font(f) { } | |
46 }; | |
47 | |
48 /** | |
49 * Returns the blob bounding box. | |
50 */ | |
51 const SkRect& bounds() const { return fBounds; } | |
52 | |
53 /** | |
54 * Return a non-zero, unique value representing the text blob. | |
55 */ | |
56 uint32_t uniqueID() const; | |
57 | |
58 /** | |
59 * Returns the number of runs in this blob. | |
60 */ | |
61 unsigned runs() const { return fRuns ? fRuns->count() : 0; } | |
62 | |
63 /** | |
64 * Returns a RunInfo struct for the given run index. | |
65 */ | |
66 const RunInfo runInfo(unsigned runIndex) const; | |
jbroman
2014/08/19 17:39:16
Returning a const struct is meaningless (it's the
f(malita)
2014/08/20 01:21:57
Removed from the API.
| |
67 | |
68 private: | |
robertphillips
2014/08/19 15:06:47
// This is ... ?
f(malita)
2014/08/20 01:21:57
Done.
| |
69 struct Run { | |
70 uint32_t count; | |
71 uint32_t glyphStart; // index into fGlyphBuffer | |
72 uint32_t posStart; // index into fPosBuffer | |
73 SkPaint font; | |
74 Positioning positioning; | |
75 }; | |
76 | |
77 SkTextBlob(const uint16_t* glyphs, const SkScalar* pos, const SkTArray<Run>* runs, | |
78 const SkRect& bounds); | |
79 friend class SkTextBlobBuilder; | |
80 | |
81 const uint16_t* fGlyphBuffer; | |
jbroman
2014/08/19 17:39:16
Any reason not to use SkAutoTMalloc or something s
f(malita)
2014/08/20 01:21:57
Done.
| |
82 const SkScalar* fPosBuffer; | |
83 const SkTArray<Run>* fRuns; | |
84 const SkRect fBounds; | |
85 | |
86 mutable uint32_t fUniqueID; | |
jbroman
2014/08/19 17:39:16
Why "mutable"? Making this lazy kind of scares me
f(malita)
2014/08/20 01:21:58
(this is the same pattern used by other Skia ID-ed
| |
87 }; | |
88 | |
89 /** \class SkTextBlobBuilder | |
90 | |
91 Helper class for constructing SkTextBlobs. | |
robertphillips
2014/08/19 15:06:47
// Expected use is:
// SkTextBlobBuilder tbb;
| |
92 */ | |
93 class SkTextBlobBuilder { | |
94 private: | |
robertphillips
2014/08/19 15:06:47
// This class ...
specifically what sort of API i
f(malita)
2014/08/20 01:21:57
Removed.
| |
95 class RunBuilderBase { | |
96 public: | |
97 RunBuilderBase(SkTextBlobBuilder* blobBuilder) : fBlobBuilder(blobBuilde r) { } | |
98 | |
99 protected: | |
100 SkTextBlobBuilder* fBlobBuilder; | |
101 }; | |
102 | |
103 public: | |
104 /** | |
105 * @param runs The number of runs to be added, if known. This is a storage hint and | |
106 * not a limit. | |
107 */ | |
108 SkTextBlobBuilder(unsigned runs = 0); | |
109 | |
110 ~SkTextBlobBuilder(); | |
111 | |
112 template <SkTextBlob::Positioning> | |
113 class RunBuilder : public RunBuilderBase { }; | |
114 | |
115 /** | |
116 * Start a text run for the given font and positioning mode. | |
117 * | |
118 * @param glyphCount The number of glyphs in this run, if known. This is a storage hint | |
119 * and not a limit. | |
120 * @param bounds The bounding box for this run, if known. If non-null, it will be used | |
121 * in the blob bounding box computation -- otherwise the builder will | |
122 * measure the run. | |
123 * @return A specialized builder for this run. The run builder is only valid | |
124 * until the next startRun() or build() call. | |
125 */ | |
126 template <SkTextBlob::Positioning POS> | |
127 RunBuilder<POS> startRun(const SkPaint& font, unsigned glyphCount = 0, | |
jbroman
2014/08/19 17:39:15
What do we get by making this a two-step process (
jbroman
2014/08/19 17:39:16
Why document the glyphCount and bounds arguments,
f(malita)
2014/08/20 01:21:57
Done.
f(malita)
2014/08/20 01:21:57
The latter forces clients to format data in a Skia
| |
128 const SkRect* bounds = NULL) { | |
robertphillips
2014/08/19 15:06:47
this->
f(malita)
2014/08/20 01:21:57
Done.
| |
129 ensureRun(font, POS, glyphCount, bounds); | |
130 return RunBuilder<POS>(this); | |
131 } | |
132 | |
133 /** | |
134 * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and | |
135 * can be reused. | |
136 */ | |
137 const SkTextBlob* build(); | |
138 | |
139 private: | |
140 void ensureRun(const SkPaint& font, SkTextBlob::Positioning positioning, uns igned count, | |
141 const SkRect* runBounds); | |
142 void updateRunBounds(); | |
143 | |
144 SkTDArray<uint16_t> fGlyphBuffer; | |
145 SkTDArray<SkScalar> fPosBuffer; | |
146 SkTArray<SkTextBlob::Run>* fRuns; | |
147 | |
148 SkRect fBounds; | |
149 bool fDeferredRunBounds; | |
150 }; | |
151 | |
152 template<> | |
153 class SkTextBlobBuilder::RunBuilder<SkTextBlob::kDefault_Positioning> : public R unBuilderBase { | |
154 public: | |
155 RunBuilder(SkTextBlobBuilder* blobBuilder) : RunBuilderBase(blobBuilder) { } | |
156 | |
157 void addGlyph(uint16_t glyph); | |
158 void addGlyphs(const uint16_t glyphs[], size_t count); | |
159 }; | |
160 | |
robertphillips
2014/08/19 15:06:47
// The Y-value will be supplied in the using SkCan
| |
161 template<> | |
162 class SkTextBlobBuilder::RunBuilder<SkTextBlob::kHorizontal_Positioning> : publi c RunBuilderBase { | |
163 public: | |
164 RunBuilder(SkTextBlobBuilder* blobBuilder) : RunBuilderBase(blobBuilder) { } | |
165 | |
166 void addGlyph(uint16_t glyph, SkScalar x); | |
jbroman
2014/08/19 17:39:16
Would we ever want to add a singular glyph? If it'
| |
167 void addGlyphs(const uint16_t glyphs[], const SkScalar xPos[], size_t count) ; | |
168 }; | |
169 | |
robertphillips
2014/08/19 15:06:47
// All the supplied positions are relative to the
| |
170 template<> | |
171 class SkTextBlobBuilder::RunBuilder<SkTextBlob::kFull_Positioning> : public RunB uilderBase { | |
172 public: | |
173 RunBuilder(SkTextBlobBuilder* blobBuilder) : RunBuilderBase(blobBuilder) { } | |
174 | |
175 void addGlyph(uint16_t glyph, SkScalar x, SkScalar y); | |
robertphillips
2014/08/19 15:06:48
const SkPoint&
| |
176 void addGlyph(uint16_t glyph, SkPoint pos); | |
177 void addGlyphs(const uint16_t glyphs[], const SkScalar xPos[], const SkScala r yPos[], | |
178 size_t count); | |
robertphillips
2014/08/19 15:06:47
pox ?
| |
179 void addGlyphs(const uint16_t glyphs[], const SkPoint pox[], size_t count); | |
jbroman
2014/08/19 17:39:16
What does this method do, given this is the "full
| |
180 }; | |
181 | |
182 #endif // SkTextBlob_DEFINED | |
OLD | NEW |