blob: 0962900c97eab46eb01ec68a09d374252ebbc12f [file] [log] [blame]
Mike Reed235cb7f2018-12-03 10:57:53 -05001#Topic Text_Blob
2#Alias Text_Blob_Reference ##
3
4#Class SkTextBlob
5
6#Code
7#Populate
8##
9
10SkTextBlob combines multiple text runs into an immutable container. Each text
11run consists of Glyphs, Paint, and position. Only parts of Paint related to
12fonts and text rendering are used by run.
13
14# ------------------------------------------------------------------------------
15
16#Method const SkRect& bounds() const
17#In Property
18#Line # returns conservative bounding box ##
19#Populate
20
21#Example
22#Height 70
Cary Clarkfc93eb02018-11-24 22:32:31 -050023 SkTextBlobBuilder textBlobBuilder;
24 const char bunny[] = "/(^x^)\\";
25 const int len = sizeof(bunny) - 1;
26 uint16_t glyphs[len];
27 SkPaint paint;
28 paint.textToGlyphs(bunny, len, glyphs);
Mike Reedc86ec972018-12-05 15:09:24 -050029 paint.setTextEncoding(kGlyphID_SkTextEncoding);
Cary Clarkfc93eb02018-11-24 22:32:31 -050030 SkFont font;
31 int runs[] = { 3, 1, 3 };
32 SkPoint textPos = { 20, 50 };
33 int glyphIndex = 0;
34 for (auto runLen : runs) {
35 font.setSize(1 == runLen ? 20 : 50);
36 paint.setTextSize(1 == runLen ? 20 : 50);
37 const SkTextBlobBuilder::RunBuffer& run =
38 textBlobBuilder.allocRun(font, runLen, textPos.fX, textPos.fY);
39 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
40 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
41 glyphIndex += runLen;
42 }
43 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
44 canvas->drawTextBlob(blob.get(), 0, 0, paint);
45 paint.setStyle(SkPaint::kStroke_Style);
46 canvas->drawRect(blob->bounds(), paint);
Mike Reed235cb7f2018-12-03 10:57:53 -050047##
48
49#SeeAlso SkPath::getBounds
50
51#Method ##
52
53# ------------------------------------------------------------------------------
54
55#Method uint32_t uniqueID() const
56#In Property
57#Line # returns identifier for Text_Blob ##
58#Populate
59
60#Example
Cary Clarkfc93eb02018-11-24 22:32:31 -050061for (int index = 0; index < 2; ++index) {
62 SkTextBlobBuilder textBlobBuilder;
63 const char bunny[] = "/(^x^)\\";
64 const int len = sizeof(bunny) - 1;
65 uint16_t glyphs[len];
66 SkPaint paint;
67 paint.textToGlyphs(bunny, len, glyphs);
Mike Reedc86ec972018-12-05 15:09:24 -050068 paint.setTextEncoding(kGlyphID_SkTextEncoding);
Cary Clarkfc93eb02018-11-24 22:32:31 -050069 paint.setTextScaleX(0.5);
70 SkFont font;
71 font.setScaleX(0.5);
72 int runs[] = { 3, 1, 3 };
73 SkPoint textPos = { 20, 50 };
74 int glyphIndex = 0;
75 for (auto runLen : runs) {
76 font.setSize(1 == runLen ? 20 : 50);
77 paint.setTextSize(1 == runLen ? 20 : 50);
78 const SkTextBlobBuilder::RunBuffer& run =
79 textBlobBuilder.allocRun(font, runLen, textPos.fX, textPos.fY);
80 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
81 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
82 glyphIndex += runLen;
83 }
84 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
85 paint.reset();
86 canvas->drawTextBlob(blob.get(), 0, 0, paint);
87 std::string id = "unique ID:" + std::to_string(blob->uniqueID());
88 canvas->drawString(id.c_str(), 30, blob->bounds().fBottom + 15, paint);
89 canvas->translate(blob->bounds().fRight + 10, 0);
90}
Mike Reed235cb7f2018-12-03 10:57:53 -050091##
92
93#SeeAlso SkRefCnt
94
95#Method ##
96
97# ------------------------------------------------------------------------------
98
Cary Clark4f738832018-12-11 08:41:11 -050099#Method int getIntercepts(const SkScalar bounds[2], SkScalar intervals[],
100 const SkPaint* paint = nullptr) const;
101#In Utility
102#Line # returns where lines intersect Text_Blob; underlines ##
103#Populate
104
105#Example
106#Height 143
107 void draw(SkCanvas* canvas) {
108 SkFont font;
109 font.setSize(120);
110 SkPoint textPos = { 20, 110 };
111 int len = 3;
112 SkTextBlobBuilder textBlobBuilder;
113 const SkTextBlobBuilder::RunBuffer& run =
114 textBlobBuilder.allocRun(font, len, textPos.fX, textPos.fY);
115 run.glyphs[0] = 10;
116 run.glyphs[1] = 20;
117 run.glyphs[2] = 30;
118 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
119 SkPaint paint;
120 SkScalar bounds[] = { 116, 134 };
121 int count = blob->getIntercepts(bounds, nullptr);
122 std::vector<SkScalar> intervals;
123 intervals.resize(count);
124 (void) paint.getTextBlobIntercepts(blob.get(), bounds, &intervals.front());
125 canvas->drawTextBlob(blob.get(), 0, 0, paint);
126 paint.setColor(0xFFFF7777);
127 SkScalar x = textPos.fX;
128 for (int i = 0; i < count; i+= 2) {
129 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
130 x = intervals[i + 1];
131 }
132 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
133 }
134##
135
136#Method ##
137
138# ------------------------------------------------------------------------------
139
Mike Reed235cb7f2018-12-03 10:57:53 -0500140#Method static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
141 SkTextEncoding encoding = kUTF8_SkTextEncoding)
142#In Constructors
143#Line # constructs Text_Blob with one run ##
144
Mike Reedc86ec972018-12-05 15:09:24 -0500145Creates Text_Blob with a single run. text meaning depends on Text_Encoding;
Mike Reed235cb7f2018-12-03 10:57:53 -0500146by default, text is encoded as UTF-8.
147
Cary Clark3e73dcf2018-12-06 08:41:14 -0500148font contains attributes used to define the run text: #font_metrics#.
Mike Reed235cb7f2018-12-03 10:57:53 -0500149
150#Param text character code points or Glyphs drawn ##
151#Param byteLength byte length of text array ##
152#Param font text size, typeface, text scale, and so on, used to draw ##
153#Param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
154 kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
155##
156
157#Return Text_Blob constructed from one run ##
158
159#Example
160#Height 24
161 SkFont font;
162 font.setSize(24);
163 SkPaint canvasPaint;
164 canvasPaint.setColor(SK_ColorBLUE); // respected
165 canvasPaint.setTextSize(2); // ignored
166 sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, font);
167 canvas->drawTextBlob(blob, 20, 20, canvasPaint);
168##
169
170#SeeAlso MakeFromString SkTextBlobBuilder
171
172##
173
174# ------------------------------------------------------------------------------
175
176#Method static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
177 SkTextEncoding encoding = kUTF8_SkTextEncoding)
178#In Constructors
179#Line # constructs Text_Blob with one run ##
180
Cary Clark3e73dcf2018-12-06 08:41:14 -0500181Creates Text_Blob with a single run. string meaning depends on Text_Encoding;
Mike Reed235cb7f2018-12-03 10:57:53 -0500182by default, string is encoded as UTF-8.
183
Cary Clark3e73dcf2018-12-06 08:41:14 -0500184font contains Font_Metrics used to define the run text: #font_metrics#.
Mike Reed235cb7f2018-12-03 10:57:53 -0500185
186#Param string character code points or Glyphs drawn ##
187#Param font text size, typeface, text scale, and so on, used to draw ##
188#Param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
189 kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
190##
191
192#Return Text_Blob constructed from one run ##
193
194#Example
195#Height 24
196 SkFont font;
197 font.setSize(24);
198 SkPaint canvasPaint;
199 canvasPaint.setColor(SK_ColorBLUE); // respected
200 canvasPaint.setTextSize(2); // ignored
201 sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("Hello World", font);
202 canvas->drawTextBlob(blob, 20, 20, canvasPaint);
203##
204
205#SeeAlso MakeFromText SkTextBlobBuilder
206
207##
208
209# ------------------------------------------------------------------------------
210
211#Method size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const
212#In Utility
213#Line # writes Text_Blob to memory ##
214#Populate
215
216#Example
217#Height 64
218###$
219$Function
220#include "SkSerialProcs.h"
221$$
222$$$#
223 SkFont blobFont;
224 blobFont.setSize(24);
225 sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont);
226 char storage[2048];
227 size_t used = blob->serialize(SkSerialProcs(), storage, sizeof(storage));
228 sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(storage, used, SkDeserialProcs());
229 canvas->drawTextBlob(copy, 20, 20, SkPaint());
230 std::string usage = "size=" + std::to_string(sizeof(storage)) + " used=" + std::to_string(used);
231 canvas->drawString(usage.c_str(), 20, 40, SkPaint());
232##
233
234#SeeAlso Deserialize SkSerialProcs
235
236#Method ##
237
238# ------------------------------------------------------------------------------
239
240#Method sk_sp<SkData> serialize(const SkSerialProcs& procs) const
241#In Utility
242#Line # writes Text_Blob to Data ##
243#Populate
244
245#Example
246#Height 24
247###$
248$Function
249#include "SkSerialProcs.h"
250$$
251$$$#
252 SkFont blobFont;
253 blobFont.setSize(24);
254 sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont);
255 sk_sp<SkData> data = blob->serialize(SkSerialProcs());
256 sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
257 canvas->drawTextBlob(copy, 20, 20, SkPaint());
258##
259
260#SeeAlso Deserialize SkData SkSerialProcs
261
262#Method ##
263
264# ------------------------------------------------------------------------------
265
266#Method static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, const SkDeserialProcs& procs)
267#In Constructors
268#Line # constructs Text_Blob from memory ##
269#Populate
270
271#Example
272#Height 24
273#Description
274Text "Hacker" replaces "World!", but does not update its metrics.
275When drawn, "Hacker" uses the spacing computed for "World!".
276##
277###$
278$Function
279#include "SkSerialProcs.h"
280$$
281$$$#
282 SkFont blobFont;
283 blobFont.setSize(24);
284 sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World!", 12, blobFont);
285 sk_sp<SkData> data = blob->serialize(SkSerialProcs());
286 uint16_t glyphs[6];
287 SkPaint blobPaint;
288 blobPaint.textToGlyphs("Hacker", 6, glyphs);
289 memcpy((char*)data->writable_data() + 0x54, glyphs, sizeof(glyphs));
290 sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
291 canvas->drawTextBlob(copy, 20, 20, SkPaint());
292##
293
294#SeeAlso serialize SkDeserialProcs
295
296#Method ##
297
298#Class SkTextBlob ##
299
300#Topic Text_Blob ##