• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /* Generated by tools/bookmaker from include/core/SkTextBlob.h and docs/SkTextBlob_Reference.bmh
9    on 2018-08-10 12:59:44. Additional documentation and examples can be found at:
10    https://skia.org/user/api/SkTextBlob_Reference
11 
12    You may edit either file directly. Structural changes to public interfaces require
13    editing both files. After editing docs/SkTextBlob_Reference.bmh, run:
14        bookmaker -b docs -i include/core/SkTextBlob.h -p
15    to create an updated version of this file.
16  */
17 
18 #ifndef SkTextBlob_DEFINED
19 #define SkTextBlob_DEFINED
20 
21 #include "../private/SkTemplates.h"
22 #include "SkFont.h"
23 #include "SkPaint.h"
24 #include "SkString.h"
25 #include "SkRefCnt.h"
26 
27 #include <atomic>
28 
29 struct SkRSXform;
30 struct SkSerialProcs;
31 struct SkDeserialProcs;
32 
33 /** \class SkTextBlob
34     SkTextBlob combines multiple text runs into an immutable container. Each text
35     run consists of glyphs, SkPaint, and position. Only parts of SkPaint related to
36     fonts and text rendering are used by run.
37 */
38 class SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> {
39 public:
40 
41     /** Returns conservative bounding box. Uses SkPaint associated with each glyph to
42         determine glyph bounds, and unions all bounds. Returned bounds may be
43         larger than the bounds of all glyphs in runs.
44 
45         @return  conservative bounding box
46     */
bounds()47     const SkRect& bounds() const { return fBounds; }
48 
49     /** Returns a non-zero value unique among all text blobs.
50 
51         @return  identifier for SkTextBlob
52     */
uniqueID()53     uint32_t uniqueID() const { return fUniqueID; }
54 
55     /** Returns the number of intervals that intersect bounds.
56         bounds describes a pair of lines parallel to the text advance.
57         The return count is zero or a multiple of two, and is at most twice the number of glyphs in
58         the the blob.
59 
60         Pass nullptr for intervals to determine the size of the interval array.
61 
62         Runs within the blob that contain SkRSXform are ignored when computing intercepts.
63 
64         @param bounds     lower and upper line parallel to the advance
65         @param intervals  returned intersections; may be nullptr
66         @param paint      specifies stroking, SkPathEffect that affects the result; may be nullptr
67         @return           number of intersections; may be zero
68      */
69     int getIntercepts(const SkScalar bounds[2], SkScalar intervals[],
70                       const SkPaint* paint = nullptr) const;
71 
72     /** Creates SkTextBlob with a single run.
73 
74         font contains attributes used to define the run text.
75 
76         When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
77         SkTextEncoding::kUTF32, this function uses the default
78         character-to-glyph mapping from the SkTypeface in font.  It does not
79         perform typeface fallback for characters not found in the SkTypeface.
80         It does not perform kerning or other complex shaping; glyphs are
81         positioned based on their default advances.
82 
83         @param text        character code points or glyphs drawn
84         @param byteLength  byte length of text array
85         @param font        text size, typeface, text scale, and so on, used to draw
86         @param encoding    text encoding used in the text array
87         @return            SkTextBlob constructed from one run
88     */
89     static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
90                                           SkTextEncoding encoding = kUTF8_SkTextEncoding);
91 
92     /** Creates SkTextBlob with a single run. string meaning depends on SkTextEncoding;
93         by default, string is encoded as UTF-8.
94 
95         font contains attributes used to define the run text.
96 
97         When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
98         SkTextEncoding::kUTF32, this function uses the default
99         character-to-glyph mapping from the SkTypeface in font.  It does not
100         perform typeface fallback for characters not found in the SkTypeface.
101         It does not perform kerning or other complex shaping; glyphs are
102         positioned based on their default advances.
103 
104         @param string   character code points or glyphs drawn
105         @param font     text size, typeface, text scale, and so on, used to draw
106         @param encoding text encoding used in the text array
107         @return         SkTextBlob constructed from one run
108     */
109     static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
110                                             SkTextEncoding encoding = kUTF8_SkTextEncoding) {
111         if (!string) {
112             return nullptr;
113         }
114         return MakeFromText(string, strlen(string), font, encoding);
115     }
116 
117     /** Experimental.
118         Returns a textblob built from a single run of text with x-positions and a single y value.
119         This is equivalent to using SkTextBlobBuilder and calling allocRunPosH().
120         Returns nullptr if byteLength is zero.
121 
122         @param text        character code points or glyphs drawn (based on encoding)
123         @param byteLength  byte length of text array
124         @param xpos    array of x-positions, must contain values for all of the character points.
125         @param constY  shared y-position for each character point, to be paired with each xpos.
126         @param font    SkFont used for this run
127         @param encoding specifies the encoding of the text array.
128         @return        new textblob or nullptr
129      */
130     static sk_sp<SkTextBlob> MakeFromPosTextH(const void* text, size_t byteLength,
131                                       const SkScalar xpos[], SkScalar constY, const SkFont& font,
132                                       SkTextEncoding encoding = kUTF8_SkTextEncoding);
133 
134     /** Experimental.
135         Returns a textblob built from a single run of text with positions.
136         This is equivalent to using SkTextBlobBuilder and calling allocRunPos().
137         Returns nullptr if byteLength is zero.
138 
139         @param text        character code points or glyphs drawn (based on encoding)
140         @param byteLength  byte length of text array
141         @param pos     array of positions, must contain values for all of the character points.
142         @param font    SkFont used for this run
143         @param encoding specifies the encoding of the text array.
144         @return        new textblob or nullptr
145      */
146     static sk_sp<SkTextBlob> MakeFromPosText(const void* text, size_t byteLength,
147                                              const SkPoint pos[], const SkFont& font,
148                                              SkTextEncoding encoding = kUTF8_SkTextEncoding);
149 
150     // Experimental
151     static sk_sp<SkTextBlob> MakeFromRSXform(const void* text, size_t byteLength,
152                                              const SkRSXform xform[], const SkFont& font,
153                                              SkTextEncoding encoding = kUTF8_SkTextEncoding);
154 
155     /** Writes data to allow later reconstruction of SkTextBlob. memory points to storage
156         to receive the encoded data, and memory_size describes the size of storage.
157         Returns bytes used if provided storage is large enough to hold all data;
158         otherwise, returns zero.
159 
160         procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
161         If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
162         may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
163         is called with a pointer to SkTypeface and user context.
164 
165         @param procs       custom serial data encoders; may be nullptr
166         @param memory      storage for data
167         @param memory_size size of storage
168         @return            bytes written, or zero if required storage is larger than memory_size
169     */
170     size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const;
171 
172     /** Returns storage containing SkData describing SkTextBlob, using optional custom
173         encoders.
174 
175         procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
176         If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
177         may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
178         is called with a pointer to SkTypeface and user context.
179 
180         @param procs  custom serial data encoders; may be nullptr
181         @return       storage containing serialized SkTextBlob
182     */
183     sk_sp<SkData> serialize(const SkSerialProcs& procs) const;
184 
185     /** Recreates SkTextBlob that was serialized into data. Returns constructed SkTextBlob
186         if successful; otherwise, returns nullptr. Fails if size is smaller than
187         required data length, or if data does not permit constructing valid SkTextBlob.
188 
189         procs.fTypefaceProc permits supplying a custom function to decode SkTypeface.
190         If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx
191         may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
192         is called with a pointer to SkTypeface data, data byte length, and user context.
193 
194         @param data   pointer for serial data
195         @param size   size of data
196         @param procs  custom serial data decoders; may be nullptr
197         @return       SkTextBlob constructed from data in memory
198     */
199     static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
200                                          const SkDeserialProcs& procs);
201 
202 private:
203     friend class SkNVRefCnt<SkTextBlob>;
204     class RunRecord;
205 
206     enum GlyphPositioning : uint8_t;
207 
208     explicit SkTextBlob(const SkRect& bounds);
209 
210     ~SkTextBlob();
211 
212     // Memory for objects of this class is created with sk_malloc rather than operator new and must
213     // be freed with sk_free.
214     void operator delete(void* p);
215     void* operator new(size_t);
216     void* operator new(size_t, void* p);
217 
218     static unsigned ScalarsPerGlyph(GlyphPositioning pos);
219 
220     // Call when this blob is part of the key to a cache entry. This allows the cache
221     // to know automatically those entries can be purged when this SkTextBlob is deleted.
notifyAddedToCache(uint32_t cacheID)222     void notifyAddedToCache(uint32_t cacheID) const {
223         fCacheID.store(cacheID);
224     }
225 
226     friend class SkGlyphRunList;
227     friend class GrTextBlobCache;
228     friend class SkTextBlobBuilder;
229     friend class SkTextBlobPriv;
230     friend class SkTextBlobRunIterator;
231 
232     const SkRect                  fBounds;
233     const uint32_t                fUniqueID;
234     mutable std::atomic<uint32_t> fCacheID;
235 
236     SkDEBUGCODE(size_t fStorageSize;)
237 
238     // The actual payload resides in externally-managed storage, following the object.
239     // (see the .cpp for more details)
240 
241     typedef SkRefCnt INHERITED;
242 };
243 
244 /** \class SkTextBlobBuilder
245     Helper class for constructing SkTextBlob.
246 */
247 class SK_API SkTextBlobBuilder {
248 public:
249 
250     /** Constructs empty SkTextBlobBuilder. By default, SkTextBlobBuilder has no runs.
251 
252         @return  empty SkTextBlobBuilder
253     */
254     SkTextBlobBuilder();
255 
256     /** Deletes data allocated internally by SkTextBlobBuilder.
257     */
258     ~SkTextBlobBuilder();
259 
260     /** Returns SkTextBlob built from runs of glyphs added by builder. Returned
261         SkTextBlob is immutable; it may be copied, but its contents may not be altered.
262         Returns nullptr if no runs of glyphs were added by builder.
263 
264         Resets SkTextBlobBuilder to its initial empty state, allowing it to be
265         reused to build a new set of runs.
266 
267         @return  SkTextBlob or nullptr
268     */
269     sk_sp<SkTextBlob> make();
270 
271     /** \struct SkTextBlobBuilder::RunBuffer
272         RunBuffer supplies storage for glyphs and positions within a run.
273 
274         A run is a sequence of glyphs sharing font metrics and positioning.
275         Each run may position its glyphs in one of three ways:
276         by specifying where the first glyph is drawn, and allowing font metrics to
277         determine the advance to subsequent glyphs; by specifying a baseline, and
278         the position on that baseline for each glyph in run; or by providing SkPoint
279         array, one per glyph.
280     */
281     struct RunBuffer {
282         SkGlyphID* glyphs;   //!< storage for glyphs in run
283         SkScalar*  pos;      //!< storage for positions in run
284         char*      utf8text; //!< reserved for future use
285         uint32_t*  clusters; //!< reserved for future use
286 
287         // experimental
pointsRunBuffer288         SkPoint*    points() const { return reinterpret_cast<SkPoint*>(pos); }
289         // experimental
xformsRunBuffer290         SkRSXform*  xforms() const { return reinterpret_cast<SkRSXform*>(pos); }
291     };
292 
293     /** Returns run with storage for glyphs. Caller must write count glyphs to
294         RunBuffer::glyphs before next call to SkTextBlobBuilder.
295 
296         RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
297 
298         Glyphs share metrics in font.
299 
300         Glyphs are positioned on a baseline at (x, y), using font metrics to
301         determine their relative placement.
302 
303         bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
304         bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
305         is computed from (x, y) and RunBuffer::glyphs metrics.
306 
307         @param font    SkFont used for this run
308         @param count   number of glyphs
309         @param x       horizontal offset within the blob
310         @param y       vertical offset within the blob
311         @param bounds  optional run bounding box
312         @return        writable glyph buffer
313     */
314     const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y,
315                               const SkRect* bounds = nullptr);
316 
317     /** Returns run with storage for glyphs and positions along baseline. Caller must
318         write count glyphs to RunBuffer::glyphs, and count scalars to RunBuffer::pos;
319         before next call to SkTextBlobBuilder.
320 
321         RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
322 
323         Glyphs share metrics in font.
324 
325         Glyphs are positioned on a baseline at y, using x-axis positions written by
326         caller to RunBuffer::pos.
327 
328         bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
329         bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
330         is computed from y, RunBuffer::pos, and RunBuffer::glyphs metrics.
331 
332         @param font    SkFont used for this run
333         @param count   number of glyphs
334         @param y       vertical offset within the blob
335         @param bounds  optional run bounding box
336         @return        writable glyph buffer and x-axis position buffer
337     */
338     const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y,
339                                   const SkRect* bounds = nullptr);
340 
341     /** Returns run with storage for glyphs and SkPoint positions. Caller must
342         write count glyphs to RunBuffer::glyphs, and count SkPoint to RunBuffer::pos;
343         before next call to SkTextBlobBuilder.
344 
345         RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
346 
347         Glyphs share metrics in font.
348 
349         Glyphs are positioned using SkPoint written by caller to RunBuffer::pos, using
350         two scalar values for each SkPoint.
351 
352         bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
353         bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
354         is computed from RunBuffer::pos, and RunBuffer::glyphs metrics.
355 
356         @param font    SkFont used for this run
357         @param count   number of glyphs
358         @param bounds  optional run bounding box
359         @return        writable glyph buffer and SkPoint buffer
360     */
361     const RunBuffer& allocRunPos(const SkFont& font, int count,
362                                  const SkRect* bounds = nullptr);
363 
364     // Experimental, RunBuffer.pos points to SkRSXform array
365     const RunBuffer& allocRunRSXform(const SkFont& font, int count);
366 
367 private:
368     const RunBuffer& allocRunText(const SkFont& font,
369                                   int count,
370                                   SkScalar x,
371                                   SkScalar y,
372                                   int textByteCount,
373                                   SkString lang,
374                                   const SkRect* bounds = nullptr);
375     const RunBuffer& allocRunTextPosH(const SkFont& font, int count, SkScalar y,
376                                       int textByteCount, SkString lang,
377                                       const SkRect* bounds = nullptr);
378     const RunBuffer& allocRunTextPos(const SkFont& font, int count,
379                                      int textByteCount, SkString lang,
380                                      const SkRect* bounds = nullptr);
381     const RunBuffer& allocRunRSXform(const SkFont& font, int count,
382                                      int textByteCount, SkString lang,
383                                      const SkRect* bounds = nullptr);
384 
385     void reserve(size_t size);
386     void allocInternal(const SkFont& font, SkTextBlob::GlyphPositioning positioning,
387                        int count, int textBytes, SkPoint offset, const SkRect* bounds);
388     bool mergeRun(const SkFont& font, SkTextBlob::GlyphPositioning positioning,
389                   uint32_t count, SkPoint offset);
390     void updateDeferredBounds();
391 
392     static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
393     static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
394 
395     friend class SkTextBlobPriv;
396     friend class SkTextBlobBuilderPriv;
397 
398     SkAutoTMalloc<uint8_t> fStorage;
399     size_t                 fStorageSize;
400     size_t                 fStorageUsed;
401 
402     SkRect                 fBounds;
403     int                    fRunCount;
404     bool                   fDeferredBounds;
405     size_t                 fLastRun; // index into fStorage
406 
407     RunBuffer              fCurrentRunBuffer;
408 };
409 
410 #endif // SkTextBlob_DEFINED
411