• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkPath.h"
13 #include "include/core/SkRRect.h"
14 #include "include/core/SkRect.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkSize.h"
17 #include "include/core/SkString.h"
18 #include "src/core/SkCanvasPriv.h"
19 
20 namespace skiagm {
21 
22 // This test exercise SkCanvas::androidFramework_replaceClip behavior
23 class ComplexClip4GM : public GM {
24 public:
ComplexClip4GM(bool aaclip)25   ComplexClip4GM(bool aaclip)
26     : fDoAAClip(aaclip) {
27         this->setBGColor(0xFFDEDFDE);
28     }
29 
30 protected:
onShortName()31     SkString onShortName() override {
32         SkString str;
33         str.printf("complexclip4_%s",
34                    fDoAAClip ? "aa" : "bw");
35         return str;
36     }
37 
onISize()38     SkISize onISize() override { return SkISize::Make(970, 780); }
39 
40     // Android Framework will still support the legacy kReplace SkClipOp on older devices, so
41     // this represents how to do so while also respecting the device restriction using the newer
42     // androidFramework_resetClip() API.
emulateDeviceRestriction(SkCanvas * canvas,const SkIRect & deviceRestriction)43     void emulateDeviceRestriction(SkCanvas* canvas, const SkIRect& deviceRestriction) {
44         // TODO(michaelludwig): It may make more sense for device clip restriction to move on to
45         // the SkSurface (which would let this GM draw correctly in viewer).
46         canvas->androidFramework_setDeviceClipRestriction(deviceRestriction);
47     }
48 
emulateClipRectReplace(SkCanvas * canvas,const SkRect & clipRect,bool aa)49     void emulateClipRectReplace(SkCanvas* canvas,
50                                 const SkRect& clipRect,
51                                 bool aa) {
52         SkCanvasPriv::ResetClip(canvas);
53         canvas->clipRect(clipRect, SkClipOp::kIntersect, aa);
54     }
55 
emulateClipRRectReplace(SkCanvas * canvas,const SkRRect & clipRRect,bool aa)56     void emulateClipRRectReplace(SkCanvas* canvas,
57                                  const SkRRect& clipRRect,
58                                  bool aa) {
59         SkCanvasPriv::ResetClip(canvas);
60         canvas->clipRRect(clipRRect, SkClipOp::kIntersect, aa);
61     }
62 
emulateClipPathReplace(SkCanvas * canvas,const SkPath & path,bool aa)63     void emulateClipPathReplace(SkCanvas* canvas,
64                                 const SkPath& path,
65                                 bool aa) {
66         SkCanvasPriv::ResetClip(canvas);
67         canvas->clipPath(path, SkClipOp::kIntersect, aa);
68     }
69 
onDraw(SkCanvas * canvas)70     void onDraw(SkCanvas* canvas) override {
71         SkPaint p;
72         p.setAntiAlias(fDoAAClip);
73         p.setColor(SK_ColorYELLOW);
74 
75         canvas->save();
76             // draw a yellow rect through a rect clip
77             canvas->save();
78                 emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(100, 100, 300, 300));
79                 canvas->drawColor(SK_ColorGREEN);
80                 emulateClipRectReplace(canvas, SkRect::MakeLTRB(100, 200, 400, 500), fDoAAClip);
81                 canvas->drawRect(SkRect::MakeLTRB(100, 200, 400, 500), p);
82             canvas->restore();
83 
84             // draw a yellow rect through a diamond clip
85             canvas->save();
86                 emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(500, 100, 800, 300));
87                 canvas->drawColor(SK_ColorGREEN);
88 
89                 SkPath pathClip = SkPath::Polygon({
90                     {650, 200},
91                     {900, 300},
92                     {650, 400},
93                     {650, 300},
94                 }, true);
95                 emulateClipPathReplace(canvas, pathClip, fDoAAClip);
96                 canvas->drawRect(SkRect::MakeLTRB(500, 200, 900, 500), p);
97             canvas->restore();
98 
99             // draw a yellow rect through a round rect clip
100             canvas->save();
101                 emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(500, 500, 800, 700));
102                 canvas->drawColor(SK_ColorGREEN);
103 
104                 emulateClipRRectReplace(
105                         canvas, SkRRect::MakeOval(SkRect::MakeLTRB(500, 600, 900, 750)), fDoAAClip);
106                 canvas->drawRect(SkRect::MakeLTRB(500, 600, 900, 750), p);
107             canvas->restore();
108 
109             // fill the clip with yellow color showing that androidFramework_replaceClip is
110             // in device space
111             canvas->save();
112                 canvas->clipRect(SkRect::MakeLTRB(100, 400, 300, 750),
113                                  SkClipOp::kIntersect, fDoAAClip);
114                 canvas->drawColor(SK_ColorGREEN);
115                 // should not affect the device-space clip
116                 canvas->rotate(20.f);
117                 canvas->translate(50.f, 50.f);
118                 emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(150, 450, 250, 700));
119                 canvas->drawColor(SK_ColorYELLOW);
120             canvas->restore();
121 
122         canvas->restore();
123     }
124 private:
125     bool    fDoAAClip;
126 
127     using INHERITED = GM;
128 };
129 
130 //////////////////////////////////////////////////////////////////////////////
131 
132 DEF_GM(return new ComplexClip4GM(false);)
133 DEF_GM(return new ComplexClip4GM(true);)
134 }  // namespace skiagm
135