blob: 9782dd82a015cac695fc246fa4b3e6f1d9898623 [file] [log] [blame]
djsollen@google.com6def2a22013-09-17 15:30:21 +00001/*
2 * Copyright 2013 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"
tfarinabcbc1782014-06-18 14:32:48 -07009
10#include "Resources.h"
joshualitt290c09b2014-12-19 13:45:20 -080011#include "SkBlurImageFilter.h"
12#include "SkColorFilterImageFilter.h"
13#include "SkColorMatrixFilter.h"
djsollen@google.com6def2a22013-09-17 15:30:21 +000014#include "SkCanvas.h"
joshualitt290c09b2014-12-19 13:45:20 -080015#include "SkGradientShader.h"
djsollen@google.com6def2a22013-09-17 15:30:21 +000016#include "SkStream.h"
17#include "SkTypeface.h"
18
joshualitt290c09b2014-12-19 13:45:20 -080019/*
20 * Spits out a dummy gradient to test blur with shader on paint
21 */
22static SkShader* MakeLinear() {
23 static const SkPoint kPts[] = { { 0, 0 }, { 32, 32 } };
24 static const SkScalar kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
25 static const SkColor kColors[] = {0x80F00080, 0xF0F08000, 0x800080F0 };
26 return SkGradientShader::CreateLinear(kPts, kColors, kPos,
27 SK_ARRAY_COUNT(kColors), SkShader::kClamp_TileMode);
28}
29
30static SkImageFilter* make_grayscale(SkImageFilter* input = NULL) {
31 SkScalar matrix[20];
32 memset(matrix, 0, 20 * sizeof(SkScalar));
33 matrix[0] = matrix[5] = matrix[10] = 0.2126f;
34 matrix[1] = matrix[6] = matrix[11] = 0.7152f;
35 matrix[2] = matrix[7] = matrix[12] = 0.0722f;
36 matrix[18] = 1.0f;
37 SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix));
38 return SkColorFilterImageFilter::Create(filter, input);
39}
40
41static SkImageFilter* make_blur(float amount, SkImageFilter* input = NULL) {
42 return SkBlurImageFilter::Create(amount, amount, input);
43}
44
djsollen@google.com6def2a22013-09-17 15:30:21 +000045namespace skiagm {
46
47class ColorEmojiGM : public GM {
48public:
49 ColorEmojiGM() {
50 fTypeface = NULL;
51 }
52
53 ~ColorEmojiGM() {
54 SkSafeUnref(fTypeface);
55 }
56protected:
57 virtual void onOnceBeforeDraw() SK_OVERRIDE {
tfarinac846f4a2014-07-01 12:35:49 -070058 SkString filename = GetResourcePath("/Funkster.ttf");
djsollen@google.com6def2a22013-09-17 15:30:21 +000059 SkAutoTUnref<SkFILEStream> stream(new SkFILEStream(filename.c_str()));
60 if (!stream->isValid()) {
61 SkDebugf("Could not find Funkster.ttf, please set --resourcePath correctly.\n");
62 return;
63 }
64
65 fTypeface = SkTypeface::CreateFromStream(stream);
66 }
67
68 virtual SkString onShortName() {
69 return SkString("coloremoji");
70 }
71
72 virtual SkISize onISize() {
joshualitt290c09b2014-12-19 13:45:20 -080073 return SkISize::Make(650, 480);
djsollen@google.com6def2a22013-09-17 15:30:21 +000074 }
75
76 virtual void onDraw(SkCanvas* canvas) {
77
78 canvas->drawColor(SK_ColorGRAY);
79
80 SkPaint paint;
81 paint.setTypeface(fTypeface);
djsollen@google.com6def2a22013-09-17 15:30:21 +000082
83 const char* text = "hamburgerfons";
84
85 // draw text at different point sizes
joshualitt290c09b2014-12-19 13:45:20 -080086 const int textSize[] = { 10, 30, 50, };
87 const int textYOffset[] = { 10, 40, 100, };
djsollen@google.com6def2a22013-09-17 15:30:21 +000088 SkASSERT(sizeof(textSize) == sizeof(textYOffset));
joshualitt290c09b2014-12-19 13:45:20 -080089 size_t y_offset = 0;
90 for (size_t y = 0; y < sizeof(textSize) / sizeof(int); y++) {
djsollen@google.comd8807972013-09-17 16:17:52 +000091 paint.setTextSize(SkIntToScalar(textSize[y]));
92 canvas->drawText(text, strlen(text), 10, SkIntToScalar(textYOffset[y]), paint);
joshualitt290c09b2014-12-19 13:45:20 -080093 y_offset += textYOffset[y];
94 }
95
96 // draw with shaders and image filters
97 for (int i = 0; i < 2; i++) {
98 for (int j = 0; j < 2; j++) {
99 for (int k = 0; k < 2; k++) {
100 SkPaint shaderPaint;
101 shaderPaint.setTypeface(fTypeface);
102 if (SkToBool(i)) {
103 shaderPaint.setShader(MakeLinear());
104 }
105
106 if (SkToBool(j) && SkToBool(k)) {
107 SkAutoTUnref<SkImageFilter> grayScale(make_grayscale(NULL));
108 SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f, grayScale));
109 shaderPaint.setImageFilter(blur);
110 } else if (SkToBool(j)) {
111 SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f, NULL));
112 shaderPaint.setImageFilter(blur);
113 } else if (SkToBool(k)) {
114 SkAutoTUnref<SkImageFilter> grayScale(make_grayscale(NULL));
115 shaderPaint.setImageFilter(grayScale);
116 }
117 shaderPaint.setTextSize(30);
118 canvas->drawText(text, strlen(text), 380, SkIntToScalar(y_offset), shaderPaint);
119 y_offset += 32;
120 }
121 }
djsollen@google.com6def2a22013-09-17 15:30:21 +0000122 }
123
124 // setup work needed to draw text with different clips
125 canvas->translate(10, 160);
126 paint.setTextSize(40);
127
128 // compute the bounds of the text
129 SkRect bounds;
130 paint.measureText(text, strlen(text), &bounds);
131
132 const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
133 const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
134 const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf;
135 const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf;
136
137 SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(),
138 boundsHalfWidth, boundsHalfHeight);
139 SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(),
140 boundsHalfWidth, boundsHalfHeight);
141 SkRect interiorClip = bounds;
142 interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight);
143
144 const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip };
145
146 SkPaint clipHairline;
147 clipHairline.setColor(SK_ColorWHITE);
148 clipHairline.setStyle(SkPaint::kStroke_Style);
149
150 for (size_t x = 0; x < sizeof(clipRects) / sizeof(SkRect); ++x) {
151 canvas->save();
152 canvas->drawRect(clipRects[x], clipHairline);
153 paint.setAlpha(0x20);
154 canvas->drawText(text, strlen(text), 0, 0, paint);
155 canvas->clipRect(clipRects[x]);
156 paint.setAlpha(0xFF);
157 canvas->drawText(text, strlen(text), 0, 0, paint);
158 canvas->restore();
159 canvas->translate(0, bounds.height() + SkIntToScalar(25));
160 }
161 }
162
163private:
164 SkTypeface* fTypeface;
165
166 typedef GM INHERITED;
167};
168
169//////////////////////////////////////////////////////////////////////////////
170
171static GM* MyFactory(void*) { return new ColorEmojiGM; }
172static GMRegistry reg(MyFactory);
djsollen@google.com6def2a22013-09-17 15:30:21 +0000173
174}