gg: fix gg.draw_rounded_rect_filled() graphical abnormalities (#14128)

tzSharing 2022-04-22 05:16:10 +08:00 committed by Jef Roosens
parent a7e8ca70dc
commit 08f45023e8
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
1 changed files with 91 additions and 49 deletions

View File

@ -278,72 +278,114 @@ pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius
// `x`,`y` is the top-left corner of the rectangle. // `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height . // `w` is the width, `h` is the height .
// `radius` is the radius of the corner-rounding in pixels. // `radius` is the radius of the corner-rounding in pixels.
// `c` is the color of the outline. // `c` is the color of the filled.
pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gx.Color) { pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
assert w > 0 && h > 0 && radius >= 0
if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip)
}
sgl.c4b(c.r, c.g, c.b, c.a) sgl.c4b(c.r, c.g, c.b, c.a)
sgl.begin_triangle_strip()
mut theta := f32(0)
mut xx := f32(0) mut xx := f32(0)
mut yy := f32(0) mut yy := f32(0)
r := radius * ctx.scale mut radians := f32(0)
mut new_radius := radius
if w >= h && radius > h / 2 {
new_radius = h / 2
} else if radius > w / 2 {
new_radius = w / 2
}
r := new_radius * ctx.scale
nx := x * ctx.scale nx := x * ctx.scale
ny := y * ctx.scale ny := y * ctx.scale
width := w * ctx.scale width := w * ctx.scale
height := h * ctx.scale height := h * ctx.scale
segments := 2 * math.pi * r
segdiv := segments / 4 // left top quarter
rb := 0 sgl.begin_triangle_strip()
lb := int(rb + segdiv) ltx := nx + r
lt := int(lb + segdiv) lty := ny + r
rt := int(lt + segdiv) for i in 0 .. 91 {
// left top if r == 0 {
lx := nx + r break
ly := ny + r
for i in lt .. rt {
theta = 2 * f32(math.pi) * f32(i) / segments
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + lx, yy + ly)
sgl.v2f(lx, ly)
} }
// right top radians = f32(math.radians(i))
mut rx := nx + width - r xx = r * math.cosf(radians)
mut ry := ny + r yy = r * math.sinf(radians)
for i in rt .. int(segments) { sgl.v2f(ltx - xx, lty - yy)
theta = 2 * f32(math.pi) * f32(i) / segments sgl.v2f(ltx, lty)
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + rx, yy + ry)
sgl.v2f(rx, ry)
} }
// right bottom
mut rbx := rx
mut rby := ny + height - r
for i in rb .. lb {
theta = 2 * f32(math.pi) * f32(i) / segments
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + rbx, yy + rby)
sgl.v2f(rbx, rby)
}
// left bottom
mut lbx := lx
mut lby := ny + height - r
for i in lb .. lt {
theta = 2 * f32(math.pi) * f32(i) / segments
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + lbx, yy + lby)
sgl.v2f(lbx, lby)
}
sgl.v2f(lx + xx, ly)
sgl.v2f(lx, ly)
sgl.end() sgl.end()
sgl.begin_quads()
sgl.v2f(lx, ly) // right top quarter
sgl.v2f(rx, ry) sgl.begin_triangle_strip()
rtx := nx + width - r
rty := ny + r
for i in 0 .. 91 {
if r == 0 {
break
}
radians = f32(math.radians(i))
xx = r * math.cosf(radians)
yy = r * math.sinf(radians)
sgl.v2f(rtx + xx, rty - yy)
sgl.v2f(rtx, rty)
}
sgl.end()
// right bottom quarter
sgl.begin_triangle_strip()
rbx := nx + width - r
rby := ny + height - r
for i in 0 .. 91 {
if r == 0 {
break
}
radians = f32(math.radians(i))
xx = r * math.cosf(radians)
yy = r * math.sinf(radians)
sgl.v2f(rbx + xx, rby + yy)
sgl.v2f(rbx, rby) sgl.v2f(rbx, rby)
}
sgl.end()
// left bottom quarter
sgl.begin_triangle_strip()
lbx := nx + r
lby := ny + height - r
for i in 0 .. 91 {
if r == 0 {
break
}
radians = f32(math.radians(i))
xx = r * math.cosf(radians)
yy = r * math.sinf(radians)
sgl.v2f(lbx - xx, lby + yy)
sgl.v2f(lbx, lby) sgl.v2f(lbx, lby)
}
sgl.end()
// Separate drawing is to prevent transparent color overlap
// top rectangle
sgl.begin_quads()
sgl.v2f(ltx, ny)
sgl.v2f(rtx, ny)
sgl.v2f(rtx, rty)
sgl.v2f(ltx, lty)
sgl.end()
// middle rectangle
sgl.begin_quads()
sgl.v2f(nx, ny + r)
sgl.v2f(rtx + r, rty)
sgl.v2f(rbx + r, rby)
sgl.v2f(nx, lby)
sgl.end()
// bottom rectangle
sgl.begin_quads()
sgl.v2f(lbx, lby)
sgl.v2f(rbx, rby)
sgl.v2f(rbx, ny + height)
sgl.v2f(lbx, ny + height)
sgl.end() sgl.end()
} }