blob: 260f8035c53ae2f6218175568ea71dcba6a34841 [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 Reed3185f902018-10-26 16:33:00 -040029#define SK_SUPPORT_LEGACY_TEXTBLOBBUILD_WITH_PAINT
30
Mike Reed8e74cbc2017-12-08 13:20:01 -050031struct SkSerialProcs;
32struct SkDeserialProcs;
33
fmalita00d5c2c2014-08-21 08:53:26 -070034/** \class SkTextBlob
Cary Clarkaf045512018-08-10 13:11:06 -040035 SkTextBlob combines multiple text runs into an immutable container. Each text
36 run consists of glyphs, SkPaint, and position. Only parts of SkPaint related to
37 fonts and text rendering are used by run.
fmalita00d5c2c2014-08-21 08:53:26 -070038*/
Mike Klein408ef212018-10-30 15:23:00 +000039class SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> {
fmalita00d5c2c2014-08-21 08:53:26 -070040public:
Cary Clarkaf045512018-08-10 13:11:06 -040041
42 /** Returns conservative bounding box. Uses SkPaint associated with each glyph to
43 determine glyph bounds, and unions all bounds. Returned bounds may be
44 larger than the bounds of all glyphs in runs.
45
46 @return conservative bounding box
47 */
fmalita00d5c2c2014-08-21 08:53:26 -070048 const SkRect& bounds() const { return fBounds; }
49
Cary Clarkaf045512018-08-10 13:11:06 -040050 /** Returns a non-zero value unique among all text blobs.
51
52 @return identifier for SkTextBlob
53 */
joshualitt2af85832015-03-25 13:40:13 -070054 uint32_t uniqueID() const { return fUniqueID; }
fmalita00d5c2c2014-08-21 08:53:26 -070055
Mike Reed3185f902018-10-26 16:33:00 -040056 /** Creates SkTextBlob with a single run.
Cary Clarkaf045512018-08-10 13:11:06 -040057
Cary Clark77b3f3a2018-11-07 14:59:03 -050058 font contains attributes used to define the run text.
Cary Clarkaf045512018-08-10 13:11:06 -040059
60 @param text character code points or glyphs drawn
61 @param byteLength byte length of text array
Mike Reed3185f902018-10-26 16:33:00 -040062 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040063 @return SkTextBlob constructed from one run
64 */
Mike Reed3185f902018-10-26 16:33:00 -040065 static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
Cary Clark14768f62018-10-29 20:33:51 -040066 SkPaint::TextEncoding encoding = SkPaint::kUTF8_TextEncoding);
Herb Derby4b3a5152018-07-17 16:10:30 -040067
Cary Clarkaf045512018-08-10 13:11:06 -040068 /** Creates SkTextBlob with a single run. string meaning depends on SkPaint::TextEncoding;
69 by default, string is encoded as UTF-8.
70
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 string character code points or glyphs drawn
Mike Reed3185f902018-10-26 16:33:00 -040074 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040075 @return SkTextBlob constructed from one run
76 */
Mike Reed3185f902018-10-26 16:33:00 -040077 static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
78 SkPaint::TextEncoding encoding = SkPaint::kUTF8_TextEncoding) {
Cary Clarke12a0902018-08-09 10:07:33 -040079 if (!string) {
80 return nullptr;
81 }
Mike Reed3185f902018-10-26 16:33:00 -040082 return MakeFromText(string, strlen(string), font, encoding);
Cary Clarke12a0902018-08-09 10:07:33 -040083 }
84
Cary Clarkaf045512018-08-10 13:11:06 -040085 /** Writes data to allow later reconstruction of SkTextBlob. memory points to storage
86 to receive the encoded data, and memory_size describes the size of storage.
87 Returns bytes used if provided storage is large enough to hold all data;
88 otherwise, returns zero.
89
90 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
91 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
92 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
93 is called with a pointer to SkTypeface and user context.
94
Cary Clark82456492018-10-31 10:54:50 -040095 @param procs custom serial data encoders; may be nullptr
96 @param memory storage for data
97 @param memory_size size of storage
98 @return bytes written, or zero if required storage is larger than memory_size
Cary Clarkaf045512018-08-10 13:11:06 -040099 */
Khushal42f8bc42018-04-03 17:51:40 -0700100 size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const;
101
Cary Clarkaf045512018-08-10 13:11:06 -0400102 /** Returns storage containing SkData describing SkTextBlob, using optional custom
103 encoders.
104
105 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
106 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
107 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
108 is called with a pointer to SkTypeface and user context.
109
110 @param procs custom serial data encoders; may be nullptr
111 @return storage containing serialized SkTextBlob
112 */
Cary Clark785586a2018-07-19 10:07:01 -0400113 sk_sp<SkData> serialize(const SkSerialProcs& procs) const;
Mike Reedaaa30562017-07-21 11:53:23 -0400114
Cary Clarkaf045512018-08-10 13:11:06 -0400115 /** Recreates SkTextBlob that was serialized into data. Returns constructed SkTextBlob
116 if successful; otherwise, returns nullptr. Fails if size is smaller than
117 required data length, or if data does not permit constructing valid SkTextBlob.
118
119 procs.fTypefaceProc permits supplying a custom function to decode SkTypeface.
120 If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx
121 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
122 is called with a pointer to SkTypeface data, data byte length, and user context.
123
124 @param data pointer for serial data
125 @param size size of data
126 @param procs custom serial data decoders; may be nullptr
127 @return SkTextBlob constructed from data in memory
128 */
Cary Clark785586a2018-07-19 10:07:01 -0400129 static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
130 const SkDeserialProcs& procs);
Mike Reed8e74cbc2017-12-08 13:20:01 -0500131
halcanary33779752015-10-27 14:01:05 -0700132private:
Mike Klein408ef212018-10-30 15:23:00 +0000133 friend class SkNVRefCnt<SkTextBlob>;
fmalita3c196de2014-09-20 05:40:22 -0700134 class RunRecord;
135
Florin Malitaab54e732018-07-27 09:47:15 -0400136 enum GlyphPositioning : uint8_t;
137
Florin Malita3a9a7a32017-03-13 09:03:24 -0400138 explicit SkTextBlob(const SkRect& bounds);
fmalita00d5c2c2014-08-21 08:53:26 -0700139
mtkleinb47cd4b2016-08-09 12:20:04 -0700140 ~SkTextBlob();
bsalomon07280312014-11-20 08:02:46 -0800141
142 // Memory for objects of this class is created with sk_malloc rather than operator new and must
143 // be freed with sk_free.
Yong-Hwan Baek688a8e52018-07-09 14:14:26 +0900144 void operator delete(void* p);
145 void* operator new(size_t);
146 void* operator new(size_t, void* p);
fmalita00d5c2c2014-08-21 08:53:26 -0700147
fmalitab7425172014-08-26 07:56:44 -0700148 static unsigned ScalarsPerGlyph(GlyphPositioning pos);
149
Florin Malita4a01ac92017-03-13 16:45:28 -0400150 // Call when this blob is part of the key to a cache entry. This allows the cache
151 // to know automatically those entries can be purged when this SkTextBlob is deleted.
Jim Van Verth474d6872017-12-14 13:00:05 -0500152 void notifyAddedToCache(uint32_t cacheID) const {
153 fCacheID.store(cacheID);
Florin Malita4a01ac92017-03-13 16:45:28 -0400154 }
155
Herb Derby8a6348e2018-07-12 15:30:35 -0400156 friend class SkGlyphRunList;
Florin Malita4a01ac92017-03-13 16:45:28 -0400157 friend class GrTextBlobCache;
fmalita00d5c2c2014-08-21 08:53:26 -0700158 friend class SkTextBlobBuilder;
Cary Clark53c87692018-07-17 08:59:34 -0400159 friend class SkTextBlobPriv;
halcanary33779752015-10-27 14:01:05 -0700160 friend class SkTextBlobRunIterator;
fmalita00d5c2c2014-08-21 08:53:26 -0700161
Mike Klein015c8992018-08-09 12:23:19 -0400162 const SkRect fBounds;
163 const uint32_t fUniqueID;
164 mutable std::atomic<uint32_t> fCacheID;
fmalita00d5c2c2014-08-21 08:53:26 -0700165
fmalita3c196de2014-09-20 05:40:22 -0700166 SkDEBUGCODE(size_t fStorageSize;)
fmalita00d5c2c2014-08-21 08:53:26 -0700167
fmalita3c196de2014-09-20 05:40:22 -0700168 // The actual payload resides in externally-managed storage, following the object.
169 // (see the .cpp for more details)
fmalita00d5c2c2014-08-21 08:53:26 -0700170
171 typedef SkRefCnt INHERITED;
172};
173
174/** \class SkTextBlobBuilder
Cary Clarkaf045512018-08-10 13:11:06 -0400175 Helper class for constructing SkTextBlob.
176*/
jbroman3053dfa2014-08-25 06:22:12 -0700177class SK_API SkTextBlobBuilder {
fmalita00d5c2c2014-08-21 08:53:26 -0700178public:
Cary Clarkaf045512018-08-10 13:11:06 -0400179
180 /** Constructs empty SkTextBlobBuilder. By default, SkTextBlobBuilder has no runs.
181
182 @return empty SkTextBlobBuilder
183 */
fmalita3c196de2014-09-20 05:40:22 -0700184 SkTextBlobBuilder();
fmalita00d5c2c2014-08-21 08:53:26 -0700185
Cary Clarkaf045512018-08-10 13:11:06 -0400186 /** Deletes data allocated internally by SkTextBlobBuilder.
187 */
fmalita00d5c2c2014-08-21 08:53:26 -0700188 ~SkTextBlobBuilder();
189
Cary Clarkaf045512018-08-10 13:11:06 -0400190 /** Returns SkTextBlob built from runs of glyphs added by builder. Returned
191 SkTextBlob is immutable; it may be copied, but its contents may not be altered.
192 Returns nullptr if no runs of glyphs were added by builder.
193
194 Resets SkTextBlobBuilder to its initial empty state, allowing it to be
195 reused to build a new set of runs.
196
197 @return SkTextBlob or nullptr
198 */
reed2ab90572016-08-10 14:16:41 -0700199 sk_sp<SkTextBlob> make();
200
Cary Clarkaf045512018-08-10 13:11:06 -0400201 /** \struct SkTextBlobBuilder::RunBuffer
202 RunBuffer supplies storage for glyphs and positions within a run.
203
Cary Clark77b3f3a2018-11-07 14:59:03 -0500204 A run is a sequence of glyphs sharing font metrics and positioning.
Cary Clarkaf045512018-08-10 13:11:06 -0400205 Each run may position its glyphs in one of three ways:
Cary Clark77b3f3a2018-11-07 14:59:03 -0500206 by specifying where the first glyph is drawn, and allowing font metrics to
Cary Clarkaf045512018-08-10 13:11:06 -0400207 determine the advance to subsequent glyphs; by specifying a baseline, and
208 the position on that baseline for each glyph in run; or by providing SkPoint
209 array, one per glyph.
210 */
fmalita00d5c2c2014-08-21 08:53:26 -0700211 struct RunBuffer {
Cary Clarkaf045512018-08-10 13:11:06 -0400212 SkGlyphID* glyphs; //!< storage for glyphs in run
213 SkScalar* pos; //!< storage for positions in run
214 char* utf8text; //!< reserved for future use
215 uint32_t* clusters; //!< reserved for future use
fmalita00d5c2c2014-08-21 08:53:26 -0700216 };
217
Cary Clarkaf045512018-08-10 13:11:06 -0400218 /** Returns run with storage for glyphs. Caller must write count glyphs to
Cary Clark77b3f3a2018-11-07 14:59:03 -0500219 RunBuffer::glyphs before next call to SkTextBlobBuilder.
Cary Clarkaf045512018-08-10 13:11:06 -0400220
Cary Clark77b3f3a2018-11-07 14:59:03 -0500221 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
Cary Clarkaf045512018-08-10 13:11:06 -0400222
Cary Clark77b3f3a2018-11-07 14:59:03 -0500223 Glyphs share metrics in font.
Cary Clarkaf045512018-08-10 13:11:06 -0400224
Cary Clark77b3f3a2018-11-07 14:59:03 -0500225 Glyphs are positioned on a baseline at (x, y), using font metrics to
Cary Clarkaf045512018-08-10 13:11:06 -0400226 determine their relative placement.
227
228 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
229 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
Cary Clark77b3f3a2018-11-07 14:59:03 -0500230 is computed from (x, y) and RunBuffer::glyphs metrics.
Cary Clarkaf045512018-08-10 13:11:06 -0400231
Cary Clark77b3f3a2018-11-07 14:59:03 -0500232 @param font SkFont used for this run
Cary Clarkaf045512018-08-10 13:11:06 -0400233 @param count number of glyphs
234 @param x horizontal offset within the blob
235 @param y vertical offset within the blob
236 @param bounds optional run bounding box
237 @return writable glyph buffer
238 */
Cary Clark77b3f3a2018-11-07 14:59:03 -0500239 const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y,
240 const SkRect* bounds = nullptr);
fmalita00d5c2c2014-08-21 08:53:26 -0700241
Cary Clarkaf045512018-08-10 13:11:06 -0400242 /** Returns run with storage for glyphs and positions along baseline. Caller must
Cary Clark77b3f3a2018-11-07 14:59:03 -0500243 write count glyphs to RunBuffer::glyphs, and count scalars to RunBuffer::pos;
244 before next call to SkTextBlobBuilder.
Cary Clarkaf045512018-08-10 13:11:06 -0400245
Cary Clark77b3f3a2018-11-07 14:59:03 -0500246 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
Cary Clarkaf045512018-08-10 13:11:06 -0400247
Cary Clark77b3f3a2018-11-07 14:59:03 -0500248 Glyphs share metrics in font.
Cary Clarkaf045512018-08-10 13:11:06 -0400249
250 Glyphs are positioned on a baseline at y, using x-axis positions written by
Cary Clark77b3f3a2018-11-07 14:59:03 -0500251 caller to RunBuffer::pos.
Cary Clarkaf045512018-08-10 13:11:06 -0400252
253 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
254 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
Cary Clark77b3f3a2018-11-07 14:59:03 -0500255 is computed from y, RunBuffer::pos, and RunBuffer::glyphs metrics.
Cary Clarkaf045512018-08-10 13:11:06 -0400256
Cary Clark77b3f3a2018-11-07 14:59:03 -0500257 @param font SkFont used for this run
Cary Clarkaf045512018-08-10 13:11:06 -0400258 @param count number of glyphs
259 @param y vertical offset within the blob
260 @param bounds optional run bounding box
261 @return writable glyph buffer and x-axis position buffer
262 */
Cary Clark77b3f3a2018-11-07 14:59:03 -0500263 const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y,
264 const SkRect* bounds = nullptr);
265
266 /** Returns run with storage for glyphs and SkPoint positions. Caller must
267 write count glyphs to RunBuffer::glyphs, and count SkPoint to RunBuffer::pos;
268 before next call to SkTextBlobBuilder.
269
270 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
271
272 Glyphs share metrics in font.
273
274 Glyphs are positioned using SkPoint written by caller to RunBuffer::pos, using
275 two scalar values for each SkPoint.
276
277 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
278 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
279 is computed from RunBuffer::pos, and RunBuffer::glyphs metrics.
280
281 @param font SkFont used for this run
282 @param count number of glyphs
283 @param bounds optional run bounding box
284 @return writable glyph buffer and SkPoint buffer
285 */
286 const RunBuffer& allocRunPos(const SkFont& font, int count,
287 const SkRect* bounds = nullptr);
288
289#ifdef SK_SUPPORT_LEGACY_TEXTBLOBBUILD_WITH_PAINT
290 /** Deprecated.
291 */
292 const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
293 const SkRect* bounds = nullptr) {
294 return this->allocRunText(font, count, x, y, 0, SkString(), bounds);
295 }
296
297 /** Deprecated.
298 */
fmalita00d5c2c2014-08-21 08:53:26 -0700299 const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400300 const SkRect* bounds = nullptr) {
halcanary4f0a23a2016-08-30 11:58:33 -0700301 return this->allocRunTextPosH(font, count, y, 0, SkString(), bounds);
302 }
fmalita00d5c2c2014-08-21 08:53:26 -0700303
Cary Clark77b3f3a2018-11-07 14:59:03 -0500304 /** Deprecated.
305 */
halcanary4f0a23a2016-08-30 11:58:33 -0700306 const RunBuffer& allocRunPos(const SkPaint& font, int count,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400307 const SkRect* bounds = nullptr) {
halcanary4f0a23a2016-08-30 11:58:33 -0700308 return this->allocRunTextPos(font, count, 0, SkString(), bounds);
309 }
Mike Reed3185f902018-10-26 16:33:00 -0400310#endif
311
fmalita00d5c2c2014-08-21 08:53:26 -0700312private:
Cary Clarke12a0902018-08-09 10:07:33 -0400313 const RunBuffer& allocRunText(const SkPaint& font,
314 int count,
315 SkScalar x,
316 SkScalar y,
317 int textByteCount,
318 SkString lang,
319 const SkRect* bounds = nullptr);
320 const RunBuffer& allocRunTextPosH(const SkPaint& font, int count, SkScalar y,
321 int textByteCount, SkString lang,
322 const SkRect* bounds = nullptr);
323 const RunBuffer& allocRunTextPos(const SkPaint& font, int count,
324 int textByteCount, SkString lang,
325 const SkRect* bounds = nullptr);
fmalita3c196de2014-09-20 05:40:22 -0700326 void reserve(size_t size);
fmalita00d5c2c2014-08-21 08:53:26 -0700327 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
halcanary4f0a23a2016-08-30 11:58:33 -0700328 int count, int textBytes, SkPoint offset, const SkRect* bounds);
fmalita3c196de2014-09-20 05:40:22 -0700329 bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
Florin Malitad923a712017-11-22 10:11:12 -0500330 uint32_t count, SkPoint offset);
fmalita00d5c2c2014-08-21 08:53:26 -0700331 void updateDeferredBounds();
332
fmalita3dc40ac2015-01-28 10:56:06 -0800333 static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
334 static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
335
Cary Clarke12a0902018-08-09 10:07:33 -0400336 friend class SkTextBlobPriv;
337 friend class SkTextBlobBuilderPriv;
338
fmalita3c196de2014-09-20 05:40:22 -0700339 SkAutoTMalloc<uint8_t> fStorage;
340 size_t fStorageSize;
341 size_t fStorageUsed;
fmalita00d5c2c2014-08-21 08:53:26 -0700342
fmalita3c196de2014-09-20 05:40:22 -0700343 SkRect fBounds;
344 int fRunCount;
345 bool fDeferredBounds;
346 size_t fLastRun; // index into fStorage
fmalita00d5c2c2014-08-21 08:53:26 -0700347
fmalita3c196de2014-09-20 05:40:22 -0700348 RunBuffer fCurrentRunBuffer;
fmalita00d5c2c2014-08-21 08:53:26 -0700349};
350
351#endif // SkTextBlob_DEFINED