blob: 95efbb2055be298dddca0caebd746a5f18e10d56 [file] [log] [blame]
fmalita1dedc3d2015-08-04 13:53:14 -07001/*
2 * Copyright 2015 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 "SkBitmap.h"
10#include "SkCanvas.h"
11#include "SkGradientShader.h"
12#include "SkImageGenerator.h"
13#include "SkPaint.h"
14#include "SkPathOps.h"
15#include "SkPicture.h"
16#include "SkPictureRecorder.h"
17
18static void draw_vector_logo(SkCanvas* canvas, const SkRect& viewBox) {
mtkleindbfd7ab2016-09-01 11:24:54 -070019 constexpr char kSkiaStr[] = "SKIA";
20 constexpr SkScalar kGradientPad = .1f;
21 constexpr SkScalar kVerticalSpacing = 0.25f;
22 constexpr SkScalar kAccentScale = 1.20f;
fmalita1dedc3d2015-08-04 13:53:14 -070023
24 SkPaint paint;
25 paint.setAntiAlias(true);
26 paint.setSubpixelText(true);
27 paint.setFakeBoldText(true);
28 sk_tool_utils::set_portable_typeface(&paint);
29
30 SkPath path;
31 SkRect iBox, skiBox, skiaBox;
32 paint.getTextPath("SKI", 3, 0, 0, &path);
33 TightBounds(path, &skiBox);
34 paint.getTextPath("I", 1, 0, 0, &path);
35 TightBounds(path, &iBox);
36 iBox.offsetTo(skiBox.fRight - iBox.width(), iBox.fTop);
37
38 const size_t textLen = strlen(kSkiaStr);
39 paint.getTextPath(kSkiaStr, textLen, 0, 0, &path);
40 TightBounds(path, &skiaBox);
41 skiaBox.outset(0, 2 * iBox.width() * (kVerticalSpacing + 1));
42
43 const SkScalar accentSize = iBox.width() * kAccentScale;
44 const SkScalar underlineY = iBox.bottom() +
45 (kVerticalSpacing + SkScalarSqrt(3) / 2) * accentSize;
46 SkMatrix m;
47 m.setRectToRect(skiaBox, viewBox, SkMatrix::kFill_ScaleToFit);
48 SkAutoCanvasRestore acr(canvas, true);
49 canvas->concat(m);
50
51 canvas->drawCircle(iBox.centerX(),
52 iBox.y() - (0.5f + kVerticalSpacing) * accentSize,
53 accentSize / 2,
54 paint);
55
56 path.reset();
57 path.moveTo(iBox.centerX() - accentSize / 2, iBox.bottom() + kVerticalSpacing * accentSize);
58 path.rLineTo(accentSize, 0);
59 path.lineTo(iBox.centerX(), underlineY);
60 canvas->drawPath(path, paint);
61
62 SkRect underlineRect = SkRect::MakeLTRB(iBox.centerX() - iBox.width() * accentSize * 3,
63 underlineY,
64 iBox.centerX(),
65 underlineY + accentSize / 10);
66 const SkPoint pts1[] = { SkPoint::Make(underlineRect.x(), 0),
67 SkPoint::Make(iBox.centerX(), 0) };
68 const SkScalar pos1[] = { 0, 0.75f };
69 const SkColor colors1[] = { SK_ColorTRANSPARENT, SK_ColorBLACK };
70 SkASSERT(SK_ARRAY_COUNT(pos1) == SK_ARRAY_COUNT(colors1));
reed1a9b9642016-03-13 14:13:58 -070071 paint.setShader(SkGradientShader::MakeLinear(pts1, colors1, pos1, SK_ARRAY_COUNT(pos1),
72 SkShader::kClamp_TileMode));
fmalita1dedc3d2015-08-04 13:53:14 -070073 canvas->drawRect(underlineRect, paint);
74
75 const SkPoint pts2[] = { SkPoint::Make(iBox.x() - iBox.width() * kGradientPad, 0),
76 SkPoint::Make(iBox.right() + iBox.width() * kGradientPad, 0) };
77 const SkScalar pos2[] = { 0, .01f, 1.0f/3, 1.0f/3, 2.0f/3, 2.0f/3, .99f, 1 };
78 const SkColor colors2[] = {
79 SK_ColorBLACK,
80 0xffca5139,
81 0xffca5139,
82 0xff8dbd53,
83 0xff8dbd53,
84 0xff5460a5,
85 0xff5460a5,
86 SK_ColorBLACK
87 };
88 SkASSERT(SK_ARRAY_COUNT(pos2) == SK_ARRAY_COUNT(colors2));
reed1a9b9642016-03-13 14:13:58 -070089 paint.setShader(SkGradientShader::MakeLinear(pts2, colors2, pos2, SK_ARRAY_COUNT(pos2),
90 SkShader::kClamp_TileMode));
fmalita1dedc3d2015-08-04 13:53:14 -070091 canvas->drawText(kSkiaStr, textLen, 0, 0, paint);
92}
93
94// This GM exercises SkPictureImageGenerator features
95// (in particular its matrix vs. bounds semantics).
96class PictureGeneratorGM : public skiagm::GM {
97protected:
98 SkString onShortName() override {
99 return SkString("pictureimagegenerator");
100 }
101
102 SkISize onISize() override {
103 return SkISize::Make(1160, 860);
104 }
105
106 void onOnceBeforeDraw() override {
107 const SkRect rect = SkRect::MakeWH(kPictureWidth, kPictureHeight);
108 SkPictureRecorder recorder;
109 SkCanvas* canvas = recorder.beginRecording(rect);
110 draw_vector_logo(canvas, rect);
reedca2622b2016-03-18 07:25:55 -0700111 fPicture = recorder.finishRecordingAsPicture();
fmalita1dedc3d2015-08-04 13:53:14 -0700112 }
113
114 void onDraw(SkCanvas* canvas) override {
115 const struct {
116 SkISize size;
117 SkScalar scaleX, scaleY;
118 SkScalar opacity;
119 } configs[] = {
120 { SkISize::Make(200, 100), 1, 1, 1 },
121 { SkISize::Make(200, 200), 1, 1, 1 },
122 { SkISize::Make(200, 200), 1, 2, 1 },
123 { SkISize::Make(400, 200), 2, 2, 1 },
124
125 { SkISize::Make(200, 100), 1, 1, 0.9f },
126 { SkISize::Make(200, 200), 1, 1, 0.75f },
127 { SkISize::Make(200, 200), 1, 2, 0.5f },
128 { SkISize::Make(400, 200), 2, 2, 0.25f },
129
130 { SkISize::Make(200, 200), 0.5f, 1, 1 },
131 { SkISize::Make(200, 200), 1, 0.5f, 1 },
132 { SkISize::Make(200, 200), 0.5f, 0.5f, 1 },
133 { SkISize::Make(200, 200), 2, 2, 1 },
134
135 { SkISize::Make(200, 100), -1, 1, 1 },
136 { SkISize::Make(200, 100), 1, -1, 1 },
137 { SkISize::Make(200, 100), -1, -1, 1 },
138 { SkISize::Make(200, 100), -1, -1, 0.5f },
139 };
140
141 const unsigned kDrawsPerRow = 4;
142 const SkScalar kDrawSize = 250;
143
144 for (size_t i = 0; i < SK_ARRAY_COUNT(configs); ++i) {
145 SkPaint p;
146 p.setAlpha(SkScalarRoundToInt(255 * configs[i].opacity));
147
148 SkMatrix m = SkMatrix::MakeScale(configs[i].scaleX, configs[i].scaleY);
149 if (configs[i].scaleX < 0) {
150 m.postTranslate(SkIntToScalar(configs[i].size.width()), 0);
151 }
152 if (configs[i].scaleY < 0) {
153 m.postTranslate(0, SkIntToScalar(configs[i].size.height()));
154 }
155 SkAutoTDelete<SkImageGenerator> gen(
156 SkImageGenerator::NewFromPicture(configs[i].size, fPicture.get(), &m,
157 p.getAlpha() != 255 ? &p : nullptr));
158 SkBitmap bm;
reed74bd9532015-09-14 08:52:12 -0700159 gen->generateBitmap(&bm);
fmalita1dedc3d2015-08-04 13:53:14 -0700160
161 const SkScalar x = kDrawSize * (i % kDrawsPerRow);
162 const SkScalar y = kDrawSize * (i / kDrawsPerRow);
163
164 p.setColor(0xfff0f0f0);
165 p.setAlpha(255);
166 canvas->drawRect(SkRect::MakeXYWH(x, y,
167 SkIntToScalar(bm.width()),
168 SkIntToScalar(bm.height())), p);
169 canvas->drawBitmap(bm, x, y);
170 }
171 }
172
173private:
reedca2622b2016-03-18 07:25:55 -0700174 sk_sp<SkPicture> fPicture;
fmalita1dedc3d2015-08-04 13:53:14 -0700175
176 const SkScalar kPictureWidth = 200;
177 const SkScalar kPictureHeight = 100;
178
179 typedef skiagm::GM INHERITED;
180};
181
halcanary385fe4d2015-08-26 13:07:48 -0700182DEF_GM(return new PictureGeneratorGM;)