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