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 "../private/SkTemplates.h" 12 #include "SkPaint.h" 13 #include "SkRefCnt.h" 14 15 class SkReadBuffer; 16 class SkWriteBuffer; 17 18 /** \class SkTextBlob 19 20 SkTextBlob combines multiple text runs into an immutable, ref-counted structure. 21 */ 22 class SK_API SkTextBlob : public SkRefCnt { 23 public: 24 /** 25 * Returns a conservative blob bounding box. 26 */ bounds()27 const SkRect& bounds() const { return fBounds; } 28 29 /** 30 * Return a non-zero, unique value representing the text blob. 31 */ uniqueID()32 uint32_t uniqueID() const { return fUniqueID; } 33 34 /** 35 * Serialize to a buffer. 36 */ 37 void flatten(SkWriteBuffer&) const; 38 39 /** 40 * Recreate an SkTextBlob that was serialized into a buffer. 41 * 42 * @param SkReadBuffer Serialized blob data. 43 * @return A new SkTextBlob representing the serialized data, or NULL if the buffer is 44 * invalid. 45 */ 46 static const SkTextBlob* CreateFromBuffer(SkReadBuffer&); 47 48 enum GlyphPositioning { 49 kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. 50 kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph. 51 kFull_Positioning = 2 // Point positioning -- two scalars per glyph. 52 }; 53 54 private: 55 class RunRecord; 56 57 SkTextBlob(int runCount, const SkRect& bounds); 58 59 virtual ~SkTextBlob(); 60 61 // Memory for objects of this class is created with sk_malloc rather than operator new and must 62 // be freed with sk_free. delete(void * p)63 void operator delete(void* p) { sk_free(p); } new(size_t)64 void* operator new(size_t) { 65 SkFAIL("All blobs are created by placement new."); 66 return sk_malloc_throw(0); 67 } new(size_t,void * p)68 void* operator new(size_t, void* p) { return p; } 69 70 static unsigned ScalarsPerGlyph(GlyphPositioning pos); 71 72 friend class SkTextBlobBuilder; 73 friend class SkTextBlobRunIterator; 74 75 const int fRunCount; 76 const SkRect fBounds; 77 const uint32_t fUniqueID; 78 79 SkDEBUGCODE(size_t fStorageSize;) 80 81 // The actual payload resides in externally-managed storage, following the object. 82 // (see the .cpp for more details) 83 84 typedef SkRefCnt INHERITED; 85 }; 86 87 /** \class SkTextBlobBuilder 88 89 Helper class for constructing SkTextBlobs. 90 */ 91 class SK_API SkTextBlobBuilder { 92 public: 93 SkTextBlobBuilder(); 94 95 ~SkTextBlobBuilder(); 96 97 /** 98 * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and 99 * can be reused. 100 */ 101 const SkTextBlob* build(); 102 103 /** 104 * Glyph and position buffers associated with a run. 105 * 106 * A run is a sequence of glyphs sharing the same font metrics and positioning mode. 107 */ 108 struct RunBuffer { 109 uint16_t* glyphs; 110 SkScalar* pos; 111 }; 112 113 /** 114 * Allocates a new default-positioned run and returns its writable glyph buffer 115 * for direct manipulation. 116 * 117 * @param font The font to be used for this run. 118 * @param count Number of glyphs. 119 * @param x,y Position within the blob. 120 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will 121 * be used when computing the blob bounds, to avoid re-measuring. 122 * 123 * @return A writable glyph buffer, valid until the next allocRun() or 124 * build() call. The buffer is guaranteed to hold @count@ glyphs. 125 */ 126 const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y, 127 const SkRect* bounds = NULL); 128 129 /** 130 * Allocates a new horizontally-positioned run and returns its writable glyph and position 131 * buffers for direct manipulation. 132 * 133 * @param font The font to be used for this run. 134 * @param count Number of glyphs. 135 * @param y Vertical offset within the blob. 136 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will 137 * be used when computing the blob bounds, to avoid re-measuring. 138 * 139 * @return Writable glyph and position buffers, valid until the next allocRun() 140 * or build() call. The buffers are guaranteed to hold @count@ elements. 141 */ 142 const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y, 143 const SkRect* bounds = NULL); 144 145 /** 146 * Allocates a new fully-positioned run and returns its writable glyph and position 147 * buffers for direct manipulation. 148 * 149 * @param font The font to be used for this run. 150 * @param count Number of glyphs. 151 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will 152 * be used when computing the blob bounds, to avoid re-measuring. 153 * 154 * @return Writable glyph and position buffers, valid until the next allocRun() 155 * or build() call. The glyph buffer and position buffer are 156 * guaranteed to hold @count@ and 2 * @count@ elements, respectively. 157 */ 158 const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL); 159 160 private: 161 void reserve(size_t size); 162 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, 163 int count, SkPoint offset, const SkRect* bounds); 164 bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, 165 int count, SkPoint offset); 166 void updateDeferredBounds(); 167 168 static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&); 169 static SkRect TightRunBounds(const SkTextBlob::RunRecord&); 170 171 SkAutoTMalloc<uint8_t> fStorage; 172 size_t fStorageSize; 173 size_t fStorageUsed; 174 175 SkRect fBounds; 176 int fRunCount; 177 bool fDeferredBounds; 178 size_t fLastRun; // index into fStorage 179 180 RunBuffer fCurrentRunBuffer; 181 }; 182 183 #endif // SkTextBlob_DEFINED 184