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