blob: 31d3f17374912f678401046ac3fce4e15ed7ed30 [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 Reed3185f902018-10-26 16:33:00 -040054 /** Creates SkTextBlob with a single run.
Cary Clarkaf045512018-08-10 13:11:06 -040055
Cary Clark77b3f3a2018-11-07 14:59:03 -050056 font contains attributes used to define the run text.
Cary Clarkaf045512018-08-10 13:11:06 -040057
58 @param text character code points or glyphs drawn
59 @param byteLength byte length of text array
Mike Reed3185f902018-10-26 16:33:00 -040060 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040061 @return SkTextBlob constructed from one run
62 */
Mike Reed3185f902018-10-26 16:33:00 -040063 static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
Mike Reed97f3cc22018-12-03 09:45:17 -050064 SkTextEncoding encoding = kUTF8_SkTextEncoding);
Herb Derby4b3a5152018-07-17 16:10:30 -040065
Mike Reed97f3cc22018-12-03 09:45:17 -050066 /** Creates SkTextBlob with a single run. string meaning depends on SkTextEncoding;
Cary Clarkaf045512018-08-10 13:11:06 -040067 by default, string is encoded as UTF-8.
68
Cary Clark77b3f3a2018-11-07 14:59:03 -050069 font contains attributes used to define the run text.
Cary Clarkaf045512018-08-10 13:11:06 -040070
71 @param string character code points or glyphs drawn
Mike Reed3185f902018-10-26 16:33:00 -040072 @param font text size, typeface, text scale, and so on, used to draw
Cary Clarkaf045512018-08-10 13:11:06 -040073 @return SkTextBlob constructed from one run
74 */
Mike Reed3185f902018-10-26 16:33:00 -040075 static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
Mike Reed97f3cc22018-12-03 09:45:17 -050076 SkTextEncoding encoding = kUTF8_SkTextEncoding) {
Cary Clarke12a0902018-08-09 10:07:33 -040077 if (!string) {
78 return nullptr;
79 }
Mike Reed3185f902018-10-26 16:33:00 -040080 return MakeFromText(string, strlen(string), font, encoding);
Cary Clarke12a0902018-08-09 10:07:33 -040081 }
82
Cary Clarkaf045512018-08-10 13:11:06 -040083 /** Writes data to allow later reconstruction of SkTextBlob. memory points to storage
84 to receive the encoded data, and memory_size describes the size of storage.
85 Returns bytes used if provided storage is large enough to hold all data;
86 otherwise, returns zero.
87
88 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
89 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
90 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
91 is called with a pointer to SkTypeface and user context.
92
Cary Clark82456492018-10-31 10:54:50 -040093 @param procs custom serial data encoders; may be nullptr
94 @param memory storage for data
95 @param memory_size size of storage
96 @return bytes written, or zero if required storage is larger than memory_size
Cary Clarkaf045512018-08-10 13:11:06 -040097 */
Khushal42f8bc42018-04-03 17:51:40 -070098 size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const;
99
Cary Clarkaf045512018-08-10 13:11:06 -0400100 /** Returns storage containing SkData describing SkTextBlob, using optional custom
101 encoders.
102
103 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface.
104 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx
105 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
106 is called with a pointer to SkTypeface and user context.
107
108 @param procs custom serial data encoders; may be nullptr
109 @return storage containing serialized SkTextBlob
110 */
Cary Clark785586a2018-07-19 10:07:01 -0400111 sk_sp<SkData> serialize(const SkSerialProcs& procs) const;
Mike Reedaaa30562017-07-21 11:53:23 -0400112
Cary Clarkaf045512018-08-10 13:11:06 -0400113 /** Recreates SkTextBlob that was serialized into data. Returns constructed SkTextBlob
114 if successful; otherwise, returns nullptr. Fails if size is smaller than
115 required data length, or if data does not permit constructing valid SkTextBlob.
116
117 procs.fTypefaceProc permits supplying a custom function to decode SkTypeface.
118 If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx
119 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc
120 is called with a pointer to SkTypeface data, data byte length, and user context.
121
122 @param data pointer for serial data
123 @param size size of data
124 @param procs custom serial data decoders; may be nullptr
125 @return SkTextBlob constructed from data in memory
126 */
Cary Clark785586a2018-07-19 10:07:01 -0400127 static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
128 const SkDeserialProcs& procs);
Mike Reed8e74cbc2017-12-08 13:20:01 -0500129
halcanary33779752015-10-27 14:01:05 -0700130private:
Mike Klein408ef212018-10-30 15:23:00 +0000131 friend class SkNVRefCnt<SkTextBlob>;
fmalita3c196de2014-09-20 05:40:22 -0700132 class RunRecord;
133
Florin Malitaab54e732018-07-27 09:47:15 -0400134 enum GlyphPositioning : uint8_t;
135
Florin Malita3a9a7a32017-03-13 09:03:24 -0400136 explicit SkTextBlob(const SkRect& bounds);
fmalita00d5c2c2014-08-21 08:53:26 -0700137
mtkleinb47cd4b2016-08-09 12:20:04 -0700138 ~SkTextBlob();
bsalomon07280312014-11-20 08:02:46 -0800139
140 // Memory for objects of this class is created with sk_malloc rather than operator new and must
141 // be freed with sk_free.
Yong-Hwan Baek688a8e52018-07-09 14:14:26 +0900142 void operator delete(void* p);
143 void* operator new(size_t);
144 void* operator new(size_t, void* p);
fmalita00d5c2c2014-08-21 08:53:26 -0700145
fmalitab7425172014-08-26 07:56:44 -0700146 static unsigned ScalarsPerGlyph(GlyphPositioning pos);
147
Florin Malita4a01ac92017-03-13 16:45:28 -0400148 // Call when this blob is part of the key to a cache entry. This allows the cache
149 // to know automatically those entries can be purged when this SkTextBlob is deleted.
Jim Van Verth474d6872017-12-14 13:00:05 -0500150 void notifyAddedToCache(uint32_t cacheID) const {
151 fCacheID.store(cacheID);
Florin Malita4a01ac92017-03-13 16:45:28 -0400152 }
153
Herb Derby8a6348e2018-07-12 15:30:35 -0400154 friend class SkGlyphRunList;
Florin Malita4a01ac92017-03-13 16:45:28 -0400155 friend class GrTextBlobCache;
fmalita00d5c2c2014-08-21 08:53:26 -0700156 friend class SkTextBlobBuilder;
Cary Clark53c87692018-07-17 08:59:34 -0400157 friend class SkTextBlobPriv;
halcanary33779752015-10-27 14:01:05 -0700158 friend class SkTextBlobRunIterator;
fmalita00d5c2c2014-08-21 08:53:26 -0700159
Mike Klein015c8992018-08-09 12:23:19 -0400160 const SkRect fBounds;
161 const uint32_t fUniqueID;
162 mutable std::atomic<uint32_t> fCacheID;
fmalita00d5c2c2014-08-21 08:53:26 -0700163
fmalita3c196de2014-09-20 05:40:22 -0700164 SkDEBUGCODE(size_t fStorageSize;)
fmalita00d5c2c2014-08-21 08:53:26 -0700165
fmalita3c196de2014-09-20 05:40:22 -0700166 // The actual payload resides in externally-managed storage, following the object.
167 // (see the .cpp for more details)
fmalita00d5c2c2014-08-21 08:53:26 -0700168
169 typedef SkRefCnt INHERITED;
170};
171
172/** \class SkTextBlobBuilder
Cary Clarkaf045512018-08-10 13:11:06 -0400173 Helper class for constructing SkTextBlob.
174*/
jbroman3053dfa2014-08-25 06:22:12 -0700175class SK_API SkTextBlobBuilder {
fmalita00d5c2c2014-08-21 08:53:26 -0700176public:
Cary Clarkaf045512018-08-10 13:11:06 -0400177
178 /** Constructs empty SkTextBlobBuilder. By default, SkTextBlobBuilder has no runs.
179
180 @return empty SkTextBlobBuilder
181 */
fmalita3c196de2014-09-20 05:40:22 -0700182 SkTextBlobBuilder();
fmalita00d5c2c2014-08-21 08:53:26 -0700183
Cary Clarkaf045512018-08-10 13:11:06 -0400184 /** Deletes data allocated internally by SkTextBlobBuilder.
185 */
fmalita00d5c2c2014-08-21 08:53:26 -0700186 ~SkTextBlobBuilder();
187
Cary Clarkaf045512018-08-10 13:11:06 -0400188 /** Returns SkTextBlob built from runs of glyphs added by builder. Returned
189 SkTextBlob is immutable; it may be copied, but its contents may not be altered.
190 Returns nullptr if no runs of glyphs were added by builder.
191
192 Resets SkTextBlobBuilder to its initial empty state, allowing it to be
193 reused to build a new set of runs.
194
195 @return SkTextBlob or nullptr
196 */
reed2ab90572016-08-10 14:16:41 -0700197 sk_sp<SkTextBlob> make();
198
Cary Clarkaf045512018-08-10 13:11:06 -0400199 /** \struct SkTextBlobBuilder::RunBuffer
200 RunBuffer supplies storage for glyphs and positions within a run.
201
Cary Clark77b3f3a2018-11-07 14:59:03 -0500202 A run is a sequence of glyphs sharing font metrics and positioning.
Cary Clarkaf045512018-08-10 13:11:06 -0400203 Each run may position its glyphs in one of three ways:
Cary Clark77b3f3a2018-11-07 14:59:03 -0500204 by specifying where the first glyph is drawn, and allowing font metrics to
Cary Clarkaf045512018-08-10 13:11:06 -0400205 determine the advance to subsequent glyphs; by specifying a baseline, and
206 the position on that baseline for each glyph in run; or by providing SkPoint
207 array, one per glyph.
208 */
fmalita00d5c2c2014-08-21 08:53:26 -0700209 struct RunBuffer {
Cary Clarkaf045512018-08-10 13:11:06 -0400210 SkGlyphID* glyphs; //!< storage for glyphs in run
211 SkScalar* pos; //!< storage for positions in run
212 char* utf8text; //!< reserved for future use
213 uint32_t* clusters; //!< reserved for future use
fmalita00d5c2c2014-08-21 08:53:26 -0700214 };
215
Cary Clarkaf045512018-08-10 13:11:06 -0400216 /** Returns run with storage for glyphs. Caller must write count glyphs to
Cary Clark77b3f3a2018-11-07 14:59:03 -0500217 RunBuffer::glyphs before next call to SkTextBlobBuilder.
Cary Clarkaf045512018-08-10 13:11:06 -0400218
Cary Clark77b3f3a2018-11-07 14:59:03 -0500219 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
Cary Clarkaf045512018-08-10 13:11:06 -0400220
Cary Clark77b3f3a2018-11-07 14:59:03 -0500221 Glyphs share metrics in font.
Cary Clarkaf045512018-08-10 13:11:06 -0400222
Cary Clark77b3f3a2018-11-07 14:59:03 -0500223 Glyphs are positioned on a baseline at (x, y), using font metrics to
Cary Clarkaf045512018-08-10 13:11:06 -0400224 determine their relative placement.
225
226 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
227 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
Cary Clark77b3f3a2018-11-07 14:59:03 -0500228 is computed from (x, y) and RunBuffer::glyphs metrics.
Cary Clarkaf045512018-08-10 13:11:06 -0400229
Cary Clark77b3f3a2018-11-07 14:59:03 -0500230 @param font SkFont used for this run
Cary Clarkaf045512018-08-10 13:11:06 -0400231 @param count number of glyphs
232 @param x horizontal offset within the blob
233 @param y vertical offset within the blob
234 @param bounds optional run bounding box
235 @return writable glyph buffer
236 */
Cary Clark77b3f3a2018-11-07 14:59:03 -0500237 const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y,
238 const SkRect* bounds = nullptr);
fmalita00d5c2c2014-08-21 08:53:26 -0700239
Cary Clarkaf045512018-08-10 13:11:06 -0400240 /** Returns run with storage for glyphs and positions along baseline. Caller must
Cary Clark77b3f3a2018-11-07 14:59:03 -0500241 write count glyphs to RunBuffer::glyphs, and count scalars to RunBuffer::pos;
242 before next call to SkTextBlobBuilder.
Cary Clarkaf045512018-08-10 13:11:06 -0400243
Cary Clark77b3f3a2018-11-07 14:59:03 -0500244 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
Cary Clarkaf045512018-08-10 13:11:06 -0400245
Cary Clark77b3f3a2018-11-07 14:59:03 -0500246 Glyphs share metrics in font.
Cary Clarkaf045512018-08-10 13:11:06 -0400247
248 Glyphs are positioned on a baseline at y, using x-axis positions written by
Cary Clark77b3f3a2018-11-07 14:59:03 -0500249 caller to RunBuffer::pos.
Cary Clarkaf045512018-08-10 13:11:06 -0400250
251 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
252 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
Cary Clark77b3f3a2018-11-07 14:59:03 -0500253 is computed from y, RunBuffer::pos, and RunBuffer::glyphs metrics.
Cary Clarkaf045512018-08-10 13:11:06 -0400254
Cary Clark77b3f3a2018-11-07 14:59:03 -0500255 @param font SkFont used for this run
Cary Clarkaf045512018-08-10 13:11:06 -0400256 @param count number of glyphs
257 @param y vertical offset within the blob
258 @param bounds optional run bounding box
259 @return writable glyph buffer and x-axis position buffer
260 */
Cary Clark77b3f3a2018-11-07 14:59:03 -0500261 const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y,
262 const SkRect* bounds = nullptr);
263
264 /** Returns run with storage for glyphs and SkPoint positions. Caller must
265 write count glyphs to RunBuffer::glyphs, and count SkPoint to RunBuffer::pos;
266 before next call to SkTextBlobBuilder.
267
268 RunBuffer::utf8text, and RunBuffer::clusters should be ignored.
269
270 Glyphs share metrics in font.
271
272 Glyphs are positioned using SkPoint written by caller to RunBuffer::pos, using
273 two scalar values for each SkPoint.
274
275 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob
276 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds
277 is computed from RunBuffer::pos, and RunBuffer::glyphs metrics.
278
279 @param font SkFont used for this run
280 @param count number of glyphs
281 @param bounds optional run bounding box
282 @return writable glyph buffer and SkPoint buffer
283 */
284 const RunBuffer& allocRunPos(const SkFont& font, int count,
285 const SkRect* bounds = nullptr);
286
fmalita00d5c2c2014-08-21 08:53:26 -0700287private:
Cary Clarke12a0902018-08-09 10:07:33 -0400288 const RunBuffer& allocRunText(const SkPaint& font,
289 int count,
290 SkScalar x,
291 SkScalar y,
292 int textByteCount,
293 SkString lang,
294 const SkRect* bounds = nullptr);
295 const RunBuffer& allocRunTextPosH(const SkPaint& font, int count, SkScalar y,
296 int textByteCount, SkString lang,
297 const SkRect* bounds = nullptr);
298 const RunBuffer& allocRunTextPos(const SkPaint& font, int count,
299 int textByteCount, SkString lang,
300 const SkRect* bounds = nullptr);
fmalita3c196de2014-09-20 05:40:22 -0700301 void reserve(size_t size);
fmalita00d5c2c2014-08-21 08:53:26 -0700302 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
halcanary4f0a23a2016-08-30 11:58:33 -0700303 int count, int textBytes, SkPoint offset, const SkRect* bounds);
fmalita3c196de2014-09-20 05:40:22 -0700304 bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
Florin Malitad923a712017-11-22 10:11:12 -0500305 uint32_t count, SkPoint offset);
fmalita00d5c2c2014-08-21 08:53:26 -0700306 void updateDeferredBounds();
307
fmalita3dc40ac2015-01-28 10:56:06 -0800308 static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
309 static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
310
Cary Clarke12a0902018-08-09 10:07:33 -0400311 friend class SkTextBlobPriv;
312 friend class SkTextBlobBuilderPriv;
313
fmalita3c196de2014-09-20 05:40:22 -0700314 SkAutoTMalloc<uint8_t> fStorage;
315 size_t fStorageSize;
316 size_t fStorageUsed;
fmalita00d5c2c2014-08-21 08:53:26 -0700317
fmalita3c196de2014-09-20 05:40:22 -0700318 SkRect fBounds;
319 int fRunCount;
320 bool fDeferredBounds;
321 size_t fLastRun; // index into fStorage
fmalita00d5c2c2014-08-21 08:53:26 -0700322
fmalita3c196de2014-09-20 05:40:22 -0700323 RunBuffer fCurrentRunBuffer;
fmalita00d5c2c2014-08-21 08:53:26 -0700324};
325
326#endif // SkTextBlob_DEFINED