| fmalita | 8483326 | 2014-09-19 11:40:51 -0700 | [diff] [blame] | 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 "SkGradientShader.h" | 
|  | 12 | #include "SkPoint.h" | 
|  | 13 | #include "SkShader.h" | 
|  | 14 | #include "SkTextBlob.h" | 
|  | 15 | #include "SkTDArray.h" | 
|  | 16 | #include "SkTypeface.h" | 
|  | 17 |  | 
|  | 18 | // This GM exercises drawTextBlob offset vs. shader space behavior. | 
|  | 19 | class TextBlobShaderGM : public skiagm::GM { | 
|  | 20 | public: | 
|  | 21 | TextBlobShaderGM(const char* txt) { | 
|  | 22 | SkPaint p; | 
|  | 23 | size_t txtLen = strlen(txt); | 
|  | 24 | fGlyphs.append(p.textToGlyphs(txt, txtLen, NULL)); | 
|  | 25 | p.textToGlyphs(txt, txtLen, fGlyphs.begin()); | 
|  | 26 | } | 
|  | 27 |  | 
|  | 28 | protected: | 
|  | 29 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 30 | void onOnceBeforeDraw() override { | 
| fmalita | 8483326 | 2014-09-19 11:40:51 -0700 | [diff] [blame] | 31 | SkPaint p; | 
|  | 32 | p.setAntiAlias(true); | 
|  | 33 | p.setSubpixelText(true); | 
|  | 34 | p.setTextSize(30); | 
|  | 35 | p.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 
|  | 36 |  | 
|  | 37 | SkTextBlobBuilder builder; | 
|  | 38 | int glyphCount = fGlyphs.count(); | 
|  | 39 | const SkTextBlobBuilder::RunBuffer* run; | 
|  | 40 |  | 
|  | 41 | run = &builder.allocRun(p, glyphCount, 10, 10, NULL); | 
|  | 42 | memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t)); | 
|  | 43 |  | 
|  | 44 | run = &builder.allocRunPosH(p, glyphCount,  80, NULL); | 
|  | 45 | memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t)); | 
|  | 46 | for (int i = 0; i < glyphCount; ++i) { | 
|  | 47 | run->pos[i] = p.getTextSize() * i * .75f; | 
|  | 48 | } | 
|  | 49 |  | 
|  | 50 | run = &builder.allocRunPos(p, glyphCount, NULL); | 
|  | 51 | memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t)); | 
|  | 52 | for (int i = 0; i < glyphCount; ++i) { | 
|  | 53 | run->pos[i * 2] = p.getTextSize() * i * .75f; | 
|  | 54 | run->pos[i * 2 + 1] = 150 + 5 * sinf((float)i * 8 / glyphCount); | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | fBlob.reset(builder.build()); | 
|  | 58 |  | 
|  | 59 | SkColor  colors[2]; | 
|  | 60 | colors[0] = SK_ColorRED; | 
|  | 61 | colors[1] = SK_ColorGREEN; | 
|  | 62 |  | 
|  | 63 | SkScalar pos[SK_ARRAY_COUNT(colors)]; | 
|  | 64 | for (unsigned i = 0; i < SK_ARRAY_COUNT(pos); ++i) { | 
|  | 65 | pos[i] = (float)i / (SK_ARRAY_COUNT(pos) - 1); | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | SkISize sz = this->onISize(); | 
|  | 69 | fShader.reset(SkGradientShader::CreateRadial(SkPoint::Make(SkIntToScalar(sz.width() / 2), | 
|  | 70 | SkIntToScalar(sz.height() / 2)), | 
|  | 71 | sz.width() * .66f, colors, pos, | 
|  | 72 | SK_ARRAY_COUNT(colors), | 
|  | 73 | SkShader::kRepeat_TileMode)); | 
|  | 74 | } | 
|  | 75 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 76 | SkString onShortName() override { | 
| fmalita | 8483326 | 2014-09-19 11:40:51 -0700 | [diff] [blame] | 77 | return SkString("textblobshader"); | 
|  | 78 | } | 
|  | 79 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 80 | SkISize onISize() override { | 
| fmalita | 8483326 | 2014-09-19 11:40:51 -0700 | [diff] [blame] | 81 | return SkISize::Make(640, 480); | 
|  | 82 | } | 
|  | 83 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 84 | void onDraw(SkCanvas* canvas) override { | 
| fmalita | 8483326 | 2014-09-19 11:40:51 -0700 | [diff] [blame] | 85 | SkPaint p; | 
|  | 86 | p.setStyle(SkPaint::kFill_Style); | 
|  | 87 | p.setShader(fShader); | 
|  | 88 |  | 
|  | 89 | SkISize sz = this->onISize(); | 
|  | 90 | static const int kXCount = 4; | 
|  | 91 | static const int kYCount = 3; | 
|  | 92 | for (int i = 0; i < kXCount; ++i) { | 
|  | 93 | for (int j = 0; j < kYCount; ++j) { | 
|  | 94 | canvas->drawTextBlob(fBlob, | 
|  | 95 | SkIntToScalar(i * sz.width() / kXCount), | 
|  | 96 | SkIntToScalar(j * sz.height() / kYCount), | 
|  | 97 | p); | 
|  | 98 | } | 
|  | 99 | } | 
|  | 100 | } | 
|  | 101 |  | 
|  | 102 | private: | 
|  | 103 | SkTDArray<uint16_t>            fGlyphs; | 
|  | 104 | SkAutoTUnref<const SkTextBlob> fBlob; | 
|  | 105 | SkAutoTUnref<SkShader>         fShader; | 
|  | 106 |  | 
|  | 107 | typedef skiagm::GM INHERITED; | 
|  | 108 | }; | 
|  | 109 |  | 
|  | 110 | DEF_GM( return SkNEW_ARGS(TextBlobShaderGM, ("Blobber")); ) |