gg: fix gg.draw_rounded_rect_empty() graphical abnormalities and some optimizations (#14186)
parent
b76095f28a
commit
85f616877f
227
vlib/gg/draw.c.v
227
vlib/gg/draw.c.v
|
@ -211,66 +211,111 @@ pub fn (ctx &Context) draw_rect_filled(x f32, y f32, w f32, h f32, c gx.Color) {
|
||||||
sgl.end()
|
sgl.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw_rounded_rect_empty draws the outline of a rounded rectangle
|
// draw_rounded_rect_empty draws the outline of a rounded rectangle with a thickness of 1 px.
|
||||||
// `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 outline.
|
||||||
pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
|
pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
|
||||||
mut theta := f32(0)
|
if w <= 0 || h <= 0 || radius < 0 {
|
||||||
mut xx := f32(0)
|
return
|
||||||
mut yy := f32(0)
|
}
|
||||||
r := radius * ctx.scale
|
if c.a != 255 {
|
||||||
nx := x * ctx.scale
|
sgl.load_pipeline(ctx.timage_pip)
|
||||||
ny := y * ctx.scale
|
}
|
||||||
|
sgl.c4b(c.r, c.g, c.b, c.a)
|
||||||
|
|
||||||
|
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
|
||||||
|
sx := x * ctx.scale // start point x
|
||||||
|
sy := y * ctx.scale
|
||||||
width := w * ctx.scale
|
width := w * ctx.scale
|
||||||
height := h * ctx.scale
|
height := h * ctx.scale
|
||||||
segments := 2 * math.pi * r
|
// circle center coordinates
|
||||||
segdiv := segments / 4
|
ltx := sx + r
|
||||||
rb := 0
|
lty := sy + r
|
||||||
lb := int(rb + segdiv)
|
rtx := sx + width - r
|
||||||
lt := int(lb + segdiv)
|
rty := lty
|
||||||
rt := int(lt + segdiv)
|
rbx := rtx
|
||||||
sgl.c4b(c.r, c.g, c.b, c.a)
|
rby := sy + height - r
|
||||||
|
lbx := ltx
|
||||||
|
lby := rby
|
||||||
|
|
||||||
|
mut rad := f32(0)
|
||||||
|
mut dx := f32(0)
|
||||||
|
mut dy := f32(0)
|
||||||
|
|
||||||
|
// left top quarter
|
||||||
sgl.begin_line_strip()
|
sgl.begin_line_strip()
|
||||||
// left top
|
for i in 0 .. 31 {
|
||||||
lx := nx + r
|
if r == 0 {
|
||||||
ly := ny + r
|
break
|
||||||
theta_coeff := 2 * f32(math.pi) / segments
|
}
|
||||||
for i in lt .. rt {
|
rad = f32(math.radians(i * 3))
|
||||||
theta = theta_coeff * f32(i)
|
dx = r * math.cosf(rad)
|
||||||
xx = r * math.cosf(theta)
|
dy = r * math.sinf(rad)
|
||||||
yy = r * math.sinf(theta)
|
sgl.v2f(ltx - dx, lty - dy)
|
||||||
sgl.v2f(xx + lx, yy + ly)
|
|
||||||
}
|
}
|
||||||
// right top
|
sgl.end()
|
||||||
mut rx := nx + width - r
|
|
||||||
mut ry := ny + r
|
// right top quarter
|
||||||
for i in rt .. int(segments) {
|
sgl.begin_line_strip()
|
||||||
theta = theta_coeff * f32(i)
|
for i in 0 .. 31 {
|
||||||
xx = r * math.cosf(theta)
|
if r == 0 {
|
||||||
yy = r * math.sinf(theta)
|
break
|
||||||
sgl.v2f(xx + rx, yy + ry)
|
}
|
||||||
|
rad = f32(math.radians(i * 3))
|
||||||
|
dx = r * math.cosf(rad)
|
||||||
|
dy = r * math.sinf(rad)
|
||||||
|
sgl.v2f(rtx + dx, rty - dy)
|
||||||
}
|
}
|
||||||
// right bottom
|
sgl.end()
|
||||||
mut rbx := rx
|
|
||||||
mut rby := ny + height - r
|
// right bottom quarter
|
||||||
for i in rb .. lb {
|
sgl.begin_line_strip()
|
||||||
theta = theta_coeff * f32(i)
|
for i in 0 .. 31 {
|
||||||
xx = r * math.cosf(theta)
|
if r == 0 {
|
||||||
yy = r * math.sinf(theta)
|
break
|
||||||
sgl.v2f(xx + rbx, yy + rby)
|
}
|
||||||
|
rad = f32(math.radians(i * 3))
|
||||||
|
dx = r * math.cosf(rad)
|
||||||
|
dy = r * math.sinf(rad)
|
||||||
|
sgl.v2f(rbx + dx, rby + dy)
|
||||||
}
|
}
|
||||||
// left bottom
|
sgl.end()
|
||||||
mut lbx := lx
|
|
||||||
mut lby := ny + height - r
|
// left bottom quarter
|
||||||
for i in lb .. lt {
|
sgl.begin_line_strip()
|
||||||
theta = theta_coeff * f32(i)
|
for i in 0 .. 31 {
|
||||||
xx = r * math.cosf(theta)
|
if r == 0 {
|
||||||
yy = r * math.sinf(theta)
|
break
|
||||||
sgl.v2f(xx + lbx, yy + lby)
|
}
|
||||||
|
rad = f32(math.radians(i * 3))
|
||||||
|
dx = r * math.cosf(rad)
|
||||||
|
dy = r * math.sinf(rad)
|
||||||
|
sgl.v2f(lbx - dx, lby + dy)
|
||||||
}
|
}
|
||||||
sgl.v2f(lx + xx, ly)
|
sgl.end()
|
||||||
|
|
||||||
|
// Currently don't use 'gg.draw_line()' directly, it will repeatedly execute '*ctx.scale'.
|
||||||
|
sgl.begin_lines()
|
||||||
|
// top
|
||||||
|
sgl.v2f(ltx, sy)
|
||||||
|
sgl.v2f(rtx, sy)
|
||||||
|
// right
|
||||||
|
sgl.v2f(rtx + r, rty)
|
||||||
|
sgl.v2f(rtx + r, rby)
|
||||||
|
// bottom
|
||||||
|
sgl.v2f(lbx, lby + r)
|
||||||
|
sgl.v2f(rbx, rby + r)
|
||||||
|
// left
|
||||||
|
sgl.v2f(sx, lty)
|
||||||
|
sgl.v2f(sx, lby)
|
||||||
sgl.end()
|
sgl.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,87 +325,91 @@ pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius
|
||||||
// `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 filled.
|
// `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 w <= 0 || h <= 0 || radius < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
if c.a != 255 {
|
if c.a != 255 {
|
||||||
sgl.load_pipeline(ctx.timage_pip)
|
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)
|
||||||
mut xx := f32(0)
|
|
||||||
mut yy := f32(0)
|
|
||||||
mut radians := f32(0)
|
|
||||||
mut new_radius := radius
|
mut new_radius := radius
|
||||||
if w >= h && radius > h / 2 {
|
if w >= h && radius > h / 2 {
|
||||||
new_radius = h / 2
|
new_radius = h / 2
|
||||||
} else if radius > w / 2 {
|
} else if radius > w / 2 {
|
||||||
new_radius = w / 2
|
new_radius = w / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
r := new_radius * ctx.scale
|
r := new_radius * ctx.scale
|
||||||
nx := x * ctx.scale
|
sx := x * ctx.scale // start point x
|
||||||
ny := y * ctx.scale
|
sy := y * ctx.scale
|
||||||
width := w * ctx.scale
|
width := w * ctx.scale
|
||||||
height := h * ctx.scale
|
height := h * ctx.scale
|
||||||
|
// circle center coordinates
|
||||||
|
ltx := sx + r
|
||||||
|
lty := sy + r
|
||||||
|
rtx := sx + width - r
|
||||||
|
rty := lty
|
||||||
|
rbx := rtx
|
||||||
|
rby := sy + height - r
|
||||||
|
lbx := ltx
|
||||||
|
lby := rby
|
||||||
|
|
||||||
|
mut rad := f32(0)
|
||||||
|
mut dx := f32(0)
|
||||||
|
mut dy := f32(0)
|
||||||
|
|
||||||
// left top quarter
|
// left top quarter
|
||||||
sgl.begin_triangle_strip()
|
sgl.begin_triangle_strip()
|
||||||
ltx := nx + r
|
for i in 0 .. 31 {
|
||||||
lty := ny + r
|
|
||||||
for i in 0 .. 91 {
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
radians = f32(math.radians(i))
|
rad = f32(math.radians(i * 3))
|
||||||
xx = r * math.cosf(radians)
|
dx = r * math.cosf(rad)
|
||||||
yy = r * math.sinf(radians)
|
dy = r * math.sinf(rad)
|
||||||
sgl.v2f(ltx - xx, lty - yy)
|
sgl.v2f(ltx - dx, lty - dy)
|
||||||
sgl.v2f(ltx, lty)
|
sgl.v2f(ltx, lty)
|
||||||
}
|
}
|
||||||
sgl.end()
|
sgl.end()
|
||||||
|
|
||||||
// right top quarter
|
// right top quarter
|
||||||
sgl.begin_triangle_strip()
|
sgl.begin_triangle_strip()
|
||||||
rtx := nx + width - r
|
for i in 0 .. 31 {
|
||||||
rty := ny + r
|
|
||||||
for i in 0 .. 91 {
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
radians = f32(math.radians(i))
|
rad = f32(math.radians(i * 3))
|
||||||
xx = r * math.cosf(radians)
|
dx = r * math.cosf(rad)
|
||||||
yy = r * math.sinf(radians)
|
dy = r * math.sinf(rad)
|
||||||
sgl.v2f(rtx + xx, rty - yy)
|
sgl.v2f(rtx + dx, rty - dy)
|
||||||
sgl.v2f(rtx, rty)
|
sgl.v2f(rtx, rty)
|
||||||
}
|
}
|
||||||
sgl.end()
|
sgl.end()
|
||||||
|
|
||||||
// right bottom quarter
|
// right bottom quarter
|
||||||
sgl.begin_triangle_strip()
|
sgl.begin_triangle_strip()
|
||||||
rbx := nx + width - r
|
for i in 0 .. 31 {
|
||||||
rby := ny + height - r
|
|
||||||
for i in 0 .. 91 {
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
radians = f32(math.radians(i))
|
rad = f32(math.radians(i * 3))
|
||||||
xx = r * math.cosf(radians)
|
dx = r * math.cosf(rad)
|
||||||
yy = r * math.sinf(radians)
|
dy = r * math.sinf(rad)
|
||||||
sgl.v2f(rbx + xx, rby + yy)
|
sgl.v2f(rbx + dx, rby + dy)
|
||||||
sgl.v2f(rbx, rby)
|
sgl.v2f(rbx, rby)
|
||||||
}
|
}
|
||||||
sgl.end()
|
sgl.end()
|
||||||
|
|
||||||
// left bottom quarter
|
// left bottom quarter
|
||||||
sgl.begin_triangle_strip()
|
sgl.begin_triangle_strip()
|
||||||
lbx := nx + r
|
for i in 0 .. 31 {
|
||||||
lby := ny + height - r
|
|
||||||
for i in 0 .. 91 {
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
radians = f32(math.radians(i))
|
rad = f32(math.radians(i * 3))
|
||||||
xx = r * math.cosf(radians)
|
dx = r * math.cosf(rad)
|
||||||
yy = r * math.sinf(radians)
|
dy = r * math.sinf(rad)
|
||||||
sgl.v2f(lbx - xx, lby + yy)
|
sgl.v2f(lbx - dx, lby + dy)
|
||||||
sgl.v2f(lbx, lby)
|
sgl.v2f(lbx, lby)
|
||||||
}
|
}
|
||||||
sgl.end()
|
sgl.end()
|
||||||
|
@ -368,24 +417,24 @@ pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radiu
|
||||||
// Separate drawing is to prevent transparent color overlap
|
// Separate drawing is to prevent transparent color overlap
|
||||||
// top rectangle
|
// top rectangle
|
||||||
sgl.begin_quads()
|
sgl.begin_quads()
|
||||||
sgl.v2f(ltx, ny)
|
sgl.v2f(ltx, sy)
|
||||||
sgl.v2f(rtx, ny)
|
sgl.v2f(rtx, sy)
|
||||||
sgl.v2f(rtx, rty)
|
sgl.v2f(rtx, rty)
|
||||||
sgl.v2f(ltx, lty)
|
sgl.v2f(ltx, lty)
|
||||||
sgl.end()
|
sgl.end()
|
||||||
// middle rectangle
|
// middle rectangle
|
||||||
sgl.begin_quads()
|
sgl.begin_quads()
|
||||||
sgl.v2f(nx, ny + r)
|
sgl.v2f(sx, lty)
|
||||||
sgl.v2f(rtx + r, rty)
|
sgl.v2f(rtx + r, rty)
|
||||||
sgl.v2f(rbx + r, rby)
|
sgl.v2f(rbx + r, rby)
|
||||||
sgl.v2f(nx, lby)
|
sgl.v2f(sx, lby)
|
||||||
sgl.end()
|
sgl.end()
|
||||||
// bottom rectangle
|
// bottom rectangle
|
||||||
sgl.begin_quads()
|
sgl.begin_quads()
|
||||||
sgl.v2f(lbx, lby)
|
sgl.v2f(lbx, lby)
|
||||||
sgl.v2f(rbx, rby)
|
sgl.v2f(rbx, rby)
|
||||||
sgl.v2f(rbx, ny + height)
|
sgl.v2f(rbx, rby + r)
|
||||||
sgl.v2f(lbx, ny + height)
|
sgl.v2f(lbx, rby + r)
|
||||||
sgl.end()
|
sgl.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue