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