SkTextBlob.h revision b7425173f96e93b090787e2386ba5f022b6c2869
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 16class SkReadBuffer; 17class SkWriteBuffer; 18 19/** \class SkTextBlob 20 21 SkTextBlob combines multiple text runs into an immutable, ref-counted structure. 22*/ 23class SK_API SkTextBlob : public SkRefCnt { 24public: 25 /** 26 * Returns the blob bounding box. 27 */ 28 const SkRect& bounds() const { return fBounds; } 29 30 /** 31 * Return a non-zero, unique value representing the text blob. 32 */ 33 uint32_t uniqueID() const; 34 35private: 36 enum GlyphPositioning { 37 kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. 38 kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph. 39 kFull_Positioning = 2 // Point positioning -- two scalars per glyph. 40 }; 41 42 class RunIterator { 43 public: 44 RunIterator(const SkTextBlob* blob); 45 46 bool done() const; 47 void next(); 48 49 uint32_t glyphCount() const; 50 const uint16_t* glyphs() const; 51 const SkScalar* pos() const; 52 const SkPoint& offset() const; 53 void applyFontToPaint(SkPaint*) const; 54 GlyphPositioning positioning() const; 55 56 private: 57 const SkTextBlob* fBlob; 58 int fIndex; 59 }; 60 61 // A run is a sequence of glyphs sharing the same font metrics and positioning mode. 62 struct Run { 63 uint32_t count; 64 uint32_t glyphStart; // index into fGlyphBuffer 65 uint32_t posStart; // index into fPosBuffer 66 SkPoint offset; // run offset (unsued for fully positioned glyphs) 67 SkPaint font; 68 GlyphPositioning positioning; 69 }; 70 71 SkTextBlob(uint16_t* glyphs, SkScalar* pos, const SkTArray<Run>* runs, const SkRect& bounds); 72 73 void flatten(SkWriteBuffer&) const; 74 static const SkTextBlob* CreateFromBuffer(SkReadBuffer&); 75 76 static unsigned ScalarsPerGlyph(GlyphPositioning pos); 77 78 friend class SkCanvas; 79 friend class SkPictureData; 80 friend class SkTextBlobBuilder; 81 friend class TextBlobTester; 82 83 const SkAutoTMalloc<uint16_t> fGlyphBuffer; 84 const SkAutoTMalloc<SkScalar> fPosBuffer; 85 86 // SkTArray required here for run font destruction. 87 SkAutoTDelete<const SkTArray<Run> > fRuns; 88 const SkRect fBounds; 89 90 mutable uint32_t fUniqueID; 91 92 typedef SkRefCnt INHERITED; 93}; 94 95/** \class SkTextBlobBuilder 96 97 Helper class for constructing SkTextBlobs. 98 */ 99class SK_API SkTextBlobBuilder { 100public: 101 /** 102 * @param runs The number of runs to be added, if known. This is a storage hint and 103 * not a limit. 104 */ 105 SkTextBlobBuilder(unsigned runs = 0); 106 107 ~SkTextBlobBuilder(); 108 109 /** 110 * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and 111 * can be reused. 112 */ 113 const SkTextBlob* build(); 114 115 /** 116 * Glyph and position buffers associated with a run. 117 * 118 * A run is a sequence of glyphs sharing the same font metrics and positioning mode. 119 */ 120 struct RunBuffer { 121 uint16_t* glyphs; 122 SkScalar* pos; 123 }; 124 125 /** 126 * Allocates a new default-positioned run and returns its writable glyph buffer 127 * for direct manipulation. 128 * 129 * @param font The font to be used for this run. 130 * @param count Number of glyphs. 131 * @param x,y Position within the blob. 132 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will 133 * be used when computing the blob bounds, to avoid re-measuring. 134 * 135 * @return A writable glyph buffer, valid until the next allocRun() or 136 * build() call. The buffer is guaranteed to hold @count@ glyphs. 137 */ 138 const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y, 139 const SkRect* bounds = NULL); 140 141 /** 142 * Allocates a new horizontally-positioned run and returns its writable glyph and position 143 * buffers for direct manipulation. 144 * 145 * @param font The font to be used for this run. 146 * @param count Number of glyphs. 147 * @param y Vertical offset within the blob. 148 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will 149 * be used when computing the blob bounds, to avoid re-measuring. 150 * 151 * @return Writable glyph and position buffers, valid until the next allocRun() 152 * or build() call. The buffers are guaranteed to hold @count@ elements. 153 */ 154 const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y, 155 const SkRect* bounds = NULL); 156 157 /** 158 * Allocates a new fully-positioned run and returns its writable glyph and position 159 * buffers for direct manipulation. 160 * 161 * @param font The font to be used for this run. 162 * @param count Number of glyphs. 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 glyph buffer and position buffer are 168 * guaranteed to hold @count@ and 2 * @count@ elements, respectively. 169 */ 170 const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL); 171 172private: 173 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, 174 int count, SkPoint offset, const SkRect* bounds); 175 void ensureRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, 176 const SkPoint& offset); 177 void updateDeferredBounds(); 178 179 SkTDArray<uint16_t> fGlyphBuffer; 180 SkTDArray<SkScalar> fPosBuffer; 181 SkTArray<SkTextBlob::Run>* fRuns; 182 183 SkRect fBounds; 184 bool fDeferredBounds; 185 186 RunBuffer fCurrentRunBuffer; 187}; 188 189#endif // SkTextBlob_DEFINED 190