blob: 4a918cb1dd358cb1d388fdddfa94047e6c4f3932 [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
8#include "gm.h"
9#include "Resources.h"
10#include "SkCanvas.h"
11#include "SkSurface.h"
12#include "SkTextBlob.h"
13#include "SkTypeface.h"
14#include "sk_tool_utils.h"
15
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 {
27 SkString name("dftext_blob_persp");
28 name.append(sk_tool_utils::platform_font_manager());
29 return name;
30 }
31
32 SkISize onISize() override { return SkISize::Make(900, 350); }
33
34 void onOnceBeforeDraw() override {
35 for (int i = 0; i < 3; ++i) {
Mike Reedea8900e2018-12-22 17:37:30 -050036 SkFont font;
37 font.setSize(32);
38 font.setEdging(i == 0 ? SkFont::Edging::kAlias :
39 (i == 1 ? SkFont::Edging::kAntiAlias :
40 SkFont::Edging::kSubpixelAntiAlias));
41 font.setSubpixel(true);
Brian Salomon5c6ac642017-12-19 11:09:32 -050042 SkTextBlobBuilder builder;
Mike Reedea8900e2018-12-22 17:37:30 -050043 sk_tool_utils::add_to_text_blob(&builder, "SkiaText", font, 0, 0);
Brian Salomon5c6ac642017-12-19 11:09:32 -050044 fBlobs.emplace_back(builder.make());
45 }
46 }
47
Mike Reedea8900e2018-12-22 17:37:30 -050048 void onDraw(SkCanvas* inputCanvas) override {
Brian Salomon5c6ac642017-12-19 11:09:32 -050049 // set up offscreen rendering with distance field text
Brian Salomon5c6ac642017-12-19 11:09:32 -050050 GrContext* ctx = inputCanvas->getGrContext();
51 SkISize size = this->onISize();
52 if (!inputCanvas->getBaseLayerSize().isEmpty()) {
53 size = inputCanvas->getBaseLayerSize();
54 }
55 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType,
56 inputCanvas->imageInfo().refColorSpace());
57 SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
58 SkSurfaceProps::kLegacyFontHost_InitType);
59 auto surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props);
60 SkCanvas* canvas = surface ? surface->getCanvas() : inputCanvas;
61 // init our new canvas with the old canvas's matrix
62 canvas->setMatrix(inputCanvas->getTotalMatrix());
Brian Salomon5c6ac642017-12-19 11:09:32 -050063 SkScalar x = 0, y = 0;
64 SkScalar maxH = 0;
65 for (auto twm : {TranslateWithMatrix::kNo, TranslateWithMatrix::kYes}) {
66 for (auto pm : {PerspMode::kNone, PerspMode::kX, PerspMode::kY, PerspMode::kXY}) {
67 for (auto& blob : fBlobs) {
68 for (bool clip : {false, true}) {
69 canvas->save();
70 SkScalar w = blob->bounds().width();
71 SkScalar h = blob->bounds().height();
72 if (clip) {
73 auto rect =
74 SkRect::MakeXYWH(x + 5, y + 5, w * 3.f / 4.f, h * 3.f / 4.f);
75 canvas->clipRect(rect, false);
76 }
77 this->drawBlob(canvas, blob.get(), SK_ColorBLACK, x, y + h, pm, twm);
78 x += w + 20.f;
79 maxH = SkTMax(h, maxH);
80 canvas->restore();
81 }
82 }
83 x = 0;
84 y += maxH + 20.f;
85 maxH = 0;
86 }
87 }
Brian Salomon5c6ac642017-12-19 11:09:32 -050088 // render offscreen buffer
89 if (surface) {
90 SkAutoCanvasRestore acr(inputCanvas, true);
91 // since we prepended this matrix already, we blit using identity
92 inputCanvas->resetMatrix();
93 inputCanvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, nullptr);
94 }
Brian Salomon5c6ac642017-12-19 11:09:32 -050095 }
96
97private:
98 enum class PerspMode { kNone, kX, kY, kXY };
99
100 enum class TranslateWithMatrix : bool { kNo, kYes };
101
102 void drawBlob(SkCanvas* canvas, SkTextBlob* blob, SkColor color, SkScalar x, SkScalar y,
103 PerspMode perspMode, TranslateWithMatrix translateWithMatrix) {
104 canvas->save();
105 SkMatrix persp = SkMatrix::I();
106 switch (perspMode) {
107 case PerspMode::kNone:
108 break;
109 case PerspMode::kX:
110 persp.setPerspX(0.005f);
111 break;
112 case PerspMode::kY:
113 persp.setPerspY(00.005f);
114 break;
115 case PerspMode::kXY:
116 persp.setPerspX(-0.001f);
117 persp.setPerspY(-0.0015f);
118 break;
119 }
120 persp = SkMatrix::Concat(persp, SkMatrix::MakeTrans(-x, -y));
121 persp = SkMatrix::Concat(SkMatrix::MakeTrans(x, y), persp);
122 canvas->concat(persp);
123 if (TranslateWithMatrix::kYes == translateWithMatrix) {
124 canvas->translate(x, y);
125 x = 0;
126 y = 0;
127 }
128 SkPaint paint;
129 paint.setColor(color);
130 canvas->drawTextBlob(blob, x, y, paint);
131 canvas->restore();
132 }
133
Brian Salomon343553a2018-09-05 15:41:23 -0400134 SkTArray<sk_sp<SkTextBlob>> fBlobs;
Brian Salomon5c6ac642017-12-19 11:09:32 -0500135 typedef skiagm::GM INHERITED;
136};
137
138DEF_GM(return new DFTextBlobPerspGM;)