1 /* 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 8 /* 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 18 #ifndef SkTextBlob_DEFINED 19 #define SkTextBlob_DEFINED 20 21 #include "../private/SkTemplates.h" 22 #include "SkFont.h" 23 #include "SkPaint.h" 24 #include "SkString.h" 25 #include "SkRefCnt.h" 26 27 #include <atomic> 28 29 struct SkRSXform; 30 struct SkSerialProcs; 31 struct SkDeserialProcs; 32 33 /** \class SkTextBlob 34 SkTextBlob combines multiple text runs into an immutable container. Each text 35 run consists of glyphs, SkPaint, and position. Only parts of SkPaint related to 36 fonts and text rendering are used by run. 37 */ 38 class SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> { 39 public: 40 41 /** Returns conservative bounding box. Uses SkPaint associated with each glyph to 42 determine glyph bounds, and unions all bounds. Returned bounds may be 43 larger than the bounds of all glyphs in runs. 44 45 @return conservative bounding box 46 */ bounds()47 const SkRect& bounds() const { return fBounds; } 48 49 /** Returns a non-zero value unique among all text blobs. 50 51 @return identifier for SkTextBlob 52 */ uniqueID()53 uint32_t uniqueID() const { return fUniqueID; } 54 55 /** Returns the number of intervals that intersect bounds. 56 bounds describes a pair of lines parallel to the text advance. 57 The return count is zero or a multiple of two, and is at most twice the number of glyphs in 58 the the blob. 59 60 Pass nullptr for intervals to determine the size of the interval array. 61 62 Runs within the blob that contain SkRSXform are ignored when computing intercepts. 63 64 @param bounds lower and upper line parallel to the advance 65 @param intervals returned intersections; may be nullptr 66 @param paint specifies stroking, SkPathEffect that affects the result; may be nullptr 67 @return number of intersections; may be zero 68 */ 69 int getIntercepts(const SkScalar bounds[2], SkScalar intervals[], 70 const SkPaint* paint = nullptr) const; 71 72 /** Creates SkTextBlob with a single run. 73 74 font contains attributes used to define the run text. 75 76 When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or 77 SkTextEncoding::kUTF32, this function uses the default 78 character-to-glyph mapping from the SkTypeface in font. It does not 79 perform typeface fallback for characters not found in the SkTypeface. 80 It does not perform kerning or other complex shaping; glyphs are 81 positioned based on their default advances. 82 83 @param text character code points or glyphs drawn 84 @param byteLength byte length of text array 85 @param font text size, typeface, text scale, and so on, used to draw 86 @param encoding text encoding used in the text array 87 @return SkTextBlob constructed from one run 88 */ 89 static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font, 90 SkTextEncoding encoding = kUTF8_SkTextEncoding); 91 92 /** Creates SkTextBlob with a single run. string meaning depends on SkTextEncoding; 93 by default, string is encoded as UTF-8. 94 95 font contains attributes used to define the run text. 96 97 When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or 98 SkTextEncoding::kUTF32, this function uses the default 99 character-to-glyph mapping from the SkTypeface in font. It does not 100 perform typeface fallback for characters not found in the SkTypeface. 101 It does not perform kerning or other complex shaping; glyphs are 102 positioned based on their default advances. 103 104 @param string character code points or glyphs drawn 105 @param font text size, typeface, text scale, and so on, used to draw 106 @param encoding text encoding used in the text array 107 @return SkTextBlob constructed from one run 108 */ 109 static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font, 110 SkTextEncoding encoding = kUTF8_SkTextEncoding) { 111 if (!string) { 112 return nullptr; 113 } 114 return MakeFromText(string, strlen(string), font, encoding); 115 } 116 117 /** Experimental. 118 Returns a textblob built from a single run of text with x-positions and a single y value. 119 This is equivalent to using SkTextBlobBuilder and calling allocRunPosH(). 120 Returns nullptr if byteLength is zero. 121 122 @param text character code points or glyphs drawn (based on encoding) 123 @param byteLength byte length of text array 124 @param xpos array of x-positions, must contain values for all of the character points. 125 @param constY shared y-position for each character point, to be paired with each xpos. 126 @param font SkFont used for this run 127 @param encoding specifies the encoding of the text array. 128 @return new textblob or nullptr 129 */ 130 static sk_sp<SkTextBlob> MakeFromPosTextH(const void* text, size_t byteLength, 131 const SkScalar xpos[], SkScalar constY, const SkFont& font, 132 SkTextEncoding encoding = kUTF8_SkTextEncoding); 133 134 /** Experimental. 135 Returns a textblob built from a single run of text with positions. 136 This is equivalent to using SkTextBlobBuilder and calling allocRunPos(). 137 Returns nullptr if byteLength is zero. 138 139 @param text character code points or glyphs drawn (based on encoding) 140 @param byteLength byte length of text array 141 @param pos array of positions, must contain values for all of the character points. 142 @param font SkFont used for this run 143 @param encoding specifies the encoding of the text array. 144 @return new textblob or nullptr 145 */ 146 static sk_sp<SkTextBlob> MakeFromPosText(const void* text, size_t byteLength, 147 const SkPoint pos[], const SkFont& font, 148 SkTextEncoding encoding = kUTF8_SkTextEncoding); 149 150 // Experimental 151 static sk_sp<SkTextBlob> MakeFromRSXform(const void* text, size_t byteLength, 152 const SkRSXform xform[], const SkFont& font, 153 SkTextEncoding encoding = kUTF8_SkTextEncoding); 154 155 /** Writes data to allow later reconstruction of SkTextBlob. memory points to storage 156 to receive the encoded data, and memory_size describes the size of storage. 157 Returns bytes used if provided storage is large enough to hold all data; 158 otherwise, returns zero. 159 160 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface. 161 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx 162 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc 163 is called with a pointer to SkTypeface and user context. 164 165 @param procs custom serial data encoders; may be nullptr 166 @param memory storage for data 167 @param memory_size size of storage 168 @return bytes written, or zero if required storage is larger than memory_size 169 */ 170 size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const; 171 172 /** Returns storage containing SkData describing SkTextBlob, using optional custom 173 encoders. 174 175 procs.fTypefaceProc permits supplying a custom function to encode SkTypeface. 176 If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx 177 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc 178 is called with a pointer to SkTypeface and user context. 179 180 @param procs custom serial data encoders; may be nullptr 181 @return storage containing serialized SkTextBlob 182 */ 183 sk_sp<SkData> serialize(const SkSerialProcs& procs) const; 184 185 /** Recreates SkTextBlob that was serialized into data. Returns constructed SkTextBlob 186 if successful; otherwise, returns nullptr. Fails if size is smaller than 187 required data length, or if data does not permit constructing valid SkTextBlob. 188 189 procs.fTypefaceProc permits supplying a custom function to decode SkTypeface. 190 If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx 191 may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc 192 is called with a pointer to SkTypeface data, data byte length, and user context. 193 194 @param data pointer for serial data 195 @param size size of data 196 @param procs custom serial data decoders; may be nullptr 197 @return SkTextBlob constructed from data in memory 198 */ 199 static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, 200 const SkDeserialProcs& procs); 201 202 private: 203 friend class SkNVRefCnt<SkTextBlob>; 204 class RunRecord; 205 206 enum GlyphPositioning : uint8_t; 207 208 explicit SkTextBlob(const SkRect& bounds); 209 210 ~SkTextBlob(); 211 212 // Memory for objects of this class is created with sk_malloc rather than operator new and must 213 // be freed with sk_free. 214 void operator delete(void* p); 215 void* operator new(size_t); 216 void* operator new(size_t, void* p); 217 218 static unsigned ScalarsPerGlyph(GlyphPositioning pos); 219 220 // Call when this blob is part of the key to a cache entry. This allows the cache 221 // to know automatically those entries can be purged when this SkTextBlob is deleted. notifyAddedToCache(uint32_t cacheID)222 void notifyAddedToCache(uint32_t cacheID) const { 223 fCacheID.store(cacheID); 224 } 225 226 friend class SkGlyphRunList; 227 friend class GrTextBlobCache; 228 friend class SkTextBlobBuilder; 229 friend class SkTextBlobPriv; 230 friend class SkTextBlobRunIterator; 231 232 const SkRect fBounds; 233 const uint32_t fUniqueID; 234 mutable std::atomic<uint32_t> fCacheID; 235 236 SkDEBUGCODE(size_t fStorageSize;) 237 238 // The actual payload resides in externally-managed storage, following the object. 239 // (see the .cpp for more details) 240 241 typedef SkRefCnt INHERITED; 242 }; 243 244 /** \class SkTextBlobBuilder 245 Helper class for constructing SkTextBlob. 246 */ 247 class SK_API SkTextBlobBuilder { 248 public: 249 250 /** Constructs empty SkTextBlobBuilder. By default, SkTextBlobBuilder has no runs. 251 252 @return empty SkTextBlobBuilder 253 */ 254 SkTextBlobBuilder(); 255 256 /** Deletes data allocated internally by SkTextBlobBuilder. 257 */ 258 ~SkTextBlobBuilder(); 259 260 /** Returns SkTextBlob built from runs of glyphs added by builder. Returned 261 SkTextBlob is immutable; it may be copied, but its contents may not be altered. 262 Returns nullptr if no runs of glyphs were added by builder. 263 264 Resets SkTextBlobBuilder to its initial empty state, allowing it to be 265 reused to build a new set of runs. 266 267 @return SkTextBlob or nullptr 268 */ 269 sk_sp<SkTextBlob> make(); 270 271 /** \struct SkTextBlobBuilder::RunBuffer 272 RunBuffer supplies storage for glyphs and positions within a run. 273 274 A run is a sequence of glyphs sharing font metrics and positioning. 275 Each run may position its glyphs in one of three ways: 276 by specifying where the first glyph is drawn, and allowing font metrics to 277 determine the advance to subsequent glyphs; by specifying a baseline, and 278 the position on that baseline for each glyph in run; or by providing SkPoint 279 array, one per glyph. 280 */ 281 struct RunBuffer { 282 SkGlyphID* glyphs; //!< storage for glyphs in run 283 SkScalar* pos; //!< storage for positions in run 284 char* utf8text; //!< reserved for future use 285 uint32_t* clusters; //!< reserved for future use 286 287 // experimental pointsRunBuffer288 SkPoint* points() const { return reinterpret_cast<SkPoint*>(pos); } 289 // experimental xformsRunBuffer290 SkRSXform* xforms() const { return reinterpret_cast<SkRSXform*>(pos); } 291 }; 292 293 /** Returns run with storage for glyphs. Caller must write count glyphs to 294 RunBuffer::glyphs before next call to SkTextBlobBuilder. 295 296 RunBuffer::utf8text, and RunBuffer::clusters should be ignored. 297 298 Glyphs share metrics in font. 299 300 Glyphs are positioned on a baseline at (x, y), using font metrics to 301 determine their relative placement. 302 303 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob 304 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds 305 is computed from (x, y) and RunBuffer::glyphs metrics. 306 307 @param font SkFont used for this run 308 @param count number of glyphs 309 @param x horizontal offset within the blob 310 @param y vertical offset within the blob 311 @param bounds optional run bounding box 312 @return writable glyph buffer 313 */ 314 const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y, 315 const SkRect* bounds = nullptr); 316 317 /** Returns run with storage for glyphs and positions along baseline. Caller must 318 write count glyphs to RunBuffer::glyphs, and count scalars to RunBuffer::pos; 319 before next call to SkTextBlobBuilder. 320 321 RunBuffer::utf8text, and RunBuffer::clusters should be ignored. 322 323 Glyphs share metrics in font. 324 325 Glyphs are positioned on a baseline at y, using x-axis positions written by 326 caller to RunBuffer::pos. 327 328 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob 329 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds 330 is computed from y, RunBuffer::pos, and RunBuffer::glyphs metrics. 331 332 @param font SkFont used for this run 333 @param count number of glyphs 334 @param y vertical offset within the blob 335 @param bounds optional run bounding box 336 @return writable glyph buffer and x-axis position buffer 337 */ 338 const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y, 339 const SkRect* bounds = nullptr); 340 341 /** Returns run with storage for glyphs and SkPoint positions. Caller must 342 write count glyphs to RunBuffer::glyphs, and count SkPoint to RunBuffer::pos; 343 before next call to SkTextBlobBuilder. 344 345 RunBuffer::utf8text, and RunBuffer::clusters should be ignored. 346 347 Glyphs share metrics in font. 348 349 Glyphs are positioned using SkPoint written by caller to RunBuffer::pos, using 350 two scalar values for each SkPoint. 351 352 bounds defines an optional bounding box, used to suppress drawing when SkTextBlob 353 bounds does not intersect SkSurface bounds. If bounds is nullptr, SkTextBlob bounds 354 is computed from RunBuffer::pos, and RunBuffer::glyphs metrics. 355 356 @param font SkFont used for this run 357 @param count number of glyphs 358 @param bounds optional run bounding box 359 @return writable glyph buffer and SkPoint buffer 360 */ 361 const RunBuffer& allocRunPos(const SkFont& font, int count, 362 const SkRect* bounds = nullptr); 363 364 // Experimental, RunBuffer.pos points to SkRSXform array 365 const RunBuffer& allocRunRSXform(const SkFont& font, int count); 366 367 private: 368 const RunBuffer& allocRunText(const SkFont& font, 369 int count, 370 SkScalar x, 371 SkScalar y, 372 int textByteCount, 373 SkString lang, 374 const SkRect* bounds = nullptr); 375 const RunBuffer& allocRunTextPosH(const SkFont& font, int count, SkScalar y, 376 int textByteCount, SkString lang, 377 const SkRect* bounds = nullptr); 378 const RunBuffer& allocRunTextPos(const SkFont& font, int count, 379 int textByteCount, SkString lang, 380 const SkRect* bounds = nullptr); 381 const RunBuffer& allocRunRSXform(const SkFont& font, int count, 382 int textByteCount, SkString lang, 383 const SkRect* bounds = nullptr); 384 385 void reserve(size_t size); 386 void allocInternal(const SkFont& font, SkTextBlob::GlyphPositioning positioning, 387 int count, int textBytes, SkPoint offset, const SkRect* bounds); 388 bool mergeRun(const SkFont& font, SkTextBlob::GlyphPositioning positioning, 389 uint32_t count, SkPoint offset); 390 void updateDeferredBounds(); 391 392 static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&); 393 static SkRect TightRunBounds(const SkTextBlob::RunRecord&); 394 395 friend class SkTextBlobPriv; 396 friend class SkTextBlobBuilderPriv; 397 398 SkAutoTMalloc<uint8_t> fStorage; 399 size_t fStorageSize; 400 size_t fStorageUsed; 401 402 SkRect fBounds; 403 int fRunCount; 404 bool fDeferredBounds; 405 size_t fLastRun; // index into fStorage 406 407 RunBuffer fCurrentRunBuffer; 408 }; 409 410 #endif // SkTextBlob_DEFINED 411