1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2014 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontTypes.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTileMode.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 24*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h" 25*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTDArray.h" 26*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h" 27*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h" 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker #include <math.h> 30*c8dee2aaSAndroid Build Coastguard Worker #include <string.h> 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker // This GM exercises drawTextBlob offset vs. shader space behavior. 33*c8dee2aaSAndroid Build Coastguard Worker class TextBlobShaderGM : public skiagm::GM { 34*c8dee2aaSAndroid Build Coastguard Worker public: TextBlobShaderGM()35*c8dee2aaSAndroid Build Coastguard Worker TextBlobShaderGM() {} 36*c8dee2aaSAndroid Build Coastguard Worker 37*c8dee2aaSAndroid Build Coastguard Worker private: onOnceBeforeDraw()38*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override { 39*c8dee2aaSAndroid Build Coastguard Worker { 40*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultPortableFont(); 41*c8dee2aaSAndroid Build Coastguard Worker const char* txt = "Blobber"; 42*c8dee2aaSAndroid Build Coastguard Worker size_t txtLen = strlen(txt); 43*c8dee2aaSAndroid Build Coastguard Worker fGlyphs.append(font.countText(txt, txtLen, SkTextEncoding::kUTF8)); 44*c8dee2aaSAndroid Build Coastguard Worker font.textToGlyphs(txt, txtLen, SkTextEncoding::kUTF8, fGlyphs.begin(), fGlyphs.size()); 45*c8dee2aaSAndroid Build Coastguard Worker } 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultPortableFont(); 48*c8dee2aaSAndroid Build Coastguard Worker font.setSubpixel(true); 49*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(SkFont::Edging::kAntiAlias); 50*c8dee2aaSAndroid Build Coastguard Worker font.setSize(30); 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilder builder; 53*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = fGlyphs.size(); 54*c8dee2aaSAndroid Build Coastguard Worker const SkTextBlobBuilder::RunBuffer* run; 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker run = &builder.allocRun(font, glyphCount, 10, 10, nullptr); 57*c8dee2aaSAndroid Build Coastguard Worker memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t)); 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker run = &builder.allocRunPosH(font, glyphCount, 80, nullptr); 60*c8dee2aaSAndroid Build Coastguard Worker memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t)); 61*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < glyphCount; ++i) { 62*c8dee2aaSAndroid Build Coastguard Worker run->pos[i] = font.getSize() * i * .75f; 63*c8dee2aaSAndroid Build Coastguard Worker } 64*c8dee2aaSAndroid Build Coastguard Worker 65*c8dee2aaSAndroid Build Coastguard Worker run = &builder.allocRunPos(font, glyphCount, nullptr); 66*c8dee2aaSAndroid Build Coastguard Worker memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t)); 67*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < glyphCount; ++i) { 68*c8dee2aaSAndroid Build Coastguard Worker run->pos[i * 2] = font.getSize() * i * .75f; 69*c8dee2aaSAndroid Build Coastguard Worker run->pos[i * 2 + 1] = 150 + 5 * sinf((float)i * 8 / glyphCount); 70*c8dee2aaSAndroid Build Coastguard Worker } 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker fBlob = builder.make(); 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[2]; 75*c8dee2aaSAndroid Build Coastguard Worker colors[0] = SK_ColorRED; 76*c8dee2aaSAndroid Build Coastguard Worker colors[1] = SK_ColorGREEN; 77*c8dee2aaSAndroid Build Coastguard Worker 78*c8dee2aaSAndroid Build Coastguard Worker SkScalar pos[std::size(colors)]; 79*c8dee2aaSAndroid Build Coastguard Worker for (unsigned i = 0; i < std::size(pos); ++i) { 80*c8dee2aaSAndroid Build Coastguard Worker pos[i] = (float)i / (std::size(pos) - 1); 81*c8dee2aaSAndroid Build Coastguard Worker } 82*c8dee2aaSAndroid Build Coastguard Worker 83*c8dee2aaSAndroid Build Coastguard Worker SkISize sz = this->getISize(); 84*c8dee2aaSAndroid Build Coastguard Worker fShader = SkGradientShader::MakeRadial(SkPoint::Make(SkIntToScalar(sz.width() / 2), 85*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(sz.height() / 2)), 86*c8dee2aaSAndroid Build Coastguard Worker sz.width() * .66f, colors, pos, 87*c8dee2aaSAndroid Build Coastguard Worker std::size(colors), 88*c8dee2aaSAndroid Build Coastguard Worker SkTileMode::kRepeat); 89*c8dee2aaSAndroid Build Coastguard Worker } 90*c8dee2aaSAndroid Build Coastguard Worker getName() const91*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("textblobshader"); } 92*c8dee2aaSAndroid Build Coastguard Worker getISize()93*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(640, 480); } 94*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)95*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 96*c8dee2aaSAndroid Build Coastguard Worker SkPaint p; 97*c8dee2aaSAndroid Build Coastguard Worker p.setAntiAlias(true); 98*c8dee2aaSAndroid Build Coastguard Worker p.setStyle(SkPaint::kFill_Style); 99*c8dee2aaSAndroid Build Coastguard Worker p.setShader(fShader); 100*c8dee2aaSAndroid Build Coastguard Worker 101*c8dee2aaSAndroid Build Coastguard Worker SkISize sz = this->getISize(); 102*c8dee2aaSAndroid Build Coastguard Worker constexpr int kXCount = 4; 103*c8dee2aaSAndroid Build Coastguard Worker constexpr int kYCount = 3; 104*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kXCount; ++i) { 105*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < kYCount; ++j) { 106*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 107*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(i * sz.width() / kXCount), 108*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(j * sz.height() / kYCount), 109*c8dee2aaSAndroid Build Coastguard Worker p); 110*c8dee2aaSAndroid Build Coastguard Worker } 111*c8dee2aaSAndroid Build Coastguard Worker } 112*c8dee2aaSAndroid Build Coastguard Worker } 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker SkTDArray<uint16_t> fGlyphs; 115*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> fBlob; 116*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> fShader; 117*c8dee2aaSAndroid Build Coastguard Worker 118*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = skiagm::GM; 119*c8dee2aaSAndroid Build Coastguard Worker }; 120*c8dee2aaSAndroid Build Coastguard Worker 121*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new TextBlobShaderGM;) 122