Skia
2D Graphics Library
SkTextBlob.h
Go to the documentation of this file.
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"
13 #include "include/core/SkRect.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkTypes.h"
17 #include "include/private/base/SkDebug.h"
18 #include "include/private/base/SkTemplates.h"
19 
20 #include <atomic>
21 #include <cstdint>
22 #include <cstring>
23 
24 class SkData;
25 class SkPaint;
26 class SkTypeface;
27 struct SkDeserialProcs;
28 struct SkPoint;
29 struct SkRSXform;
30 struct SkSerialProcs;
31 
32 namespace sktext {
33 class GlyphRunList;
34 }
35 
41 class SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> {
42 private:
43  class RunRecord;
44 
45 public:
46 
53  const SkRect& bounds() const { return fBounds; }
54 
59  uint32_t uniqueID() const { return fUniqueID; }
60 
75  int getIntercepts(const SkScalar bounds[2], SkScalar intervals[],
76  const SkPaint* paint = nullptr) const;
77 
95  static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
97 
115  static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
117  if (!string) {
118  return nullptr;
119  }
120  return MakeFromText(string, strlen(string), font, encoding);
121  }
122 
135  static sk_sp<SkTextBlob> MakeFromPosTextH(const void* text, size_t byteLength,
136  const SkScalar xpos[], SkScalar constY, const SkFont& font,
138 
150  static sk_sp<SkTextBlob> MakeFromPosText(const void* text, size_t byteLength,
151  const SkPoint pos[], const SkFont& font,
153 
154  static sk_sp<SkTextBlob> MakeFromRSXform(const void* text, size_t byteLength,
155  const SkRSXform xform[], const SkFont& font,
157 
175  size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const;
176 
190  sk_sp<SkData> serialize(const SkSerialProcs& procs) const;
191 
206  static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
207  const SkDeserialProcs& procs);
208 
209  class SK_API Iter {
210  public:
211  struct Run {
214  const uint16_t* fGlyphIndices;
215 #ifdef SK_UNTIL_CRBUG_1187654_IS_FIXED
216  const uint32_t* fClusterIndex_forTest;
217  int fUtf8Size_forTest;
218  const char* fUtf8_forTest;
219 #endif
220  };
221 
222  Iter(const SkTextBlob&);
223 
228  bool next(Run*);
229 
230  // Experimental, DO NO USE, will change/go-away
233  int count;
234  const uint16_t* glyphs;
235  const SkPoint* positions;
236  };
238 
239  private:
240  const RunRecord* fRunRecord;
241  };
242 
243 private:
244  friend class SkNVRefCnt<SkTextBlob>;
245 
246  enum GlyphPositioning : uint8_t;
247 
248  explicit SkTextBlob(const SkRect& bounds);
249 
250  ~SkTextBlob();
251 
252  // Memory for objects of this class is created with sk_malloc rather than operator new and must
253  // be freed with sk_free.
254  void operator delete(void* p);
255  void* operator new(size_t);
256  void* operator new(size_t, void* p);
257 
258  static unsigned ScalarsPerGlyph(GlyphPositioning pos);
259 
260  using PurgeDelegate = void (*)(uint32_t blobID, uint32_t cacheID);
261 
262  // Call when this blob is part of the key to a cache entry. This allows the cache
263  // to know automatically those entries can be purged when this SkTextBlob is deleted.
264  void notifyAddedToCache(uint32_t cacheID, PurgeDelegate purgeDelegate) const {
265  fCacheID.store(cacheID);
266  fPurgeDelegate.store(purgeDelegate);
267  }
268 
269  friend class sktext::GlyphRunList;
270  friend class SkTextBlobBuilder;
271  friend class SkTextBlobPriv;
272  friend class SkTextBlobRunIterator;
273 
274  const SkRect fBounds;
275  const uint32_t fUniqueID;
276  mutable std::atomic<uint32_t> fCacheID;
277  mutable std::atomic<PurgeDelegate> fPurgeDelegate;
278 
279  SkDEBUGCODE(size_t fStorageSize;)
280 
281  // The actual payload resides in externally-managed storage, following the object.
282  // (see the .cpp for more details)
283 
284  using INHERITED = SkRefCnt;
285 };
286 
290 class SK_API SkTextBlobBuilder {
291 public:
292 
300 
304 
317 
328  struct RunBuffer {
331  char* utf8text;
332  uint32_t* clusters;
333 
334  // Helpers, since the "pos" field can be different types (always some number of floats).
335  SkPoint* points() const { return reinterpret_cast<SkPoint*>(pos); }
336  SkRSXform* xforms() const { return reinterpret_cast<SkRSXform*>(pos); }
337  };
338 
360  const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y,
361  const SkRect* bounds = nullptr);
362 
384  const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y,
385  const SkRect* bounds = nullptr);
386 
407  const RunBuffer& allocRunPos(const SkFont& font, int count,
408  const SkRect* bounds = nullptr);
409 
410  // RunBuffer.pos points to SkRSXform array
411  const RunBuffer& allocRunRSXform(const SkFont& font, int count);
412 
437  const RunBuffer& allocRunText(const SkFont& font, int count, SkScalar x, SkScalar y,
438  int textByteCount, const SkRect* bounds = nullptr);
439 
462  const RunBuffer& allocRunTextPosH(const SkFont& font, int count, SkScalar y, int textByteCount,
463  const SkRect* bounds = nullptr);
464 
486  const RunBuffer& allocRunTextPos(const SkFont& font, int count, int textByteCount,
487  const SkRect* bounds = nullptr);
488 
489  // RunBuffer.pos points to SkRSXform array
490  const RunBuffer& allocRunTextRSXform(const SkFont& font, int count, int textByteCount,
491  const SkRect* bounds = nullptr);
492 
493 private:
494  void reserve(size_t size);
495  void allocInternal(const SkFont& font, SkTextBlob::GlyphPositioning positioning,
496  int count, int textBytes, SkPoint offset, const SkRect* bounds);
497  bool mergeRun(const SkFont& font, SkTextBlob::GlyphPositioning positioning,
498  uint32_t count, SkPoint offset);
499  void updateDeferredBounds();
500 
501  static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
502  static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
503 
504  friend class SkTextBlobPriv;
505  friend class SkTextBlobBuilderPriv;
506 
507  skia_private::AutoTMalloc<uint8_t> fStorage;
508  size_t fStorageSize;
509  size_t fStorageUsed;
510 
511  SkRect fBounds;
512  int fRunCount;
513  bool fDeferredBounds;
514  size_t fLastRun; // index into fStorage
515 
516  RunBuffer fCurrentRunBuffer;
517 };
518 
519 #endif // SkTextBlob_DEFINED
SkTextEncoding
Definition: SkFontTypes.h:11
@ kUTF8
uses bytes to represent UTF-8 or ASCII
float SkScalar
Definition: SkScalar.h:14
uint16_t SkGlyphID
16 bit unsigned integer to hold a glyph index
Definition: SkTypes.h:171
SkData holds an immutable data buffer.
Definition: SkData.h:25
SkFont controls options applied when drawing and measuring text.
Definition: SkFont.h:36
Definition: SkRefCnt.h:160
SkPaint controls options applied when drawing.
Definition: SkPaint.h:44
Definition: SkRefCnt.h:119
Helper class for constructing SkTextBlob.
Definition: SkTextBlob.h:290
SkTextBlobBuilder()
Constructs empty SkTextBlobBuilder.
const RunBuffer & allocRunTextRSXform(const SkFont &font, int count, int textByteCount, const SkRect *bounds=nullptr)
const RunBuffer & allocRunText(const SkFont &font, int count, SkScalar x, SkScalar y, int textByteCount, const SkRect *bounds=nullptr)
Returns run with storage for glyphs, text, and clusters.
const RunBuffer & allocRun(const SkFont &font, int count, SkScalar x, SkScalar y, const SkRect *bounds=nullptr)
Returns run with storage for glyphs.
const RunBuffer & allocRunPos(const SkFont &font, int count, const SkRect *bounds=nullptr)
Returns run with storage for glyphs and SkPoint positions.
const RunBuffer & allocRunTextPosH(const SkFont &font, int count, SkScalar y, int textByteCount, const SkRect *bounds=nullptr)
Returns run with storage for glyphs, positions along baseline, text, and clusters.
const RunBuffer & allocRunPosH(const SkFont &font, int count, SkScalar y, const SkRect *bounds=nullptr)
Returns run with storage for glyphs and positions along baseline.
sk_sp< SkTextBlob > make()
Returns SkTextBlob built from runs of glyphs added by builder.
~SkTextBlobBuilder()
Deletes data allocated internally by SkTextBlobBuilder.
const RunBuffer & allocRunRSXform(const SkFont &font, int count)
const RunBuffer & allocRunTextPos(const SkFont &font, int count, int textByteCount, const SkRect *bounds=nullptr)
Returns run with storage for glyphs, SkPoint positions, text, and clusters.
Definition: SkTextBlob.h:209
bool next(Run *)
Returns true for each "run" inside the textblob, setting the Run fields (if not null).
bool experimentalNext(ExperimentalRun *)
Iter(const SkTextBlob &)
SkTextBlob combines multiple text runs into an immutable container.
Definition: SkTextBlob.h:41
static sk_sp< SkTextBlob > MakeFromPosText(const void *text, size_t byteLength, const SkPoint pos[], const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Returns a textblob built from a single run of text with positions.
int getIntercepts(const SkScalar bounds[2], SkScalar intervals[], const SkPaint *paint=nullptr) const
Returns the number of intervals that intersect bounds.
const SkRect & bounds() const
Returns conservative bounding box.
Definition: SkTextBlob.h:53
static sk_sp< SkTextBlob > MakeFromString(const char *string, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Creates SkTextBlob with a single run.
Definition: SkTextBlob.h:115
uint32_t uniqueID() const
Returns a non-zero value unique among all text blobs.
Definition: SkTextBlob.h:59
static sk_sp< SkTextBlob > MakeFromRSXform(const void *text, size_t byteLength, const SkRSXform xform[], const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
static sk_sp< SkTextBlob > MakeFromPosTextH(const void *text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Returns a textblob built from a single run of text with x-positions and a single y value.
static sk_sp< SkTextBlob > Deserialize(const void *data, size_t size, const SkDeserialProcs &procs)
Recreates SkTextBlob that was serialized into data.
sk_sp< SkData > serialize(const SkSerialProcs &procs) const
Returns storage containing SkData describing SkTextBlob, using optional custom encoders.
static sk_sp< SkTextBlob > MakeFromText(const void *text, size_t byteLength, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Creates SkTextBlob with a single run.
size_t serialize(const SkSerialProcs &procs, void *memory, size_t memory_size) const
Writes data to allow later reconstruction of SkTextBlob.
The SkTypeface class specifies the typeface and intrinsic style of a font.
Definition: SkTypeface.h:52
Definition: SkCanvas.h:42
Definition: SkSerialProcs.h:97
A compressed form of a rotation+scale matrix.
Definition: SkRSXform.h:21
SkRect holds four float coordinates describing the upper and lower bounds of a rectangle.
Definition: SkRect.h:582
Definition: SkSerialProcs.h:86
RunBuffer supplies storage for glyphs and positions within a run.
Definition: SkTextBlob.h:328
SkRSXform * xforms() const
Definition: SkTextBlob.h:336
SkScalar * pos
storage for glyph positions in run
Definition: SkTextBlob.h:330
char * utf8text
storage for text UTF-8 code units in run
Definition: SkTextBlob.h:331
SkGlyphID * glyphs
storage for glyph indexes in run
Definition: SkTextBlob.h:329
SkPoint * points() const
Definition: SkTextBlob.h:335
uint32_t * clusters
storage for glyph clusters (index of UTF-8 code unit)
Definition: SkTextBlob.h:332
Definition: SkTextBlob.h:231
SkFont font
Definition: SkTextBlob.h:232
const SkPoint * positions
Definition: SkTextBlob.h:235
int count
Definition: SkTextBlob.h:233
const uint16_t * glyphs
Definition: SkTextBlob.h:234
Definition: SkTextBlob.h:211
SkTypeface * fTypeface
Definition: SkTextBlob.h:212
int fGlyphCount
Definition: SkTextBlob.h:213
const uint16_t * fGlyphIndices
Definition: SkTextBlob.h:214