1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2020 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/SkRSXform.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTileMode.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h" 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker // Exercises RSX text blobs + shader with various local matrix combinations. 19*c8dee2aaSAndroid Build Coastguard Worker // Yellow grid should stay aligned for text vs. background. 20*c8dee2aaSAndroid Build Coastguard Worker class RSXShaderGM : public skiagm::GM { 21*c8dee2aaSAndroid Build Coastguard Worker public: 22*c8dee2aaSAndroid Build Coastguard Worker private: getName() const23*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("rsx_blob_shader"); } 24*c8dee2aaSAndroid Build Coastguard Worker getISize()25*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(kSZ * kScale * 2.1f, kSZ * kScale * 2.1f); } 26*c8dee2aaSAndroid Build Coastguard Worker onOnceBeforeDraw()27*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override { 28*c8dee2aaSAndroid Build Coastguard Worker const SkFontStyle style(SkFontStyle::kExtraBlack_Weight, 29*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kNormal_Width, 30*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant); 31*c8dee2aaSAndroid Build Coastguard Worker SkFont font(ToolUtils::CreatePortableTypeface("Sans", style), kFontSZ); 32*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(SkFont::Edging::kAntiAlias); 33*c8dee2aaSAndroid Build Coastguard Worker 34*c8dee2aaSAndroid Build Coastguard Worker static constexpr char txt[] = "TEST"; 35*c8dee2aaSAndroid Build Coastguard Worker SkGlyphID glyphs[16]; 36*c8dee2aaSAndroid Build Coastguard Worker float widths[16]; 37*c8dee2aaSAndroid Build Coastguard Worker const auto glyph_count = font.textToGlyphs(txt, strlen(txt), SkTextEncoding::kUTF8, 38*c8dee2aaSAndroid Build Coastguard Worker glyphs, std::size(glyphs)); 39*c8dee2aaSAndroid Build Coastguard Worker font.getWidths(glyphs, glyph_count, widths); 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilder builder; 42*c8dee2aaSAndroid Build Coastguard Worker const auto& buf = builder.allocRunRSXform(font, glyph_count); 43*c8dee2aaSAndroid Build Coastguard Worker std::copy(glyphs, glyphs + glyph_count, buf.glyphs); 44*c8dee2aaSAndroid Build Coastguard Worker 45*c8dee2aaSAndroid Build Coastguard Worker float x = 0; 46*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < glyph_count; ++i) { 47*c8dee2aaSAndroid Build Coastguard Worker buf.xforms()[i] = { 48*c8dee2aaSAndroid Build Coastguard Worker 1, 0, 49*c8dee2aaSAndroid Build Coastguard Worker x, 0, 50*c8dee2aaSAndroid Build Coastguard Worker }; 51*c8dee2aaSAndroid Build Coastguard Worker x += widths[i]; 52*c8dee2aaSAndroid Build Coastguard Worker } 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker fBlob = builder.make(); 55*c8dee2aaSAndroid Build Coastguard Worker } 56*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)57*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 58*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(kScale, kScale); 59*c8dee2aaSAndroid Build Coastguard Worker this->draw_one(canvas, 60*c8dee2aaSAndroid Build Coastguard Worker {0, 0}, SkMatrix::I(), SkMatrix::I()); 61*c8dee2aaSAndroid Build Coastguard Worker this->draw_one(canvas, 62*c8dee2aaSAndroid Build Coastguard Worker {kSZ*1.1f, 0}, SkMatrix::Scale(2, 2), SkMatrix::I()); 63*c8dee2aaSAndroid Build Coastguard Worker this->draw_one(canvas, 64*c8dee2aaSAndroid Build Coastguard Worker {0, kSZ*1.1f}, SkMatrix::I(), SkMatrix::RotateDeg(45)); 65*c8dee2aaSAndroid Build Coastguard Worker this->draw_one(canvas, 66*c8dee2aaSAndroid Build Coastguard Worker {kSZ*1.1f, kSZ*1.1f}, SkMatrix::Scale(2, 2), SkMatrix::RotateDeg(45)); 67*c8dee2aaSAndroid Build Coastguard Worker } 68*c8dee2aaSAndroid Build Coastguard Worker draw_one(SkCanvas * canvas,SkPoint pos,const SkMatrix & lm,const SkMatrix & outer_lm) const69*c8dee2aaSAndroid Build Coastguard Worker void draw_one(SkCanvas* canvas, SkPoint pos, const SkMatrix& lm, 70*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix& outer_lm) const { 71*c8dee2aaSAndroid Build Coastguard Worker SkAutoCanvasRestore acr(canvas, true); 72*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(pos.fX, pos.fY); 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker SkPaint p; 75*c8dee2aaSAndroid Build Coastguard Worker p.setShader(make_shader(lm, outer_lm)); 76*c8dee2aaSAndroid Build Coastguard Worker p.setAlphaf(0.75f); 77*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeWH(kSZ, kSZ), p); 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker p.setAlphaf(1); 80*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, kFontSZ*1, p); 81*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, kFontSZ*2, p); 82*c8dee2aaSAndroid Build Coastguard Worker } 83*c8dee2aaSAndroid Build Coastguard Worker make_shader(const SkMatrix & lm,const SkMatrix & outer_lm)84*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> make_shader(const SkMatrix& lm, const SkMatrix& outer_lm) { 85*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkISize kTileSize = { 30, 30 }; 86*c8dee2aaSAndroid Build Coastguard Worker auto surface = SkSurfaces::Raster( 87*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo::MakeN32Premul(kTileSize.width(), kTileSize.height())); 88*c8dee2aaSAndroid Build Coastguard Worker 89*c8dee2aaSAndroid Build Coastguard Worker SkPaint p; 90*c8dee2aaSAndroid Build Coastguard Worker p.setColor(0xffffff00); 91*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->drawPaint(p); 92*c8dee2aaSAndroid Build Coastguard Worker p.setColor(0xff008000); 93*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas() 94*c8dee2aaSAndroid Build Coastguard Worker ->drawRect({0, 0, kTileSize.width()*0.9f, kTileSize.height()*0.9f}, p); 95*c8dee2aaSAndroid Build Coastguard Worker 96*c8dee2aaSAndroid Build Coastguard Worker return surface->makeImageSnapshot() 97*c8dee2aaSAndroid Build Coastguard Worker ->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, 98*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions(SkFilterMode::kLinear), &lm) 99*c8dee2aaSAndroid Build Coastguard Worker ->makeWithLocalMatrix(outer_lm); 100*c8dee2aaSAndroid Build Coastguard Worker } 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr float kSZ = 300, 103*c8dee2aaSAndroid Build Coastguard Worker kFontSZ = kSZ * 0.38, 104*c8dee2aaSAndroid Build Coastguard Worker kScale = 1.4f; 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> fBlob; 107*c8dee2aaSAndroid Build Coastguard Worker }; 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new RSXShaderGM;) 110