blob: fcf1766c3ee1898a4fffce64121e462f9fc8f8b1 [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*/
jbroman3053dfa2014-08-25 06:22:12 -070020class SK_API SkTextBlob : public SkRefCnt {
fmalita00d5c2c2014-08-21 08:53:26 -070021public:
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;
fmalita37ecbaf2014-08-22 09:01:19 -070050 void applyFontToPaint(SkPaint*) const;
fmalita00d5c2c2014-08-21 08:53:26 -070051 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;
fmalitac6765d62014-08-21 15:03:04 -070072 friend class TextBlobTester;
fmalita00d5c2c2014-08-21 08:53:26 -070073
74 const SkAutoTMalloc<uint16_t> fGlyphBuffer;
75 const SkAutoTMalloc<SkScalar> fPosBuffer;
76
77 // SkTArray required here for run font destruction.
78 SkAutoTDelete<const SkTArray<Run> > fRuns;
79 const SkRect fBounds;
80
81 mutable uint32_t fUniqueID;
82
83 typedef SkRefCnt INHERITED;
84};
85
86/** \class SkTextBlobBuilder
87
88 Helper class for constructing SkTextBlobs.
89 */
jbroman3053dfa2014-08-25 06:22:12 -070090class SK_API SkTextBlobBuilder {
fmalita00d5c2c2014-08-21 08:53:26 -070091public:
92 /**
93 * @param runs The number of runs to be added, if known. This is a storage hint and
94 * not a limit.
95 */
96 SkTextBlobBuilder(unsigned runs = 0);
97
98 ~SkTextBlobBuilder();
99
100 /**
101 * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and
102 * can be reused.
103 */
104 const SkTextBlob* build();
105
106 /**
107 * Glyph and position buffers associated with a run.
108 *
109 * A run is a sequence of glyphs sharing the same font metrics and positioning mode.
110 */
111 struct RunBuffer {
112 uint16_t* glyphs;
113 SkScalar* pos;
114 };
115
116 /**
117 * Allocates a new default-positioned run and returns its writable glyph buffer
118 * for direct manipulation.
119 *
120 * @param font The font to be used for this run.
121 * @param count Number of glyphs.
122 * @param x,y Position within the blob.
123 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
124 * be used when computing the blob bounds, to avoid re-measuring.
125 *
126 * @return A writable glyph buffer, valid until the next allocRun() or
127 * build() call. The buffer is guaranteed to hold @count@ glyphs.
128 */
129 const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
130 const SkRect* bounds = NULL);
131
132 /**
133 * Allocates a new horizontally-positioned run and returns its writable glyph and position
134 * buffers for direct manipulation.
135 *
136 * @param font The font to be used for this run.
137 * @param count Number of glyphs.
138 * @param y Vertical offset within the blob.
139 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
140 * be used when computing the blob bounds, to avoid re-measuring.
141 *
142 * @return Writable glyph and position buffers, valid until the next allocRun()
143 * or build() call. The buffers are guaranteed to hold @count@ elements.
144 */
145 const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
146 const SkRect* bounds = NULL);
147
148 /**
149 * Allocates a new fully-positioned run and returns its writable glyph and position
150 * buffers for direct manipulation.
151 *
152 * @param font The font to be used for this run.
153 * @param count Number of glyphs.
154 * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
155 * be used when computing the blob bounds, to avoid re-measuring.
156 *
157 * @return Writable glyph and position buffers, valid until the next allocRun()
158 * or build() call. The glyph buffer and position buffer are
159 * guaranteed to hold @count@ and 2 * @count@ elements, respectively.
160 */
161 const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL);
162
163private:
164 void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
165 int count, SkPoint offset, const SkRect* bounds);
166 void ensureRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
167 const SkPoint& offset);
168 void updateDeferredBounds();
169
170 SkTDArray<uint16_t> fGlyphBuffer;
171 SkTDArray<SkScalar> fPosBuffer;
172 SkTArray<SkTextBlob::Run>* fRuns;
173
174 SkRect fBounds;
175 bool fDeferredBounds;
176
177 RunBuffer fCurrentRunBuffer;
178};
179
180#endif // SkTextBlob_DEFINED