Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 1 | #Topic Text_Blob |
| 2 | #Alias Text_Blob_Reference ## |
| 3 | |
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 4 | #Class SkTextBlob |
| 5 | |
Cary Clark | 61313f3 | 2018-10-08 14:57:48 -0400 | [diff] [blame] | 6 | #Code |
| 7 | #Populate |
| 8 | ## |
| 9 | |
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 10 | SkTextBlob combines multiple text runs into an immutable container. Each text |
| 11 | run consists of Glyphs, Paint, and position. Only parts of Paint related to |
| 12 | fonts 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 | |
| 20 | Returns conservative bounding box. Uses Paint associated with each glyph to |
| 21 | determine glyph bounds, and unions all bounds. Returned bounds may be |
| 22 | larger than the bounds of all Glyphs in runs. |
| 23 | |
| 24 | #Return conservative bounding box ## |
| 25 | |
| 26 | #Example |
| 27 | #Height 70 |
| 28 | SkTextBlobBuilder textBlobBuilder;
|
| 29 | const char bunny[] = "/(^x^)\\";
|
| 30 | const int len = sizeof(bunny) - 1;
|
| 31 | uint16_t glyphs[len];
|
| 32 | SkPaint paint;
|
| 33 | paint.textToGlyphs(bunny, len, glyphs);
|
| 34 | paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
| 35 | int runs[] = { 3, 1, 3 };
|
| 36 | SkPoint textPos = { 20, 50 };
|
| 37 | int glyphIndex = 0;
|
| 38 | for (auto runLen : runs) {
|
| 39 | paint.setTextSize(1 == runLen ? 20 : 50);
|
| 40 | const SkTextBlobBuilder::RunBuffer& run =
|
| 41 | textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
|
| 42 | memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
|
| 43 | textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
|
| 44 | glyphIndex += runLen;
|
| 45 | }
|
| 46 | sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
|
| 47 | paint.reset();
|
| 48 | canvas->drawTextBlob(blob.get(), 0, 0, paint);
|
| 49 | paint.setStyle(SkPaint::kStroke_Style);
|
| 50 | canvas->drawRect(blob->bounds(), paint); |
| 51 | ## |
| 52 | |
| 53 | #SeeAlso SkPath::getBounds |
| 54 | |
| 55 | #Method ## |
| 56 | |
| 57 | # ------------------------------------------------------------------------------ |
| 58 | |
| 59 | #Method uint32_t uniqueID() const |
| 60 | #In Property |
| 61 | #Line # returns identifier for Text_Blob ## |
| 62 | |
| 63 | Returns a non-zero value unique among all text blobs. |
| 64 | |
| 65 | #Return identifier for Text_Blob ## |
| 66 | |
| 67 | #Example |
| 68 | for (int index = 0; index < 2; ++index) {
|
| 69 | SkTextBlobBuilder textBlobBuilder;
|
| 70 | const char bunny[] = "/(^x^)\\";
|
| 71 | const int len = sizeof(bunny) - 1;
|
| 72 | uint16_t glyphs[len];
|
| 73 | SkPaint paint;
|
| 74 | paint.textToGlyphs(bunny, len, glyphs);
|
| 75 | paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
| 76 | paint.setTextScaleX(0.5);
|
| 77 | int runs[] = { 3, 1, 3 };
|
| 78 | SkPoint textPos = { 20, 50 };
|
| 79 | int glyphIndex = 0;
|
| 80 | for (auto runLen : runs) {
|
| 81 | paint.setTextSize(1 == runLen ? 20 : 50);
|
| 82 | const SkTextBlobBuilder::RunBuffer& run =
|
| 83 | textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
|
| 84 | memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
|
| 85 | textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
|
| 86 | glyphIndex += runLen;
|
| 87 | }
|
| 88 | sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
|
| 89 | paint.reset();
|
| 90 | canvas->drawTextBlob(blob.get(), 0, 0, paint);
|
| 91 | std::string id = "unique ID:" + std::to_string(blob->uniqueID());
|
| 92 | canvas->drawString(id.c_str(), 30, blob->bounds().fBottom + 15, paint);
|
| 93 | canvas->translate(blob->bounds().fRight + 10, 0);
|
| 94 | } |
| 95 | ## |
| 96 | |
| 97 | #SeeAlso SkRefCnt |
| 98 | |
| 99 | #Method ## |
| 100 | |
| 101 | # ------------------------------------------------------------------------------ |
| 102 | |
| 103 | #Method static sk_sp<SkTextBlob> MakeFromText( |
| 104 | const void* text, size_t byteLength, const SkPaint& paint) |
Cary Clark | 61313f3 | 2018-10-08 14:57:48 -0400 | [diff] [blame] | 105 | #In Constructors |
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 106 | #Line # constructs Text_Blob with one run ## |
| 107 | |
| 108 | Creates Text_Blob with a single run. text meaning depends on Paint_Text_Encoding; |
| 109 | by default, text is encoded as UTF-8. |
| 110 | |
| 111 | paint contains attributes used to define the run text: #paint_font_metrics#. |
| 112 | |
| 113 | #Param text character code points or Glyphs drawn ## |
| 114 | #Param byteLength byte length of text array ## |
| 115 | #Param paint text size, typeface, text scale, and so on, used to draw ## |
| 116 | |
| 117 | #Return Text_Blob constructed from one run ## |
| 118 | |
| 119 | #Example |
| 120 | #Height 24 |
| 121 | SkPaint blobPaint; |
| 122 | blobPaint.setColor(SK_ColorRED); // ignored |
| 123 | blobPaint.setTextSize(24); // respected |
| 124 | blobPaint.setAntiAlias(true); // ignored |
| 125 | SkPaint canvasPaint = blobPaint; |
| 126 | canvasPaint.setColor(SK_ColorBLUE); // respected |
| 127 | canvasPaint.setTextSize(2); // ignored |
| 128 | sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobPaint); |
| 129 | canvas->drawTextBlob(blob, 20, 20, canvasPaint); |
| 130 | ## |
| 131 | |
| 132 | #SeeAlso MakeFromString TextBlobBuilder |
| 133 | |
| 134 | ## |
| 135 | |
| 136 | # ------------------------------------------------------------------------------ |
| 137 | |
| 138 | #Method static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkPaint& paint) |
Cary Clark | 61313f3 | 2018-10-08 14:57:48 -0400 | [diff] [blame] | 139 | #In Constructors |
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 140 | #Line # constructs Text_Blob with one run ## |
| 141 | |
| 142 | Creates Text_Blob with a single run. string meaning depends on Paint_Text_Encoding; |
| 143 | by default, string is encoded as UTF-8. |
| 144 | |
| 145 | paint contains Paint_Font_Metrics used to define the run text: #paint_font_metrics#. |
| 146 | |
| 147 | #Param string character code points or Glyphs drawn ## |
| 148 | #Param paint text size, typeface, text scale, and so on, used to draw ## |
| 149 | |
| 150 | #Return Text_Blob constructed from one run ## |
| 151 | |
| 152 | #Example |
| 153 | #Height 24 |
| 154 | SkPaint blobPaint; |
| 155 | blobPaint.setColor(SK_ColorRED); // ignored |
| 156 | blobPaint.setTextSize(24); // respected |
| 157 | blobPaint.setAntiAlias(true); // ignored |
| 158 | SkPaint canvasPaint = blobPaint; |
| 159 | canvasPaint.setColor(SK_ColorBLUE); // respected |
| 160 | canvasPaint.setTextSize(2); // ignored |
| 161 | sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("Hello World", blobPaint); |
| 162 | canvas->drawTextBlob(blob, 20, 20, canvasPaint); |
| 163 | ## |
| 164 | |
| 165 | #SeeAlso MakeFromText TextBlobBuilder |
| 166 | |
| 167 | ## |
| 168 | |
| 169 | # ------------------------------------------------------------------------------ |
| 170 | |
| 171 | #Method size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const |
| 172 | #In Utility |
| 173 | #Line # writes Text_Blob to memory ## |
| 174 | |
| 175 | Writes data to allow later reconstruction of Text_Blob. memory points to storage |
| 176 | to receive the encoded data, and memory_size describes the size of storage. |
| 177 | Returns bytes used if provided storage is large enough to hold all data; |
| 178 | otherwise, returns zero. |
| 179 | |
| 180 | procs.fTypefaceProc permits supplying a custom function to encode Typeface. |
| 181 | If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx |
| 182 | may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc |
| 183 | is called with a pointer to Typeface and user context. |
| 184 | |
| 185 | #Param procs custom serial data encoders; may be nullptr ## |
| 186 | #Param memory storage for data ## |
| 187 | #Param size size of storage ## |
| 188 | |
| 189 | #Return bytes written, or zero if required storage is larger than memory_size ## |
| 190 | |
| 191 | #Example |
| 192 | #Height 64 |
| 193 | ###$ |
| 194 | $Function |
| 195 | #include "SkSerialProcs.h" |
| 196 | $$ |
| 197 | $$$# |
| 198 | SkPaint blobPaint;
|
| 199 | blobPaint.setTextSize(24);
|
Cary Clark | 57ca297 | 2018-08-10 15:49:01 -0400 | [diff] [blame] | 200 | sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobPaint);
|
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 201 | char storage[2048];
|
| 202 | size_t used = blob->serialize(SkSerialProcs(), storage, sizeof(storage));
|
| 203 | sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(storage, used, SkDeserialProcs());
|
| 204 | canvas->drawTextBlob(copy, 20, 20, SkPaint());
|
| 205 | std::string usage = "size=" + std::to_string(sizeof(storage)) + " used=" + std::to_string(used);
|
| 206 | canvas->drawString(usage.c_str(), 20, 40, SkPaint()); |
| 207 | ## |
| 208 | |
| 209 | #SeeAlso Deserialize SkSerialProcs |
| 210 | |
| 211 | #Method ## |
| 212 | |
| 213 | # ------------------------------------------------------------------------------ |
| 214 | |
| 215 | #Method sk_sp<SkData> serialize(const SkSerialProcs& procs) const |
| 216 | #In Utility |
| 217 | #Line # writes Text_Blob to Data ## |
| 218 | Returns storage containing Data describing Text_Blob, using optional custom |
| 219 | encoders. |
| 220 | |
| 221 | procs.fTypefaceProc permits supplying a custom function to encode Typeface. |
| 222 | If procs.fTypefaceProc is nullptr, default encoding is used. procs.fTypefaceCtx |
| 223 | may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc |
| 224 | is called with a pointer to Typeface and user context. |
| 225 | |
| 226 | #Param procs custom serial data encoders; may be nullptr ## |
| 227 | |
| 228 | #Return storage containing serialized Text_Blob ## |
| 229 | |
| 230 | #Example |
| 231 | #Height 24 |
| 232 | ###$ |
| 233 | $Function |
| 234 | #include "SkSerialProcs.h" |
| 235 | $$ |
| 236 | $$$# |
| 237 | SkPaint blobPaint;
|
| 238 | blobPaint.setTextSize(24);
|
Cary Clark | 57ca297 | 2018-08-10 15:49:01 -0400 | [diff] [blame] | 239 | sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobPaint);
|
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 240 | sk_sp<SkData> data = blob->serialize(SkSerialProcs());
|
| 241 | sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
|
| 242 | canvas->drawTextBlob(copy, 20, 20, SkPaint()); |
| 243 | ## |
| 244 | |
| 245 | #SeeAlso Deserialize SkData SkSerialProcs |
| 246 | |
| 247 | #Method ## |
| 248 | |
| 249 | # ------------------------------------------------------------------------------ |
| 250 | |
| 251 | #Method static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, const SkDeserialProcs& procs) |
Cary Clark | 61313f3 | 2018-10-08 14:57:48 -0400 | [diff] [blame] | 252 | #In Constructors |
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 253 | #Line # constructs Text_Blob from memory ## |
| 254 | |
| 255 | Recreates Text_Blob that was serialized into data. Returns constructed Text_Blob |
| 256 | if successful; otherwise, returns nullptr. Fails if size is smaller than |
| 257 | required data length, or if data does not permit constructing valid Text_Blob. |
| 258 | |
| 259 | procs.fTypefaceProc permits supplying a custom function to decode Typeface. |
| 260 | If procs.fTypefaceProc is nullptr, default decoding is used. procs.fTypefaceCtx |
| 261 | may be used to provide user context to procs.fTypefaceProc; procs.fTypefaceProc |
| 262 | is called with a pointer to Typeface data, data byte length, and user context. |
| 263 | |
| 264 | #Param data pointer for serial data ## |
| 265 | #Param size size of data ## |
| 266 | #Param procs custom serial data decoders; may be nullptr ## |
| 267 | |
| 268 | #Return Text_Blob constructed from data in memory ## |
| 269 | |
| 270 | #Example |
| 271 | #Height 24 |
| 272 | #Description |
| 273 | Text "Hacker" replaces "World!", but does not update its metrics. |
| 274 | When drawn, "Hacker" uses the spacing computed for "World!". |
| 275 | ## |
| 276 | ###$ |
| 277 | $Function |
| 278 | #include "SkSerialProcs.h" |
| 279 | $$ |
| 280 | $$$# |
| 281 | SkPaint blobPaint;
|
| 282 | blobPaint.setTextSize(24);
|
Cary Clark | 57ca297 | 2018-08-10 15:49:01 -0400 | [diff] [blame] | 283 | sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World!", 12, blobPaint);
|
Cary Clark | d2ca79c | 2018-08-10 13:09:13 -0400 | [diff] [blame] | 284 | sk_sp<SkData> data = blob->serialize(SkSerialProcs());
|
| 285 | uint16_t glyphs[6];
|
| 286 | blobPaint.textToGlyphs("Hacker", 6, glyphs);
|
| 287 | memcpy((char*)data->writable_data() + 0x54, glyphs, sizeof(glyphs));
|
| 288 | sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
|
| 289 | canvas->drawTextBlob(copy, 20, 20, SkPaint()); |
| 290 | ## |
| 291 | |
| 292 | #SeeAlso serialize SkDeserialProcs |
| 293 | |
| 294 | #Method ## |
| 295 | |
| 296 | #Class SkTextBlob ## |
| 297 | |
| 298 | #Topic Text_Blob ## |