• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google LLC.
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 
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkPath.h"
13 
14 /**
15  * Repro case for https://bugs.chromium.org/p/chromium/issues/detail?id=913223
16  *
17  * The original bug was filed against square caps, but here we also draw the labyrinth using round
18  * and butt caps.
19  *
20  * Square and round caps expose over-coverage on overlaps when using coverage counting.
21  *
22  * Butt caps expose under-coverage on abutted strokes when using a 'max()' coverage function.
23  */
draw_labyrinth(SkCanvas * canvas,SkPaint::Cap cap)24 static void draw_labyrinth(SkCanvas* canvas, SkPaint::Cap cap) {
25     constexpr static bool kRows[11][12] = {
26         {1,1,1,1,1,1,1,1,1,1,1,1},
27         {0,1,0,1,0,1,0,0,0,0,1,1},
28         {0,0,0,0,1,0,0,0,0,1,1,1},
29         {1,0,1,0,0,0,0,1,0,0,0,0},
30         {0,1,1,0,0,0,0,0,0,1,1,1},
31         {1,0,0,1,0,0,0,0,1,1,1,0},
32         {0,1,0,1,1,1,0,0,1,1,1,0},
33         {1,0,1,0,1,1,1,1,0,1,1,1},
34         {0,0,1,0,0,1,0,0,0,0,0,1},
35         {0,1,1,1,0,0,1,1,1,1,0,0},
36         {1,1,1,1,1,1,1,1,1,1,1,1},
37     };
38 
39     constexpr static bool kCols[13][10] = {
40         {1,1,1,1,0,1,1,1,1,1},
41         {0,0,1,0,0,0,1,1,1,0},
42         {0,1,1,0,1,1,1,0,0,1},
43         {1,1,0,0,0,0,1,0,1,0},
44         {0,0,1,0,1,0,0,0,0,1},
45         {0,0,1,1,1,0,0,0,1,0},
46         {0,1,0,1,1,1,0,0,0,0},
47         {1,1,1,0,1,1,1,0,1,0},
48         {1,1,0,1,1,0,0,0,1,0},
49         {0,0,1,0,0,0,0,0,0,1},
50         {0,0,1,1,0,0,0,0,1,0},
51         {0,0,0,0,0,0,1,0,0,1},
52         {1,1,1,1,1,1,0,1,1,1},
53     };
54 
55     SkPath maze;
56     for (size_t y = 0; y < SK_ARRAY_COUNT(kRows); ++y) {
57         for (size_t x = 0; x < SK_ARRAY_COUNT(kRows[0]); ++x) {
58             if (kRows[y][x]) {
59                 maze.moveTo(x, y);
60                 maze.lineTo(x+1, y);
61             }
62         }
63     }
64     for (size_t x = 0; x < SK_ARRAY_COUNT(kCols); ++x) {
65         for (size_t y = 0; y < SK_ARRAY_COUNT(kCols[0]); ++y) {
66             if (kCols[x][y]) {
67                 maze.moveTo(x, y);
68                 maze.lineTo(x, y+1);
69             }
70         }
71     }
72 
73     SkPaint paint;
74     paint.setStyle(SkPaint::kStroke_Style);
75     paint.setStrokeWidth(.1f);
76     paint.setColor(0xff406060);
77     paint.setAntiAlias(true);
78     paint.setStrokeCap(cap);
79 
80     canvas->translate(10.5, 10.5);
81     canvas->scale(40, 40);
82     canvas->drawPath(maze, paint);
83 }
84 
85 constexpr static int kWidth = 500;
86 constexpr static int kHeight = 420;
87 
DEF_SIMPLE_GM(labyrinth_square,canvas,kWidth,kHeight)88 DEF_SIMPLE_GM(labyrinth_square, canvas, kWidth, kHeight) {
89     draw_labyrinth(canvas, SkPaint::kSquare_Cap);
90 }
91 
DEF_SIMPLE_GM(labyrinth_round,canvas,kWidth,kHeight)92 DEF_SIMPLE_GM(labyrinth_round, canvas, kWidth, kHeight) {
93     draw_labyrinth(canvas, SkPaint::kRound_Cap);
94 }
95 
DEF_SIMPLE_GM(labyrinth_butt,canvas,kWidth,kHeight)96 DEF_SIMPLE_GM(labyrinth_butt, canvas, kWidth, kHeight) {
97     draw_labyrinth(canvas, SkPaint::kButt_Cap);
98 }
99