blob: 70111e4c2a91d6d0d4a3a0982fb7b499b9938220 [file] [log] [blame]
Brian Salomon5c6ac642017-12-19 11:09:32 -05001/*
2 * Copyright 2017 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
Brian Salomon5c6ac642017-12-19 11:09:32 -05008#include "Resources.h"
9#include "SkCanvas.h"
10#include "SkSurface.h"
11#include "SkTextBlob.h"
12#include "SkTypeface.h"
Mike Kleinea3f0142019-03-20 11:12:10 -050013#include "ToolUtils.h"
14#include "gm.h"
Brian Salomon5c6ac642017-12-19 11:09:32 -050015
16/**
17 * This GM tests reusing the same text blobs with distance fields rendering using various
18 * combinations of perspective and non-perspetive matrices, scissor clips, and different x,y params
19 * passed to the draw.
20 */
21class DFTextBlobPerspGM : public skiagm::GM {
22public:
23 DFTextBlobPerspGM() { this->setBGColor(0xFFFFFFFF); }
24
25protected:
26 SkString onShortName() override {
Mike Kleinbea1f942019-03-08 11:11:55 -060027 return SkString("dftext_blob_persp");
Brian Salomon5c6ac642017-12-19 11:09:32 -050028 }
29
30 SkISize onISize() override { return SkISize::Make(900, 350); }
31
32 void onOnceBeforeDraw() override {
33 for (int i = 0; i < 3; ++i) {
Mike Reedea8900e2018-12-22 17:37:30 -050034 SkFont font;
35 font.setSize(32);
36 font.setEdging(i == 0 ? SkFont::Edging::kAlias :
37 (i == 1 ? SkFont::Edging::kAntiAlias :
38 SkFont::Edging::kSubpixelAntiAlias));
39 font.setSubpixel(true);
Brian Salomon5c6ac642017-12-19 11:09:32 -050040 SkTextBlobBuilder builder;
Mike Kleinea3f0142019-03-20 11:12:10 -050041 ToolUtils::add_to_text_blob(&builder, "SkiaText", font, 0, 0);
Brian Salomon5c6ac642017-12-19 11:09:32 -050042 fBlobs.emplace_back(builder.make());
43 }
44 }
45
Mike Reedea8900e2018-12-22 17:37:30 -050046 void onDraw(SkCanvas* inputCanvas) override {
Brian Salomon5c6ac642017-12-19 11:09:32 -050047 // set up offscreen rendering with distance field text
Brian Salomon5c6ac642017-12-19 11:09:32 -050048 GrContext* ctx = inputCanvas->getGrContext();
49 SkISize size = this->onISize();
50 if (!inputCanvas->getBaseLayerSize().isEmpty()) {
51 size = inputCanvas->getBaseLayerSize();
52 }
53 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType,
54 inputCanvas->imageInfo().refColorSpace());
55 SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
56 SkSurfaceProps::kLegacyFontHost_InitType);
57 auto surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props);
58 SkCanvas* canvas = surface ? surface->getCanvas() : inputCanvas;
59 // init our new canvas with the old canvas's matrix
60 canvas->setMatrix(inputCanvas->getTotalMatrix());
Brian Salomon5c6ac642017-12-19 11:09:32 -050061 SkScalar x = 0, y = 0;
62 SkScalar maxH = 0;
63 for (auto twm : {TranslateWithMatrix::kNo, TranslateWithMatrix::kYes}) {
64 for (auto pm : {PerspMode::kNone, PerspMode::kX, PerspMode::kY, PerspMode::kXY}) {
65 for (auto& blob : fBlobs) {
66 for (bool clip : {false, true}) {
67 canvas->save();
68 SkScalar w = blob->bounds().width();
69 SkScalar h = blob->bounds().height();
70 if (clip) {
71 auto rect =
72 SkRect::MakeXYWH(x + 5, y + 5, w * 3.f / 4.f, h * 3.f / 4.f);
73 canvas->clipRect(rect, false);
74 }
75 this->drawBlob(canvas, blob.get(), SK_ColorBLACK, x, y + h, pm, twm);
76 x += w + 20.f;
77 maxH = SkTMax(h, maxH);
78 canvas->restore();
79 }
80 }
81 x = 0;
82 y += maxH + 20.f;
83 maxH = 0;
84 }
85 }
Brian Salomon5c6ac642017-12-19 11:09:32 -050086 // render offscreen buffer
87 if (surface) {
88 SkAutoCanvasRestore acr(inputCanvas, true);
89 // since we prepended this matrix already, we blit using identity
90 inputCanvas->resetMatrix();
91 inputCanvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, nullptr);
92 }
Brian Salomon5c6ac642017-12-19 11:09:32 -050093 }
94
95private:
96 enum class PerspMode { kNone, kX, kY, kXY };
97
98 enum class TranslateWithMatrix : bool { kNo, kYes };
99
100 void drawBlob(SkCanvas* canvas, SkTextBlob* blob, SkColor color, SkScalar x, SkScalar y,
101 PerspMode perspMode, TranslateWithMatrix translateWithMatrix) {
102 canvas->save();
103 SkMatrix persp = SkMatrix::I();
104 switch (perspMode) {
105 case PerspMode::kNone:
106 break;
107 case PerspMode::kX:
108 persp.setPerspX(0.005f);
109 break;
110 case PerspMode::kY:
111 persp.setPerspY(00.005f);
112 break;
113 case PerspMode::kXY:
114 persp.setPerspX(-0.001f);
115 persp.setPerspY(-0.0015f);
116 break;
117 }
118 persp = SkMatrix::Concat(persp, SkMatrix::MakeTrans(-x, -y));
119 persp = SkMatrix::Concat(SkMatrix::MakeTrans(x, y), persp);
120 canvas->concat(persp);
121 if (TranslateWithMatrix::kYes == translateWithMatrix) {
122 canvas->translate(x, y);
123 x = 0;
124 y = 0;
125 }
126 SkPaint paint;
127 paint.setColor(color);
128 canvas->drawTextBlob(blob, x, y, paint);
129 canvas->restore();
130 }
131
Brian Salomon343553a2018-09-05 15:41:23 -0400132 SkTArray<sk_sp<SkTextBlob>> fBlobs;
Brian Salomon5c6ac642017-12-19 11:09:32 -0500133 typedef skiagm::GM INHERITED;
134};
135
136DEF_GM(return new DFTextBlobPerspGM;)