-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcontext_clip_depth_test.go
More file actions
117 lines (95 loc) · 3.28 KB
/
Copy pathcontext_clip_depth_test.go
File metadata and controls
117 lines (95 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package gg
import (
"testing"
)
func TestClipCircle_CPUPixels(t *testing.T) {
// Verify CPU arbitrary path clip works at pixel level.
// This is the baseline — if CPU clip works, GPU depth clip should match.
dc := NewContext(100, 100)
defer func() { _ = dc.Close() }()
// Draw white background.
dc.SetRGBA(1, 1, 1, 1)
dc.Clear()
// Clip to circle at center, radius 30.
dc.DrawCircle(50, 50, 30)
dc.Clip()
// Fill entire canvas red.
dc.SetRGBA(1, 0, 0, 1)
dc.DrawRectangle(0, 0, 100, 100)
_ = dc.Fill()
pm := dc.ResizeTarget()
// Pixel at center (50,50) — inside circle — should be red.
center := pm.GetPixel(50, 50)
if center.R < 0.9 {
t.Errorf("center pixel should be red, got R=%.2f G=%.2f B=%.2f", center.R, center.G, center.B)
}
// Pixel at corner (5,5) — outside circle — should NOT be red (clipped out).
// Background is white from Clear(), but pixmap may start transparent.
corner := pm.GetPixel(5, 5)
if corner.R > 0.5 && corner.G < 0.1 {
t.Errorf("corner pixel is red — clip NOT working! got R=%.2f G=%.2f B=%.2f", corner.R, corner.G, corner.B)
}
// Pixel just outside circle (50, 15) — 35 units from center, outside radius 30.
outside := pm.GetPixel(50, 15)
if outside.R > 0.5 && outside.G < 0.1 {
t.Errorf("pixel at (50,15) is red — outside circle but not clipped! R=%.2f G=%.2f B=%.2f",
outside.R, outside.G, outside.B)
}
// Pixel just inside circle (50, 25) — 25 units from center, inside radius 30.
inside := pm.GetPixel(50, 25)
if inside.R < 0.5 {
t.Errorf("pixel at (50,25) should be red (inside circle clip), got R=%.2f G=%.2f B=%.2f",
inside.R, inside.G, inside.B)
}
}
func TestClipCircle_GPUClipPathBridge(t *testing.T) {
// Verify that dc.Clip() with arbitrary path stores gpuClipPath.
dc := NewContext(100, 100)
defer func() { _ = dc.Close() }()
// Before clip — no path stored.
if dc.gpuClipPath != nil {
t.Error("gpuClipPath should be nil before Clip()")
}
// Apply circular clip.
dc.DrawCircle(50, 50, 30)
dc.Clip()
// After clip — path should be stored.
if dc.gpuClipPath == nil {
t.Fatal("gpuClipPath should be non-nil after Clip() with circle path")
}
if dc.gpuClipPath.NumVerbs() == 0 {
t.Error("gpuClipPath should have verbs (circle = 4 cubics + close)")
}
// clipStack should NOT be rect-only or rrect-only.
if dc.clipStack.IsRectOnly() {
t.Error("clipStack.IsRectOnly() should be false for circle clip")
}
if dc.clipStack.IsRRectOnly() {
t.Error("clipStack.IsRRectOnly() should be false for circle clip")
}
// setGPUClipRect should detect path clip and call setGPUClipPath.
// Without GPU context, it returns no-op but gpuClipPath is still set.
cleanup := dc.setGPUClipRect()
defer cleanup()
// After Pop, gpuClipPath should be cleared.
dc.Push()
dc.DrawCircle(50, 50, 20)
dc.Clip()
dc.Pop()
// gpuClipPath may or may not be nil after Pop depending on implementation.
// The important thing is that it doesn't crash.
}
func TestClipCircle_IsNotRectOrRRect(t *testing.T) {
dc := NewContext(100, 100)
defer func() { _ = dc.Close() }()
dc.DrawCircle(50, 50, 30)
dc.Clip()
rectOnly := dc.clipStack.IsRectOnly()
rrectOnly := dc.clipStack.IsRRectOnly()
if rectOnly {
t.Error("circle clip should NOT be IsRectOnly")
}
if rrectOnly {
t.Error("circle clip should NOT be IsRRectOnly")
}
}