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