blob: e59697942cb0c95bbb81110770822fc0dcf95a06 [file] [log] [blame]
fmalita00d5c2c2014-08-21 08:53:26 -07001/*
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
Cary Clarkaf045512018-08-10 13:11:06 -04008/* 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
fmalita00d5c2c2014-08-21 08:53:26 -070018#ifndef SkTextBlob_DEFINED
19#define SkTextBlob_DEFINED
20
bungemanbf521ff2016-02-17 13:13:44 -080021#include "../private/SkTemplates.h"
Mike Reed3185f902018-10-26 16:33:00 -040022#include "SkFont.h"
fmalita00d5c2c2014-08-21 08:53:26 -070023#include "SkPaint.h"
halcanary4f0a23a2016-08-30 11:58:33 -070024#include "SkString.h"
fmalita00d5c2c2014-08-21 08:53:26 -070025#include "SkRefCnt.h"
Hal Canaryc2d0fb12018-09-19 10:28:59 -040026
Mike Klein015c8992018-08-09 12:23:19 -040027#include <atomic>
fmalita00d5c2c2014-08-21 08:53:26 -070028
Mike Reed8e74cbc2017-12-08 13:20:01 -050029struct SkSerialProcs;
30struct SkDeserialProcs;
31
fmalita00d5c2c2014-08-21 08:53:26 -070032/** \class SkTextBlob
Cary Clarkaf045512018-08-10 13:11:06 -040033 SkTextBlob combines multiple text runs into an immutable container. Each text
34 run consists of glyphs, SkPaint, and position. Only parts of SkPaint related to
35 fonts and text rendering are used by run.
fmalita00d5c2c2014-08-21 08:53:26 -070036*/
Mike Klein408ef212018-10-30 15:23:00 +000037class SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> {
fmalita00d5c2c2014-08-21 08:53:26 -070038public:
Cary Clarkaf045512018-08-10 13:11:06 -040039
40 /** Returns conservative bounding box. Uses SkPaint associated with each glyph to
41 determine glyph bounds, and unions all bounds. Returned bounds may be
42 larger than the bounds of all glyphs in runs.
43
44 @return conservative bounding box
45 */
fmalita00d5c2c2014-08-21 08:53:26 -070046 const SkRect& bounds() const { return fBounds; }
47
Cary Clarkaf045512018-08-10 13:11:06 -040048 /** Returns a non-zero value unique among all text blobs.
49
50 @return identifier for SkTextBlob
51 */
joshualitt2af85832015-03-25 13:40:13 -070052 uint32_t uniqueID() const { return fUniqueID; }
fmalita00d5c2c2014-08-21 08:53:26 -070053
Mike Reedae0d8602018-12-10 22:02:17 -050054 /** Returns the number of intervals that intersect bounds.
55 bounds describes a pair of lines parallel to the text advance.
56 The return count is zero or a multiple of two, and is at most twice the number of glyphs in
57 the the blob.
58
59 Pass nullptr for intervals to determine the size of the interval array.
60
61 @param bounds lower and upper line parallel to the advance
62 @param intervals returned intersections; may be nullptr
63 @param paint specifies stroking, patheffect that may affect the result; may be nullptr
64 @return number of intersections; may be zero
65 */
66 int getIntercepts(const SkScalar bounds[2], SkScalar intervals[],
67 const SkPaint* paint = nullptr) const;
68
Mike Reed3185f902018-10-26 16:33:00 -040069 /** Creates SkTextBlob with a single run.
Cary Clarkaf045512018-08-10 13:11:06 -040070
Cary Clark77b3f3a2018-11-07 14:59:03 -050071 font contains attributes used to define the run text.
Cary Clarkaf045512018-08-10 13:11:06 -040072
73 @param text character code points or glyphs drawn
74 @param byteLength byte length of text array
Mike Reed3185f902018-10-26 16:33:00 -040075 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040076 @return SkTextBlob constructed from one run
77 */
Mike Reed3185f902018-10-26 16:33:00 -040078 static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
Mike Reed97f3cc22018-12-03 09:45:17 -050079 SkTextEncoding encoding = kUTF8_SkTextEncoding);
Herb Derby4b3a5152018-07-17 16:10:30 -040080
Mike Reed97f3cc22018-12-03 09:45:17 -050081 /** Creates SkTextBlob with a single run. string meaning depends on SkTextEncoding;
Cary Clarkaf045512018-08-10 13:11:06 -040082 by default, string is encoded as UTF-8.
83
Cary Clark77b3f3a2018-11-07 14:59:03 -050084 font contains attributes used to define the run text.
Cary Clarkaf045512018-08-10 13:11:06 -040085
86 @param string character code points or glyphs drawn
Mike Reed3185f902018-10-26 16:33:00 -040087 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040088 @return SkTextBlob constructed from one run
89 */
Mike Reed3185f902018-10-26 16:33:00 -040090 static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
Mike Reed97f3cc22018-12-03 09:45:17 -050091 SkTextEncoding encoding = kUTF8_SkTextEncoding) {
Cary Clarke12a0902018-08-09 10:07:33 -040092 if (!string) {
93 return nullptr;
94 }
Mike Reed3185f902018-10-26 16:33:00 -040095 return MakeFromText(string, strlen(string), font, encoding);
Cary Clarke12a0902018-08-09 10:07:33 -040096 }
97
Mike Reedefb518d2018-12-06 13:30:23 -050098 /** Experimental.
99 Returns a textblob built from a single run of text with x-positions and a single y value.
100 This is equivalent to using SkTextBlobBuilder and calling allocRunPosH().
101 Returns nullptr if byteLength is zero.
102
103 @param text character code points or glyphs drawn (based on encoding)
104 @param byteLength byte length of text array
105 @param xpos array of x-positions, must contain values for all of the character points.
106 @param constY shared y-position for each character point, to be paired with each xpos.
107 @param font SkFont used for this run
108 @param encoding specifies the encoding of the text array.
109 @return new textblob or nullptr
110 */
111 static sk_sp<SkTextBlob> MakeFromPosTextH(const void* text, size_t byteLength,
112 const SkScalar xpos[], SkScalar constY, const SkFont& font,
113 SkTextEncoding encoding = kUTF8_SkTextEncoding);
114
115 /** Experimental.
116 Returns a textblob built from a single run of text with positions.
117 This is equivalent to using SkTextBlobBuilder and calling allocRunPos().
118 Returns nullptr if byteLength is zero.
119
120 @param text character code points or glyphs drawn (based on encoding)
121 @param byteLength byte length of text array
122 @param pos array of positions, must contain values for all of the character points.
123 @param font SkFont used for this run
124 @param encoding specifies the encoding of the text array.
125 @return new textblob or nullptr
126 */
127 static sk_sp<SkTextBlob> MakeFromPosText(const void* text, size_t byteLength,
128 const SkPoint pos[], const SkFont& font,
129 SkTextEncoding encoding = kUTF8_SkTextEncoding);
130
Cary Clarkaf045512018-08-10 13:11:06 -0400131 /** Writes data to allow later reconstruction of SkTextBlob. memory points to storage
132 to receive the encoded data, and memory_size describes the size of storage.
133 Returns bytes used if provided storage is large enough to hold all data;
134 otherwise, returns zero.
135
136 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
137 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
138 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
139 is called with a pointer to SkTypeface and user context.
140
Cary Clark82456492018-10-31 10:54:50 -0400141 @param procs custom serial data encoders; may be nullptr
142 @param memory storage for data
143 @param memory_size size of storage
144 @return bytes written, or zero if required storage is larger than memory_size
Cary Clarkaf045512018-08-10 13:11:06 -0400145 */
Khushal42f8bc42018-04-03 17:51:40 -0700146 size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const;
147
Cary Clarkaf045512018-08-10 13:11:06 -0400148 /** Returns storage containing SkData describing SkTextBlob, using optional custom
149 encoders.
150
151 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
152 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
153 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
154 is called with a pointer to SkTypeface and user context.
155
156 @param procs custom serial data encoders; may be nullptr
157 @return storage containing serialized SkTextBlob
158 */
Cary Clark785586a2018-07-19 10:07:01 -0400159 sk_sp<SkData> serialize(const SkSerialProcs& procs) const;
Mike Reedaaa30562017-07-21 11:53:23 -0400160
Cary Clarkaf045512018-08-10 13:11:06 -0400161 /** Recreates SkTextBlob that was serialized into data. Returns constructed SkTextBlob
162 if successful; otherwise, returns nullptr. Fails if size is smaller than
163 required data length, or if data does not permit constructing valid SkTextBlob.
164
165 procs.fTypefaceProc permits supplying a custom function to decode SkTypeface.
166 If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx
167 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
168 is called with a pointer to SkTypeface data, data byte length, and user context.
169
170 @param data pointer for serial data
171 @param size size of data
172 @param procs custom serial data decoders; may be nullptr
173 @return SkTextBlob constructed from data in memory
174 */
Cary Clark785586a2018-07-19 10:07:01 -0400175 static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
176 const SkDeserialProcs& procs);
Mike Reed8e74cbc2017-12-08 13:20:01 -0500177
halcanary33779752015-10-27 14:01:05 -0700178private:
Mike Klein408ef212018-10-30 15:23:00 +0000179 friend class SkNVRefCnt<SkTextBlob>;
fmalita3c196de2014-09-20 05:40:22 -0700180 class RunRecord;
181
Florin Malitaab54e732018-07-27 09:47:15 -0400182 enum GlyphPositioning : uint8_t;
183
Florin Malita3a9a7a32017-03-13 09:03:24 -0400184 explicit SkTextBlob(const SkRect& bounds);
fmalita00d5c2c2014-08-21 08:53:26 -0700185
mtkleinb47cd4b2016-08-09 12:20:04 -0700186 ~SkTextBlob();
bsalomon07280312014-11-20 08:02:46 -0800187
188 // Memory for objects of this class is created with sk_malloc rather than operator new and must
189 // be freed with sk_free.
Yong-Hwan Baek688a8e52018-07-09 14:14:26 +0900190 void operator delete(void* p);
191 void* operator new(size_t);
192 void* operator new(size_t, void* p);
fmalita00d5c2c2014-08-21 08:53:26 -0700193
fmalitab7425172014-08-26 07:56:44 -0700194 static unsigned ScalarsPerGlyph(GlyphPositioning pos);
195
Florin Malita4a01ac92017-03-13 16:45:28 -0400196 // Call when this blob is part of the key to a cache entry. This allows the cache
197 // to know automatically those entries can be purged when this SkTextBlob is deleted.
Jim Van Verth474d6872017-12-14 13:00:05 -0500198 void notifyAddedToCache(uint32_t cacheID) const {
199 fCacheID.store(cacheID);
Florin Malita4a01ac92017-03-13 16:45:28 -0400200 }
201
Herb Derby8a6348e2018-07-12 15:30:35 -0400202 friend class SkGlyphRunList;
Florin Malita4a01ac92017-03-13 16:45:28 -0400203 friend class GrTextBlobCache;
fmalita00d5c2c2014-08-21 08:53:26 -0700204 friend class SkTextBlobBuilder;
Cary Clark53c87692018-07-17 08:59:34 -0400205 friend class SkTextBlobPriv;
halcanary33779752015-10-27 14:01:05 -0700206 friend class SkTextBlobRunIterator;
fmalita00d5c2c2014-08-21 08:53:26 -0700207
Mike Klein015c8992018-08-09 12:23:19 -0400208 const SkRect fBounds;
209 const uint32_t fUniqueID;
210 mutable std::atomic<uint32_t> fCacheID;
fmalita00d5c2c2014-08-21 08:53:26 -0700211
fmalita3c196de2014-09-20 05:40:22 -0700212 SkDEBUGCODE(size_t fStorageSize;)
fmalita00d5c2c2014-08-21 08:53:26 -0700213
fmalita3c196de2014-09-20 05:40:22 -0700214 // The actual payload resides in externally-managed storage, following the object.
215 // (see the .cpp for more details)
fmalita00d5c2c2014-08-21 08:53:26 -0700216
217 typedef SkRefCnt INHERITED;
218};
219
220/** \class SkTextBlobBuilder
Cary Clarkaf045512018-08-10 13:11:06 -0400221 Helper class for constructing SkTextBlob.
222*/
jbroman3053dfa2014-08-25 06:22:12 -0700223class SK_API SkTextBlobBuilder {
fmalita00d5c2c2014-08-21 08:53:26 -0700224public:
Cary Clarkaf045512018-08-10 13:11:06 -0400225
226 /** Constructs empty SkTextBlobBuilder. By default, SkTextBlobBuilder has no runs.
227
228 @return empty SkTextBlobBuilder
229 */
fmalita3c196de2014-09-20 05:40:22 -0700230 SkTextBlobBuilder();
fmalita00d5c2c2014-08-21 08:53:26 -0700231
Cary Clarkaf045512018-08-10 13:11:06 -0400232 /** Deletes data allocated internally by SkTextBlobBuilder.
233 */
fmalita00d5c2c2014-08-21 08:53:26 -0700234 ~SkTextBlobBuilder();
235
Cary Clarkaf045512018-08-10 13:11:06 -0400236 /** Returns SkTextBlob built from runs of glyphs added by builder. Returned
237 SkTextBlob is immutable; it may be copied, but its contents may not be altered.
238 Returns nullptr if no runs of glyphs were added by builder.
239
240 Resets SkTextBlobBuilder to its initial empty state, allowing it to be
241 reused to build a new set of runs.
242
243 @return SkTextBlob or nullptr
244 */
reed2ab90572016-08-10 14:16:41 -0700245 sk_sp<SkTextBlob> make();
246
Cary Clarkaf045512018-08-10 13:11:06 -0400247 /** \struct SkTextBlobBuilder::RunBuffer
248 RunBuffer supplies storage for glyphs and positions within a run.
249
Cary Clark77b3f3a2018-11-07 14:59:03 -0500250 A run is a sequence of glyphs sharing font metrics and positioning.
Cary Clarkaf045512018-08-10 13:11:06 -0400251 Each run may position its glyphs in one of three ways:
Cary Clark77b3f3a2018-11-07 14:59:03 -0500252 by specifying where the first glyph is drawn, and allowing font metrics to
Cary Clarkaf045512018-08-10 13:11:06 -0400253 determine the advance to subsequent glyphs; by specifying a baseline, and
254 the position on that baseline for each glyph in run; or by providing SkPoint
255 array, one per glyph.
256 */
fmalita00d5c2c2014-08-21 08:53:26 -0700257 struct RunBuffer {
Cary Clarkaf045512018-08-10 13:11:06 -0400258 SkGlyphID* glyphs; //!< storage for glyphs in run
259 SkScalar* pos; //!< storage for positions in run
260 char* utf8text; //!< reserved for future use
261 uint32_t* clusters; //!< reserved for future use
fmalita00d5c2c2014-08-21 08:53:26 -0700262 };
263
Cary Clarkaf045512018-08-10 13:11:06 -0400264 /** Returns run with storage for glyphs. Caller must write count glyphs to
Cary Clark77b3f3a2018-11-07 14:59:03 -0500265 RunBuffer::glyphs before next call to SkTextBlobBuilder.
Cary Clarkaf045512018-08-10 13:11:06 -0400266
Cary Clark77b3f3a2018-11-07 14:59:03 -0500267 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
Cary Clarkaf045512018-08-10 13:11:06 -0400268
Cary Clark77b3f3a2018-11-07 14:59:03 -0500269 Glyphs share metrics in font.
Cary Clarkaf045512018-08-10 13:11:06 -0400270
Cary Clark77b3f3a2018-11-07 14:59:03 -0500271 Glyphs are positioned on a baseline at (x, y), using font metrics to
Cary Clarkaf045512018-08-10 13:11:06 -0400272 determine their relative placement.
273
274 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
275 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
Cary Clark77b3f3a2018-11-07 14:59:03 -0500276 is computed from (x, y) and RunBuffer::glyphs metrics.
Cary Clarkaf045512018-08-10 13:11:06 -0400277
Cary Clark77b3f3a2018-11-07 14:59:03 -0500278 @param font SkFont used for this run
Cary Clarkaf045512018-08-10 13:11:06 -0400279 @param count number of glyphs
280 @param x horizontal offset within the blob
281 @param y vertical offset within the blob
282 @param bounds optional run bounding box
283 @return writable glyph buffer
284 */
Cary Clark77b3f3a2018-11-07 14:59:03 -0500285 const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y,
286 const SkRect* bounds = nullptr);
fmalita00d5c2c2014-08-21 08:53:26 -0700287
Cary Clarkaf045512018-08-10 13:11:06 -0400288 /** Returns run with storage for glyphs and positions along baseline. Caller must
Cary Clark77b3f3a2018-11-07 14:59:03 -0500289 write count glyphs to RunBuffer::glyphs, and count scalars to RunBuffer::pos;
290 before next call to SkTextBlobBuilder.
Cary Clarkaf045512018-08-10 13:11:06 -0400291
Cary Clark77b3f3a2018-11-07 14:59:03 -0500292 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
Cary Clarkaf045512018-08-10 13:11:06 -0400293
Cary Clark77b3f3a2018-11-07 14:59:03 -0500294 Glyphs share metrics in font.
Cary Clarkaf045512018-08-10 13:11:06 -0400295
296 Glyphs are positioned on a baseline at y, using x-axis positions written by
Cary Clark77b3f3a2018-11-07 14:59:03 -0500297 caller to RunBuffer::pos.
Cary Clarkaf045512018-08-10 13:11:06 -0400298
299 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
300 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
Cary Clark77b3f3a2018-11-07 14:59:03 -0500301 is computed from y, RunBuffer::pos, and RunBuffer::glyphs metrics.
Cary Clarkaf045512018-08-10 13:11:06 -0400302
Cary Clark77b3f3a2018-11-07 14:59:03 -0500303 @param font SkFont used for this run
Cary Clarkaf045512018-08-10 13:11:06 -0400304 @param count number of glyphs
305 @param y vertical offset within the blob
306 @param bounds optional run bounding box
307 @return writable glyph buffer and x-axis position buffer
308 */
Cary Clark77b3f3a2018-11-07 14:59:03 -0500309 const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y,
310 const SkRect* bounds = nullptr);
311
312 /** Returns run with storage for glyphs and SkPoint positions. Caller must
313 write count glyphs to RunBuffer::glyphs, and count SkPoint to RunBuffer::pos;
314 before next call to SkTextBlobBuilder.
315
316 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
317
318 Glyphs share metrics in font.
319
320 Glyphs are positioned using SkPoint written by caller to RunBuffer::pos, using
321 two scalar values for each SkPoint.
322
323 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
324 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
325 is computed from RunBuffer::pos, and RunBuffer::glyphs metrics.
326
327 @param font SkFont used for this run
328 @param count number of glyphs
329 @param bounds optional run bounding box
330 @return writable glyph buffer and SkPoint buffer
331 */
332 const RunBuffer& allocRunPos(const SkFont& font, int count,
333 const SkRect* bounds = nullptr);
334
fmalita00d5c2c2014-08-21 08:53:26 -0700335private:
Mike Reed6d595682018-12-05 17:28:14 -0500336 const RunBuffer& allocRunText(const SkFont& font,
Cary Clarke12a0902018-08-09 10:07:33 -0400337 int count,
338 SkScalar x,
339 SkScalar y,
340 int textByteCount,
341 SkString lang,
342 const SkRect* bounds = nullptr);
Mike Reed6d595682018-12-05 17:28:14 -0500343 const RunBuffer& allocRunTextPosH(const SkFont& font, int count, SkScalar y,
Cary Clarke12a0902018-08-09 10:07:33 -0400344 int textByteCount, SkString lang,
345 const SkRect* bounds = nullptr);
Mike Reed6d595682018-12-05 17:28:14 -0500346 const RunBuffer& allocRunTextPos(const SkFont& font, int count,
Cary Clarke12a0902018-08-09 10:07:33 -0400347 int textByteCount, SkString lang,
348 const SkRect* bounds = nullptr);
fmalita3c196de2014-09-20 05:40:22 -0700349 void reserve(size_t size);
Mike Reedb3f4aac2018-12-05 15:40:29 -0500350 void allocInternal(const SkFont& font, SkTextBlob::GlyphPositioning positioning,
halcanary4f0a23a2016-08-30 11:58:33 -0700351 int count, int textBytes, SkPoint offset, const SkRect* bounds);
Mike Reedb3f4aac2018-12-05 15:40:29 -0500352 bool mergeRun(const SkFont& font, SkTextBlob::GlyphPositioning positioning,
Florin Malitad923a712017-11-22 10:11:12 -0500353 uint32_t count, SkPoint offset);
fmalita00d5c2c2014-08-21 08:53:26 -0700354 void updateDeferredBounds();
355
fmalita3dc40ac2015-01-28 10:56:06 -0800356 static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
357 static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
358
Cary Clarke12a0902018-08-09 10:07:33 -0400359 friend class SkTextBlobPriv;
360 friend class SkTextBlobBuilderPriv;
361
fmalita3c196de2014-09-20 05:40:22 -0700362 SkAutoTMalloc<uint8_t> fStorage;
363 size_t fStorageSize;
364 size_t fStorageUsed;
fmalita00d5c2c2014-08-21 08:53:26 -0700365
fmalita3c196de2014-09-20 05:40:22 -0700366 SkRect fBounds;
367 int fRunCount;
368 bool fDeferredBounds;
369 size_t fLastRun; // index into fStorage
fmalita00d5c2c2014-08-21 08:53:26 -0700370
fmalita3c196de2014-09-20 05:40:22 -0700371 RunBuffer fCurrentRunBuffer;
fmalita00d5c2c2014-08-21 08:53:26 -0700372};
373
374#endif // SkTextBlob_DEFINED