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