xref: /aosp_15_r20/external/skia/gm/rsxtext.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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