From 08f45023e8b7d5295640896d04f5c2bdb84a6efb Mon Sep 17 00:00:00 2001 From: tzSharing <90680948+tzSharing@users.noreply.github.com> Date: Fri, 22 Apr 2022 05:16:10 +0800 Subject: [PATCH] gg: fix gg.draw_rounded_rect_filled() graphical abnormalities (#14128) --- vlib/gg/draw.c.v | 140 ++++++++++++++++++++++++++++++----------------- 1 file changed, 91 insertions(+), 49 deletions(-) diff --git a/vlib/gg/draw.c.v b/vlib/gg/draw.c.v index fc8fef98b7..1e4b588960 100644 --- a/vlib/gg/draw.c.v +++ b/vlib/gg/draw.c.v @@ -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. // `w` is the width, `h` is the height . // `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) { + 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.begin_triangle_strip() - mut theta := f32(0) mut xx := 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 ny := y * ctx.scale width := w * ctx.scale height := h * ctx.scale - segments := 2 * math.pi * r - segdiv := segments / 4 - rb := 0 - lb := int(rb + segdiv) - lt := int(lb + segdiv) - rt := int(lt + segdiv) - // left top - lx := nx + r - 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) + + // left top quarter + sgl.begin_triangle_strip() + ltx := nx + r + lty := 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(ltx - xx, lty - yy) + sgl.v2f(ltx, lty) } - // right top - mut rx := nx + width - r - mut ry := ny + r - for i in rt .. int(segments) { - theta = 2 * f32(math.pi) * f32(i) / segments - xx = r * math.cosf(theta) - yy = r * math.sinf(theta) - sgl.v2f(xx + rx, yy + ry) - sgl.v2f(rx, ry) + sgl.end() + + // right top quarter + 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) } - // 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.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) } - // 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.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(lx + xx, ly) - sgl.v2f(lx, ly) 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(lx, ly) - sgl.v2f(rx, ry) - sgl.v2f(rbx, rby) sgl.v2f(lbx, lby) + sgl.v2f(rbx, rby) + sgl.v2f(rbx, ny + height) + sgl.v2f(lbx, ny + height) sgl.end() }