| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 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 #include "gm.h" | 
|  | 9 | 
|  | 10 #include "SkCanvas.h" | 
|  | 11 #include "SkPoint.h" | 
|  | 12 #include "SkTextBlob.h" | 
|  | 13 #include "SkTDArray.h" | 
|  | 14 | 
|  | 15 namespace  { | 
|  | 16 | 
|  | 17 enum Pos { | 
|  | 18     kDefault_Pos = 0, | 
|  | 19     kScalar_Pos  = 1, | 
|  | 20     kPoint_Pos   = 2, | 
|  | 21 }; | 
|  | 22 | 
|  | 23 const struct BlobCfg { | 
|  | 24     unsigned count; | 
|  | 25     Pos      pos; | 
|  | 26     SkScalar scale; | 
|  | 27 } blobConfigs[][3][3] = { | 
|  | 28     { | 
|  | 29         { { 1024, kDefault_Pos, 1 }, { 0, kDefault_Pos, 0 }, { 0, kDefault_Pos, 
     0 } }, | 
|  | 30         { { 1024,  kScalar_Pos, 1 }, { 0,  kScalar_Pos, 0 }, { 0,  kScalar_Pos, 
     0 } }, | 
|  | 31         { { 1024,   kPoint_Pos, 1 }, { 0,   kPoint_Pos, 0 }, { 0,   kPoint_Pos, 
     0 } }, | 
|  | 32     }, | 
|  | 33     { | 
|  | 34         { { 4, kDefault_Pos, 1},     { 4, kDefault_Pos, 1},  { 4, kDefault_Pos, 
     1} }, | 
|  | 35         { { 4,  kScalar_Pos, 1},     { 4,  kScalar_Pos, 1},  { 4,  kScalar_Pos, 
     1} }, | 
|  | 36         { { 4,   kPoint_Pos, 1},     { 4,   kPoint_Pos, 1},  { 4,   kPoint_Pos, 
     1} }, | 
|  | 37     }, | 
|  | 38 | 
|  | 39     { | 
|  | 40         { { 4, kDefault_Pos, 1},     { 4, kDefault_Pos, 1},  { 4,  kScalar_Pos, 
     1} }, | 
|  | 41         { { 4,  kScalar_Pos, 1},     { 4,  kScalar_Pos, 1},  { 4,   kPoint_Pos, 
     1} }, | 
|  | 42         { { 4,   kPoint_Pos, 1},     { 4,   kPoint_Pos, 1},  { 4, kDefault_Pos, 
     1} }, | 
|  | 43     }, | 
|  | 44 | 
|  | 45     { | 
|  | 46         { { 4, kDefault_Pos, 1},     { 4,  kScalar_Pos, 1},  { 4,   kPoint_Pos, 
     1} }, | 
|  | 47         { { 4,  kScalar_Pos, 1},     { 4,   kPoint_Pos, 1},  { 4, kDefault_Pos, 
     1} }, | 
|  | 48         { { 4,   kPoint_Pos, 1},     { 4, kDefault_Pos, 1},  { 4,  kScalar_Pos, 
     1} }, | 
|  | 49     }, | 
|  | 50 }; | 
|  | 51 | 
|  | 52 const SkScalar kFontSize = 16; | 
|  | 53 } | 
|  | 54 | 
|  | 55 class TextBlobGM : public skiagm::GM { | 
|  | 56 public: | 
|  | 57     TextBlobGM(const char* txt) { | 
|  | 58         SkPaint p; | 
|  | 59         size_t txtLen = strlen(txt); | 
|  | 60         int glyphCount = p.textToGlyphs(txt, txtLen, NULL); | 
|  | 61 | 
|  | 62         fGlyphs.append(glyphCount); | 
|  | 63         p.textToGlyphs(txt, txtLen, fGlyphs.begin()); | 
|  | 64     } | 
|  | 65 | 
|  | 66 protected: | 
|  | 67     virtual SkString onShortName() SK_OVERRIDE { | 
|  | 68         return SkString("textblob"); | 
|  | 69     } | 
|  | 70 | 
|  | 71     virtual SkISize onISize() SK_OVERRIDE { | 
|  | 72         return SkISize::Make(640, 480); | 
|  | 73     } | 
|  | 74 | 
|  | 75     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 
|  | 76         for (unsigned b = 0; b < SK_ARRAY_COUNT(blobConfigs); ++b) { | 
|  | 77             SkAutoTUnref<const SkTextBlob> blob(makeBlob(b)); | 
|  | 78 | 
|  | 79             SkPaint p; | 
|  | 80             p.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 
|  | 81             p.setTextSize(kFontSize); | 
|  | 82             p.setAntiAlias(true); | 
|  | 83             p.setSubpixelText(true); | 
|  | 84 | 
|  | 85             SkPoint offset = SkPoint::Make(SkIntToScalar(10 + 300 * (b % 2)), | 
|  | 86                                            SkIntToScalar(20 + 150 * (b / 2))); | 
|  | 87 | 
|  | 88             canvas->drawTextBlob(blob, offset.x(), offset.y(), p); | 
|  | 89 | 
|  | 90             p.setColor(SK_ColorBLUE); | 
|  | 91             p.setStyle(SkPaint::kStroke_Style); | 
|  | 92             SkRect box = blob->bounds(); | 
|  | 93             box.offset(offset); | 
|  | 94             canvas->drawRect(box, p); | 
|  | 95 | 
|  | 96         } | 
|  | 97     } | 
|  | 98 | 
|  | 99 private: | 
|  | 100     const SkTextBlob* makeBlob(unsigned blobIndex) { | 
|  | 101         SkTextBlobBuilder builder; | 
|  | 102 | 
|  | 103         SkPaint font; | 
|  | 104         font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 
|  | 105 | 
|  | 106         for (unsigned l = 0; l < SK_ARRAY_COUNT(blobConfigs[blobIndex]); ++l) { | 
|  | 107             unsigned currentGlyph = 0; | 
|  | 108 | 
|  | 109             for (unsigned c = 0; c < SK_ARRAY_COUNT(blobConfigs[blobIndex][l]); 
     ++c) { | 
|  | 110                 const BlobCfg* cfg = &blobConfigs[blobIndex][l][c]; | 
|  | 111                 unsigned count = cfg->count; | 
|  | 112 | 
|  | 113                 if (count > fGlyphs.count() - currentGlyph) { | 
|  | 114                     count = fGlyphs.count() - currentGlyph; | 
|  | 115                 } | 
|  | 116                 if (0 == count) { | 
|  | 117                     break; | 
|  | 118                 } | 
|  | 119 | 
|  | 120                 font.setTextSize(kFontSize * cfg->scale); | 
|  | 121                 const SkScalar advanceX = font.getTextSize() * 0.85f; | 
|  | 122                 const SkScalar advanceY = font.getTextSize() * 1.5f; | 
|  | 123 | 
|  | 124                 SkPoint offset = SkPoint::Make(currentGlyph * advanceX + c * adv
     anceX, | 
|  | 125                                                advanceY * l); | 
|  | 126                 switch (cfg->pos) { | 
|  | 127                 case kDefault_Pos: { | 
|  | 128                     const SkTextBlobBuilder::RunBuffer& buf = builder.allocRun(f
     ont, count, | 
|  | 129                                                                                o
     ffset.x(), | 
|  | 130                                                                                o
     ffset.y()); | 
|  | 131                     memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * s
     izeof(uint16_t)); | 
|  | 132                 } break; | 
|  | 133                 case kScalar_Pos: { | 
|  | 134                     const SkTextBlobBuilder::RunBuffer& buf = builder.allocRunPo
     sH(font, count, | 
|  | 135                                                                                 
        offset.y()); | 
|  | 136                     SkTDArray<SkScalar> pos; | 
|  | 137                     for (unsigned i = 0; i < count; ++i) { | 
|  | 138                         *pos.append() = offset.x() + i * advanceX; | 
|  | 139                     } | 
|  | 140 | 
|  | 141                     memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * s
     izeof(uint16_t)); | 
|  | 142                     memcpy(buf.pos, pos.begin(), count * sizeof(SkScalar)); | 
|  | 143                 } break; | 
|  | 144                 case kPoint_Pos: { | 
|  | 145                     const SkTextBlobBuilder::RunBuffer& buf = builder.allocRunPo
     s(font, count); | 
|  | 146 | 
|  | 147                     SkTDArray<SkScalar> pos; | 
|  | 148                     for (unsigned i = 0; i < count; ++i) { | 
|  | 149                         *pos.append() = offset.x() + i * advanceX; | 
|  | 150                         *pos.append() = offset.y() + i * (advanceY / count); | 
|  | 151                     } | 
|  | 152 | 
|  | 153                     memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * s
     izeof(uint16_t)); | 
|  | 154                     memcpy(buf.pos, pos.begin(), count * sizeof(SkScalar) * 2); | 
|  | 155                 } break; | 
|  | 156                 default: | 
|  | 157                     SkFAIL("unhandled pos value"); | 
|  | 158                 } | 
|  | 159 | 
|  | 160                 currentGlyph += count; | 
|  | 161             } | 
|  | 162         } | 
|  | 163 | 
|  | 164         return builder.build(); | 
|  | 165     } | 
|  | 166 | 
|  | 167     SkTDArray<uint16_t> fGlyphs; | 
|  | 168 | 
|  | 169     typedef skiagm::GM INHERITED; | 
|  | 170 }; | 
|  | 171 | 
|  | 172 DEF_GM( return SkNEW_ARGS(TextBlobGM, ("hamburgefons")); ) | 
| OLD | NEW | 
|---|