• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/compiler_specific.h"
6 #include "skia/ext/analysis_canvas.h"
7 #include "skia/ext/refptr.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/skia/include/core/SkShader.h"
10 #include "third_party/skia/include/effects/SkOffsetImageFilter.h"
11 
12 namespace {
13 
SolidColorFill(skia::AnalysisCanvas & canvas)14 void SolidColorFill(skia::AnalysisCanvas& canvas) {
15   canvas.clear(SkColorSetARGB(255, 255, 255, 255));
16 }
17 
TransparentFill(skia::AnalysisCanvas & canvas)18 void TransparentFill(skia::AnalysisCanvas& canvas) {
19   canvas.clear(SkColorSetARGB(0, 0, 0, 0));
20 }
21 
22 } // namespace
23 namespace skia {
24 
TEST(AnalysisCanvasTest,EmptyCanvas)25 TEST(AnalysisCanvasTest, EmptyCanvas) {
26   skia::AnalysisCanvas canvas(255, 255);
27 
28   SkColor color;
29   EXPECT_TRUE(canvas.GetColorIfSolid(&color));
30   EXPECT_EQ(color, SkColorSetARGB(0, 0, 0, 0));
31 }
32 
TEST(AnalysisCanvasTest,ClearCanvas)33 TEST(AnalysisCanvasTest, ClearCanvas) {
34   skia::AnalysisCanvas canvas(255, 255);
35 
36   // Transparent color
37   SkColor color = SkColorSetARGB(0, 12, 34, 56);
38   canvas.clear(color);
39 
40   SkColor outputColor;
41   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
42   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
43 
44   // Solid color
45   color = SkColorSetARGB(255, 65, 43, 21);
46   canvas.clear(color);
47 
48   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
49   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
50   EXPECT_EQ(outputColor, color);
51 
52   // Translucent color
53   color = SkColorSetARGB(128, 11, 22, 33);
54   canvas.clear(color);
55 
56   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
57 
58   // Test helper methods
59   SolidColorFill(canvas);
60   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
61   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
62 
63   TransparentFill(canvas);
64   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
65   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
66 }
67 
TEST(AnalysisCanvasTest,ComplexActions)68 TEST(AnalysisCanvasTest, ComplexActions) {
69   skia::AnalysisCanvas canvas(255, 255);
70 
71   // Draw paint test.
72   SkColor color = SkColorSetARGB(255, 11, 22, 33);
73   SkPaint paint;
74   paint.setColor(color);
75 
76   canvas.drawPaint(paint);
77 
78   SkColor outputColor;
79   //TODO(vmpstr): This should return true. (crbug.com/180597)
80   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
81 
82   // Draw points test.
83   SkPoint points[4] = {
84     SkPoint::Make(0, 0),
85     SkPoint::Make(255, 0),
86     SkPoint::Make(255, 255),
87     SkPoint::Make(0, 255)
88   };
89 
90   SolidColorFill(canvas);
91   canvas.drawPoints(SkCanvas::kLines_PointMode, 4, points, paint);
92 
93   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
94 
95   // Draw oval test.
96   SolidColorFill(canvas);
97   canvas.drawOval(SkRect::MakeWH(255, 255), paint);
98 
99   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
100 
101   // Draw bitmap test.
102   SolidColorFill(canvas);
103   SkBitmap secondBitmap;
104   secondBitmap.allocN32Pixels(255, 255);
105   canvas.drawBitmap(secondBitmap, 0, 0);
106 
107   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
108 }
109 
TEST(AnalysisCanvasTest,SimpleDrawRect)110 TEST(AnalysisCanvasTest, SimpleDrawRect) {
111   skia::AnalysisCanvas canvas(255, 255);
112 
113   SkColor color = SkColorSetARGB(255, 11, 22, 33);
114   SkPaint paint;
115   paint.setColor(color);
116   canvas.clipRect(SkRect::MakeWH(255, 255));
117   canvas.drawRect(SkRect::MakeWH(255, 255), paint);
118 
119   SkColor outputColor;
120   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
121   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
122   EXPECT_EQ(color, outputColor);
123 
124   color = SkColorSetARGB(255, 22, 33, 44);
125   paint.setColor(color);
126   canvas.translate(-128, -128);
127   canvas.drawRect(SkRect::MakeWH(382, 382), paint);
128 
129   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
130 
131   color = SkColorSetARGB(255, 33, 44, 55);
132   paint.setColor(color);
133   canvas.drawRect(SkRect::MakeWH(383, 383), paint);
134 
135   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
136   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
137   EXPECT_EQ(color, outputColor);
138 
139   color = SkColorSetARGB(0, 0, 0, 0);
140   paint.setColor(color);
141   canvas.drawRect(SkRect::MakeWH(383, 383), paint);
142 
143   // This test relies on canvas treating a paint with 0-color as a no-op
144   // thus not changing its "is_solid" status.
145   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
146   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
147   EXPECT_EQ(outputColor, SkColorSetARGB(255, 33, 44, 55));
148 
149   color = SkColorSetARGB(128, 128, 128, 128);
150   paint.setColor(color);
151   canvas.drawRect(SkRect::MakeWH(383, 383), paint);
152 
153   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
154 
155   paint.setXfermodeMode(SkXfermode::kClear_Mode);
156   canvas.drawRect(SkRect::MakeWH(382, 382), paint);
157 
158   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
159 
160   canvas.drawRect(SkRect::MakeWH(383, 383), paint);
161 
162   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
163   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
164 
165   canvas.translate(128, 128);
166   color = SkColorSetARGB(255, 11, 22, 33);
167   paint.setColor(color);
168   paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
169   canvas.drawRect(SkRect::MakeWH(255, 255), paint);
170 
171   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
172   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
173   EXPECT_EQ(color, outputColor);
174 
175   canvas.rotate(50);
176   canvas.drawRect(SkRect::MakeWH(255, 255), paint);
177 
178   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
179 }
180 
TEST(AnalysisCanvasTest,FilterPaint)181 TEST(AnalysisCanvasTest, FilterPaint) {
182   skia::AnalysisCanvas canvas(255, 255);
183   SkPaint paint;
184 
185   skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(SkOffsetImageFilter::Create(10, 10));
186   paint.setImageFilter(filter.get());
187   canvas.drawRect(SkRect::MakeWH(255, 255), paint);
188 
189   SkColor outputColor;
190   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
191 }
192 
TEST(AnalysisCanvasTest,ClipPath)193 TEST(AnalysisCanvasTest, ClipPath) {
194   skia::AnalysisCanvas canvas(255, 255);
195 
196   // Skia will look for paths that are actually rects and treat
197   // them as such. We add a divot to the following path to prevent
198   // this optimization and truly test clipPath's behavior.
199   SkPath path;
200   path.moveTo(0, 0);
201   path.lineTo(128, 50);
202   path.lineTo(255, 0);
203   path.lineTo(255, 255);
204   path.lineTo(0, 255);
205 
206   SkColor outputColor;
207   SolidColorFill(canvas);
208   canvas.clipPath(path);
209   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
210 
211   canvas.save();
212   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
213 
214   canvas.clipPath(path);
215   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
216 
217   canvas.restore();
218   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
219 
220   SolidColorFill(canvas);
221   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
222 }
223 
TEST(AnalysisCanvasTest,SaveLayerRestore)224 TEST(AnalysisCanvasTest, SaveLayerRestore) {
225   skia::AnalysisCanvas canvas(255, 255);
226 
227   SkColor outputColor;
228   SolidColorFill(canvas);
229   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
230 
231   SkRect bounds = SkRect::MakeWH(255, 255);
232   SkPaint paint;
233   paint.setColor(SkColorSetARGB(255, 255, 255, 255));
234   paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
235 
236   // This should force non-transparency
237   canvas.saveLayer(&bounds, &paint);
238   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
239   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
240 
241   TransparentFill(canvas);
242   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
243 
244   SolidColorFill(canvas);
245   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
246   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
247 
248   paint.setXfermodeMode(SkXfermode::kDst_Mode);
249 
250   // This should force non-solid color
251   canvas.saveLayer(&bounds, &paint);
252   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
253 
254   TransparentFill(canvas);
255   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
256 
257   SolidColorFill(canvas);
258   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
259 
260   canvas.restore();
261   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
262 
263   TransparentFill(canvas);
264   EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
265 
266   SolidColorFill(canvas);
267   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
268   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
269 
270   canvas.restore();
271   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
272   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
273 
274   TransparentFill(canvas);
275   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
276   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
277 
278   SolidColorFill(canvas);
279   EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
280   EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
281 }
282 
TEST(AnalysisCanvasTest,HasText)283 TEST(AnalysisCanvasTest, HasText) {
284   int width = 200;
285   int height = 100;
286 
287   const char* text = "A";
288   size_t byteLength = 1;
289 
290   SkPoint point = SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25));
291   SkPath path;
292   path.moveTo(point);
293   path.lineTo(SkIntToScalar(75), SkIntToScalar(75));
294 
295   SkPaint paint;
296   paint.setColor(SK_ColorGRAY);
297   paint.setTextSize(SkIntToScalar(10));
298 
299   {
300     skia::AnalysisCanvas canvas(width, height);
301     // Test after initialization.
302     EXPECT_FALSE(canvas.HasText());
303     // Test drawing anything other than text.
304     canvas.drawRect(SkRect::MakeWH(width/2, height), paint);
305     EXPECT_FALSE(canvas.HasText());
306   }
307   {
308     // Test SkCanvas::drawText.
309     skia::AnalysisCanvas canvas(width, height);
310     canvas.drawText(text, byteLength, point.fX, point.fY, paint);
311     EXPECT_TRUE(canvas.HasText());
312   }
313   {
314     // Test SkCanvas::drawPosText.
315     skia::AnalysisCanvas canvas(width, height);
316     canvas.drawPosText(text, byteLength, &point, paint);
317     EXPECT_TRUE(canvas.HasText());
318   }
319   {
320     // Test SkCanvas::drawPosTextH.
321     skia::AnalysisCanvas canvas(width, height);
322     canvas.drawPosTextH(text, byteLength, &point.fX, point.fY, paint);
323     EXPECT_TRUE(canvas.HasText());
324   }
325   {
326     // Test SkCanvas::drawTextOnPathHV.
327     skia::AnalysisCanvas canvas(width, height);
328     canvas.drawTextOnPathHV(text, byteLength, path, point.fX, point.fY, paint);
329     EXPECT_TRUE(canvas.HasText());
330   }
331   {
332     // Test SkCanvas::drawTextOnPath.
333     skia::AnalysisCanvas canvas(width, height);
334     canvas.drawTextOnPath(text, byteLength, path, NULL, paint);
335     EXPECT_TRUE(canvas.HasText());
336   }
337   {
338     // Text under opaque rect.
339     skia::AnalysisCanvas canvas(width, height);
340     canvas.drawText(text, byteLength, point.fX, point.fY, paint);
341     EXPECT_TRUE(canvas.HasText());
342     canvas.drawRect(SkRect::MakeWH(width, height), paint);
343     EXPECT_FALSE(canvas.HasText());
344   }
345   {
346     // Text under translucent rect.
347     skia::AnalysisCanvas canvas(width, height);
348     canvas.drawText(text, byteLength, point.fX, point.fY, paint);
349     EXPECT_TRUE(canvas.HasText());
350     SkPaint translucentPaint;
351     translucentPaint.setColor(0x88FFFFFF);
352     canvas.drawRect(SkRect::MakeWH(width, height), translucentPaint);
353     EXPECT_TRUE(canvas.HasText());
354   }
355   {
356     // Text under rect in clear mode.
357     skia::AnalysisCanvas canvas(width, height);
358     canvas.drawText(text, byteLength, point.fX, point.fY, paint);
359     EXPECT_TRUE(canvas.HasText());
360     SkPaint clearModePaint;
361     clearModePaint.setXfermodeMode(SkXfermode::kClear_Mode);
362     canvas.drawRect(SkRect::MakeWH(width, height), clearModePaint);
363     EXPECT_FALSE(canvas.HasText());
364   }
365   {
366     // Clear.
367     skia::AnalysisCanvas canvas(width, height);
368     canvas.drawText(text, byteLength, point.fX, point.fY, paint);
369     EXPECT_TRUE(canvas.HasText());
370     canvas.clear(SK_ColorGRAY);
371     EXPECT_FALSE(canvas.HasText());
372   }
373   {
374     // Text inside clip region.
375     skia::AnalysisCanvas canvas(width, height);
376     canvas.clipRect(SkRect::MakeWH(100, 100));
377     canvas.drawText(text, byteLength, point.fX, point.fY, paint);
378     EXPECT_TRUE(canvas.HasText());
379   }
380   {
381     // Text outside clip region.
382     skia::AnalysisCanvas canvas(width, height);
383     canvas.clipRect(SkRect::MakeXYWH(100, 0, 100, 100));
384     canvas.drawText(text, byteLength, point.fX, point.fY, paint);
385     // Analysis device does not do any clipping.
386     // So even when text is outside the clip region,
387     // it is marked as having the text.
388     // TODO(alokp): We may be able to do some trivial rejection.
389     EXPECT_TRUE(canvas.HasText());
390   }
391 }
392 
393 }  // namespace skia
394