blob: afef54003a0c69b11b83bbb798686a99a883b98c [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
Mike Reed3185f902018-10-26 16:33:00 -040058 font contains attributes used to define the run text:
Cary Clarkaf045512018-08-10 13:11:06 -040059 SkTypeface, SkPaint text size, SkPaint text scale x,
Mike Reed3185f902018-10-26 16:33:00 -040060 SkFont text skew x, SkPaint::Align, SkFont::Hinting, anti-alias, SkFont fake bold,
61 SkFont font embedded bitmaps, SkFont full hinting spacing, LCD text, SkFont linear text,
62 and SkFont subpixel text.
Cary Clarkaf045512018-08-10 13:11:06 -040063
64 @param text character code points or glyphs drawn
65 @param byteLength byte length of text array
Mike Reed3185f902018-10-26 16:33:00 -040066 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040067 @return SkTextBlob constructed from one run
68 */
Mike Reed3185f902018-10-26 16:33:00 -040069 static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
Cary Clark14768f62018-10-29 20:33:51 -040070 SkPaint::TextEncoding encoding = SkPaint::kUTF8_TextEncoding);
Herb Derby4b3a5152018-07-17 16:10:30 -040071
Cary Clarkaf045512018-08-10 13:11:06 -040072 /** Creates SkTextBlob with a single run. string meaning depends on SkPaint::TextEncoding;
73 by default, string is encoded as UTF-8.
74
Mike Reed3185f902018-10-26 16:33:00 -040075 font contains attributes used to define the run text:
Cary Clarkaf045512018-08-10 13:11:06 -040076 SkTypeface, SkPaint text size, SkPaint text scale x,
Mike Reed3185f902018-10-26 16:33:00 -040077 SkFont text skew x, SkPaint::Align, SkFont::Hinting, anti-alias, SkFont fake bold,
78 SkFont font embedded bitmaps, SkFont full hinting spacing, LCD text, SkFont linear text,
79 and SkFont subpixel text.
Cary Clarkaf045512018-08-10 13:11:06 -040080
81 @param string character code points or glyphs drawn
Mike Reed3185f902018-10-26 16:33:00 -040082 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040083 @return SkTextBlob constructed from one run
84 */
Mike Reed3185f902018-10-26 16:33:00 -040085 static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
86 SkPaint::TextEncoding encoding = SkPaint::kUTF8_TextEncoding) {
Cary Clarke12a0902018-08-09 10:07:33 -040087 if (!string) {
88 return nullptr;
89 }
Mike Reed3185f902018-10-26 16:33:00 -040090 return MakeFromText(string, strlen(string), font, encoding);
Cary Clarke12a0902018-08-09 10:07:33 -040091 }
92
Cary Clarkaf045512018-08-10 13:11:06 -040093 /** Writes data to allow later reconstruction of SkTextBlob. memory points to storage
94 to receive the encoded data, and memory_size describes the size of storage.
95 Returns bytes used if provided storage is large enough to hold all data;
96 otherwise, returns zero.
97
98 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
99 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
100 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
101 is called with a pointer to SkTypeface and user context.
102
Cary Clark82456492018-10-31 10:54:50 -0400103 @param procs custom serial data encoders; may be nullptr
104 @param memory storage for data
105 @param memory_size size of storage
106 @return bytes written, or zero if required storage is larger than memory_size
Cary Clarkaf045512018-08-10 13:11:06 -0400107 */
Khushal42f8bc42018-04-03 17:51:40 -0700108 size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const;
109
Cary Clarkaf045512018-08-10 13:11:06 -0400110 /** Returns storage containing SkData describing SkTextBlob, using optional custom
111 encoders.
112
113 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
114 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
115 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
116 is called with a pointer to SkTypeface and user context.
117
118 @param procs custom serial data encoders; may be nullptr
119 @return storage containing serialized SkTextBlob
120 */
Cary Clark785586a2018-07-19 10:07:01 -0400121 sk_sp<SkData> serialize(const SkSerialProcs& procs) const;
Mike Reedaaa30562017-07-21 11:53:23 -0400122
Cary Clarkaf045512018-08-10 13:11:06 -0400123 /** Recreates SkTextBlob that was serialized into data. Returns constructed SkTextBlob
124 if successful; otherwise, returns nullptr. Fails if size is smaller than
125 required data length, or if data does not permit constructing valid SkTextBlob.
126
127 procs.fTypefaceProc permits supplying a custom function to decode SkTypeface.
128 If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx
129 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
130 is called with a pointer to SkTypeface data, data byte length, and user context.
131
132 @param data pointer for serial data
133 @param size size of data
134 @param procs custom serial data decoders; may be nullptr
135 @return SkTextBlob constructed from data in memory
136 */
Cary Clark785586a2018-07-19 10:07:01 -0400137 static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
138 const SkDeserialProcs& procs);
Mike Reed8e74cbc2017-12-08 13:20:01 -0500139
halcanary33779752015-10-27 14:01:05 -0700140private:
Mike Klein408ef212018-10-30 15:23:00 +0000141 friend class SkNVRefCnt<SkTextBlob>;
fmalita3c196de2014-09-20 05:40:22 -0700142 class RunRecord;
143
Florin Malitaab54e732018-07-27 09:47:15 -0400144 enum GlyphPositioning : uint8_t;
145
Florin Malita3a9a7a32017-03-13 09:03:24 -0400146 explicit SkTextBlob(const SkRect& bounds);
fmalita00d5c2c2014-08-21 08:53:26 -0700147
mtkleinb47cd4b2016-08-09 12:20:04 -0700148 ~SkTextBlob();
bsalomon07280312014-11-20 08:02:46 -0800149
150 // Memory for objects of this class is created with sk_malloc rather than operator new and must
151 // be freed with sk_free.
Yong-Hwan Baek688a8e52018-07-09 14:14:26 +0900152 void operator delete(void* p);
153 void* operator new(size_t);
154 void* operator new(size_t, void* p);
fmalita00d5c2c2014-08-21 08:53:26 -0700155
fmalitab7425172014-08-26 07:56:44 -0700156 static unsigned ScalarsPerGlyph(GlyphPositioning pos);
157
Florin Malita4a01ac92017-03-13 16:45:28 -0400158 // Call when this blob is part of the key to a cache entry. This allows the cache
159 // to know automatically those entries can be purged when this SkTextBlob is deleted.
Jim Van Verth474d6872017-12-14 13:00:05 -0500160 void notifyAddedToCache(uint32_t cacheID) const {
161 fCacheID.store(cacheID);
Florin Malita4a01ac92017-03-13 16:45:28 -0400162 }
163
Herb Derby8a6348e2018-07-12 15:30:35 -0400164 friend class SkGlyphRunList;
Florin Malita4a01ac92017-03-13 16:45:28 -0400165 friend class GrTextBlobCache;
fmalita00d5c2c2014-08-21 08:53:26 -0700166 friend class SkTextBlobBuilder;
Cary Clark53c87692018-07-17 08:59:34 -0400167 friend class SkTextBlobPriv;
halcanary33779752015-10-27 14:01:05 -0700168 friend class SkTextBlobRunIterator;
fmalita00d5c2c2014-08-21 08:53:26 -0700169
Mike Klein015c8992018-08-09 12:23:19 -0400170 const SkRect fBounds;
171 const uint32_t fUniqueID;
172 mutable std::atomic<uint32_t> fCacheID;
fmalita00d5c2c2014-08-21 08:53:26 -0700173
fmalita3c196de2014-09-20 05:40:22 -0700174 SkDEBUGCODE(size_t fStorageSize;)
fmalita00d5c2c2014-08-21 08:53:26 -0700175
fmalita3c196de2014-09-20 05:40:22 -0700176 // The actual payload resides in externally-managed storage, following the object.
177 // (see the .cpp for more details)
fmalita00d5c2c2014-08-21 08:53:26 -0700178
179 typedef SkRefCnt INHERITED;
180};
181
182/** \class SkTextBlobBuilder
Cary Clarkaf045512018-08-10 13:11:06 -0400183 Helper class for constructing SkTextBlob.
184*/
jbroman3053dfa2014-08-25 06:22:12 -0700185class SK_API SkTextBlobBuilder {
fmalita00d5c2c2014-08-21 08:53:26 -0700186public:
Cary Clarkaf045512018-08-10 13:11:06 -0400187
188 /** Constructs empty SkTextBlobBuilder. By default, SkTextBlobBuilder has no runs.
189
190 @return empty SkTextBlobBuilder
191 */
fmalita3c196de2014-09-20 05:40:22 -0700192 SkTextBlobBuilder();
fmalita00d5c2c2014-08-21 08:53:26 -0700193
Cary Clarkaf045512018-08-10 13:11:06 -0400194 /** Deletes data allocated internally by SkTextBlobBuilder.
195 */
fmalita00d5c2c2014-08-21 08:53:26 -0700196 ~SkTextBlobBuilder();
197
Cary Clarkaf045512018-08-10 13:11:06 -0400198 /** Returns SkTextBlob built from runs of glyphs added by builder. Returned
199 SkTextBlob is immutable; it may be copied, but its contents may not be altered.
200 Returns nullptr if no runs of glyphs were added by builder.
201
202 Resets SkTextBlobBuilder to its initial empty state, allowing it to be
203 reused to build a new set of runs.
204
205 @return SkTextBlob or nullptr
206 */
reed2ab90572016-08-10 14:16:41 -0700207 sk_sp<SkTextBlob> make();
208
Cary Clarkaf045512018-08-10 13:11:06 -0400209 /** \struct SkTextBlobBuilder::RunBuffer
210 RunBuffer supplies storage for glyphs and positions within a run.
211
212 A run is a sequence of glyphs sharing SkPaint::FontMetrics and positioning.
213 Each run may position its glyphs in one of three ways:
214 by specifying where the first glyph is drawn, and allowing SkPaint::FontMetrics to
215 determine the advance to subsequent glyphs; by specifying a baseline, and
216 the position on that baseline for each glyph in run; or by providing SkPoint
217 array, one per glyph.
218 */
fmalita00d5c2c2014-08-21 08:53:26 -0700219 struct RunBuffer {
Cary Clarkaf045512018-08-10 13:11:06 -0400220 SkGlyphID* glyphs; //!< storage for glyphs in run
221 SkScalar* pos; //!< storage for positions in run
222 char* utf8text; //!< reserved for future use
223 uint32_t* clusters; //!< reserved for future use
fmalita00d5c2c2014-08-21 08:53:26 -0700224 };
225
Mike Reed3185f902018-10-26 16:33:00 -0400226#ifdef SK_SUPPORT_LEGACY_TEXTBLOBBUILD_WITH_PAINT
Cary Clarkaf045512018-08-10 13:11:06 -0400227 /** Returns run with storage for glyphs. Caller must write count glyphs to
228 RunBuffer.glyphs() before next call to FontBlobBuilder.
229
230 RunBuffer.utf8text(), and RunBuffer.clusters() should be ignored.
231
232 Glyphs share SkPaint::FontMetrics in font, including:
233 SkTypeface, SkPaint text size, SkPaint text scale x,
234 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
235 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
236 and SkPaint subpixel text.
237
238 Glyphs are positioned on a baseline at (x, y), using font SkPaint::FontMetrics to
239 determine their relative placement.
240
241 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
242 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
243 is computed from (x, y) and RunBuffer.glyphs() SkPaint::FontMetrics.
244
245 @param font SkPaint used for this run
246 @param count number of glyphs
247 @param x horizontal offset within the blob
248 @param y vertical offset within the blob
249 @param bounds optional run bounding box
250 @return writable glyph buffer
251 */
fmalita00d5c2c2014-08-21 08:53:26 -0700252 const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400253 const SkRect* bounds = nullptr) {
halcanary4f0a23a2016-08-30 11:58:33 -0700254 return this->allocRunText(font, count, x, y, 0, SkString(), bounds);
255 }
fmalita00d5c2c2014-08-21 08:53:26 -0700256
Cary Clarkaf045512018-08-10 13:11:06 -0400257 /** Returns run with storage for glyphs and positions along baseline. Caller must
258 write count glyphs to RunBuffer.glyphs(), and count scalars to RunBuffer.pos();
259 before next call to FontBlobBuilder.
260
261 RunBuffer.utf8text(), and RunBuffer.clusters() should be ignored.
262
263 Glyphs share SkPaint::FontMetrics in font, including:
264 SkTypeface, SkPaint text size, SkPaint text scale x,
265 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
266 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
267 and SkPaint subpixel text.
268
269 Glyphs are positioned on a baseline at y, using x-axis positions written by
270 caller to RunBuffer.pos().
271
272 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
273 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
274 is computed from y, RunBuffer.pos(), and RunBuffer.glyphs() SkPaint::FontMetrics.
275
276 @param font SkPaint used for this run
277 @param count number of glyphs
278 @param y vertical offset within the blob
279 @param bounds optional run bounding box
280 @return writable glyph buffer and x-axis position buffer
281 */
fmalita00d5c2c2014-08-21 08:53:26 -0700282 const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400283 const SkRect* bounds = nullptr) {
halcanary4f0a23a2016-08-30 11:58:33 -0700284 return this->allocRunTextPosH(font, count, y, 0, SkString(), bounds);
285 }
fmalita00d5c2c2014-08-21 08:53:26 -0700286
Cary Clarkaf045512018-08-10 13:11:06 -0400287 /** Returns run with storage for glyphs and SkPoint positions. Caller must
288 write count glyphs to RunBuffer.glyphs(), and count SkPoint to RunBuffer.pos();
289 before next call to FontBlobBuilder.
290
291 RunBuffer.utf8text(), and RunBuffer.clusters() should be ignored.
292
293 Glyphs share SkPaint::FontMetrics in font, including:
294 SkTypeface, SkPaint text size, SkPaint text scale x,
295 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
296 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
297 and SkPaint subpixel text.
298
299 Glyphs are positioned using SkPoint written by caller to RunBuffer.pos(), using
300 two scalar values for each SkPoint.
301
302 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
303 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
304 is computed from RunBuffer.pos(), and RunBuffer.glyphs() SkPaint::FontMetrics.
305
306 @param font SkPaint used for this run
307 @param count number of glyphs
308 @param bounds optional run bounding box
309 @return writable glyph buffer and SkPoint buffer
310 */
halcanary4f0a23a2016-08-30 11:58:33 -0700311 const RunBuffer& allocRunPos(const SkPaint& font, int count,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400312 const SkRect* bounds = nullptr) {
halcanary4f0a23a2016-08-30 11:58:33 -0700313 return this->allocRunTextPos(font, count, 0, SkString(), bounds);
314 }
Mike Reed3185f902018-10-26 16:33:00 -0400315#endif
316
317 const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y,
318 const SkRect* bounds = nullptr);
319 const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y,
320 const SkRect* bounds = nullptr);
321 const RunBuffer& allocRunPos(const SkFont& font, int count,
322 const SkRect* bounds = nullptr);
fmalita00d5c2c2014-08-21 08:53:26 -0700323
324private:
Cary Clarke12a0902018-08-09 10:07:33 -0400325 const RunBuffer& allocRunText(const SkPaint& font,
326 int count,
327 SkScalar x,
328 SkScalar y,
329 int textByteCount,
330 SkString lang,
331 const SkRect* bounds = nullptr);
332 const RunBuffer& allocRunTextPosH(const SkPaint& font, int count, SkScalar y,
333 int textByteCount, SkString lang,
334 const SkRect* bounds = nullptr);
335 const RunBuffer& allocRunTextPos(const SkPaint& font, int count,
336 int textByteCount, SkString lang,
337 const SkRect* bounds = nullptr);
fmalita3c196de2014-09-20 05:40:22 -0700338 void reserve(size_t size);
fmalita00d5c2c2014-08-21 08:53:26 -0700339 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
halcanary4f0a23a2016-08-30 11:58:33 -0700340 int count, int textBytes, SkPoint offset, const SkRect* bounds);
fmalita3c196de2014-09-20 05:40:22 -0700341 bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
Florin Malitad923a712017-11-22 10:11:12 -0500342 uint32_t count, SkPoint offset);
fmalita00d5c2c2014-08-21 08:53:26 -0700343 void updateDeferredBounds();
344
fmalita3dc40ac2015-01-28 10:56:06 -0800345 static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
346 static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
347
Cary Clarke12a0902018-08-09 10:07:33 -0400348 friend class SkTextBlobPriv;
349 friend class SkTextBlobBuilderPriv;
350
fmalita3c196de2014-09-20 05:40:22 -0700351 SkAutoTMalloc<uint8_t> fStorage;
352 size_t fStorageSize;
353 size_t fStorageUsed;
fmalita00d5c2c2014-08-21 08:53:26 -0700354
fmalita3c196de2014-09-20 05:40:22 -0700355 SkRect fBounds;
356 int fRunCount;
357 bool fDeferredBounds;
358 size_t fLastRun; // index into fStorage
fmalita00d5c2c2014-08-21 08:53:26 -0700359
fmalita3c196de2014-09-20 05:40:22 -0700360 RunBuffer fCurrentRunBuffer;
fmalita00d5c2c2014-08-21 08:53:26 -0700361};
362
363#endif // SkTextBlob_DEFINED