blob: 88bdec0e20848e638af1b125ce26979a651e8655 [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"
fmalita00d5c2c2014-08-21 08:53:26 -070022#include "SkPaint.h"
halcanary4f0a23a2016-08-30 11:58:33 -070023#include "SkString.h"
fmalita00d5c2c2014-08-21 08:53:26 -070024#include "SkRefCnt.h"
Mike Klein015c8992018-08-09 12:23:19 -040025#include <atomic>
fmalita00d5c2c2014-08-21 08:53:26 -070026
Mike Reed8e74cbc2017-12-08 13:20:01 -050027struct SkSerialProcs;
28struct SkDeserialProcs;
29
fmalita00d5c2c2014-08-21 08:53:26 -070030/** \class SkTextBlob
Cary Clarkaf045512018-08-10 13:11:06 -040031 SkTextBlob combines multiple text runs into an immutable container. Each text
32 run consists of glyphs, SkPaint, and position. Only parts of SkPaint related to
33 fonts and text rendering are used by run.
fmalita00d5c2c2014-08-21 08:53:26 -070034*/
Mike Klein93ce79d2018-08-10 12:41:57 +000035class SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> {
fmalita00d5c2c2014-08-21 08:53:26 -070036public:
Cary Clarkaf045512018-08-10 13:11:06 -040037
38 /** Returns conservative bounding box. Uses SkPaint associated with each glyph to
39 determine glyph bounds, and unions all bounds. Returned bounds may be
40 larger than the bounds of all glyphs in runs.
41
42 @return conservative bounding box
43 */
fmalita00d5c2c2014-08-21 08:53:26 -070044 const SkRect& bounds() const { return fBounds; }
45
Cary Clarkaf045512018-08-10 13:11:06 -040046 /** Returns a non-zero value unique among all text blobs.
47
48 @return identifier for SkTextBlob
49 */
joshualitt2af85832015-03-25 13:40:13 -070050 uint32_t uniqueID() const { return fUniqueID; }
fmalita00d5c2c2014-08-21 08:53:26 -070051
Cary Clarkaf045512018-08-10 13:11:06 -040052 /** Creates SkTextBlob with a single run. text meaning depends on SkPaint::TextEncoding;
53 by default, text is encoded as UTF-8.
54
55 paint contains attributes used to define the run text:
56 SkTypeface, SkPaint text size, SkPaint text scale x,
57 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
58 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
59 and SkPaint subpixel text.
60
61 @param text character code points or glyphs drawn
62 @param byteLength byte length of text array
63 @param paint text size, typeface, text scale, and so on, used to draw
64 @return SkTextBlob constructed from one run
65 */
Herb Derbyc3bc69f2018-07-27 16:28:01 -040066 static sk_sp<SkTextBlob> MakeFromText(
Herb Derby4b3a5152018-07-17 16:10:30 -040067 const void* text, size_t byteLength, const SkPaint& paint);
68
Cary Clarkaf045512018-08-10 13:11:06 -040069 /** Creates SkTextBlob with a single run. string meaning depends on SkPaint::TextEncoding;
70 by default, string is encoded as UTF-8.
71
72 paint contains SkPaint::FontMetrics used to define the run text:
73 SkTypeface, SkPaint text size, SkPaint text scale x,
74 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
75 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
76 and SkPaint subpixel text.
77
78 @param string character code points or glyphs drawn
79 @param paint text size, typeface, text scale, and so on, used to draw
80 @return SkTextBlob constructed from one run
81 */
Cary Clarke12a0902018-08-09 10:07:33 -040082 static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkPaint& paint) {
83 if (!string) {
84 return nullptr;
85 }
86 return MakeFromText(string, strlen(string), paint);
87 }
88
Cary Clarkaf045512018-08-10 13:11:06 -040089 /** Writes data to allow later reconstruction of SkTextBlob. memory points to storage
90 to receive the encoded data, and memory_size describes the size of storage.
91 Returns bytes used if provided storage is large enough to hold all data;
92 otherwise, returns zero.
93
94 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
95 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
96 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
97 is called with a pointer to SkTypeface and user context.
98
99 @param procs custom serial data encoders; may be nullptr
100 @param memory storage for data
101 @param size size of storage
102 @return bytes written, or zero if required storage is larger than memory_size
103 */
Khushal42f8bc42018-04-03 17:51:40 -0700104 size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const;
105
Cary Clarkaf045512018-08-10 13:11:06 -0400106 /** Returns storage containing SkData describing SkTextBlob, using optional custom
107 encoders.
108
109 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
110 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
111 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
112 is called with a pointer to SkTypeface and user context.
113
114 @param procs custom serial data encoders; may be nullptr
115 @return storage containing serialized SkTextBlob
116 */
Cary Clark785586a2018-07-19 10:07:01 -0400117 sk_sp<SkData> serialize(const SkSerialProcs& procs) const;
Mike Reedaaa30562017-07-21 11:53:23 -0400118
Cary Clarkaf045512018-08-10 13:11:06 -0400119 /** Recreates SkTextBlob that was serialized into data. Returns constructed SkTextBlob
120 if successful; otherwise, returns nullptr. Fails if size is smaller than
121 required data length, or if data does not permit constructing valid SkTextBlob.
122
123 procs.fTypefaceProc permits supplying a custom function to decode SkTypeface.
124 If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx
125 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
126 is called with a pointer to SkTypeface data, data byte length, and user context.
127
128 @param data pointer for serial data
129 @param size size of data
130 @param procs custom serial data decoders; may be nullptr
131 @return SkTextBlob constructed from data in memory
132 */
Cary Clark785586a2018-07-19 10:07:01 -0400133 static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
134 const SkDeserialProcs& procs);
Mike Reed8e74cbc2017-12-08 13:20:01 -0500135
halcanary33779752015-10-27 14:01:05 -0700136private:
mtkleinb47cd4b2016-08-09 12:20:04 -0700137 friend class SkNVRefCnt<SkTextBlob>;
fmalita3c196de2014-09-20 05:40:22 -0700138 class RunRecord;
139
Florin Malitaab54e732018-07-27 09:47:15 -0400140 enum GlyphPositioning : uint8_t;
141
Florin Malita3a9a7a32017-03-13 09:03:24 -0400142 explicit SkTextBlob(const SkRect& bounds);
fmalita00d5c2c2014-08-21 08:53:26 -0700143
mtkleinb47cd4b2016-08-09 12:20:04 -0700144 ~SkTextBlob();
bsalomon07280312014-11-20 08:02:46 -0800145
146 // Memory for objects of this class is created with sk_malloc rather than operator new and must
147 // be freed with sk_free.
Yong-Hwan Baek688a8e52018-07-09 14:14:26 +0900148 void operator delete(void* p);
149 void* operator new(size_t);
150 void* operator new(size_t, void* p);
fmalita00d5c2c2014-08-21 08:53:26 -0700151
fmalitab7425172014-08-26 07:56:44 -0700152 static unsigned ScalarsPerGlyph(GlyphPositioning pos);
153
Florin Malita4a01ac92017-03-13 16:45:28 -0400154 // Call when this blob is part of the key to a cache entry. This allows the cache
155 // to know automatically those entries can be purged when this SkTextBlob is deleted.
Jim Van Verth474d6872017-12-14 13:00:05 -0500156 void notifyAddedToCache(uint32_t cacheID) const {
157 fCacheID.store(cacheID);
Florin Malita4a01ac92017-03-13 16:45:28 -0400158 }
159
Herb Derby8a6348e2018-07-12 15:30:35 -0400160 friend class SkGlyphRunList;
Florin Malita4a01ac92017-03-13 16:45:28 -0400161 friend class GrTextBlobCache;
fmalita00d5c2c2014-08-21 08:53:26 -0700162 friend class SkTextBlobBuilder;
Cary Clark53c87692018-07-17 08:59:34 -0400163 friend class SkTextBlobPriv;
halcanary33779752015-10-27 14:01:05 -0700164 friend class SkTextBlobRunIterator;
fmalita00d5c2c2014-08-21 08:53:26 -0700165
Mike Klein015c8992018-08-09 12:23:19 -0400166 const SkRect fBounds;
167 const uint32_t fUniqueID;
168 mutable std::atomic<uint32_t> fCacheID;
fmalita00d5c2c2014-08-21 08:53:26 -0700169
fmalita3c196de2014-09-20 05:40:22 -0700170 SkDEBUGCODE(size_t fStorageSize;)
fmalita00d5c2c2014-08-21 08:53:26 -0700171
fmalita3c196de2014-09-20 05:40:22 -0700172 // The actual payload resides in externally-managed storage, following the object.
173 // (see the .cpp for more details)
fmalita00d5c2c2014-08-21 08:53:26 -0700174
175 typedef SkRefCnt INHERITED;
176};
177
178/** \class SkTextBlobBuilder
Cary Clarkaf045512018-08-10 13:11:06 -0400179 Helper class for constructing SkTextBlob.
180*/
jbroman3053dfa2014-08-25 06:22:12 -0700181class SK_API SkTextBlobBuilder {
fmalita00d5c2c2014-08-21 08:53:26 -0700182public:
Cary Clarkaf045512018-08-10 13:11:06 -0400183
184 /** Constructs empty SkTextBlobBuilder. By default, SkTextBlobBuilder has no runs.
185
186 @return empty SkTextBlobBuilder
187 */
fmalita3c196de2014-09-20 05:40:22 -0700188 SkTextBlobBuilder();
fmalita00d5c2c2014-08-21 08:53:26 -0700189
Cary Clarkaf045512018-08-10 13:11:06 -0400190 /** Deletes data allocated internally by SkTextBlobBuilder.
191 */
fmalita00d5c2c2014-08-21 08:53:26 -0700192 ~SkTextBlobBuilder();
193
Cary Clarkaf045512018-08-10 13:11:06 -0400194 /** Returns SkTextBlob built from runs of glyphs added by builder. Returned
195 SkTextBlob is immutable; it may be copied, but its contents may not be altered.
196 Returns nullptr if no runs of glyphs were added by builder.
197
198 Resets SkTextBlobBuilder to its initial empty state, allowing it to be
199 reused to build a new set of runs.
200
201 @return SkTextBlob or nullptr
202 */
reed2ab90572016-08-10 14:16:41 -0700203 sk_sp<SkTextBlob> make();
204
Cary Clarkaf045512018-08-10 13:11:06 -0400205 /** \struct SkTextBlobBuilder::RunBuffer
206 RunBuffer supplies storage for glyphs and positions within a run.
207
208 A run is a sequence of glyphs sharing SkPaint::FontMetrics and positioning.
209 Each run may position its glyphs in one of three ways:
210 by specifying where the first glyph is drawn, and allowing SkPaint::FontMetrics to
211 determine the advance to subsequent glyphs; by specifying a baseline, and
212 the position on that baseline for each glyph in run; or by providing SkPoint
213 array, one per glyph.
214 */
fmalita00d5c2c2014-08-21 08:53:26 -0700215 struct RunBuffer {
Cary Clarkaf045512018-08-10 13:11:06 -0400216 SkGlyphID* glyphs; //!< storage for glyphs in run
217 SkScalar* pos; //!< storage for positions in run
218 char* utf8text; //!< reserved for future use
219 uint32_t* clusters; //!< reserved for future use
fmalita00d5c2c2014-08-21 08:53:26 -0700220 };
221
Cary Clarkaf045512018-08-10 13:11:06 -0400222 /** Returns run with storage for glyphs. Caller must write count glyphs to
223 RunBuffer.glyphs() before next call to FontBlobBuilder.
224
225 RunBuffer.utf8text(), and RunBuffer.clusters() should be ignored.
226
227 Glyphs share SkPaint::FontMetrics in font, including:
228 SkTypeface, SkPaint text size, SkPaint text scale x,
229 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
230 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
231 and SkPaint subpixel text.
232
233 Glyphs are positioned on a baseline at (x, y), using font SkPaint::FontMetrics to
234 determine their relative placement.
235
236 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
237 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
238 is computed from (x, y) and RunBuffer.glyphs() SkPaint::FontMetrics.
239
240 @param font SkPaint used for this run
241 @param count number of glyphs
242 @param x horizontal offset within the blob
243 @param y vertical offset within the blob
244 @param bounds optional run bounding box
245 @return writable glyph buffer
246 */
fmalita00d5c2c2014-08-21 08:53:26 -0700247 const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400248 const SkRect* bounds = nullptr) {
halcanary4f0a23a2016-08-30 11:58:33 -0700249 return this->allocRunText(font, count, x, y, 0, SkString(), bounds);
250 }
fmalita00d5c2c2014-08-21 08:53:26 -0700251
Cary Clarkaf045512018-08-10 13:11:06 -0400252 /** Returns run with storage for glyphs and positions along baseline. Caller must
253 write count glyphs to RunBuffer.glyphs(), and count scalars to RunBuffer.pos();
254 before next call to FontBlobBuilder.
255
256 RunBuffer.utf8text(), and RunBuffer.clusters() should be ignored.
257
258 Glyphs share SkPaint::FontMetrics in font, including:
259 SkTypeface, SkPaint text size, SkPaint text scale x,
260 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
261 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
262 and SkPaint subpixel text.
263
264 Glyphs are positioned on a baseline at y, using x-axis positions written by
265 caller to RunBuffer.pos().
266
267 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
268 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
269 is computed from y, RunBuffer.pos(), and RunBuffer.glyphs() SkPaint::FontMetrics.
270
271 @param font SkPaint used for this run
272 @param count number of glyphs
273 @param y vertical offset within the blob
274 @param bounds optional run bounding box
275 @return writable glyph buffer and x-axis position buffer
276 */
fmalita00d5c2c2014-08-21 08:53:26 -0700277 const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400278 const SkRect* bounds = nullptr) {
halcanary4f0a23a2016-08-30 11:58:33 -0700279 return this->allocRunTextPosH(font, count, y, 0, SkString(), bounds);
280 }
fmalita00d5c2c2014-08-21 08:53:26 -0700281
Cary Clarkaf045512018-08-10 13:11:06 -0400282 /** Returns run with storage for glyphs and SkPoint positions. Caller must
283 write count glyphs to RunBuffer.glyphs(), and count SkPoint to RunBuffer.pos();
284 before next call to FontBlobBuilder.
285
286 RunBuffer.utf8text(), and RunBuffer.clusters() should be ignored.
287
288 Glyphs share SkPaint::FontMetrics in font, including:
289 SkTypeface, SkPaint text size, SkPaint text scale x,
290 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
291 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
292 and SkPaint subpixel text.
293
294 Glyphs are positioned using SkPoint written by caller to RunBuffer.pos(), using
295 two scalar values for each SkPoint.
296
297 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
298 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
299 is computed from RunBuffer.pos(), and RunBuffer.glyphs() SkPaint::FontMetrics.
300
301 @param font SkPaint used for this run
302 @param count number of glyphs
303 @param bounds optional run bounding box
304 @return writable glyph buffer and SkPoint buffer
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 }
fmalita00d5c2c2014-08-21 08:53:26 -0700310
311private:
Cary Clarke12a0902018-08-09 10:07:33 -0400312 const RunBuffer& allocRunText(const SkPaint& font,
313 int count,
314 SkScalar x,
315 SkScalar y,
316 int textByteCount,
317 SkString lang,
318 const SkRect* bounds = nullptr);
319 const RunBuffer& allocRunTextPosH(const SkPaint& font, int count, SkScalar y,
320 int textByteCount, SkString lang,
321 const SkRect* bounds = nullptr);
322 const RunBuffer& allocRunTextPos(const SkPaint& font, int count,
323 int textByteCount, SkString lang,
324 const SkRect* bounds = nullptr);
fmalita3c196de2014-09-20 05:40:22 -0700325 void reserve(size_t size);
fmalita00d5c2c2014-08-21 08:53:26 -0700326 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
halcanary4f0a23a2016-08-30 11:58:33 -0700327 int count, int textBytes, SkPoint offset, const SkRect* bounds);
fmalita3c196de2014-09-20 05:40:22 -0700328 bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
Florin Malitad923a712017-11-22 10:11:12 -0500329 uint32_t count, SkPoint offset);
fmalita00d5c2c2014-08-21 08:53:26 -0700330 void updateDeferredBounds();
331
fmalita3dc40ac2015-01-28 10:56:06 -0800332 static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
333 static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
334
Cary Clarke12a0902018-08-09 10:07:33 -0400335 friend class SkTextBlobPriv;
336 friend class SkTextBlobBuilderPriv;
337
fmalita3c196de2014-09-20 05:40:22 -0700338 SkAutoTMalloc<uint8_t> fStorage;
339 size_t fStorageSize;
340 size_t fStorageUsed;
fmalita00d5c2c2014-08-21 08:53:26 -0700341
fmalita3c196de2014-09-20 05:40:22 -0700342 SkRect fBounds;
343 int fRunCount;
344 bool fDeferredBounds;
345 size_t fLastRun; // index into fStorage
fmalita00d5c2c2014-08-21 08:53:26 -0700346
fmalita3c196de2014-09-20 05:40:22 -0700347 RunBuffer fCurrentRunBuffer;
fmalita00d5c2c2014-08-21 08:53:26 -0700348};
349
350#endif // SkTextBlob_DEFINED