blob: 8ee1d1919628b10e0d3f3ca6085a02ad619a68b2 [file] [log] [blame]
David Ghandehari9e5b5872016-07-28 09:50:04 -07001/*
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
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
49private:
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
72 private:
73 const RunRecord* fCurrentRun;
74 int fRemainingRuns;
75
76 SkDEBUGCODE(uint8_t* fStorageTop;)
77 };
78
79 SkTextBlob(int runCount, const SkRect& bounds);
80
81 virtual ~SkTextBlob();
82 virtual void internal_dispose() const SK_OVERRIDE;
83
84 static unsigned ScalarsPerGlyph(GlyphPositioning pos);
85
86 friend class SkBaseDevice;
87 friend class SkTextBlobBuilder;
88 friend class TextBlobTester;
89
90 const int fRunCount;
91 const SkRect fBounds;
92 mutable uint32_t fUniqueID;
93
94 SkDEBUGCODE(size_t fStorageSize;)
95
96 // The actual payload resides in externally-managed storage, following the object.
97 // (see the .cpp for more details)
98
99 typedef SkRefCnt INHERITED;
100};
101
102/** \class SkTextBlobBuilder
103
104 Helper class for constructing SkTextBlobs.
105 */
106class SK_API SkTextBlobBuilder {
107public:
108 SkTextBlobBuilder();
109
110 ~SkTextBlobBuilder();
111
112 /**
113 * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and
114 * can be reused.
115 */
116 const SkTextBlob* build();
117
118 /**
119 * Glyph and position buffers associated with a run.
120 *
121 * A run is a sequence of glyphs sharing the same font metrics and positioning mode.
122 */
123 struct RunBuffer {
124 uint16_t* glyphs;
125 SkScalar* pos;
126 };
127
128 /**
129 * Allocates a new default-positioned run and returns its writable glyph buffer
130 * for direct manipulation.
131 *
132 * @param font The font to be used for this run.
133 * @param count Number of glyphs.
134 * @param x,y Position within the blob.
135 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
136 * be used when computing the blob bounds, to avoid re-measuring.
137 *
138 * @return A writable glyph buffer, valid until the next allocRun() or
139 * build() call. The buffer is guaranteed to hold @count@ glyphs.
140 */
141 const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
142 const SkRect* bounds = NULL);
143
144 /**
145 * Allocates a new horizontally-positioned run and returns its writable glyph and position
146 * buffers for direct manipulation.
147 *
148 * @param font The font to be used for this run.
149 * @param count Number of glyphs.
150 * @param y Vertical offset within the blob.
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 buffers are guaranteed to hold @count@ elements.
156 */
157 const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
158 const SkRect* bounds = NULL);
159
160 /**
161 * Allocates a new fully-positioned run and returns its writable glyph and position
162 * buffers for direct manipulation.
163 *
164 * @param font The font to be used for this run.
165 * @param count Number of glyphs.
166 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
167 * be used when computing the blob bounds, to avoid re-measuring.
168 *
169 * @return Writable glyph and position buffers, valid until the next allocRun()
170 * or build() call. The glyph buffer and position buffer are
171 * guaranteed to hold @count@ and 2 * @count@ elements, respectively.
172 */
173 const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL);
174
175private:
176 void reserve(size_t size);
177 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
178 int count, SkPoint offset, const SkRect* bounds);
179 bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
180 int count, SkPoint offset);
181 void updateDeferredBounds();
182
183 SkAutoTMalloc<uint8_t> fStorage;
184 size_t fStorageSize;
185 size_t fStorageUsed;
186
187 SkRect fBounds;
188 int fRunCount;
189 bool fDeferredBounds;
190 size_t fLastRun; // index into fStorage
191
192 RunBuffer fCurrentRunBuffer;
193};
194
195#endif // SkTextBlob_DEFINED