• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
9 
10 #include "Resources.h"
11 #include "SkBlurImageFilter.h"
12 #include "SkColorFilterImageFilter.h"
13 #include "SkColorMatrixFilter.h"
14 #include "SkCanvas.h"
15 #include "SkGradientShader.h"
16 #include "SkStream.h"
17 #include "SkTypeface.h"
18 
19 /*
20  * Spits out a dummy gradient to test blur with shader on paint
21  */
MakeLinear()22 static 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 
make_grayscale(SkImageFilter * input=nullptr)30 static SkImageFilter* make_grayscale(SkImageFilter* input = nullptr) {
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 
make_blur(float amount,SkImageFilter * input=nullptr)41 static SkImageFilter* make_blur(float amount, SkImageFilter* input = nullptr) {
42     return SkBlurImageFilter::Create(amount, amount, input);
43 }
44 
45 namespace skiagm {
46 
47 class ColorEmojiGM : public GM {
48 public:
ColorEmojiGM()49     ColorEmojiGM() { }
50 
51 protected:
52     struct EmojiFont {
53         SkAutoTUnref<SkTypeface> typeface;
54         const char* text;
55     } emojiFont;
onOnceBeforeDraw()56     virtual void onOnceBeforeDraw() override {
57         sk_tool_utils::emoji_typeface(&emojiFont.typeface);
58         emojiFont.text = sk_tool_utils::emoji_sample_text();
59     }
60 
onShortName()61     SkString onShortName() override {
62         SkString name("coloremoji");
63         name.append(sk_tool_utils::platform_os_emoji());
64         return name;
65     }
66 
onISize()67     SkISize onISize() override {
68         return SkISize::Make(650, 900);
69     }
70 
onDraw(SkCanvas * canvas)71     void onDraw(SkCanvas* canvas) override {
72 
73         canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorGRAY));
74 
75         SkPaint paint;
76         paint.setTypeface(emojiFont.typeface);
77         const char* text = emojiFont.text;
78 
79         // draw text at different point sizes
80         const int textSize[] = { 10, 30, 50, };
81         const int textYOffset[] = { 10, 40, 100, };
82         SkASSERT(sizeof(textSize) == sizeof(textYOffset));
83         size_t y_offset = 0;
84         for (size_t y = 0; y < sizeof(textSize) / sizeof(int); y++) {
85             paint.setTextSize(SkIntToScalar(textSize[y]));
86             canvas->drawText(text, strlen(text), 10, SkIntToScalar(textYOffset[y]), paint);
87             y_offset += textYOffset[y];
88         }
89 
90         // draw with shaders and image filters
91         for (int makeLinear = 0; makeLinear < 2; makeLinear++) {
92             for (int makeBlur = 0; makeBlur < 2; makeBlur++) {
93                 for (int makeGray = 0; makeGray < 2; makeGray++) {
94                     SkPaint shaderPaint;
95                     shaderPaint.setTypeface(paint.getTypeface());
96                     if (SkToBool(makeLinear)) {
97                         shaderPaint.setShader(MakeLinear())->unref();
98                     }
99 
100                     if (SkToBool(makeBlur) && SkToBool(makeGray)) {
101                         SkAutoTUnref<SkImageFilter> grayScale(make_grayscale(nullptr));
102                         SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f, grayScale));
103                         shaderPaint.setImageFilter(blur);
104                     } else if (SkToBool(makeBlur)) {
105                         SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f, nullptr));
106                         shaderPaint.setImageFilter(blur);
107                     } else if (SkToBool(makeGray)) {
108                         SkAutoTUnref<SkImageFilter> grayScale(make_grayscale(nullptr));
109                         shaderPaint.setImageFilter(grayScale);
110                     }
111                     shaderPaint.setTextSize(30);
112                     canvas->drawText(text, strlen(text), 380, SkIntToScalar(y_offset),
113                                      shaderPaint);
114                     y_offset += 32;
115                 }
116             }
117         }
118 
119         // setup work needed to draw text with different clips
120         canvas->translate(10, 160);
121         paint.setTextSize(40);
122 
123         // compute the bounds of the text
124         SkRect bounds;
125         paint.measureText(text, strlen(text), &bounds);
126 
127         const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
128         const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
129         const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf;
130         const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf;
131 
132         SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(),
133                                                 boundsHalfWidth, boundsHalfHeight);
134         SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(),
135                                                  boundsHalfWidth, boundsHalfHeight);
136         SkRect interiorClip = bounds;
137         interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight);
138 
139         const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip };
140 
141         SkPaint clipHairline;
142         clipHairline.setColor(SK_ColorWHITE);
143         clipHairline.setStyle(SkPaint::kStroke_Style);
144 
145         for (size_t x = 0; x < sizeof(clipRects) / sizeof(SkRect); ++x) {
146             canvas->save();
147             canvas->drawRect(clipRects[x], clipHairline);
148             paint.setAlpha(0x20);
149             canvas->drawText(text, strlen(text), 0, 0, paint);
150             canvas->clipRect(clipRects[x]);
151             paint.setAlpha(0xFF);
152             canvas->drawText(text, strlen(text), 0, 0, paint);
153             canvas->restore();
154             canvas->translate(0, bounds.height() + SkIntToScalar(25));
155         }
156     }
157 
158     typedef GM INHERITED;
159 };
160 
161 //////////////////////////////////////////////////////////////////////////////
162 
MyFactory(void *)163 static GM* MyFactory(void*) { return new ColorEmojiGM; }
164 static GMRegistry reg(MyFactory);
165 
166 }
167