@@ -22,6 +22,15 @@ proc drawOuterBox*[R](ctx: R, rect: Rect, padding: float32, color: Color) =
22
22
ctx.drawRect(rectBottom, color)
23
23
ctx.drawRect(rectRight, color)
24
24
25
+ proc toHex*(h: Hash): string =
26
+ const HexChars = "0123456789ABCDEF"
27
+ result = newString(sizeof(Hash) * 2)
28
+ var h = h
29
+ for i in countdown(result .high, 0):
30
+ result [i] = HexChars[h and 0xF]
31
+ h = h shr 4
32
+
33
+
25
34
proc drawRoundedRect*[R](
26
35
ctx: R,
27
36
rect: Rect,
@@ -45,106 +54,119 @@ proc drawRoundedRect*[R](
45
54
bw = cbs.sideSize.float32
46
55
bh = cbs.sideSize.float32
47
56
48
- let hash = hash((6217, int (cbs.sideSize), int (cbs.maxRadius), int (weight), doStroke, outerShadowFill))
57
+ # let hash = hash((6217, int (cbs.sideSize), int (cbs.maxRadius), int (weight), doStroke, outerShadowFill))
58
+ let hash = hash((6217, doStroke, outerShadowFill, cbs.padding, cbs.weightSize))
59
+ let cornerCbs = cbs.roundedBoxCornerSizes(radii, innerShadow = false)
49
60
50
61
block drawCorners:
51
62
var cornerHashes: array [DirectionCorners, Hash]
52
63
for corner in DirectionCorners:
53
64
cornerHashes[corner] = hash((hash, 41, int (radii[corner])))
54
65
55
- var missingAnyCorner = false
66
+ let fill = rgba(255, 255, 255, 255)
67
+ let clear = rgba(0, 0, 0, 0)
68
+
56
69
for corner in DirectionCorners:
57
- if cornerHashes[corner] notin ctx.entries:
58
- # echo "missing corner: ", corner, " hash: ", cornerHashes[corner], " radius: ", radii[corner], " sideSize: ", cbs.sideSize, " maxRadius: ", cbs.maxRadius, " weight: ", weight, " doStroke: ", doStroke, " outerShadowFill: ", outerShadowFill
59
- missingAnyCorner = true
60
- break
61
-
62
- if missingAnyCorner:
63
- let fill = rgba(255, 255, 255, 255)
64
- let clear = rgba(0, 0, 0, 0)
65
- var center = vec2(bw, bh)
66
- let wh = vec2(2*bw+1, 2*bh+1)
67
- let corners = radii.cornersToSdfRadii()
68
- var circle = newImage(int (2*bw), int (2*bh))
70
+ if cornerHashes[corner] in ctx.entries:
71
+ continue
72
+
73
+ let cornerCbs = cornerCbs[corner]
74
+ let corners = vec4(cornerCbs.radius.float32 )
75
+ var image = newImage(cornerCbs.sideSize, cornerCbs.sideSize)
76
+ let wh = vec2(2*cornerCbs.sideSize.float32 , 2*cornerCbs.sideSize.float32 )
69
77
70
78
if doStroke:
71
- drawSdfShape(circle ,
72
- center = center,
79
+ drawSdfShape(image ,
80
+ center = vec2(cornerCbs. center. float32 ) ,
73
81
wh = wh,
74
82
params = RoundedBoxParams(r: corners),
75
83
pos = fill.to(ColorRGBA),
76
84
neg = clear.to(ColorRGBA),
77
- factor = weight + 0.5 ,
85
+ factor = cbs.weightSize. float32 ,
78
86
spread = 0.0,
79
87
mode = sdfModeAnnular)
80
88
else:
81
- drawSdfShape(circle ,
82
- center = center,
89
+ drawSdfShape(image ,
90
+ center = vec2(cornerCbs. center. float32 , cornerCbs.center. float32 ) ,
83
91
wh = wh,
84
92
params = RoundedBoxParams(r: corners),
85
93
pos = fill.to(ColorRGBA),
86
94
neg = clear.to(ColorRGBA),
87
95
mode = sdfModeClipAA)
88
96
89
- let patches = sliceToNinePatch(circle)
90
- # Store each piece in the atlas
91
- let cornerImages: array [DirectionCorners, Image] = [
92
- dcTopLeft: patches.topLeft,
93
- dcTopRight: patches.topRight,
94
- dcBottomLeft: patches.bottomLeft,
95
- dcBottomRight: patches.bottomRight,
96
- ]
97
-
98
- for corner in DirectionCorners:
99
- let cornerHash = cornerHashes[corner]
100
- if cornerHash notin ctx.entries:
101
- let image = cornerImages[corner]
102
- case corner:
103
- of dcTopLeft:
104
- discard
105
- of dcTopRight:
106
- image.flipHorizontal()
107
- of dcBottomRight:
108
- image.flipHorizontal()
109
- image.flipVertical()
110
- of dcBottomLeft:
111
- image.flipVertical()
112
- ctx.putImage(toKey(cornerHash), image)
97
+ if color.a != 1.0 and false:
98
+ var msg = "corner"
99
+ msg &= (if doStroke: "-stroke" else: "-noStroke")
100
+ msg &= "-weight" & $weight
101
+ msg &= "-radius" & $cornerCbs.radius
102
+ msg &= "-sideSize" & $cornerCbs.sideSize
103
+ msg &= "-wh" & $wh.x
104
+ msg &= "-padding" & $cbs.padding
105
+ msg &= "-center" & $cornerCbs.center
106
+ msg &= "-doStroke" & (if doStroke: "true" else: "false")
107
+ msg &= "-outerShadowFill" & (if outerShadowFill: "true" else: "false")
108
+ msg &= "-corner-" & $corner
109
+ msg &= "-hash" & toHex(cornerHashes[corner])
110
+ echo "generating corner: ", msg
111
+ image.writeFile("examples/" & msg & ".png")
112
+
113
+ ctx.putImage(toKey(cornerHashes[corner]), image)
113
114
114
115
let
115
116
xy = rect.xy
116
117
zero = vec2(0, 0)
117
118
cornerSize = vec2(bw, bh)
118
- topLeft = xy + vec2(0 , 0 )
119
- topRight = xy + vec2(w - bw, 0 )
120
- bottomLeft = xy + vec2(0 , h - bh)
121
- bottomRight = xy + vec2(w - bw, h - bh)
122
-
123
- ctx.saveTransform()
124
- ctx.translate(topLeft)
125
- ctx.drawImage(cornerHashes[dcTopLeft], zero, color)
126
- ctx.restoreTransform()
127
-
128
- ctx.saveTransform()
129
- ctx.translate(topRight + cornerSize / 2 )
130
- ctx.rotate(- Pi/ 2 )
131
- ctx.translate(- cornerSize / 2 )
132
- ctx.drawImage(cornerHashes[dcTopRight], zero, color)
133
- ctx.restoreTransform()
134
-
135
- ctx.saveTransform()
136
- ctx.translate(bottomLeft + cornerSize / 2 )
137
- ctx.rotate(Pi/ 2 )
138
- ctx.translate(- cornerSize / 2 )
139
- ctx.drawImage(cornerHashes[dcBottomLeft], zero, color)
140
- ctx.restoreTransform()
141
-
142
- ctx.saveTransform()
143
- ctx.translate(bottomRight + cornerSize / 2 )
144
- ctx.rotate(Pi)
145
- ctx.translate(- cornerSize / 2 )
146
- ctx.drawImage(cornerHashes[dcBottomRight], zero, color)
147
- ctx.restoreTransform()
119
+
120
+ cpos = [
121
+ dcTopLeft: xy + vec2(0, 0),
122
+ dcTopRight: xy + vec2(w - bw, 0),
123
+ dcBottomLeft: xy + vec2(0, h - bh),
124
+ dcBottomRight: xy + vec2(w - bw, h - bh)
125
+ ]
126
+
127
+ coffset = [
128
+ dcTopLeft: vec2(0 , 0 ),
129
+ dcTopRight: vec2(cornerCbs[dcTopRight].sideDelta.float32 , 0 ) ,
130
+ dcBottomLeft: vec2(0 , cornerCbs[dcBottomLeft].sideDelta.float32 ) ,
131
+ dcBottomRight: vec2(cornerCbs[dcBottomRight].sideDelta.float32 , cornerCbs[dcBottomRight].sideDelta.float32 )
132
+ ]
133
+
134
+ ccenter = [
135
+ dcTopLeft: vec2(0.0 , 0.0 ),
136
+ dcTopRight: vec2(cornerCbs[dcTopRight].sideSize.float32 , cornerCbs[dcTopRight].sideSize.float32 ) ,
137
+ dcBottomLeft: vec2(cornerCbs[dcBottomLeft].sideSize.float32 , cornerCbs[dcBottomLeft].sideSize.float32 ) ,
138
+ dcBottomRight: vec2(cornerCbs[dcBottomRight].sideSize.float32 , cornerCbs[dcBottomRight].sideSize.float32 )
139
+ ]
140
+
141
+ darkGrey = rgba(50 , 50 , 50 , 255 ).to(Color)
142
+
143
+ angles = [dcTopLeft: 0.0 , dcTopRight: - Pi/ 2 , dcBottomLeft: Pi/ 2 , dcBottomRight: Pi]
144
+
145
+ # if color.a != 1.0:
146
+ # echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " color: " & $color & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize & " blPos: " & $(bottomLeft + blCornerSize / 2) & " delta: " & $cornerCbs[dcBottomLeft].sideDelta & " doStroke: " & $doStroke
147
+
148
+ for corner in DirectionCorners:
149
+ ctx.saveTransform()
150
+ ctx.translate(cpos[corner] + coffset[corner] + ccenter[corner] / 2 )
151
+ ctx.rotate(angles[corner])
152
+ ctx.translate(- ccenter[corner] / 2 )
153
+ ctx.drawImage(cornerHashes[corner], zero, color)
154
+
155
+ if cornerCbs[corner].sideDelta > 0 :
156
+ let inner = cornerCbs[corner].inner.float32
157
+ let sideDelta = cornerCbs[corner].sideDelta.float32
158
+ let sideSize = cornerCbs[corner].sideSize.float32
159
+ # inner patch left, right, and then center
160
+ if doStroke:
161
+ ctx.drawRect(rect(0 , inner, cbs.weightSize.float32 , sideDelta), color)
162
+ ctx.drawRect(rect(inner, 0 , sideDelta, cbs.weightSize.float32 ), color)
163
+ else :
164
+ ctx.drawRect(rect(0 , inner, inner, sideDelta), color)
165
+ ctx.drawRect(rect(inner, 0 , sideDelta, sideSize), color)
166
+ # we could do two boxes, but this matches our shadow needs
167
+ ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), color)
168
+
169
+ ctx.restoreTransform()
148
170
149
171
block drawEdgeBoxes:
150
172
let
0 commit comments