blob: 92082acd6f0b5a7faaaf93b7eebad9afa0998e7e [file] [log] [blame]
Florin Malitace613002020-12-23 11:58:16 -05001/*
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"
Kevin Lubick8a0152a2023-06-05 11:41:39 -040014#include "include/core/SkTileMode.h"
Florin Malitace613002020-12-23 11:58:16 -050015#include "tools/ToolUtils.h"
Kevin Lubicke836c3a2023-10-20 06:55:35 -040016#include "tools/fonts/FontToolUtils.h"
Florin Malitace613002020-12-23 11:58:16 -050017
18// Exercises RSX text blobs + shader with various local matrix combinations.
19// Yellow grid should stay aligned for text vs. background.
20class RSXShaderGM : public skiagm::GM {
21public:
22private:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000023 SkString getName() const override { return SkString("rsx_blob_shader"); }
Florin Malitace613002020-12-23 11:58:16 -050024
Leandro Lovisolo8f023882023-08-15 21:13:52 +000025 SkISize getISize() override { return SkISize::Make(kSZ * kScale * 2.1f, kSZ * kScale * 2.1f); }
Florin Malitace613002020-12-23 11:58:16 -050026
27 void onOnceBeforeDraw() override {
28 const SkFontStyle style(SkFontStyle::kExtraBlack_Weight,
29 SkFontStyle::kNormal_Width,
30 SkFontStyle::kUpright_Slant);
Kevin Lubicke836c3a2023-10-20 06:55:35 -040031 SkFont font(ToolUtils::CreatePortableTypeface("Sans", style), kFontSZ);
Florin Malita697e2462020-12-30 13:12:58 +000032 font.setEdging(SkFont::Edging::kAntiAlias);
Florin Malitace613002020-12-23 11:58:16 -050033
34 static constexpr char txt[] = "TEST";
35 SkGlyphID glyphs[16];
36 float widths[16];
37 const auto glyph_count = font.textToGlyphs(txt, strlen(txt), SkTextEncoding::kUTF8,
Herb Derbyc37b3862022-06-21 09:49:17 -040038 glyphs, std::size(glyphs));
Florin Malitace613002020-12-23 11:58:16 -050039 font.getWidths(glyphs, glyph_count, widths);
40
41 SkTextBlobBuilder builder;
42 const auto& buf = builder.allocRunRSXform(font, glyph_count);
43 std::copy(glyphs, glyphs + glyph_count, buf.glyphs);
44
45 float x = 0;
46 for (int i = 0; i < glyph_count; ++i) {
47 buf.xforms()[i] = {
48 1, 0,
49 x, 0,
50 };
51 x += widths[i];
52 }
53
54 fBlob = builder.make();
55 }
56
57 void onDraw(SkCanvas* canvas) override {
58 canvas->scale(kScale, kScale);
59 this->draw_one(canvas,
60 {0, 0}, SkMatrix::I(), SkMatrix::I());
61 this->draw_one(canvas,
62 {kSZ*1.1f, 0}, SkMatrix::Scale(2, 2), SkMatrix::I());
63 this->draw_one(canvas,
64 {0, kSZ*1.1f}, SkMatrix::I(), SkMatrix::RotateDeg(45));
65 this->draw_one(canvas,
66 {kSZ*1.1f, kSZ*1.1f}, SkMatrix::Scale(2, 2), SkMatrix::RotateDeg(45));
67 }
68
69 void draw_one(SkCanvas* canvas, SkPoint pos, const SkMatrix& lm,
70 const SkMatrix& outer_lm) const {
71 SkAutoCanvasRestore acr(canvas, true);
72 canvas->translate(pos.fX, pos.fY);
73
74 SkPaint p;
75 p.setShader(make_shader(lm, outer_lm));
76 p.setAlphaf(0.75f);
77 canvas->drawRect(SkRect::MakeWH(kSZ, kSZ), p);
78
79 p.setAlphaf(1);
80 canvas->drawTextBlob(fBlob, 0, kFontSZ*1, p);
81 canvas->drawTextBlob(fBlob, 0, kFontSZ*2, p);
82 }
83
84 static sk_sp<SkShader> make_shader(const SkMatrix& lm, const SkMatrix& outer_lm) {
85 static constexpr SkISize kTileSize = { 30, 30 };
Kevin Lubick5c93acf2023-05-09 12:11:43 -040086 auto surface = SkSurfaces::Raster(
87 SkImageInfo::MakeN32Premul(kTileSize.width(), kTileSize.height()));
Florin Malitace613002020-12-23 11:58:16 -050088
89 SkPaint p;
90 p.setColor(0xffffff00);
91 surface->getCanvas()->drawPaint(p);
92 p.setColor(0xff008000);
93 surface->getCanvas()
94 ->drawRect({0, 0, kTileSize.width()*0.9f, kTileSize.height()*0.9f}, p);
95
96 return surface->makeImageSnapshot()
Florin Malita697e2462020-12-30 13:12:58 +000097 ->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
Mike Reed5ec22382021-01-14 21:59:01 -050098 SkSamplingOptions(SkFilterMode::kLinear), &lm)
Florin Malitace613002020-12-23 11:58:16 -050099 ->makeWithLocalMatrix(outer_lm);
100 }
101
Brian Salomon9fa47cc2021-10-08 18:48:26 -0400102 inline static constexpr float kSZ = 300,
103 kFontSZ = kSZ * 0.38,
104 kScale = 1.4f;
Florin Malitace613002020-12-23 11:58:16 -0500105
106 sk_sp<SkTextBlob> fBlob;
107};
108
109DEF_GM(return new RSXShaderGM;)