From b41b253416428f203db405184461cd46dac729b6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 00:17:48 -0600 Subject: [PATCH 001/225] add sdfy --- atlas.lock | 348 -------------------------------------------------- figuro.nimble | 3 +- 2 files changed, 2 insertions(+), 349 deletions(-) delete mode 100644 atlas.lock diff --git a/atlas.lock b/atlas.lock deleted file mode 100644 index 00a08cf77..000000000 --- a/atlas.lock +++ /dev/null @@ -1,348 +0,0 @@ -{ - "items": { - "nimsimd": { - "dir": "/Volumes/projects/nims/cssgrid/deps/nimsimd", - "url": "https://github.com/guzba/nimsimd", - "commit": "3f6b2668ffb0867d0bf786a658b817763e611350", - "version": "" - }, - "cssgrid": { - "dir": "/Volumes/projects/nims/cssgrid", - "url": "link:///Volumes/projects/nims/cssgrid/cssgrid.nimble", - "commit": "3a8637254ecfd21ba4a83bc7f53c59efb878624b", - "version": "" - }, - "threading": { - "dir": "$deps/threading", - "url": "https://github.com/nim-lang/threading", - "commit": "c5a39a039f24d48ba9503dcb9a0aee68a0fbb36d", - "version": "" - }, - "chroma": { - "dir": "/Volumes/projects/nims/cssgrid/deps/chroma", - "url": "https://github.com/treeform/chroma", - "commit": "b2e71179174e040884ebf6a16cbac711c84620b9", - "version": "" - }, - "macroutils": { - "dir": "/Volumes/projects/nims/cssgrid/deps/macroutils", - "url": "https://github.com/PMunch/macroutils", - "commit": "b460c6804c97df8cfdc80c308b574ae90b30ac61", - "version": "" - }, - "pixie": { - "dir": "/Volumes/projects/nims/cssgrid/deps/pixie", - "url": "https://github.com/treeform/pixie", - "commit": "3b65ca5605a1156987041bf0295449e4c56128cf", - "version": "" - }, - "supersnappy": { - "dir": "$deps/supersnappy", - "url": "https://github.com/guzba/supersnappy", - "commit": "e4df8cb5468dd96fc5a4764028e20c8a3942f16a", - "version": "" - }, - "chronicles": { - "dir": "$deps/chronicles", - "url": "https://github.com/status-im/nim-chronicles", - "commit": "32ac8679680ea699f7dbc046e8e0131cac97d41a", - "version": "" - }, - "sigils": { - "dir": "$deps/sigils", - "url": "https://github.com/elcritch/sigils", - "commit": "2d9f97ad301bccfc8d898c8863aefd9e2e316130", - "version": "" - }, - "patty": { - "dir": "/Volumes/projects/nims/cssgrid/deps/patty", - "url": "https://github.com/andreaferretti/patty", - "commit": "31bb61b990b8b3bae1cba2f353fb978448942318", - "version": "" - }, - "cdecl": { - "dir": "$deps/cdecl", - "url": "https://github.com/elcritch/cdecl", - "commit": "29811e54f2b190c68c3fdcaa4c45adbfb6e5315c", - "version": "" - }, - "dmon": { - "dir": "$deps/dmon", - "url": "https://github.com/elcritch/dmon-nim", - "commit": "b068e274bd5a45e44ef91a337261dd3eee7423b5", - "version": "" - }, - "stack_strings": { - "dir": "$deps/stack_strings", - "url": "https://github.com/termermc/nim-stack-strings", - "commit": "8fa11c46787a7754d6fc13df1e51f7193bbab5e8", - "version": "" - }, - "micros": { - "dir": "$deps/micros", - "url": "https://github.com/beef331/micros", - "commit": "4dfeac6a47ba8b6287081b048158981a07832063", - "version": "" - }, - "opengl": { - "dir": "$deps/opengl", - "url": "https://github.com/nim-lang/opengl", - "commit": "8e2e098f82dc5eefd874488c37b5830233cd18f4", - "version": "" - }, - "pretty": { - "dir": "/Volumes/projects/nims/cssgrid/deps/pretty", - "url": "https://github.com/treeform/pretty", - "commit": "9e770046c5cdf23d395d6b21c4657345481b1c76", - "version": "" - }, - "msgpack4nim": { - "dir": "$deps/msgpack4nim", - "url": "https://github.com/jangko/msgpack4nim", - "commit": "f4cc097ca9694f17feced9f82994f583ef7911fe", - "version": "" - }, - "Nimscripter": { - "dir": "$deps/Nimscripter", - "url": "https://github.com/beef331/nimscripter", - "commit": "581485c65262d6395559dd2f6cbe4200c91ef078", - "version": "" - }, - "zippy": { - "dir": "/Volumes/projects/nims/cssgrid/deps/zippy", - "url": "https://github.com/guzba/zippy", - "commit": "a99f6a7d8a8e3e0213b3cad0daf0ea974bf58e3f", - "version": "" - }, - "bumpy": { - "dir": "/Volumes/projects/nims/cssgrid/deps/bumpy", - "url": "https://github.com/treeform/bumpy", - "commit": "d7eaf00c24820ad0317c9926737402e62431e931", - "version": "" - }, - "windex.elcritch.github.com": { - "dir": "$deps/windex.elcritch.github.com", - "url": "https://github.com/elcritch/windex", - "commit": "6109fd8391e1b07082665e60e750afc4937e7eb3", - "version": "" - }, - "asynctools": { - "dir": "$deps/asynctools", - "url": "https://github.com/cheatfate/asynctools", - "commit": "a314fb8d18a08954fc7ea43e40673acb348ce7cc", - "version": "" - }, - "stylus": { - "dir": "$deps/stylus", - "url": "https://github.com/ferus-web/stylus", - "commit": "d9182090b0b280d0232e056a2f12469a4ee27cbe", - "version": "" - }, - "variant": { - "dir": "$deps/variant", - "url": "https://github.com/yglukhov/variant", - "commit": "097031a499d18d5f4b1fe2f4c16d3f1ded8c7f45", - "version": "" - }, - "flatty": { - "dir": "/Volumes/projects/nims/cssgrid/deps/flatty", - "url": "https://github.com/treeform/flatty", - "commit": "07f6ba8ab96238e5bd1264cf0cea1d1746abb00c", - "version": "" - }, - "ws": { - "dir": "$deps/ws", - "url": "https://github.com/treeform/ws", - "commit": "9536bf99ddf5948db221ccb7bb3663aa238a8e21", - "version": "" - }, - "json_serialization": { - "dir": "$deps/json_serialization", - "url": "https://github.com/status-im/nim-json-serialization", - "commit": "6eadb6e939ffa7882ff5437033c11a9464d3385c", - "version": "" - }, - "results": { - "dir": "$deps/results", - "url": "https://github.com/arnetheduck/nim-results", - "commit": "df8113dda4c2d74d460a8fa98252b0b771bf1f27", - "version": "" - }, - "assume.disruptek.github.com": { - "dir": "$deps/assume.disruptek.github.com", - "url": "https://github.com/disruptek/assume", - "commit": "ebed5f2b726134400a4aca489d39e54a2e6dcd95", - "version": "" - }, - "urlly": { - "dir": "$deps/urlly", - "url": "https://github.com/treeform/urlly", - "commit": "94e9f864115c64debcfcce5db04c636838a4b408", - "version": "" - }, - "winim": { - "dir": "$deps/winim", - "url": "https://github.com/khchen/winim", - "commit": "6fdee629140baa0d7060ddf86662457d11f50d35", - "version": "" - }, - "testutils": { - "dir": "$deps/testutils", - "url": "https://github.com/status-im/nim-testutils", - "commit": "94d68e796c045d5b37cabc6be32d7bfa168f8857", - "version": "" - }, - "crunchy": { - "dir": "/Volumes/projects/nims/cssgrid/deps/crunchy", - "url": "https://github.com/guzba/crunchy", - "commit": "98eb6526982bb8aae8eec6e8781f4539fa19e049", - "version": "" - }, - "macosutils": { - "dir": "$deps/macosutils", - "url": "https://github.com/elcritch/macosutils", - "commit": "bb2c2ca53b6650a4a82f63db09b527e6fd570ac8", - "version": "" - }, - "vmath": { - "dir": "/Volumes/projects/nims/cssgrid/deps/vmath", - "url": "https://github.com/treeform/vmath", - "commit": "7282ae1247f2f384ebeaec3826d7fa38fd0e1df1", - "version": "" - }, - "serialization": { - "dir": "$deps/serialization", - "url": "https://github.com/status-im/nim-serialization", - "commit": "2086c99608b4bf472e1ef5fe063710f280243396", - "version": "" - }, - "unittest2": { - "dir": "$deps/unittest2", - "url": "https://github.com/status-im/nim-unittest2", - "commit": "9c716f162ad4f44def506dcdf9f6ebd0563991dc", - "version": "" - }, - "stew": { - "dir": "$deps/stew", - "url": "https://github.com/status-im/nim-stew", - "commit": "79e4fa5a9d3374db17ed63622714d3e1094c7f34", - "version": "" - }, - "faststreams": { - "dir": "$deps/faststreams", - "url": "https://github.com/status-im/nim-faststreams", - "commit": "3a0ab42573e566ce52625760f6bbf7e0bbb6ebc4", - "version": "" - }, - "chronos": { - "dir": "$deps/chronos", - "url": "https://github.com/status-im/nim-chronos", - "commit": "0646c444fce7c7ed08ef6f2c9a7abfd172ffe655", - "version": "" - }, - "httputils": { - "dir": "$deps/httputils", - "url": "https://github.com/status-im/nim-http-utils", - "commit": "4b113176de2534be63377de68f31302a3c1f770e", - "version": "" - }, - "bearssl": { - "dir": "$deps/bearssl", - "url": "https://github.com/status-im/nim-bearssl", - "commit": "667b40440a53a58e9f922e29e20818720c62d9ac", - "version": "" - } - }, - "nimcfg": [ - "############# begin Atlas config section ##########", - "--noNimblePath", - "--path:\"../cssgrid/deps/nimsimd/src\"", - "--path:\"../cssgrid/src\"", - "--path:\"deps/threading\"", - "--path:\"../cssgrid/deps/chroma/src\"", - "--path:\"../cssgrid/deps/macroutils/src\"", - "--path:\"../cssgrid/deps/pixie/src\"", - "--path:\"deps/supersnappy/src\"", - "--path:\"deps/chronicles\"", - "--path:\"deps/sigils\"", - "--path:\"../cssgrid/deps/patty\"", - "--path:\"deps/cdecl/src\"", - "--path:\"deps/dmon/src\"", - "--path:\"deps/stack_strings\"", - "--path:\"deps/micros/src\"", - "--path:\"deps/opengl/src\"", - "--path:\"../cssgrid/deps/pretty/src\"", - "--path:\"deps/msgpack4nim/src\"", - "--path:\"deps/Nimscripter/src\"", - "--path:\"../cssgrid/deps/zippy/src\"", - "--path:\"../cssgrid/deps/bumpy/src\"", - "--path:\"deps/windex.elcritch.github.com/src\"", - "--path:\"deps/asynctools\"", - "--path:\"deps/stylus/src\"", - "--path:\"deps/variant\"", - "--path:\"../cssgrid/deps/flatty/src\"", - "--path:\"deps/ws/src\"", - "--path:\"deps/json_serialization\"", - "--path:\"deps/results\"", - "--path:\"deps/assume.disruptek.github.com\"", - "--path:\"deps/urlly/src\"", - "--path:\"deps/winim\"", - "--path:\"deps/testutils\"", - "--path:\"../cssgrid/deps/crunchy/src\"", - "--path:\"deps/macosutils/src\"", - "--path:\"../cssgrid/deps/vmath/src\"", - "--path:\"deps/serialization\"", - "--path:\"deps/unittest2\"", - "--path:\"deps/stew\"", - "--path:\"deps/faststreams\"", - "--path:\"deps/chronos\"", - "--path:\"deps/httputils\"", - "--path:\"deps/bearssl\"", - "############# end Atlas config section ##########", - "" - ], - "nimbleFile": { - "filename": "figuro.nimble", - "content": [ - "version = \"0.12.11\"", - "author = \"Jaremy Creechley\"", - "description = \"UI Engine for Nim\"", - "license = \"MIT\"", - "srcDir = \"src\"", - "", - "# Dependencies", - "", - "requires \"nim >= 2.0.10\"", - "requires \"sigils >= 0.11.8\"", - "requires \"pixie >= 5.0.1\"", - "requires \"cssgrid >= 0.10.0\"", - "requires \"chroma >= 0.2.7\"", - "requires \"bumpy\"", - "requires \"pretty\"", - "requires \"supersnappy >= 2.1.3\"", - "requires \"variant >= 0.2.12\"", - "requires \"opengl >= 1.2.6\"", - "requires \"zippy >= 0.10.4\"", - "requires \"patty >= 0.3.4\"", - "requires \"macroutils >= 1.2.0\"", - "requires \"cdecl >= 0.7.5\"", - "requires \"asynctools >= 0.1.1\"", - "requires \"nimsimd >= 1.2.5\"", - "requires \"threading >= 0.2.1\"", - "requires \"nimscripter >= 1.1.5\"", - "requires \"msgpack4nim\"", - "requires \"stack_strings\"", - "requires \"micros\"", - "requires \"stylus\"", - "requires \"https://github.com/elcritch/windex >= 0.1.0\"", - "requires \"chronicles >= 0.10.3\"", - "requires \"dmon >= 0.4.0\"", - "" - ] - }, - "hostOS": "macosx", - "hostCPU": "arm64", - "nimVersion": "2.2.2", - "gccVersion": "", - "clangVersion": "" -} \ No newline at end of file diff --git a/figuro.nimble b/figuro.nimble index f6d0c858f..2fbad929c 100644 --- a/figuro.nimble +++ b/figuro.nimble @@ -15,6 +15,7 @@ requires "bumpy" requires "pretty" requires "stew == 0.2.0" requires "chronicles >= 0.10.3" +requires "https://github.com/elcritch/sdfy >= 0.5.0" requires "supersnappy >= 2.1.3" requires "variant >= 0.2.12" requires "opengl >= 1.2.6" @@ -25,7 +26,6 @@ requires "cdecl >= 0.7.5" requires "asynctools >= 0.1.1" requires "nimsimd >= 1.2.5" requires "threading >= 0.2.1" -requires "msgpack4nim" requires "stack_strings" requires "micros" requires "stylus >= 0.1.3" @@ -41,6 +41,7 @@ feature "boxy": feature "nimvm": requires "nimscripter >= 1.1.5" + requires "msgpack4nim" feature "thorvg": requires "https://github.com/thorvg/thorvg#head" From 9c0cef0fa33afd7fa44caeb0fda4390940970974 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 01:18:23 -0600 Subject: [PATCH 002/225] refactor --- src/figuro/renderer/opengl/glcontext.nim | 151 +------------------- src/figuro/renderer/opengl/renderer.nim | 1 + src/figuro/renderer/utils/drawextras.nim | 41 ++---- src/figuro/renderer/utils/drawshadows.nim | 163 ++++++++++++++++++++++ src/figuro/renderer/utils/drawutils.nim | 23 +++ src/figuro/widgets/button.nim | 3 +- 6 files changed, 204 insertions(+), 178 deletions(-) create mode 100644 src/figuro/renderer/utils/drawshadows.nim create mode 100644 src/figuro/renderer/utils/drawutils.nim diff --git a/src/figuro/renderer/opengl/glcontext.nim b/src/figuro/renderer/opengl/glcontext.nim index e894aad51..014c7b8c4 100644 --- a/src/figuro/renderer/opengl/glcontext.nim +++ b/src/figuro/renderer/opengl/glcontext.nim @@ -9,6 +9,7 @@ import pkg/chronicles import ../../commons import ../utils/boxes import ../utils/drawextras +import ../utils/drawshadows export drawextras @@ -687,153 +688,3 @@ proc toScreen*(ctx: Context, windowFrame: Vec2, v: Vec2): Vec2 = ## Takes a point from current transform and translates it to screen. result = (ctx.mat * vec3(v.x, v.y, 1)).xy result.y = -result.y + windowFrame.y - -var shadowCache: Table[Hash, Image] = initTable[Hash, Image]() - -proc fillRoundedRectWithShadow*( - ctx: Context, - rect: Rect, - radii: array[DirectionCorners, float32], - shadowX, shadowY, shadowBlur, shadowSpread: float32, - shadowColor: Color, - innerShadow = false, -) = - ## Draws a rounded rectangle with a shadow underneath using 9-patch technique - ## The shadow is drawn with padding around the main rectangle - if rect.w <= 0 or rect.h <= 0: - return - - # First, draw the shadow - # Generate shadow key for caching - proc getShadowKey(blur: float32, spread: float32, radius: float32, innerShadow: bool): Hash = - hash((7723, (blur * 1).int, (spread * 1).int, (radius * 1).int, innerShadow)) - - let - radii = clampRadii(radii, rect) - radiusLimit = max(radii) - # maxRadius = radiusLimit - shadowBlurSizeLimit = 14.0 - shadowSpreadLimit = 14.0 - shadowBlurSize = shadowBlur - shadowSpread = shadowSpread - shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) - - let (maxRadius, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread) - - var ninePatchHashes: array[8, Hash] - for i in 0..7: - ninePatchHashes[i] = shadowKey !& i - - # Check if we've already generated this shadow - let shadowKeyBase = shadowKey !& 0 - # let newSize = max(shadowBlur.int + shadowSpread.int + maxRadius.int, 2) - let newSize = totalSize - - if shadowKeyBase notin ctx.entries: - var shadowImg: Image = - if innerShadow: - let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) - # Generate shadow image - if mainKey notin shadowCache: - echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow - let mainImg = generateCircleBox( - radii = radii, - offset = vec2(0, 0), - spread = shadowSpread, - blur = shadowBlur, - stroked = true, - lineWidth = 1.0, - innerShadow = true, - outerShadow = false, - innerShadowBorder = true, - outerShadowFill = true, - ) - # mainImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & ".png") - shadowCache[mainKey] = mainImg - mainImg - else: - shadowCache[mainKey] - else: - let mainKey = getShadowKey(shadowBlurSizeLimit, shadowSpreadLimit, radiusLimit, innerShadow) - if mainKey notin shadowCache: - let mainImg = generateCircleBox( - radii = radii, - offset = vec2(0, 0), - spread = shadowSpreadLimit, - blur = shadowBlurSizeLimit, - stroked = false, - lineWidth = 1.0, - outerShadow = true, - innerShadow = false, - innerShadowBorder = true, - outerShadowFill = false, - ) - # mainImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & ".png") - shadowCache[mainKey] = mainImg - mainImg - else: - shadowCache[mainKey] - - if shadowImg.width != newSize or shadowImg.height != newSize: - shadowImg = shadowImg.resize(newSize, newSize) - - # Slice it into 9-patch pieces - let patches = sliceToNinePatch(shadowImg) - - # Store each piece in the atlas - let patchArray = [ - patches.topLeft, patches.topRight, - patches.bottomLeft, patches.bottomRight, - patches.top, patches.right, - patches.bottom, patches.left - ] - - for i in 0..7: - ninePatchHashes[i] = shadowKey !& i - ctx.putImage(ninePatchHashes[i], patchArray[i]) - - var - # totalPadding = int(shadowBlur+shadowSpread) - 1 - totalPadding = padding.int - corner = totalPadding.float32 + inner.float32/2 + 1 - - let - sbox = rect( - rect.x - totalPadding.float32 + shadowX, - rect.y - totalPadding.float32 + shadowY, - rect.w + 2 * totalPadding.float32, - rect.h + 2 * totalPadding.float32 - ) - halfW = sbox.w / 2 - halfH = sbox.h / 2 - centerX = sbox.x + halfW - centerY = sbox.y + halfH - - # Draw the corners - let - topLeft = rect(sbox.x, sbox.y, corner, corner) - topRight = rect(sbox.x + sbox.w - corner, sbox.y, corner, corner) - bottomLeft = rect(sbox.x, sbox.y + sbox.h - corner, corner, corner) - bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) - - # Draw corners - ctx.drawImageAdj(ninePatchHashes[0], topLeft.xy, shadowColor, topLeft.wh) - ctx.drawImageAdj(ninePatchHashes[1], topRight.xy, shadowColor, topRight.wh) - ctx.drawImageAdj(ninePatchHashes[2], bottomLeft.xy, shadowColor, bottomLeft.wh) - ctx.drawImageAdj(ninePatchHashes[3], bottomRight.xy, shadowColor, bottomRight.wh) - - # Draw edges - # Top edge (stretched horizontally) - let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) - let rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor*1.0, rightEdge.wh) - let bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor*1.0, bottomEdge.wh) - let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor*1.0, leftEdge.wh) - - # Center (stretched both ways) - let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) - if not innerShadow: - ctx.drawRect(center, shadowColor) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 8ce1a8441..a2672e6e4 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -10,6 +10,7 @@ import ../../common/rchannels import ../../common/nodes/uinodes import ../utils/glutils import ../utils/baserenderer +import ../utils/drawshadows import glcommons, glcontext import std/locks diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 3833eb00c..062def457 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -9,20 +9,9 @@ import pkg/sigils import pkg/chronicles import ../utils/boxes +import ./drawutils -proc hash(v: Vec2): Hash = - hash((v.x, v.y)) - -proc hash(radii: array[DirectionCorners, float32]): Hash = - for r in radii: - result = result !& hash(r) - -proc clampRadii*(radii: array[DirectionCorners, float32], rect: Rect): array[DirectionCorners, float32] = - result = radii - for r in result.mitems(): - r = max(1.0, min(r, min(rect.w / 2, rect.h / 2))).ceil() - -proc drawOuterBox*[R](bxy: R, rect: Rect, padding: float32, color: Color) = +proc drawOuterBox*[R](ctx: R, rect: Rect, padding: float32, color: Color) = var obox = rect obox.xy = obox.xy - vec2(padding, padding) @@ -33,13 +22,13 @@ proc drawOuterBox*[R](bxy: R, rect: Rect, padding: float32, color: Color) = let rectBottom = rect(xy + vec2(0, obox.h - padding), vec2(obox.w, padding)) let rectRight = rect(xy + vec2(obox.w - padding, padding), vec2(padding, obox.h - 2*padding)) - bxy.drawRect(rectTop, color) - bxy.drawRect(rectLeft, color) - bxy.drawRect(rectBottom, color) - bxy.drawRect(rectRight, color) + ctx.drawRect(rectTop, color) + ctx.drawRect(rectLeft, color) + ctx.drawRect(rectBottom, color) + ctx.drawRect(rectRight, color) proc drawRoundedRect*[R]( - bxy: R, + ctx: R, rect: Rect, color: Color, radii: array[DirectionCorners, float32], @@ -69,7 +58,7 @@ proc drawRoundedRect*[R]( let qhash = hash !& quadrant.int hashes[quadrant] = qhash - if not bxy.hasImage(toKey(hashes[dcTopRight])): + if not ctx.hasImage(toKey(hashes[dcTopRight])): let circle = if doStroke: generateCircleBox(radii, stroked = true, lineWidth = weight, outerShadowFill = outerShadowFill) @@ -87,7 +76,7 @@ proc drawRoundedRect*[R]( for quadrant in DirectionCorners: let img = patchArray[quadrant] - bxy.addImage(toKey(hashes[quadrant]), img) + ctx.addImage(toKey(hashes[quadrant]), img) let xy = rect.xy @@ -102,7 +91,7 @@ proc drawRoundedRect*[R]( let pt = ceil(xy + offsets[corner]) - bxy.drawImage(toKey(hashes[corner]), pt, color) + ctx.drawImage(toKey(hashes[corner]), pt, color) block drawEdgeBoxes: let @@ -113,10 +102,10 @@ proc drawRoundedRect*[R]( hrh = h - 2 * rh if not doStroke: - bxy.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) - bxy.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) - bxy.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) - bxy.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) - bxy.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) + ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) + ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim new file mode 100644 index 000000000..53fa2d0f5 --- /dev/null +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -0,0 +1,163 @@ +# import glcommons +import std/hashes + +import ../../commons +import ../../common/nodes/render + +import pkg/chroma +import pkg/sigils +import pkg/chronicles +import pkg/pixie/images + +import ../utils/boxes +import ./drawutils + +var shadowCache: Table[Hash, Image] = initTable[Hash, Image]() + +proc fillRoundedRectWithShadow*[R]( + ctx: R, + rect: Rect, + radii: array[DirectionCorners, float32], + shadowX, shadowY, shadowBlur, shadowSpread: float32, + shadowColor: Color, + innerShadow = false, +) = + ## Draws a rounded rectangle with a shadow underneath using 9-patch technique + ## The shadow is drawn with padding around the main rectangle + if rect.w <= 0 or rect.h <= 0: + return + + # First, draw the shadow + # Generate shadow key for caching + proc getShadowKey(blur: float32, spread: float32, radius: float32, innerShadow: bool): Hash = + hash((7723, (blur * 1).int, (spread * 1).int, (radius * 1).int, innerShadow)) + + let + radii = clampRadii(radii, rect) + radiusLimit = max(radii) + # maxRadius = radiusLimit + shadowBlurSizeLimit = 14.0 + shadowSpreadLimit = 14.0 + shadowBlurSize = shadowBlur + shadowSpread = shadowSpread + shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) + + let (maxRadius, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread) + + var ninePatchHashes: array[8, Hash] + for i in 0..7: + ninePatchHashes[i] = shadowKey !& i + + # Check if we've already generated this shadow + let shadowKeyBase = shadowKey !& 0 + # let newSize = max(shadowBlur.int + shadowSpread.int + maxRadius.int, 2) + let newSize = totalSize + + if shadowKeyBase notin ctx.entries: + var shadowImg: Image = + if innerShadow: + let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) + # Generate shadow image + if mainKey notin shadowCache: + echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow + let mainImg = generateCircleBox( + radii = radii, + offset = vec2(0, 0), + spread = shadowSpread, + blur = shadowBlur, + stroked = true, + lineWidth = 1.0, + innerShadow = true, + outerShadow = false, + innerShadowBorder = true, + outerShadowFill = true, + ) + # mainImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & ".png") + shadowCache[mainKey] = mainImg + mainImg + else: + shadowCache[mainKey] + else: + let mainKey = getShadowKey(shadowBlurSizeLimit, shadowSpreadLimit, radiusLimit, innerShadow) + if mainKey notin shadowCache: + let mainImg = generateCircleBox( + radii = radii, + offset = vec2(0, 0), + spread = shadowSpreadLimit, + blur = shadowBlurSizeLimit, + stroked = false, + lineWidth = 1.0, + outerShadow = true, + innerShadow = false, + innerShadowBorder = true, + outerShadowFill = false, + ) + # mainImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & ".png") + shadowCache[mainKey] = mainImg + mainImg + else: + shadowCache[mainKey] + + if shadowImg.width != newSize or shadowImg.height != newSize: + shadowImg = shadowImg.resize(newSize, newSize) + + # Slice it into 9-patch pieces + let patches = sliceToNinePatch(shadowImg) + + # Store each piece in the atlas + let patchArray = [ + patches.topLeft, patches.topRight, + patches.bottomLeft, patches.bottomRight, + patches.top, patches.right, + patches.bottom, patches.left + ] + + for i in 0..7: + ninePatchHashes[i] = shadowKey !& i + ctx.putImage(ninePatchHashes[i], patchArray[i]) + + var + # totalPadding = int(shadowBlur+shadowSpread) - 1 + totalPadding = padding.int + corner = totalPadding.float32 + inner.float32/2 + 1 + + let + sbox = rect( + rect.x - totalPadding.float32 + shadowX, + rect.y - totalPadding.float32 + shadowY, + rect.w + 2 * totalPadding.float32, + rect.h + 2 * totalPadding.float32 + ) + halfW = sbox.w / 2 + halfH = sbox.h / 2 + centerX = sbox.x + halfW + centerY = sbox.y + halfH + + # Draw the corners + let + topLeft = rect(sbox.x, sbox.y, corner, corner) + topRight = rect(sbox.x + sbox.w - corner, sbox.y, corner, corner) + bottomLeft = rect(sbox.x, sbox.y + sbox.h - corner, corner, corner) + bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) + + # Draw corners + ctx.drawImageAdj(ninePatchHashes[0], topLeft.xy, shadowColor, topLeft.wh) + ctx.drawImageAdj(ninePatchHashes[1], topRight.xy, shadowColor, topRight.wh) + ctx.drawImageAdj(ninePatchHashes[2], bottomLeft.xy, shadowColor, bottomLeft.wh) + ctx.drawImageAdj(ninePatchHashes[3], bottomRight.xy, shadowColor, bottomRight.wh) + + # Draw edges + # Top edge (stretched horizontally) + let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) + ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) + let rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) + ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor*1.0, rightEdge.wh) + let bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) + ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor*1.0, bottomEdge.wh) + let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) + ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor*1.0, leftEdge.wh) + + # Center (stretched both ways) + let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) + if not innerShadow: + ctx.drawRect(center, shadowColor) \ No newline at end of file diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim new file mode 100644 index 000000000..a4fd11ce3 --- /dev/null +++ b/src/figuro/renderer/utils/drawutils.nim @@ -0,0 +1,23 @@ +import std/hashes + +import ../../commons +import ../../common/nodes/render + +import pkg/chroma +import pkg/sigils +import pkg/chronicles + +import ../utils/boxes + + +proc hash(v: Vec2): Hash = + hash((v.x, v.y)) + +proc hash(radii: array[DirectionCorners, float32]): Hash = + for r in radii: + result = result !& hash(r) + +proc clampRadii*(radii: array[DirectionCorners, float32], rect: Rect): array[DirectionCorners, float32] = + result = radii + for r in result.mitems(): + r = max(1.0, min(r, min(rect.w / 2, rect.h / 2))).ceil() diff --git a/src/figuro/widgets/button.nim b/src/figuro/widgets/button.nim index 825d9ce9e..fdfe49485 100644 --- a/src/figuro/widgets/button.nim +++ b/src/figuro/widgets/button.nim @@ -58,8 +58,7 @@ proc draw*[T](self: Button[T]) {.slot.} = ## button widget! withWidget(self): - with this: - clipContent true + clipContent true withOptional self: cornerRadius 10.0'ui From 0dba5bc38d023e8a2b71e4cec2806fa31a8f644c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 01:32:06 -0600 Subject: [PATCH 003/225] refactor --- src/figuro/runtime/utils/timers.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/figuro/runtime/utils/timers.nim b/src/figuro/runtime/utils/timers.nim index 25d6eae08..a6d242594 100644 --- a/src/figuro/runtime/utils/timers.nim +++ b/src/figuro/runtime/utils/timers.nim @@ -11,6 +11,7 @@ proc logTiming(name, time: string) = const timeItSmoothing {.intdefine.} = 10 alpha = 1.0 / timeItSmoothing.toFloat + printEvery = 1_00 proc toMillis*(t: TimeIt): float = round(t.micros / 1_000.0, 3) @@ -28,7 +29,7 @@ macro timeIt*(timer, blk: untyped) = let micros = res.inMicroseconds.toFloat `timer`.micros = alpha * micros + (1.0-alpha) * `timer`.micros `timer`.count.inc - if `timer`.count mod 1_000 == 0: + if `timer`.count mod printEvery == 0: let num = toMillis(`timer`) logTiming($`name`, $num.formatBiggestFloat(ffDecimal, 3) & " ms") else: From ee6887ed4c984e5fd4614319cf4413965804e8ff Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 01:55:00 -0600 Subject: [PATCH 004/225] adding in sdfy --- examples/simd/sdneon.nim | 295 ----------------------- examples/simd/test_sdneon.nim | 66 ----- src/figuro/renderer/utils/drawextras.nim | 36 ++- 3 files changed, 33 insertions(+), 364 deletions(-) delete mode 100644 examples/simd/sdneon.nim delete mode 100644 examples/simd/test_sdneon.nim diff --git a/examples/simd/sdneon.nim b/examples/simd/sdneon.nim deleted file mode 100644 index 7ee88782a..000000000 --- a/examples/simd/sdneon.nim +++ /dev/null @@ -1,295 +0,0 @@ -import std/math -import pixie, vmath, chroma -import nimsimd/hassimd, nimsimd/neon - -import ../sdftypes - -when defined(release): - {.push checks: off.} - -when not compiles(vabsq_f32(float32x4(0.0))): - func vabsq_f32*(a: float32x4): float32x4 {.header: "arm_neon.h".} -when not compiles(vsqrtq_f32(float32x4(0.0))): - func vsqrtq_f32*(a: float32x4): float32x4 {.header: "arm_neon.h".} -when not compiles(vcvtq_u32_f32(float32x4(0.0))): - func vcvtq_u32_f32*(a: float32x4): uint32x4 {.header: "arm_neon.h".} - -proc sdRoundedBoxSimd*(px, py: float32x4, bx, by: float32, r: Vec4): float32x4 {.inline, raises: [].} = - ## SIMD version of signed distance function for rounded box - ## Processes 4 pixels at once - - let - zero = vmovq_n_f32(0.0) - rx_xy = vmovq_n_f32(r.x) # top-right radius - ry_xy = vmovq_n_f32(r.y) # bottom-right radius - rz_zw = vmovq_n_f32(r.z) # bottom-left radius - rw_zw = vmovq_n_f32(r.w) # top-left radius - bx_vec = vmovq_n_f32(bx) - by_vec = vmovq_n_f32(by) - - # Select corner radius based on quadrant - # cornerRadius.xy = if p.x > 0.0: r.xy else: r.zw - let - px_pos = vcgtq_f32(px, zero) # px > 0 - py_pos = vcgtq_f32(py, zero) # py > 0 - - # Select x-based radius (r.x/r.y if px > 0, else r.z/r.w) - let radius_x = vbslq_f32(px_pos, rx_xy, rz_zw) - let radius_y = vbslq_f32(px_pos, ry_xy, rw_zw) - - # cornerRadius.x = if p.y > 0.0: cornerRadius.x else: cornerRadius.y - let corner_radius = vbslq_f32(py_pos, radius_x, radius_y) - - # Calculate q = abs(p) - b + vec2(cornerRadius.x, cornerRadius.x) - let - abs_px = vabsq_f32(px) - abs_py = vabsq_f32(py) - qx = vaddq_f32(vsubq_f32(abs_px, bx_vec), corner_radius) - qy = vaddq_f32(vsubq_f32(abs_py, by_vec), corner_radius) - - # max(q, 0.0) - let - max_qx = vmaxq_f32(qx, zero) - max_qy = vmaxq_f32(qy, zero) - - # length(max(q, 0.0)) = sqrt(max_qx^2 + max_qy^2) - let - max_qx_sq = vmulq_f32(max_qx, max_qx) - max_qy_sq = vmulq_f32(max_qy, max_qy) - length_sq = vaddq_f32(max_qx_sq, max_qy_sq) - - # sqrt approximation using vsqrtq_f32 (available in ARMv8) - when defined(arm64) or defined(aarch64): - let length_vec = vsqrtq_f32(length_sq) - else: - # Fallback for older ARM processors - var length_array: array[4, float32] - vst1q_f32(length_array[0].addr, length_sq) - for i in 0..3: - length_array[i] = sqrt(length_array[i]) - let length_vec = vld1q_f32(length_array[0].addr) - - # min(max(q.x, q.y), 0.0) + length - cornerRadius - let - max_q = vmaxq_f32(qx, qy) - min_max_q = vminq_f32(max_q, zero) - - result = vaddq_f32(vsubq_f32(vaddq_f32(min_max_q, length_vec), corner_radius), zero) - -proc signedRoundedBoxNeon*( - image: Image, - center: Vec2, - wh: Vec2, - r: Vec4, - pos: ColorRGBA, neg: ColorRGBA, - factor: float32 = 4.0, - spread: float32 = 0.0, - mode: SDFMode = sdfModeFeather -) {.simd, raises: [].} = - ## NEON SIMD optimized version of signedRoundedBoxFeather - ## Processes pixels in chunks of 4 with padding for remaining pixels - ## clip: if true, use solid colors without feathering based on SDF sign - - let - pos_rgbx = pos.rgbx() - neg_rgbx = neg.rgbx() - center_x = center.x - center_y = center.y - b_x = wh.x / 2.0 - b_y = wh.y / 2.0 - four_vec = vmovq_n_f32(factor) - offset_vec = vmovq_n_f32(127.0) - zero_vec = vmovq_n_f32(0.0) - f255_vec = vmovq_n_f32(255.0) - - for y in 0 ..< image.height: - let - py_scalar = y.float32 - center_y - py_vec = vmovq_n_f32(py_scalar) - row_start = image.dataIndex(0, y) - - var x = 0 - - # Process all pixels in chunks of 4, with padding for the last chunk - while x < image.width: - # Calculate how many pixels we actually need to process in this chunk - let remainingPixels = min(4, image.width - x) - - # Calculate px for up to 4 pixels, padding with the last valid pixel - var px_array: array[4, float32] - for i in 0..3: - let actualX = if i < remainingPixels: x + i else: x + remainingPixels - 1 - px_array[i] = actualX.float32 - center_x - - let px_vec = vld1q_f32(px_array[0].addr) - - # Calculate signed distances for 4 pixels - let sd_vec = sdRoundedBoxSimd(px_vec, py_vec, b_x, b_y, r) - - # Extract individual values for color selection - var sd_array: array[4, float32] - vst1q_f32(sd_array[0].addr, sd_vec) - - case mode: - of sdfModeClip: - # Clipped mode: use solid colors based on SDF sign - for i in 0 ..< remainingPixels: - let - sd = sd_array[i] - final_color = if sd < 0.0: pos_rgbx else: neg_rgbx - idx = row_start + x + i - - image.data[idx] = final_color - - of sdfModeFeather: - # Feathered mode: calculate alpha values using SIMD - # Calculate alpha values: uint8(max(0.0, min(255, (factor*sd) + 127))) - let - scaled_sd = vmulq_f32(sd_vec, four_vec) - alpha_float = vaddq_f32(scaled_sd, offset_vec) - alpha_clamped_low = vmaxq_f32(alpha_float, zero_vec) - alpha_clamped = vminq_f32(alpha_clamped_low, f255_vec) - - # Convert to uint8 - let alpha_u32 = vcvtq_u32_f32(alpha_clamped) - var alpha_array: array[4, uint32] - vst1q_u32(alpha_array[0].addr, alpha_u32) - - # Process only the actual pixels (not the padded ones) - for i in 0 ..< remainingPixels: - let - sd = sd_array[i] - base_color = if sd < 0.0: pos_rgbx else: neg_rgbx - alpha = alpha_array[i].uint8 - idx = row_start + x + i - - var final_color = base_color - final_color.a = alpha - image.data[idx] = final_color - - of sdfModeFeatherInv: - # Inverted feathered mode: calculate alpha values using SIMD then invert - # Calculate alpha values: 255 - uint8(max(0.0, min(255, (factor*sd) + 127))) - let - scaled_sd = vmulq_f32(sd_vec, four_vec) - alpha_float = vaddq_f32(scaled_sd, offset_vec) - alpha_clamped_low = vmaxq_f32(alpha_float, zero_vec) - alpha_clamped = vminq_f32(alpha_clamped_low, f255_vec) - # Invert alpha by subtracting from 255 - alpha_inverted = vsubq_f32(f255_vec, alpha_clamped) - - # Convert to uint8 - let alpha_u32 = vcvtq_u32_f32(alpha_inverted) - var alpha_array: array[4, uint32] - vst1q_u32(alpha_array[0].addr, alpha_u32) - - # Process only the actual pixels (not the padded ones) - for i in 0 ..< remainingPixels: - let - sd = sd_array[i] - base_color = if sd < 0.0: pos_rgbx else: neg_rgbx - alpha = alpha_array[i].uint8 - idx = row_start + x + i - - var final_color = base_color - final_color.a = alpha - image.data[idx] = final_color - - of sdfModeFeatherGaussian: - # Gaussian feathered mode: calculate Gaussian alpha values - # f = 1 / sqrt(2 * PI * s^2) * exp(-1 * sd^2 / (2 * s^2)) - const - s = 2.2'f32 - s_squared = s * s - two_s_squared = 2.0'f32 * s_squared - gaussian_coeff = 1.0'f32 / sqrt(2.0'f32 * PI * s_squared) - - # Calculate sd^2 using SIMD for all 4 pixels - let sd_squared = vmulq_f32(sd_vec, sd_vec) - - # Extract values for exponential calculation (no efficient SIMD exp available) - var sd_squared_array: array[4, float32] - vst1q_f32(sd_squared_array[0].addr, sd_squared) - - var alpha_array: array[4, uint8] - for i in 0 ..< 4: - let - exp_val = exp(-1.0'f32 * sd_squared_array[i] / two_s_squared) - f = gaussian_coeff * exp_val - alpha_val = f * 255.0'f32 - alpha_array[i] = uint8(min(255.0'f32, max(0.0'f32, alpha_val))) - - # Process only the actual pixels (not the padded ones) - for i in 0 ..< remainingPixels: - let - sd = sd_array[i] - base_color = if sd < 0.0: pos_rgbx else: neg_rgbx - alpha = alpha_array[i] - idx = row_start + x + i - - var final_color = base_color - final_color.a = alpha - image.data[idx] = final_color - - of sdfModeDropShadow: - # Drop shadow mode: transform sd and apply Gaussian with conditional alpha - # sd = sd / factor * s - spread / 8.8 - # f = 1 / sqrt(2 * PI * s^2) * exp(-1 * sd^2 / (2 * s^2)) - # alpha = if sd > 0.0: min(f * 255 * 6, 255) else: 255 - const - s = 2.2'f32 - s_squared = s * s - two_s_squared = 2.0'f32 * s_squared - gaussian_coeff = 1.0'f32 / sqrt(2.0'f32 * PI * s_squared) - - # Transform sd values using SIMD: sd = sd / factor * s - spread / 8.8 - let - factor_vec = vmovq_n_f32(factor) - s_vec = vmovq_n_f32(s) - spread_offset = vmovq_n_f32(spread / 8.8'f32) - # Use multiplication by reciprocal instead of division - factor_reciprocal = vmovq_n_f32(1.0'f32 / factor) - transformed_sd = vsubq_f32( - vmulq_f32(vmulq_f32(sd_vec, factor_reciprocal), s_vec), - spread_offset - ) - - # Calculate sd^2 using SIMD for all 4 pixels - let sd_squared = vmulq_f32(transformed_sd, transformed_sd) - - # Extract values for exponential calculation and conditional logic - var - sd_squared_array: array[4, float32] - transformed_sd_array: array[4, float32] - vst1q_f32(sd_squared_array[0].addr, sd_squared) - vst1q_f32(transformed_sd_array[0].addr, transformed_sd) - - var alpha_array: array[4, uint8] - for i in 0 ..< 4: - let - transformed_sd_val = transformed_sd_array[i] - exp_val = exp(-1.0'f32 * sd_squared_array[i] / two_s_squared) - f = gaussian_coeff * exp_val - - if transformed_sd_val > 0.0'f32: - let alpha_val = min(f * 255.0'f32 * 6.0'f32, 255.0'f32) - alpha_array[i] = uint8(alpha_val) - else: - alpha_array[i] = 255'u8 - - # Process only the actual pixels (not the padded ones) - for i in 0 ..< remainingPixels: - let - sd = sd_array[i] - base_color = if sd < 0.0: pos_rgbx else: neg_rgbx - alpha = alpha_array[i] - idx = row_start + x + i - - var final_color = base_color - final_color.a = alpha - image.data[idx] = final_color - - x += remainingPixels - -when defined(release): - {.pop.} diff --git a/examples/simd/test_sdneon.nim b/examples/simd/test_sdneon.nim deleted file mode 100644 index 7b670d985..000000000 --- a/examples/simd/test_sdneon.nim +++ /dev/null @@ -1,66 +0,0 @@ -import std/math, std/monotimes, std/times -import pixie, vmath, pixie/simd -import sdneon -import ../sdftypes - -template timeIt(name: string, body: untyped) = - let start = getMonoTime() - body - let stop = getMonoTime() - echo name, ": ", inMilliseconds(stop - start), "ms" - -proc main() = - let - width = 400 - height = 400 - center = vec2(200.0, 200.0) - wh = vec2(200.0, 200.0) - r = vec4(0.0, 20.0, 50.0, 70.0) - pos = rgba(255, 0, 0, 255) - neg = rgba(0, 0, 255, 255) - - echo "Testing NEON SIMD implementation with different modes" - echo "Image size: ", width, "x", height - - # Test clipped mode - let imageClipped = newImage(width, height) - timeIt("NEON SIMD implementation (clipped)"): - signedRoundedBoxNeon(imageClipped, center, wh, r, pos, neg, factor = 4.0, mode = sdfModeClip) - - # Test feathered mode - let imageFeathered = newImage(width, height) - timeIt("NEON SIMD implementation (feathered)"): - signedRoundedBoxNeon(imageFeathered, center, wh, r, pos, neg, factor = 4.0, mode = sdfModeFeather) - - # Test inverted feathered mode - let imageFeatheredInv = newImage(width, height) - timeIt("NEON SIMD implementation (feathered inverted)"): - signedRoundedBoxNeon(imageFeatheredInv, center, wh, r, pos, neg, factor = 4.0, mode = sdfModeFeatherInv) - - # Test Gaussian feathered mode - let imageGaussian = newImage(width, height) - timeIt("NEON SIMD implementation (Gaussian feathered)"): - signedRoundedBoxNeon(imageGaussian, center, wh, r, pos, neg, factor = 4.0, mode = sdfModeFeatherGaussian) - - # Test drop shadow mode - let imageDropShadow = newImage(width, height) - timeIt("NEON SIMD implementation (drop shadow)"): - signedRoundedBoxNeon(imageDropShadow, center, wh, r, pos, neg, factor = 10.0, spread = 20.0, mode = sdfModeDropShadow) - - # Save test images - imageClipped.writeFile("test_simd_clipped.png") - imageFeathered.writeFile("test_simd_feathered.png") - imageFeatheredInv.writeFile("test_simd_feathered_inv.png") - imageGaussian.writeFile("test_simd_gaussian.png") - imageDropShadow.writeFile("test_simd_drop_shadow.png") - - echo "\nImages saved as:" - echo " test_simd_clipped.png (SIMD clipped to solid colors)" - echo " test_simd_feathered.png (SIMD with standard feathering)" - echo " test_simd_feathered_inv.png (SIMD with inverted feathering)" - echo " test_simd_gaussian.png (SIMD with Gaussian feathering)" - echo " test_simd_drop_shadow.png (SIMD with drop shadow effect)" - - echo "\n✓ All SIMD modes tested successfully!" - -main() \ No newline at end of file diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 062def457..cdd3dd05e 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -7,6 +7,8 @@ import ../../common/nodes/render import pkg/chroma import pkg/sigils import pkg/chronicles +import pkg/pixie/images +import pkg/sdfy import ../utils/boxes import ./drawutils @@ -60,10 +62,38 @@ proc drawRoundedRect*[R]( if not ctx.hasImage(toKey(hashes[dcTopRight])): let circle = - if doStroke: - generateCircleBox(radii, stroked = true, lineWidth = weight, outerShadowFill = outerShadowFill) + when defined(figuroNoSDF): + if doStroke: + generateCircleBox(radii, stroked = true, lineWidth = weight, outerShadowFill = outerShadowFill) + else: + generateCircleBox(radii, stroked = false, lineWidth = weight) else: - generateCircleBox(radii, stroked = false, lineWidth = weight) + block: + var center = vec2(rect.x + rw, rect.y + rh) + let wh = vec2(2*rw, 2*rh) + let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) + let circle = newImage(int(2*rw), int(2*rh)) + if doStroke: + drawSdfShape(circle, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = color.to(ColorRGBA), + neg = rgba(0, 0, 0, 0).to(ColorRGBA), + factor = 4.0, + spread = 0.0, + mode = sdfModeFeather) + else: + drawSdfShape(circle, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = color.to(ColorRGBA), + neg = rgba(0, 0, 0, 0).to(ColorRGBA), + factor = 4.0, + spread = 0.0, + mode = sdfModeFeather) + circle let patches = sliceToNinePatch(circle) # Store each piece in the atlas From 43d0a3efffa7da97e531820b3657df8053672ce1 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 02:23:33 -0600 Subject: [PATCH 005/225] adding in sdfy --- src/figuro/renderer/utils/drawextras.nim | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index cdd3dd05e..a76aa3cc4 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -7,7 +7,7 @@ import ../../common/nodes/render import pkg/chroma import pkg/sigils import pkg/chronicles -import pkg/pixie/images +import pkg/pixie import pkg/sdfy import ../utils/boxes @@ -69,6 +69,8 @@ proc drawRoundedRect*[R]( generateCircleBox(radii, stroked = false, lineWidth = weight) else: block: + let fill = rgba(255, 255, 255, 255) + let clear = rgba(0, 0, 0, 0) var center = vec2(rect.x + rw, rect.y + rh) let wh = vec2(2*rw, 2*rh) let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) @@ -78,21 +80,22 @@ proc drawRoundedRect*[R]( center = center, wh = wh, params = RoundedBoxParams(r: corners), - pos = color.to(ColorRGBA), - neg = rgba(0, 0, 0, 0).to(ColorRGBA), - factor = 4.0, + pos = fill.to(ColorRGBA), + neg = clear.to(ColorRGBA), + factor = 6.0, spread = 0.0, - mode = sdfModeFeather) + mode = sdfModeAnnular) else: drawSdfShape(circle, center = center, wh = wh, params = RoundedBoxParams(r: corners), - pos = color.to(ColorRGBA), - neg = rgba(0, 0, 0, 0).to(ColorRGBA), - factor = 4.0, + pos = fill.to(ColorRGBA), + neg = clear.to(ColorRGBA), + factor = 6.0, spread = 0.0, - mode = sdfModeFeather) + mode = sdfModeClipAA) + # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") circle let patches = sliceToNinePatch(circle) From 9612de4015b8fe7147195e88f3e113398afca166 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 02:33:49 -0600 Subject: [PATCH 006/225] adding in sdfy --- .gitignore | 1 + src/figuro/renderer/utils/drawextras.nim | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 85e6c010c..9e82d8b0a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ nim.cfg vendor/*/ nimcache *.out +.DS_Store .tool-versions *.dSYM/ diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index a76aa3cc4..cc4dfa25a 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -74,7 +74,8 @@ proc drawRoundedRect*[R]( var center = vec2(rect.x + rw, rect.y + rh) let wh = vec2(2*rw, 2*rh) let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) - let circle = newImage(int(2*rw), int(2*rh)) + let cbs = getCircleBoxSizes(radii, 0.0, 0.0) + let circle = newImage(cbs.totalSize, cbs.totalSize) if doStroke: drawSdfShape(circle, center = center, From dd003682144eef830f6da15f059e1b49926c46be Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 02:38:15 -0600 Subject: [PATCH 007/225] adding in sdfy --- src/figuro/renderer/utils/drawextras.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index cc4dfa25a..6562f870b 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -83,7 +83,7 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = 6.0, + factor = 5.5, spread = 0.0, mode = sdfModeAnnular) else: @@ -93,7 +93,7 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = 6.0, + factor = 5.5, spread = 0.0, mode = sdfModeClipAA) # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") From c8dbd8c206fc97f061281dc1bfe4e3f31a344335 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 03:03:57 -0600 Subject: [PATCH 008/225] adding in sdfy --- src/figuro/renderer/utils/drawextras.nim | 47 ++++++++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 6562f870b..0f65b7f82 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -57,8 +57,12 @@ proc drawRoundedRect*[R]( block drawCorners: var hashes: array[DirectionCorners, Hash] for quadrant in DirectionCorners: - let qhash = hash !& quadrant.int + let qhash = hash !& hash(19) !& quadrant.int hashes[quadrant] = qhash + var sideHashes: array[Directions, Hash] + for side in Directions: + let shash = hash !& hash(23) !& side.int + sideHashes[side] = shash if not ctx.hasImage(toKey(hashes[dcTopRight])): let circle = @@ -73,7 +77,9 @@ proc drawRoundedRect*[R]( let clear = rgba(0, 0, 0, 0) var center = vec2(rect.x + rw, rect.y + rh) let wh = vec2(2*rw, 2*rh) - let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) + # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) + # let corners = vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) + let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) let cbs = getCircleBoxSizes(radii, 0.0, 0.0) let circle = newImage(cbs.totalSize, cbs.totalSize) if doStroke: @@ -96,7 +102,7 @@ proc drawRoundedRect*[R]( factor = 5.5, spread = 0.0, mode = sdfModeClipAA) - # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") + circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") circle let patches = sliceToNinePatch(circle) @@ -112,6 +118,19 @@ proc drawRoundedRect*[R]( let img = patchArray[quadrant] ctx.addImage(toKey(hashes[quadrant]), img) + let sidePatchArray = [ + dTop: patches.top, + dRight: patches.right, + dBottom: patches.bottom, + dLeft: patches.left, + ] + + for side in Directions: + let img = sidePatchArray[side] + ctx.addImage(toKey(sideHashes[side]), img) + + img.writeFile("tests/circlebox-side-" & $side & "-stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") + let xy = rect.xy offsets = [ @@ -120,12 +139,23 @@ proc drawRoundedRect*[R]( dcBottomRight: vec2(w - rw, h - rh), dcBottomLeft: vec2(0, h - rh), ] + sideOffsets = [ + dTop: vec2(rw, 0), + dRight: vec2(w - rw, rh), + dBottom: vec2(w - rw, h - rh), + dLeft: vec2(0, h - rh), + ] for corner in DirectionCorners: let pt = ceil(xy + offsets[corner]) ctx.drawImage(toKey(hashes[corner]), pt, color) + + for side in Directions: + let + pt = ceil(xy + sideOffsets[side]) + ctx.drawImage(toKey(sideHashes[side]), pt, color) block drawEdgeBoxes: let @@ -136,10 +166,11 @@ proc drawRoundedRect*[R]( hrh = h - 2 * rh if not doStroke: - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) + ctx.drawRect(rect(ceil(rect.x + rw + 1), ceil(rect.y + rh + 1), wrw, hrh), color) - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) + when defined(figuroNoSDF): + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) - ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) - ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) + ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) + ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) From f712ec33b9750d7e03f75623fecec699018559fd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 03:04:31 -0600 Subject: [PATCH 009/225] adding in sdfy --- src/figuro/renderer/utils/drawextras.nim | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 0f65b7f82..94c0690f9 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -150,7 +150,7 @@ proc drawRoundedRect*[R]( let pt = ceil(xy + offsets[corner]) - ctx.drawImage(toKey(hashes[corner]), pt, color) + # ctx.drawImage(toKey(hashes[corner]), pt, color) for side in Directions: let @@ -165,12 +165,15 @@ proc drawRoundedRect*[R]( wrw = w - 2 * rw hrh = h - 2 * rh - if not doStroke: - ctx.drawRect(rect(ceil(rect.x + rw + 1), ceil(rect.y + rh + 1), wrw, hrh), color) - when defined(figuroNoSDF): + if not doStroke: + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) + else: + if not doStroke: + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) + From c0b0ad204a2c1d575a8a332bb58ab80efdadde31 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 8 Jun 2025 03:17:18 -0600 Subject: [PATCH 010/225] adding in sdfy --- src/figuro/renderer/utils/drawextras.nim | 26 ++++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 94c0690f9..ab8079b5a 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -139,23 +139,31 @@ proc drawRoundedRect*[R]( dcBottomRight: vec2(w - rw, h - rh), dcBottomLeft: vec2(0, h - rh), ] - sideOffsets = [ - dTop: vec2(rw, 0), - dRight: vec2(w - rw, rh), - dBottom: vec2(w - rw, h - rh), - dLeft: vec2(0, h - rh), - ] - for corner in DirectionCorners: let pt = ceil(xy + offsets[corner]) - # ctx.drawImage(toKey(hashes[corner]), pt, color) + ctx.drawImage(toKey(hashes[corner]), pt, color) + let + sideOffsets = [ + dTop: vec2(rw, 0), + dRight: vec2(w - rw, rh), + dBottom: vec2(rw, h - rh), + dLeft: vec2(0, rh), + ] + sideDims = [ + dTop: vec2(w - 2*rw, rh), + dRight: vec2(rw, h - 2*rh), + dBottom: vec2(w - 2*rw, rh), + dLeft: vec2(rw, h - 2*rh), + ] + for side in Directions: let pt = ceil(xy + sideOffsets[side]) - ctx.drawImage(toKey(sideHashes[side]), pt, color) + dim = sideDims[side] + ctx.drawImageAdj(toKey(sideHashes[side]), pt, color, dim) block drawEdgeBoxes: let From b3408933b8f612a591635bc382eda9519e30d7c5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 17:40:08 -0600 Subject: [PATCH 011/225] update sdfy --- figuro.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/figuro.nimble b/figuro.nimble index 2fbad929c..1043df13d 100644 --- a/figuro.nimble +++ b/figuro.nimble @@ -15,7 +15,7 @@ requires "bumpy" requires "pretty" requires "stew == 0.2.0" requires "chronicles >= 0.10.3" -requires "https://github.com/elcritch/sdfy >= 0.5.0" +requires "https://github.com/elcritch/sdfy >= 0.7.3" requires "supersnappy >= 2.1.3" requires "variant >= 0.2.12" requires "opengl >= 1.2.6" From 1d15cdca92829d38bc44d0ed287729c1f2554343 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 18:01:46 -0600 Subject: [PATCH 012/225] revert back draw extras --- src/figuro/renderer/utils/boxes.nim | 5 +- src/figuro/renderer/utils/drawextras.nim | 69 +++++------------------- 2 files changed, 16 insertions(+), 58 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 15d7b178b..fe089b43b 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -69,13 +69,14 @@ proc sliceToNinePatch*(img: Image): tuple[ proc getCircleBoxSizes*( radii: array[DirectionCorners, float32], blur: float32, - spread: float32 + spread: float32, + weight: float32 = 0.0, ): tuple[maxRadius: int, totalSize: int, padding: int, inner: int] = result.maxRadius = 0 for r in radii: result.maxRadius = max(result.maxRadius, r.ceil().int) result.padding = spread.ceil().int + blur.ceil().int - result.totalSize = max(2*result.maxRadius + 2*result.padding, 4*result.padding) + result.totalSize = max(max(2*result.maxRadius + 2*result.padding, 4*result.padding), weight.ceil().int) result.inner = result.totalSize - 2*result.padding proc generateCircleBox*( diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index ab8079b5a..a76aa3cc4 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -57,12 +57,8 @@ proc drawRoundedRect*[R]( block drawCorners: var hashes: array[DirectionCorners, Hash] for quadrant in DirectionCorners: - let qhash = hash !& hash(19) !& quadrant.int + let qhash = hash !& quadrant.int hashes[quadrant] = qhash - var sideHashes: array[Directions, Hash] - for side in Directions: - let shash = hash !& hash(23) !& side.int - sideHashes[side] = shash if not ctx.hasImage(toKey(hashes[dcTopRight])): let circle = @@ -77,11 +73,8 @@ proc drawRoundedRect*[R]( let clear = rgba(0, 0, 0, 0) var center = vec2(rect.x + rw, rect.y + rh) let wh = vec2(2*rw, 2*rh) - # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) - # let corners = vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) - let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) - let cbs = getCircleBoxSizes(radii, 0.0, 0.0) - let circle = newImage(cbs.totalSize, cbs.totalSize) + let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) + let circle = newImage(int(2*rw), int(2*rh)) if doStroke: drawSdfShape(circle, center = center, @@ -89,7 +82,7 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = 5.5, + factor = 6.0, spread = 0.0, mode = sdfModeAnnular) else: @@ -99,10 +92,10 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = 5.5, + factor = 6.0, spread = 0.0, mode = sdfModeClipAA) - circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") + # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") circle let patches = sliceToNinePatch(circle) @@ -118,19 +111,6 @@ proc drawRoundedRect*[R]( let img = patchArray[quadrant] ctx.addImage(toKey(hashes[quadrant]), img) - let sidePatchArray = [ - dTop: patches.top, - dRight: patches.right, - dBottom: patches.bottom, - dLeft: patches.left, - ] - - for side in Directions: - let img = sidePatchArray[side] - ctx.addImage(toKey(sideHashes[side]), img) - - img.writeFile("tests/circlebox-side-" & $side & "-stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") - let xy = rect.xy offsets = [ @@ -139,31 +119,12 @@ proc drawRoundedRect*[R]( dcBottomRight: vec2(w - rw, h - rh), dcBottomLeft: vec2(0, h - rh), ] + for corner in DirectionCorners: let pt = ceil(xy + offsets[corner]) ctx.drawImage(toKey(hashes[corner]), pt, color) - - let - sideOffsets = [ - dTop: vec2(rw, 0), - dRight: vec2(w - rw, rh), - dBottom: vec2(rw, h - rh), - dLeft: vec2(0, rh), - ] - sideDims = [ - dTop: vec2(w - 2*rw, rh), - dRight: vec2(rw, h - 2*rh), - dBottom: vec2(w - 2*rw, rh), - dLeft: vec2(rw, h - 2*rh), - ] - - for side in Directions: - let - pt = ceil(xy + sideOffsets[side]) - dim = sideDims[side] - ctx.drawImageAdj(toKey(sideHashes[side]), pt, color, dim) block drawEdgeBoxes: let @@ -173,15 +134,11 @@ proc drawRoundedRect*[R]( wrw = w - 2 * rw hrh = h - 2 * rh - when defined(figuroNoSDF): - if not doStroke: - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) + if not doStroke: + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) - ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) - ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) - else: - if not doStroke: - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) + ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) + ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) + ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) From 6b0768210e8bf51cc286beee3e40f825f4744db3 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 22:57:43 -0600 Subject: [PATCH 013/225] update sdfy --- figuro.nimble | 2 +- src/figuro/renderer/utils/drawextras.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/figuro.nimble b/figuro.nimble index 1043df13d..abe0a7e5f 100644 --- a/figuro.nimble +++ b/figuro.nimble @@ -15,7 +15,7 @@ requires "bumpy" requires "pretty" requires "stew == 0.2.0" requires "chronicles >= 0.10.3" -requires "https://github.com/elcritch/sdfy >= 0.7.3" +requires "https://github.com/elcritch/sdfy >= 0.7.4" requires "supersnappy >= 2.1.3" requires "variant >= 0.2.12" requires "opengl >= 1.2.6" diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index a76aa3cc4..3ed8c9c01 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -95,7 +95,7 @@ proc drawRoundedRect*[R]( factor = 6.0, spread = 0.0, mode = sdfModeClipAA) - # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rect.w & "x" & $rect.h & ".png") + # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rw & "x" & $rh & ".png") circle let patches = sliceToNinePatch(circle) From 670e5ce57acc653b52123aabe42df78881644079 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 23:31:24 -0600 Subject: [PATCH 014/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 2 +- src/figuro/renderer/utils/drawextras.nim | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index fe089b43b..22e2ca100 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -76,7 +76,7 @@ proc getCircleBoxSizes*( for r in radii: result.maxRadius = max(result.maxRadius, r.ceil().int) result.padding = spread.ceil().int + blur.ceil().int - result.totalSize = max(max(2*result.maxRadius + 2*result.padding, 4*result.padding), weight.ceil().int) + result.totalSize = max(max(2*result.maxRadius + 2*result.padding, 4*result.padding), ceil(2*weight).int) result.inner = result.totalSize - 2*result.padding proc generateCircleBox*( diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 3ed8c9c01..c0264b501 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -46,10 +46,12 @@ proc drawRoundedRect*[R]( let w = rect.w.ceil() h = rect.h.ceil() - radii = clampRadii(radii, rect) - maxRadius = max(radii) - rw = maxRadius - rh = maxRadius + # radii = clampRadii(radii, rect) + # maxRadius = max(radii) + cbs = getCircleBoxSizes(radii, 0.0, 0.0, weight) + maxRadius = cbs.maxRadius + rw = cbs.totalSize.float32 + rh = cbs.totalSize.float32 let hash = hash((6217, (rw * 10).int, (rh * 10).int, hash(radii), (weight * 10).int, doStroke)) @@ -57,7 +59,7 @@ proc drawRoundedRect*[R]( block drawCorners: var hashes: array[DirectionCorners, Hash] for quadrant in DirectionCorners: - let qhash = hash !& quadrant.int + let qhash = hash !& hash(41) !& quadrant.int hashes[quadrant] = qhash if not ctx.hasImage(toKey(hashes[dcTopRight])): @@ -95,7 +97,7 @@ proc drawRoundedRect*[R]( factor = 6.0, spread = 0.0, mode = sdfModeClipAA) - # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rw & "x" & $rh & ".png") + # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rw & "x" & $rh & "-mr" & $maxRadius & ".png") circle let patches = sliceToNinePatch(circle) @@ -128,7 +130,7 @@ proc drawRoundedRect*[R]( block drawEdgeBoxes: let - ww = if doStroke: weight else: maxRadius + ww = if doStroke: weight else: maxRadius.float32 rrw = if doStroke: w - weight else: w - rw rrh = if doStroke: h - weight else: h - rh wrw = w - 2 * rw From 091c27dc6b90cae44cdcb9b99cf9d7fa76a73cd7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 23:32:56 -0600 Subject: [PATCH 015/225] update sdfy --- src/figuro/renderer/utils/drawextras.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index c0264b501..c33674eda 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -84,7 +84,7 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = 6.0, + factor = weight, spread = 0.0, mode = sdfModeAnnular) else: @@ -94,7 +94,7 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = 6.0, + factor = weight, spread = 0.0, mode = sdfModeClipAA) # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rw & "x" & $rh & "-mr" & $maxRadius & ".png") From ab13e576d09d3377d1163bbc06344d7915768d68 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 23:44:46 -0600 Subject: [PATCH 016/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 7 +++++-- src/figuro/renderer/utils/drawextras.nim | 9 +++++---- src/figuro/renderer/utils/drawshadows.nim | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 22e2ca100..10b9cb482 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -71,10 +71,13 @@ proc getCircleBoxSizes*( blur: float32, spread: float32, weight: float32 = 0.0, -): tuple[maxRadius: int, totalSize: int, padding: int, inner: int] = + width = float32.high(), + height = float32.high(), +): tuple[maxRadius, sideSize, totalSize, padding, inner: int] = result.maxRadius = 0 for r in radii: result.maxRadius = max(result.maxRadius, r.ceil().int) + result.sideSize = max(result.maxRadius.min(width.ceil().int).min(height.ceil().int), 2*weight.ceil().int) result.padding = spread.ceil().int + blur.ceil().int result.totalSize = max(max(2*result.maxRadius + 2*result.padding, 4*result.padding), ceil(2*weight).int) result.inner = result.totalSize - 2*result.padding @@ -96,7 +99,7 @@ proc generateCircleBox*( # Additional size for spread and blur let lw = lineWidth.ceil() - let (maxRadius, totalSize, padding, inner) = getCircleBoxSizes(radii, blur, spread) + let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, blur, spread, lineWidth) # Create a canvas large enough to contain the box with all effects let img = newImage(totalSize, totalSize) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index c33674eda..2108f5986 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -48,10 +48,10 @@ proc drawRoundedRect*[R]( h = rect.h.ceil() # radii = clampRadii(radii, rect) # maxRadius = max(radii) - cbs = getCircleBoxSizes(radii, 0.0, 0.0, weight) + cbs = getCircleBoxSizes(radii, 0.0, 0.0, weight, w, h) maxRadius = cbs.maxRadius - rw = cbs.totalSize.float32 - rh = cbs.totalSize.float32 + rw = cbs.sideSize.float32 + rh = cbs.sideSize.float32 let hash = hash((6217, (rw * 10).int, (rh * 10).int, hash(radii), (weight * 10).int, doStroke)) @@ -130,7 +130,8 @@ proc drawRoundedRect*[R]( block drawEdgeBoxes: let - ww = if doStroke: weight else: maxRadius.float32 + ww = if doStroke: weight else: cbs.sideSize.float32 + # ww = cbs.sideSize.float32 rrw = if doStroke: w - weight else: w - rw rrh = if doStroke: h - weight else: h - rh wrw = w - 2 * rw diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 53fa2d0f5..fde408d50 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -42,7 +42,7 @@ proc fillRoundedRectWithShadow*[R]( shadowSpread = shadowSpread shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) - let (maxRadius, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread) + let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread, 0.0, rect.w, rect.h) var ninePatchHashes: array[8, Hash] for i in 0..7: From 7f59623818c78cf7dd629dc8504566d1f557fc4c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 23:46:22 -0600 Subject: [PATCH 017/225] update sdfy --- src/figuro/renderer/openglBackend.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 346f77bd0..08ab4a79e 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 1024 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) From 81b576a514c61606bb7d14a759cb6a23520b2783 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 23:56:19 -0600 Subject: [PATCH 018/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 4 ++-- src/figuro/renderer/utils/drawextras.nim | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 10b9cb482..8433d1a21 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -77,9 +77,9 @@ proc getCircleBoxSizes*( result.maxRadius = 0 for r in radii: result.maxRadius = max(result.maxRadius, r.ceil().int) - result.sideSize = max(result.maxRadius.min(width.ceil().int).min(height.ceil().int), 2*weight.ceil().int) + result.sideSize = max(result.maxRadius.min(width.ceil().int).min(height.ceil().int), int(1.5*weight.ceil())) result.padding = spread.ceil().int + blur.ceil().int - result.totalSize = max(max(2*result.maxRadius + 2*result.padding, 4*result.padding), ceil(2*weight).int) + result.totalSize = max(max(2*result.maxRadius + 2*result.padding, 4*result.padding), int(1.5*weight.ceil())) result.inner = result.totalSize - 2*result.padding proc generateCircleBox*( diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 2108f5986..96a82bc4b 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -74,7 +74,7 @@ proc drawRoundedRect*[R]( let fill = rgba(255, 255, 255, 255) let clear = rgba(0, 0, 0, 0) var center = vec2(rect.x + rw, rect.y + rh) - let wh = vec2(2*rw, 2*rh) + let wh = vec2(2*rw+1, 2*rh+1) let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) let circle = newImage(int(2*rw), int(2*rh)) if doStroke: @@ -84,7 +84,7 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = weight, + factor = weight + 0.5, spread = 0.0, mode = sdfModeAnnular) else: From 2b273d0a0dece2b152e27acfb827f37ea87ec589 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 9 Jun 2025 23:56:43 -0600 Subject: [PATCH 019/225] update sdfy --- src/figuro/renderer/utils/drawextras.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 96a82bc4b..17657fc7d 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -94,8 +94,6 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = weight, - spread = 0.0, mode = sdfModeClipAA) # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rw & "x" & $rh & "-mr" & $maxRadius & ".png") circle From bf35058f64bbb38a12f895530670dd6fb9d9630d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:01:53 -0600 Subject: [PATCH 020/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index fde408d50..e58123406 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -57,7 +57,7 @@ proc fillRoundedRectWithShadow*[R]( var shadowImg: Image = if innerShadow: let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) - # Generate shadow image + # Generate shadow image if mainKey notin shadowCache: echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow let mainImg = generateCircleBox( From f3b421e2cfe94c057054ef7b9505085d3746c38f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:03:04 -0600 Subject: [PATCH 021/225] update sdfy --- src/figuro/renderer/utils/drawextras.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 17657fc7d..dffd3b081 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -75,7 +75,8 @@ proc drawRoundedRect*[R]( let clear = rgba(0, 0, 0, 0) var center = vec2(rect.x + rw, rect.y + rh) let wh = vec2(2*rw+1, 2*rh+1) - let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) + # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) + let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) let circle = newImage(int(2*rw), int(2*rh)) if doStroke: drawSdfShape(circle, From df72a7de83883d78db41a7c54c2e8e732fd7a03b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:05:02 -0600 Subject: [PATCH 022/225] update sdfy --- src/figuro/renderer/utils/drawextras.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index dffd3b081..7f7718a7b 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -54,7 +54,7 @@ proc drawRoundedRect*[R]( rh = cbs.sideSize.float32 let hash = - hash((6217, (rw * 10).int, (rh * 10).int, hash(radii), (weight * 10).int, doStroke)) + hash((6217, (rw * 1).int, (rh * 1).int, hash(radii), (weight * 1).int, doStroke)) block drawCorners: var hashes: array[DirectionCorners, Hash] From 5e7e57b714e2f2867365607c7847a7bb17c8544a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:22:34 -0600 Subject: [PATCH 023/225] update sdfy --- src/figuro/renderer/boxy/renderer.nim | 4 ++-- src/figuro/renderer/opengl/renderer.nim | 2 -- src/figuro/renderer/utils/boxes.nim | 2 +- src/figuro/renderer/utils/drawextras.nim | 5 +++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/boxy/renderer.nim b/src/figuro/renderer/boxy/renderer.nim index 44d005c67..7d11b7901 100644 --- a/src/figuro/renderer/boxy/renderer.nim +++ b/src/figuro/renderer/boxy/renderer.nim @@ -213,7 +213,7 @@ proc renderBoxes(bxy: Boxy, node: Node) = rect = node.screenBox, color = node.fill, radii = node.cornerRadius, - weight = node.stroke.weight, + # weight = node.stroke.weight, ) else: bxy.drawRect(node.screenBox, node.fill) @@ -224,7 +224,7 @@ proc renderBoxes(bxy: Boxy, node: Node) = rect = node.screenBox, color = node.highlight, radii = node.cornerRadius, - weight = node.stroke.weight, + # weight = node.stroke.weight, ) else: bxy.drawRect(node.screenBox, node.highlight) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index a2672e6e4..353d86cf8 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -180,7 +180,6 @@ proc renderBoxes(ctx: Context, node: Node) = rect = node.screenBox.atXY(0'f32, 0'f32), color = node.fill, radii = node.cornerRadius, - weight = node.stroke.weight, ) else: ctx.drawRect(node.screenBox.atXY(0'f32, 0'f32), node.fill) @@ -191,7 +190,6 @@ proc renderBoxes(ctx: Context, node: Node) = rect = node.screenBox.atXY(0'f32, 0'f32), color = node.highlight, radii = node.cornerRadius, - weight = node.stroke.weight, ) else: ctx.drawRect(node.screenBox.atXY(0'f32, 0'f32), node.highlight) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 8433d1a21..bacfd1dcb 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -17,7 +17,7 @@ proc sliceToNinePatch*(img: Image): tuple[ halfW = width div 2 halfH = height div 2 - echo "sliceToNinePatch: ", width, "x", height, " halfW: ", halfW, " halfH: ", halfH + # echo "sliceToNinePatch: ", width, "x", height, " halfW: ", halfW, " halfH: ", halfH # Create the corner images - using the actual corner size or half the image size, whichever is smaller let diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 7f7718a7b..eaacc8e7c 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -53,8 +53,8 @@ proc drawRoundedRect*[R]( rw = cbs.sideSize.float32 rh = cbs.sideSize.float32 - let hash = - hash((6217, (rw * 1).int, (rh * 1).int, hash(radii), (weight * 1).int, doStroke)) + let rhash = radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int + let hash = hash((6217, (rw * 1).int, (rh * 1).int, (weight * 1).int, doStroke)) !& rhash block drawCorners: var hashes: array[DirectionCorners, Hash] @@ -78,6 +78,7 @@ proc drawRoundedRect*[R]( # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) let circle = newImage(int(2*rw), int(2*rh)) + echo "drawing circle: ", doStroke, " sz:", rect.w, "x", rect.h, " ", rw, "x", rh, " weight: ", weight, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")", " rhash: ", rhash, " " if doStroke: drawSdfShape(circle, center = center, From bb8ae348acdba2b03c892a093cade1d30d8be239 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:24:50 -0600 Subject: [PATCH 024/225] update sdfy --- src/figuro/renderer/utils/drawextras.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index eaacc8e7c..436fcbd0f 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -54,7 +54,7 @@ proc drawRoundedRect*[R]( rh = cbs.sideSize.float32 let rhash = radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int - let hash = hash((6217, (rw * 1).int, (rh * 1).int, (weight * 1).int, doStroke)) !& rhash + let hash = hash((6217, int(rw * 1), int(rh * 1), int(weight * 1), int(cbs.sideSize * 1), doStroke, outerShadowFill)) !& rhash block drawCorners: var hashes: array[DirectionCorners, Hash] From 874d333e0a490ac2b996ce5df5bc8d86f0a28ee2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:26:02 -0600 Subject: [PATCH 025/225] update sdfy --- src/figuro/renderer/openglBackend.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 08ab4a79e..346f77bd0 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 1024 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) From 4bfb2b23bbf2c5cdee04331a3de2e54ab6950c16 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:43:52 -0600 Subject: [PATCH 026/225] update sdfy --- src/figuro/renderer/opengl/renderer.nim | 2 + src/figuro/renderer/utils/drawshadows.nim | 146 +++++++++++++++++++++- 2 files changed, 142 insertions(+), 6 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 353d86cf8..141fd324d 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -133,6 +133,8 @@ proc renderInnerShadows(ctx: Context, node: Node) = ## drawing poor man's inner shadows ## this is even more incorrect than drop shadows, but it's something ## and I don't actually want to think today ;) + return + when FastShadows: let shadow = node.shadow[InnerShadow] let n = shadow.blur.toInt diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index e58123406..a17c8dacc 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -8,6 +8,7 @@ import pkg/chroma import pkg/sigils import pkg/chronicles import pkg/pixie/images +import pkg/sdfy import ../utils/boxes import ./drawutils @@ -36,8 +37,6 @@ proc fillRoundedRectWithShadow*[R]( radii = clampRadii(radii, rect) radiusLimit = max(radii) # maxRadius = radiusLimit - shadowBlurSizeLimit = 14.0 - shadowSpreadLimit = 14.0 shadowBlurSize = shadowBlur shadowSpread = shadowSpread shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) @@ -59,7 +58,7 @@ proc fillRoundedRectWithShadow*[R]( let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) # Generate shadow image if mainKey notin shadowCache: - echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow + echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSize.round(2), " spread: ", shadowSpread.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow let mainImg = generateCircleBox( radii = radii, offset = vec2(0, 0), @@ -78,13 +77,13 @@ proc fillRoundedRectWithShadow*[R]( else: shadowCache[mainKey] else: - let mainKey = getShadowKey(shadowBlurSizeLimit, shadowSpreadLimit, radiusLimit, innerShadow) + let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) if mainKey notin shadowCache: let mainImg = generateCircleBox( radii = radii, offset = vec2(0, 0), - spread = shadowSpreadLimit, - blur = shadowBlurSizeLimit, + spread = shadowSpread, + blur = shadowBlurSize, stroked = false, lineWidth = 1.0, outerShadow = true, @@ -157,6 +156,141 @@ proc fillRoundedRectWithShadow*[R]( let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor*1.0, leftEdge.wh) + # Center (stretched both ways) + let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) + if not innerShadow: + ctx.drawRect(center, shadowColor) + +proc fillRoundedRectWithShadowSdf*[R]( + ctx: R, + rect: Rect, + radii: array[DirectionCorners, float32], + shadowX, shadowY, shadowBlur, shadowSpread: float32, + shadowColor: Color, + innerShadow = false, +) = + ## Draws a rounded rectangle with a shadow underneath using 9-patch technique + ## The shadow is drawn with padding around the main rectangle + if rect.w <= 0 or rect.h <= 0: + return + + # First, draw the shadow + # Generate shadow key for caching + proc getShadowKey(blur: float32, spread: float32, radius: float32, innerShadow: bool): Hash = + hash((7723, (blur * 1).int, (spread * 1).int, (radius * 1).int, innerShadow)) + + let + radii = clampRadii(radii, rect) + # maxRadius = radiusLimit + cbs = getCircleBoxSizes(radii, 0.0, 0.0, 0.0, rect.w, rect.h) + radiusLimit = cbs.maxRadius + # shadowBlurSizeLimit = shadowBlur + # shadowSpreadLimit = shadowSpread + shadowBlurSize = shadowBlur + shadowSpread = shadowSpread + shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) + + let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread, 0.0, rect.w, rect.h) + + var ninePatchHashes: array[8, Hash] + for i in 0..7: + ninePatchHashes[i] = shadowKey !& i + + # Check if we've already generated this shadow + let shadowKeyBase = shadowKey !& 0 + # let newSize = max(shadowBlur.int + shadowSpread.int + maxRadius.int, 2) + let newSize = totalSize + + if shadowKeyBase notin ctx.entries: + const whiteColor = rgba(255, 255, 255, 255) + var center = vec2(rect.x + cbs.sideSize.float32, rect.y + cbs.sideSize.float32) + let wh = vec2(2*cbs.sideSize.float32, 2*cbs.sideSize.float32) + let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) + let shadowImg = newImage(newSize, newSize) + + if innerShadow: + let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) + # Generate shadow image + if mainKey notin shadowCache: + # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow + discard + else: + shadowImg = shadowCache[mainKey] + else: + let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) + # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow + if mainKey notin shadowCache: + drawSdfShape( + shadowImg, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = whiteColor, + neg = whiteColor, + factor = shadowBlur, + spread = shadowSpread, + mode = sdfModeDropShadow) + shadowCache[mainKey] = shadowImg + shadowImg + else: + shadowImg = shadowCache[mainKey] + + # Slice it into 9-patch pieces + let patches = sliceToNinePatch(shadowImg) + + # Store each piece in the atlas + let patchArray = [ + patches.topLeft, patches.topRight, + patches.bottomLeft, patches.bottomRight, + patches.top, patches.right, + patches.bottom, patches.left + ] + + for i in 0..7: + ninePatchHashes[i] = shadowKey !& i + ctx.putImage(ninePatchHashes[i], patchArray[i]) + + var + # totalPadding = int(shadowBlur+shadowSpread) - 1 + totalPadding = padding.int + corner = totalPadding.float32 + inner.float32/2 + 1 + + let + sbox = rect( + rect.x - totalPadding.float32 + shadowX, + rect.y - totalPadding.float32 + shadowY, + rect.w + 2 * totalPadding.float32, + rect.h + 2 * totalPadding.float32 + ) + halfW = sbox.w / 2 + halfH = sbox.h / 2 + centerX = sbox.x + halfW + centerY = sbox.y + halfH + + # Draw the corners + let + topLeft = rect(sbox.x, sbox.y, corner, corner) + topRight = rect(sbox.x + sbox.w - corner, sbox.y, corner, corner) + bottomLeft = rect(sbox.x, sbox.y + sbox.h - corner, corner, corner) + bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) + + # Draw corners + ctx.drawImageAdj(ninePatchHashes[0], topLeft.xy, shadowColor, topLeft.wh) + ctx.drawImageAdj(ninePatchHashes[1], topRight.xy, shadowColor, topRight.wh) + ctx.drawImageAdj(ninePatchHashes[2], bottomLeft.xy, shadowColor, bottomLeft.wh) + ctx.drawImageAdj(ninePatchHashes[3], bottomRight.xy, shadowColor, bottomRight.wh) + + # Draw edges + # Top edge (stretched horizontally) + let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) + ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) + let rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) + ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor*1.0, rightEdge.wh) + let bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) + ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor*1.0, bottomEdge.wh) + let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) + ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor*1.0, leftEdge.wh) + # Center (stretched both ways) let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) if not innerShadow: From f81ec1a111bd53cee5d440f32b19f87d8e6c130a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:49:03 -0600 Subject: [PATCH 027/225] update sdfy --- src/figuro/renderer/opengl/renderer.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 141fd324d..f3715ad61 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -118,7 +118,7 @@ proc renderDropShadows(ctx: Context, node: Node) = let box = node.screenBox.atXY(x = shadow.x + xblur, y = shadow.y + yblur) ctx.drawRoundedRect(rect = box, color = color, radius = node.cornerRadius) else: - ctx.fillRoundedRectWithShadow( + ctx.fillRoundedRectWithShadowSdf( rect = node.screenBox.atXY(0'f32, 0'f32), radii = node.cornerRadius, shadowX = shadow.x, diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index a17c8dacc..3eb1fea35 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -7,7 +7,7 @@ import ../../common/nodes/render import pkg/chroma import pkg/sigils import pkg/chronicles -import pkg/pixie/images +import pkg/pixie import pkg/sdfy import ../utils/boxes @@ -188,7 +188,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # shadowSpreadLimit = shadowSpread shadowBlurSize = shadowBlur shadowSpread = shadowSpread - shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) + shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit.float32, innerShadow) let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread, 0.0, rect.w, rect.h) @@ -206,10 +206,10 @@ proc fillRoundedRectWithShadowSdf*[R]( var center = vec2(rect.x + cbs.sideSize.float32, rect.y + cbs.sideSize.float32) let wh = vec2(2*cbs.sideSize.float32, 2*cbs.sideSize.float32) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) - let shadowImg = newImage(newSize, newSize) + let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit.float32, innerShadow) + var shadowImg = newImage(newSize, newSize) if innerShadow: - let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) # Generate shadow image if mainKey notin shadowCache: # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow @@ -217,7 +217,6 @@ proc fillRoundedRectWithShadowSdf*[R]( else: shadowImg = shadowCache[mainKey] else: - let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow if mainKey notin shadowCache: drawSdfShape( @@ -231,7 +230,8 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg - shadowImg + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " ", cbs.sideSize, "x", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")" + shadowImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") else: shadowImg = shadowCache[mainKey] From 5579b9042705af54fe6d2109b56d1b999c2c86a7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:57:42 -0600 Subject: [PATCH 028/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3eb1fea35..b318aa09d 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -181,14 +181,11 @@ proc fillRoundedRectWithShadowSdf*[R]( let radii = clampRadii(radii, rect) - # maxRadius = radiusLimit cbs = getCircleBoxSizes(radii, 0.0, 0.0, 0.0, rect.w, rect.h) - radiusLimit = cbs.maxRadius - # shadowBlurSizeLimit = shadowBlur - # shadowSpreadLimit = shadowSpread shadowBlurSize = shadowBlur shadowSpread = shadowSpread - shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit.float32, innerShadow) + maxRadius = cbs.maxRadius + shadowKey = getShadowKey(shadowBlurSize, shadowSpread, maxRadius.float32, innerShadow) let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread, 0.0, rect.w, rect.h) @@ -206,7 +203,7 @@ proc fillRoundedRectWithShadowSdf*[R]( var center = vec2(rect.x + cbs.sideSize.float32, rect.y + cbs.sideSize.float32) let wh = vec2(2*cbs.sideSize.float32, 2*cbs.sideSize.float32) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) - let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit.float32, innerShadow) + let mainKey = getShadowKey(shadowBlurSize, shadowSpread, maxRadius.float32, innerShadow) var shadowImg = newImage(newSize, newSize) if innerShadow: From 071eaede74698951e20d148857151b973f3f9b1c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 00:59:30 -0600 Subject: [PATCH 029/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index b318aa09d..6b3675566 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -186,8 +186,7 @@ proc fillRoundedRectWithShadowSdf*[R]( shadowSpread = shadowSpread maxRadius = cbs.maxRadius shadowKey = getShadowKey(shadowBlurSize, shadowSpread, maxRadius.float32, innerShadow) - - let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread, 0.0, rect.w, rect.h) + wh = vec2(2*cbs.totalSize.float32, 2*cbs.totalSize.float32) var ninePatchHashes: array[8, Hash] for i in 0..7: @@ -196,12 +195,11 @@ proc fillRoundedRectWithShadowSdf*[R]( # Check if we've already generated this shadow let shadowKeyBase = shadowKey !& 0 # let newSize = max(shadowBlur.int + shadowSpread.int + maxRadius.int, 2) - let newSize = totalSize + let newSize = cbs.totalSize if shadowKeyBase notin ctx.entries: const whiteColor = rgba(255, 255, 255, 255) - var center = vec2(rect.x + cbs.sideSize.float32, rect.y + cbs.sideSize.float32) - let wh = vec2(2*cbs.sideSize.float32, 2*cbs.sideSize.float32) + let center = vec2(rect.x + cbs.totalSize.float32, rect.y + cbs.totalSize.float32) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) let mainKey = getShadowKey(shadowBlurSize, shadowSpread, maxRadius.float32, innerShadow) var shadowImg = newImage(newSize, newSize) @@ -249,8 +247,8 @@ proc fillRoundedRectWithShadowSdf*[R]( var # totalPadding = int(shadowBlur+shadowSpread) - 1 - totalPadding = padding.int - corner = totalPadding.float32 + inner.float32/2 + 1 + totalPadding = cbs.padding.int + corner = totalPadding.float32 + cbs.sideSize.float32/2 + 1 let sbox = rect( From 5e3df9d6e736910563015d0ac7c11c3fbf5b041e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:01:18 -0600 Subject: [PATCH 030/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 6b3675566..bcd49efb5 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -225,8 +225,8 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " ", cbs.sideSize, "x", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")" - shadowImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")" + shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") else: shadowImg = shadowCache[mainKey] From 03e4f2bf7188fcb8109cab221e7b65f5d1929979 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:27:05 -0600 Subject: [PATCH 031/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 13 ++++++++++--- src/figuro/renderer/utils/drawshadows.nim | 14 ++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index bacfd1dcb..b94c28277 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -77,9 +77,16 @@ proc getCircleBoxSizes*( result.maxRadius = 0 for r in radii: result.maxRadius = max(result.maxRadius, r.ceil().int) - result.sideSize = max(result.maxRadius.min(width.ceil().int).min(height.ceil().int), int(1.5*weight.ceil())) - result.padding = spread.ceil().int + blur.ceil().int - result.totalSize = max(max(2*result.maxRadius + 2*result.padding, 4*result.padding), int(1.5*weight.ceil())) + let ww = int(1.5*weight.ceil()) + let bw = width.ceil().int + let bh = height.ceil().int + let blur = blur.ceil().int + let spread = spread.ceil().int + let padding = spread + blur + + result.padding = padding + result.sideSize = max(min(result.maxRadius, min(bw, bh)), ww).max(padding) + result.totalSize = max(ww, max(2*result.maxRadius + 2*padding, 4*padding)) result.inner = result.totalSize - 2*result.padding proc generateCircleBox*( diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index bcd49efb5..cccee4003 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -181,12 +181,10 @@ proc fillRoundedRectWithShadowSdf*[R]( let radii = clampRadii(radii, rect) - cbs = getCircleBoxSizes(radii, 0.0, 0.0, 0.0, rect.w, rect.h) - shadowBlurSize = shadowBlur - shadowSpread = shadowSpread + cbs = getCircleBoxSizes(radii, blur = shadowBlur, spread = shadowSpread, weight = 0.0, width = rect.w, height = rect.h) maxRadius = cbs.maxRadius - shadowKey = getShadowKey(shadowBlurSize, shadowSpread, maxRadius.float32, innerShadow) - wh = vec2(2*cbs.totalSize.float32, 2*cbs.totalSize.float32) + shadowKey = getShadowKey(shadowBlur, shadowSpread, maxRadius.float32, innerShadow) + wh = vec2(cbs.inner.float32/2, cbs.inner.float32/2) var ninePatchHashes: array[8, Hash] for i in 0..7: @@ -201,7 +199,7 @@ proc fillRoundedRectWithShadowSdf*[R]( const whiteColor = rgba(255, 255, 255, 255) let center = vec2(rect.x + cbs.totalSize.float32, rect.y + cbs.totalSize.float32) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) - let mainKey = getShadowKey(shadowBlurSize, shadowSpread, maxRadius.float32, innerShadow) + let mainKey = getShadowKey(shadowBlur, shadowSpread, maxRadius.float32, innerShadow) var shadowImg = newImage(newSize, newSize) if innerShadow: @@ -225,8 +223,8 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")" - shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius, " padding:", cbs.padding, " inner:", cbs.inner + shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") else: shadowImg = shadowCache[mainKey] From f8119cdaae64e42ad2f578f90f2a8b58a4382f48 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:40:12 -0600 Subject: [PATCH 032/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 5 +++-- src/figuro/renderer/utils/drawshadows.nim | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index b94c28277..7744aaa7f 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -85,9 +85,10 @@ proc getCircleBoxSizes*( let padding = spread + blur result.padding = padding - result.sideSize = max(min(result.maxRadius, min(bw, bh)), ww).max(padding) + result.sideSize = max(min(result.maxRadius, min(bw, bh)), ww) result.totalSize = max(ww, max(2*result.maxRadius + 2*padding, 4*padding)) - result.inner = result.totalSize - 2*result.padding + # result.inner = result.totalSize - 2*result.padding + result.inner = 2*result.sideSize proc generateCircleBox*( radii: array[DirectionCorners, float32], diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index cccee4003..d1745a1db 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -197,7 +197,7 @@ proc fillRoundedRectWithShadowSdf*[R]( if shadowKeyBase notin ctx.entries: const whiteColor = rgba(255, 255, 255, 255) - let center = vec2(rect.x + cbs.totalSize.float32, rect.y + cbs.totalSize.float32) + let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) let mainKey = getShadowKey(shadowBlur, shadowSpread, maxRadius.float32, innerShadow) var shadowImg = newImage(newSize, newSize) @@ -219,11 +219,11 @@ proc fillRoundedRectWithShadowSdf*[R]( params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur, + factor = shadowBlur * 0.8, spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius, " padding:", cbs.padding, " inner:", cbs.inner + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") else: shadowImg = shadowCache[mainKey] From 591f192fbf72e3345275c952e8de17c5ab9aad82 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:42:31 -0600 Subject: [PATCH 033/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index d1745a1db..2d96e82ea 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -219,7 +219,7 @@ proc fillRoundedRectWithShadowSdf*[R]( params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur * 0.8, + factor = shadowBlur * 0.6, spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg From e1d77eb433f456b381c4f60b672ba061e21cf97a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:43:05 -0600 Subject: [PATCH 034/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 7744aaa7f..681c20d5f 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -86,7 +86,7 @@ proc getCircleBoxSizes*( result.padding = padding result.sideSize = max(min(result.maxRadius, min(bw, bh)), ww) - result.totalSize = max(ww, max(2*result.maxRadius + 2*padding, 4*padding)) + result.totalSize = max(ww, max(2*result.maxRadius + 3*padding, 5*padding)) # result.inner = result.totalSize - 2*result.padding result.inner = 2*result.sideSize diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 2d96e82ea..d1745a1db 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -219,7 +219,7 @@ proc fillRoundedRectWithShadowSdf*[R]( params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur * 0.6, + factor = shadowBlur * 0.8, spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg From 539af94af334859d1f314c9c4e1ec360d3a7e18c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:45:46 -0600 Subject: [PATCH 035/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 681c20d5f..7744aaa7f 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -86,7 +86,7 @@ proc getCircleBoxSizes*( result.padding = padding result.sideSize = max(min(result.maxRadius, min(bw, bh)), ww) - result.totalSize = max(ww, max(2*result.maxRadius + 3*padding, 5*padding)) + result.totalSize = max(ww, max(2*result.maxRadius + 2*padding, 4*padding)) # result.inner = result.totalSize - 2*result.padding result.inner = 2*result.sideSize diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index d1745a1db..f070f69b2 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -219,12 +219,12 @@ proc fillRoundedRectWithShadowSdf*[R]( params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur * 0.8, + factor = shadowBlur * 0.7, spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") + # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") else: shadowImg = shadowCache[mainKey] From e9d36ee5ff085752d5187ab610d44cc3755c3ae1 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:47:34 -0600 Subject: [PATCH 036/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index f070f69b2..00c85a874 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -219,7 +219,7 @@ proc fillRoundedRectWithShadowSdf*[R]( params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur * 0.7, + factor = shadowBlur * 0.75, spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg From 0b0f378b5403ec06529489c73c2bbc0c8f86e17e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:47:53 -0600 Subject: [PATCH 037/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 00c85a874..9920b265a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -219,7 +219,7 @@ proc fillRoundedRectWithShadowSdf*[R]( params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur * 0.75, + factor = shadowBlur * 0.72, spread = shadowSpread, mode = sdfModeDropShadow) shadowCache[mainKey] = shadowImg From 94efe7d60ad4726634973c6ef78487816fb47314 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:49:53 -0600 Subject: [PATCH 038/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 9920b265a..5f777abb7 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -176,14 +176,15 @@ proc fillRoundedRectWithShadowSdf*[R]( # First, draw the shadow # Generate shadow key for caching - proc getShadowKey(blur: float32, spread: float32, radius: float32, innerShadow: bool): Hash = - hash((7723, (blur * 1).int, (spread * 1).int, (radius * 1).int, innerShadow)) + proc getShadowKey(blur: float32, spread: float32, innerShadow: bool): Hash = + hash((7723, (blur * 1).int, (spread * 1).int, innerShadow)) let radii = clampRadii(radii, rect) + rhash = radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int cbs = getCircleBoxSizes(radii, blur = shadowBlur, spread = shadowSpread, weight = 0.0, width = rect.w, height = rect.h) maxRadius = cbs.maxRadius - shadowKey = getShadowKey(shadowBlur, shadowSpread, maxRadius.float32, innerShadow) + shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow) !& rhash wh = vec2(cbs.inner.float32/2, cbs.inner.float32/2) var ninePatchHashes: array[8, Hash] From b7fccb115f72e50811ba8f803bb0014700754a98 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 01:56:57 -0600 Subject: [PATCH 039/225] update sdfy --- src/figuro/renderer/openglBackend.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 346f77bd0..08ab4a79e 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 1024 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 5f777abb7..539f3dd5b 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -200,34 +200,30 @@ proc fillRoundedRectWithShadowSdf*[R]( const whiteColor = rgba(255, 255, 255, 255) let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) - let mainKey = getShadowKey(shadowBlur, shadowSpread, maxRadius.float32, innerShadow) var shadowImg = newImage(newSize, newSize) if innerShadow: # Generate shadow image - if mainKey notin shadowCache: + if shadowKey notin shadowCache: # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow discard else: - shadowImg = shadowCache[mainKey] + shadowImg = shadowCache[shadowKey] else: # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow - if mainKey notin shadowCache: - drawSdfShape( + drawSdfShape( shadowImg, center = center, wh = wh, params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur * 0.72, + factor = shadowBlur * 0.6, spread = shadowSpread, mode = sdfModeDropShadow) - shadowCache[mainKey] = shadowImg - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") - else: - shadowImg = shadowCache[mainKey] + # shadowCache[shadowKey] = shadowImg + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius + # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) From c9c3bf35e8d30a92ec208409854c77a2c3117a4c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 02:00:15 -0600 Subject: [PATCH 040/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 7744aaa7f..6d353ad4b 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -85,9 +85,8 @@ proc getCircleBoxSizes*( let padding = spread + blur result.padding = padding - result.sideSize = max(min(result.maxRadius, min(bw, bh)), ww) + result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) result.totalSize = max(ww, max(2*result.maxRadius + 2*padding, 4*padding)) - # result.inner = result.totalSize - 2*result.padding result.inner = 2*result.sideSize proc generateCircleBox*( From 7b97218c9a1c5bb06b6fa232ce29c9823c08e9ce Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 02:03:15 -0600 Subject: [PATCH 041/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 539f3dd5b..5d74b1806 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -241,9 +241,9 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.putImage(ninePatchHashes[i], patchArray[i]) var - # totalPadding = int(shadowBlur+shadowSpread) - 1 totalPadding = cbs.padding.int - corner = totalPadding.float32 + cbs.sideSize.float32/2 + 1 + # corner = totalPadding.float32 + cbs.sideSize.float32/2 + 1 + corner = totalPadding.float32 + 1 let sbox = rect( From f57a3fa84a7edaa089e3809c369988053c34b63d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 02:09:01 -0600 Subject: [PATCH 042/225] update sdfy --- src/figuro/renderer/utils/boxes.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 6d353ad4b..15427dc29 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -82,11 +82,11 @@ proc getCircleBoxSizes*( let bh = height.ceil().int let blur = blur.ceil().int let spread = spread.ceil().int - let padding = spread + blur + let padding = max(spread + blur, result.maxRadius) result.padding = padding result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) - result.totalSize = max(ww, max(2*result.maxRadius + 2*padding, 4*padding)) + result.totalSize = 2*result.sidesize + 3*padding result.inner = 2*result.sideSize proc generateCircleBox*( From 3c9c580781b28348ef28da32877bcd3c35995b65 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 02:11:14 -0600 Subject: [PATCH 043/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 5d74b1806..99070d1e5 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -223,7 +223,7 @@ proc fillRoundedRectWithShadowSdf*[R]( mode = sdfModeDropShadow) # shadowCache[shadowKey] = shadowImg echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") + shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) From 6d696ad1ec299fc3fd5da92f39a270619fdaa657 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 23:16:56 -0600 Subject: [PATCH 044/225] update sdfy --- figuro.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/figuro.nimble b/figuro.nimble index abe0a7e5f..6625a84df 100644 --- a/figuro.nimble +++ b/figuro.nimble @@ -15,7 +15,7 @@ requires "bumpy" requires "pretty" requires "stew == 0.2.0" requires "chronicles >= 0.10.3" -requires "https://github.com/elcritch/sdfy >= 0.7.4" +requires "https://github.com/elcritch/sdfy >= 0.7.6" requires "supersnappy >= 2.1.3" requires "variant >= 0.2.12" requires "opengl >= 1.2.6" From 80969a96489da0eb0173a8a12e505e2064f66636 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 23:40:31 -0600 Subject: [PATCH 045/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 99070d1e5..15dfdaa25 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -176,15 +176,15 @@ proc fillRoundedRectWithShadowSdf*[R]( # First, draw the shadow # Generate shadow key for caching - proc getShadowKey(blur: float32, spread: float32, innerShadow: bool): Hash = - hash((7723, (blur * 1).int, (spread * 1).int, innerShadow)) + proc getShadowKey(blur: float32, spread: float32, innerShadow: bool, radii: array[DirectionCorners, float32]): Hash = + result = hash((7723, (blur * 1).int, (spread * 1).int, innerShadow)) + result = result !& radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int let radii = clampRadii(radii, rect) - rhash = radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int cbs = getCircleBoxSizes(radii, blur = shadowBlur, spread = shadowSpread, weight = 0.0, width = rect.w, height = rect.h) maxRadius = cbs.maxRadius - shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow) !& rhash + shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow, radii) wh = vec2(cbs.inner.float32/2, cbs.inner.float32/2) var ninePatchHashes: array[8, Hash] @@ -223,7 +223,7 @@ proc fillRoundedRectWithShadowSdf*[R]( mode = sdfModeDropShadow) # shadowCache[shadowKey] = shadowImg echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & ".png") + shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) @@ -242,8 +242,8 @@ proc fillRoundedRectWithShadowSdf*[R]( var totalPadding = cbs.padding.int - # corner = totalPadding.float32 + cbs.sideSize.float32/2 + 1 - corner = totalPadding.float32 + 1 + corner = totalPadding.float32 + cbs.sideSize.float32/2 + 1 + # corner = totalPadding.float32 + 1 let sbox = rect( From d3df867910697fa47347744940edbde7e84408dc Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 23:51:31 -0600 Subject: [PATCH 046/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 15dfdaa25..289e90cc7 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -182,10 +182,12 @@ proc fillRoundedRectWithShadowSdf*[R]( let radii = clampRadii(radii, rect) + shadowBlur = shadowBlur.ceil().float32 + shadowSpread = shadowSpread.ceil().float32 cbs = getCircleBoxSizes(radii, blur = shadowBlur, spread = shadowSpread, weight = 0.0, width = rect.w, height = rect.h) maxRadius = cbs.maxRadius shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow, radii) - wh = vec2(cbs.inner.float32/2, cbs.inner.float32/2) + wh = vec2(cbs.inner.float32, cbs.inner.float32) var ninePatchHashes: array[8, Hash] for i in 0..7: From 7ba5cb213e4def29d4b1498514e8c7943d241244 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 23:53:33 -0600 Subject: [PATCH 047/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 289e90cc7..e2874d863 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -244,7 +244,7 @@ proc fillRoundedRectWithShadowSdf*[R]( var totalPadding = cbs.padding.int - corner = totalPadding.float32 + cbs.sideSize.float32/2 + 1 + corner = totalPadding.float32 + cbs.sideSize.float32 + 1 # corner = totalPadding.float32 + 1 let From 129788110e19b3680c6b64524d2254346e7648e5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 23:53:46 -0600 Subject: [PATCH 048/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index e2874d863..bfe05a920 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -224,7 +224,7 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = shadowSpread, mode = sdfModeDropShadow) # shadowCache[shadowKey] = shadowImg - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius + # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces From 561e7ed52aeeb33d3a532089ee58dc136a33f364 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 23:57:08 -0600 Subject: [PATCH 049/225] update sdfy --- src/figuro/renderer/opengl/renderer.nim | 4 ++-- src/figuro/renderer/utils/drawextras.nim | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index f3715ad61..51d047f09 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -241,7 +241,7 @@ proc render( ctx.rotate(node.rotation / 180 * PI) ctx.translate(-node.screenBox.wh / 2) - ifrender node.kind == nkRectangle and node.shadow[DropShadow].blur > 0.0: + ifrender node.kind == nkRectangle and (node.shadow[DropShadow].blur > 0.0 or node.shadow[DropShadow].spread > 0.0): ctx.renderDropShadows(node) # handle clipping children content based on this node @@ -260,7 +260,7 @@ proc render( elif node.kind == nkRectangle: ctx.renderBoxes(node) - ifrender node.kind == nkRectangle and node.shadow[InnerShadow].blur > 0.0: + ifrender node.kind == nkRectangle and (node.shadow[InnerShadow].blur > 0.0 or node.shadow[InnerShadow].spread > 0.0): ctx.beginMask() ctx.drawMasks(node) ctx.endMask() diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 436fcbd0f..851034bd1 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -78,7 +78,7 @@ proc drawRoundedRect*[R]( # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) let circle = newImage(int(2*rw), int(2*rh)) - echo "drawing circle: ", doStroke, " sz:", rect.w, "x", rect.h, " ", rw, "x", rh, " weight: ", weight, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")", " rhash: ", rhash, " " + # echo "drawing circle: ", doStroke, " sz:", rect.w, "x", rect.h, " ", rw, "x", rh, " weight: ", weight, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")", " rhash: ", rhash, " " if doStroke: drawSdfShape(circle, center = center, From 4bb98d05652046330c2fbdc1c6181c4ac26e805a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 10 Jun 2025 23:59:15 -0600 Subject: [PATCH 050/225] update sdfy --- src/figuro/renderer/opengl/renderer.nim | 62 +++++++++++++------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 51d047f09..7a45a33c2 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -102,38 +102,42 @@ proc drawMasks(ctx: Context, node: Node) = proc renderDropShadows(ctx: Context, node: Node) = ## drawing shadows with 9-patch technique let shadow = node.shadow[DropShadow] - if shadow.blur > 0.0: - when FastShadows: - ## should add a primitive to opengl.context to - ## do this with pixie and 9-patch, but that's a headache - let shadow = node.shadow[DropShadow] - var color = shadow.color - const N = 3 - color.a = color.a * 1.0/(N*N*N) - let blurAmt = shadow.blur * shadow.spread / (12*N*N) - for i in -N .. N: - for j in -N .. N: - let xblur: float32 = i.toFloat() * blurAmt - let yblur: float32 = j.toFloat() * blurAmt - let box = node.screenBox.atXY(x = shadow.x + xblur, y = shadow.y + yblur) - ctx.drawRoundedRect(rect = box, color = color, radius = node.cornerRadius) - else: - ctx.fillRoundedRectWithShadowSdf( - rect = node.screenBox.atXY(0'f32, 0'f32), - radii = node.cornerRadius, - shadowX = shadow.x, - shadowY = shadow.y, - shadowBlur = shadow.blur, - shadowSpread = shadow.spread.float32, - shadowColor = shadow.color, - innerShadow = false, - ) + if shadow.blur <= 0.0 and shadow.spread <= 0.0: + return + + when FastShadows: + ## should add a primitive to opengl.context to + ## do this with pixie and 9-patch, but that's a headache + let shadow = node.shadow[DropShadow] + var color = shadow.color + const N = 3 + color.a = color.a * 1.0/(N*N*N) + let blurAmt = shadow.blur * shadow.spread / (12*N*N) + for i in -N .. N: + for j in -N .. N: + let xblur: float32 = i.toFloat() * blurAmt + let yblur: float32 = j.toFloat() * blurAmt + let box = node.screenBox.atXY(x = shadow.x + xblur, y = shadow.y + yblur) + ctx.drawRoundedRect(rect = box, color = color, radius = node.cornerRadius) + else: + ctx.fillRoundedRectWithShadowSdf( + rect = node.screenBox.atXY(0'f32, 0'f32), + radii = node.cornerRadius, + shadowX = shadow.x, + shadowY = shadow.y, + shadowBlur = shadow.blur, + shadowSpread = shadow.spread.float32, + shadowColor = shadow.color, + innerShadow = false, + ) proc renderInnerShadows(ctx: Context, node: Node) = ## drawing poor man's inner shadows ## this is even more incorrect than drop shadows, but it's something ## and I don't actually want to think today ;) - return + let shadow = node.shadow[InnerShadow] + if shadow.blur <= 0.0 and shadow.spread <= 0.0: + return when FastShadows: let shadow = node.shadow[InnerShadow] @@ -241,7 +245,7 @@ proc render( ctx.rotate(node.rotation / 180 * PI) ctx.translate(-node.screenBox.wh / 2) - ifrender node.kind == nkRectangle and (node.shadow[DropShadow].blur > 0.0 or node.shadow[DropShadow].spread > 0.0): + ifrender node.kind == nkRectangle: ctx.renderDropShadows(node) # handle clipping children content based on this node @@ -260,7 +264,7 @@ proc render( elif node.kind == nkRectangle: ctx.renderBoxes(node) - ifrender node.kind == nkRectangle and (node.shadow[InnerShadow].blur > 0.0 or node.shadow[InnerShadow].spread > 0.0): + ifrender node.kind == nkRectangle: ctx.beginMask() ctx.drawMasks(node) ctx.endMask() From 60299eb725c258b19c908e6b3895cdcde7dfd2d1 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 00:01:25 -0600 Subject: [PATCH 051/225] update sdfy --- src/figuro/renderer/opengl/renderer.nim | 5 +--- src/figuro/renderer/utils/drawshadows.nim | 35 +++++++++-------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 7a45a33c2..a0fe50f10 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -108,7 +108,6 @@ proc renderDropShadows(ctx: Context, node: Node) = when FastShadows: ## should add a primitive to opengl.context to ## do this with pixie and 9-patch, but that's a headache - let shadow = node.shadow[DropShadow] var color = shadow.color const N = 3 color.a = color.a * 1.0/(N*N*N) @@ -140,7 +139,6 @@ proc renderInnerShadows(ctx: Context, node: Node) = return when FastShadows: - let shadow = node.shadow[InnerShadow] let n = shadow.blur.toInt var color = shadow.color color.a = 2*color.a/n.toFloat @@ -164,9 +162,8 @@ proc renderInnerShadows(ctx: Context, node: Node) = radius = node.cornerRadius - blur, ) else: - let shadow = node.shadow[InnerShadow] var rect = node.screenBox.atXY(0'f32, 0'f32) - ctx.fillRoundedRectWithShadow( + ctx.fillRoundedRectWithShadowSdf( rect = node.screenBox.atXY(0'f32, 0'f32), radii = node.cornerRadius, shadowX = shadow.x, diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index bfe05a920..9e6f53677 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -204,28 +204,19 @@ proc fillRoundedRectWithShadowSdf*[R]( let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) var shadowImg = newImage(newSize, newSize) - if innerShadow: - # Generate shadow image - if shadowKey notin shadowCache: - # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow - discard - else: - shadowImg = shadowCache[shadowKey] - else: - # echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSizeLimit.round(2), " spread: ", shadowSpreadLimit.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow - drawSdfShape( - shadowImg, - center = center, - wh = wh, - params = RoundedBoxParams(r: corners), - pos = whiteColor, - neg = whiteColor, - factor = shadowBlur * 0.6, - spread = shadowSpread, - mode = sdfModeDropShadow) - # shadowCache[shadowKey] = shadowImg - # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow + drawSdfShape( + shadowImg, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = whiteColor, + neg = whiteColor, + factor = shadowBlur * 0.6, + spread = shadowSpread, + mode = sdfModeDropShadow) + # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius + # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) From ae09537dcf54992a782c3d82c71f974fdd07cbf8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 00:03:59 -0600 Subject: [PATCH 052/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 9e6f53677..1e6afe3d7 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -212,11 +212,11 @@ proc fillRoundedRectWithShadowSdf*[R]( params = RoundedBoxParams(r: corners), pos = whiteColor, neg = whiteColor, - factor = shadowBlur * 0.6, + factor = shadowBlur, spread = shadowSpread, - mode = sdfModeDropShadow) + mode = mode) # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) From f719cf209da3d9dcd817d461f25dce9289deadcd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 00:16:09 -0600 Subject: [PATCH 053/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 1e6afe3d7..be4fcfadd 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -216,7 +216,7 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = shadowSpread, mode = mode) # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) @@ -275,6 +275,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor*1.0, leftEdge.wh) # Center (stretched both ways) - let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) if not innerShadow: + let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) ctx.drawRect(center, shadowColor) \ No newline at end of file From 12342a19d9ef4f251af569537d578844dafc374b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 00:29:00 -0600 Subject: [PATCH 054/225] update sdfy --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index be4fcfadd..e51e9dc23 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -216,7 +216,7 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = shadowSpread, mode = mode) # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) From 69ed7e3c45667f95f2792bfcd0de08dd7b24eeff Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 16:03:13 -0600 Subject: [PATCH 055/225] update sdfy --- src/figuro/renderer/opengl/renderer.nim | 1 + src/figuro/renderer/utils/boxes.nim | 4 ++-- src/figuro/renderer/utils/drawshadows.nim | 8 +++++++- tests/tbutton.nim | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index a0fe50f10..a9d1f40f3 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -162,6 +162,7 @@ proc renderInnerShadows(ctx: Context, node: Node) = radius = node.cornerRadius - blur, ) else: + echo "inner shadow color: ", shadow.color var rect = node.screenBox.atXY(0'f32, 0'f32) ctx.fillRoundedRectWithShadowSdf( rect = node.screenBox.atXY(0'f32, 0'f32), diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 15427dc29..0f213a9cd 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -86,8 +86,8 @@ proc getCircleBoxSizes*( result.padding = padding result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) - result.totalSize = 2*result.sidesize + 3*padding - result.inner = 2*result.sideSize + result.totalSize = 3*result.sidesize + 3*padding + result.inner = 3*result.sideSize proc generateCircleBox*( radii: array[DirectionCorners, float32], diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index e51e9dc23..58b21409c 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -177,7 +177,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # First, draw the shadow # Generate shadow key for caching proc getShadowKey(blur: float32, spread: float32, innerShadow: bool, radii: array[DirectionCorners, float32]): Hash = - result = hash((7723, (blur * 1).int, (spread * 1).int, innerShadow)) + result = hash((7723, blur.int, spread.int, innerShadow)) result = result !& radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int let @@ -233,6 +233,9 @@ proc fillRoundedRectWithShadowSdf*[R]( ninePatchHashes[i] = shadowKey !& i ctx.putImage(ninePatchHashes[i], patchArray[i]) + if innerShadow: + echo "making inner shadow", " top left hash: ", ninePatchHashes[0], " shadow keybase: ", shadowKeyBase + var totalPadding = cbs.padding.int corner = totalPadding.float32 + cbs.sideSize.float32 + 1 @@ -263,6 +266,9 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(ninePatchHashes[2], bottomLeft.xy, shadowColor, bottomLeft.wh) ctx.drawImageAdj(ninePatchHashes[3], bottomRight.xy, shadowColor, bottomRight.wh) + if innerShadow: + echo "inner shadow", " top left hash: ", ninePatchHashes[0] + # Draw edges # Top edge (stretched horizontally) let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) diff --git a/tests/tbutton.nim b/tests/tbutton.nim index d68cc21b5..040cea66c 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -73,7 +73,7 @@ proc draw*(self: Main) {.slot.} = spread: self.fades[FkSpread].amount.UiScalar, x: self.fades[FkX].amount.UiScalar, y: self.fades[FkY].amount.UiScalar, - color: Color(r: 1.0, g: 1.0, b: 1.0, a: 0.6)) + color: Color(r: 1.0, g: 1.0, b: 1.0, a: 0.99)) Text.new "btnText": size 100'pp, 100'pp From 230b4603b0e1064c790b6eefa7976d38472c996d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 16:21:30 -0600 Subject: [PATCH 056/225] update sdfy --- src/figuro/renderer/opengl/renderer.nim | 8 ++++---- src/figuro/renderer/utils/drawshadows.nim | 10 ++++++---- tests/tbutton.nim | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index a9d1f40f3..ba1bb25c8 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -263,11 +263,11 @@ proc render( ctx.renderBoxes(node) ifrender node.kind == nkRectangle: - ctx.beginMask() - ctx.drawMasks(node) - ctx.endMask() + # ctx.beginMask() + # ctx.drawMasks(node) + # ctx.endMask() ctx.renderInnerShadows(node) - ctx.popMask() + # ctx.popMask() # restores the opengl context back to the parent node's (see above) ctx.restoreTransform() diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 58b21409c..f3b50592f 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -233,6 +233,8 @@ proc fillRoundedRectWithShadowSdf*[R]( ninePatchHashes[i] = shadowKey !& i ctx.putImage(ninePatchHashes[i], patchArray[i]) + patchArray[0].writeFile("tests/renderer-shadowImage-topleft-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + if innerShadow: echo "making inner shadow", " top left hash: ", ninePatchHashes[0], " shadow keybase: ", shadowKeyBase @@ -272,13 +274,13 @@ proc fillRoundedRectWithShadowSdf*[R]( # Draw edges # Top edge (stretched horizontally) let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) + # ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) let rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor*1.0, rightEdge.wh) + ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor, rightEdge.wh) let bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor*1.0, bottomEdge.wh) + ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor, bottomEdge.wh) let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor*1.0, leftEdge.wh) + # ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor, leftEdge.wh) # Center (stretched both ways) if not innerShadow: diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 040cea66c..f615992b9 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -52,7 +52,7 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 30'ux, 30'pp, 30'pp fill css"#2B9F2B" - border 5'ui, css"red" + # border 5'ui, css"red" corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, @@ -66,14 +66,14 @@ proc draw*(self: Main) {.slot.} = blur: self.fades[FkBlur].amount.UiScalar, spread: self.fades[FkSpread].amount.UiScalar, x: self.fades[FkX].amount.UiScalar, y: self.fades[FkY].amount.UiScalar, - color: Color(r: 0.0, g: 0.0, b: 0.0, a: 0.99)) + color: Color(r: 1.0, g: 0.0, b: 0.0, a: 0.99)) when true: this.shadow[InnerShadow] = Shadow( blur: self.fades[FkBlur].amount.UiScalar, spread: self.fades[FkSpread].amount.UiScalar, x: self.fades[FkX].amount.UiScalar, y: self.fades[FkY].amount.UiScalar, - color: Color(r: 1.0, g: 1.0, b: 1.0, a: 0.99)) + color: Color(r: 0.0, g: 0.0, b: 1.0, a: 0.99)) Text.new "btnText": size 100'pp, 100'pp From 42f9db9139a14c84778a6b9253e3bdd0a15e95ab Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 17:01:04 -0600 Subject: [PATCH 057/225] fix simd rgbx --- src/figuro/renderer/utils/drawshadows.nim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index f3b50592f..67912fcce 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -216,7 +216,7 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = shadowSpread, mode = mode) # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) @@ -233,10 +233,10 @@ proc fillRoundedRectWithShadowSdf*[R]( ninePatchHashes[i] = shadowKey !& i ctx.putImage(ninePatchHashes[i], patchArray[i]) - patchArray[0].writeFile("tests/renderer-shadowImage-topleft-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + # patchArray[0].writeFile("tests/renderer-shadowImage-topleft-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") - if innerShadow: - echo "making inner shadow", " top left hash: ", ninePatchHashes[0], " shadow keybase: ", shadowKeyBase + # if innerShadow: + # echo "making inner shadow", " top left hash: ", ninePatchHashes[0], " shadow keybase: ", shadowKeyBase var totalPadding = cbs.padding.int @@ -274,13 +274,13 @@ proc fillRoundedRectWithShadowSdf*[R]( # Draw edges # Top edge (stretched horizontally) let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) - # ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) + ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) let rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor, rightEdge.wh) let bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor, bottomEdge.wh) let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) - # ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor, leftEdge.wh) + ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor, leftEdge.wh) # Center (stretched both ways) if not innerShadow: From 92ea9da8bb39a30e1b0d7d87eda47a8e0cf75cdf Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 17:01:46 -0600 Subject: [PATCH 058/225] fix simd rgbx --- src/figuro/renderer/utils/drawshadows.nim | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 67912fcce..0573f968a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -268,9 +268,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(ninePatchHashes[2], bottomLeft.xy, shadowColor, bottomLeft.wh) ctx.drawImageAdj(ninePatchHashes[3], bottomRight.xy, shadowColor, bottomRight.wh) - if innerShadow: - echo "inner shadow", " top left hash: ", ninePatchHashes[0] - # Draw edges # Top edge (stretched horizontally) let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) From 613242a093fce0e6fd62853deeed7957e51ec6bc Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 17:04:54 -0600 Subject: [PATCH 059/225] fix simd rgbx --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- src/figuro/renderer/utils/drawutils.nim | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 0573f968a..55e393cc0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -182,8 +182,8 @@ proc fillRoundedRectWithShadowSdf*[R]( let radii = clampRadii(radii, rect) - shadowBlur = shadowBlur.ceil().float32 - shadowSpread = shadowSpread.ceil().float32 + shadowBlur = shadowBlur.round().float32 + shadowSpread = shadowSpread.round().float32 cbs = getCircleBoxSizes(radii, blur = shadowBlur, spread = shadowSpread, weight = 0.0, width = rect.w, height = rect.h) maxRadius = cbs.maxRadius shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow, radii) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index a4fd11ce3..812f1e5f9 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -20,4 +20,4 @@ proc hash(radii: array[DirectionCorners, float32]): Hash = proc clampRadii*(radii: array[DirectionCorners, float32], rect: Rect): array[DirectionCorners, float32] = result = radii for r in result.mitems(): - r = max(1.0, min(r, min(rect.w / 2, rect.h / 2))).ceil() + r = max(1.0, min(r, min(rect.w / 2, rect.h / 2))).round() From f2ca36692708b40c6e4f21a9b5638fa3fd440dd7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 17:10:08 -0600 Subject: [PATCH 060/225] fix simd rgbx --- src/figuro/renderer/opengl/renderer.nim | 1 - src/figuro/renderer/openglBackend.nim | 2 +- src/figuro/renderer/utils/boxes.nim | 6 +++++- src/figuro/renderer/utils/drawshadows.nim | 7 ++++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index ba1bb25c8..9f954ac42 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -162,7 +162,6 @@ proc renderInnerShadows(ctx: Context, node: Node) = radius = node.cornerRadius - blur, ) else: - echo "inner shadow color: ", shadow.color var rect = node.screenBox.atXY(0'f32, 0'f32) ctx.fillRoundedRectWithShadowSdf( rect = node.screenBox.atXY(0'f32, 0'f32), diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 08ab4a79e..9fc27829c 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 3072 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 0f213a9cd..1349b133a 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -73,6 +73,7 @@ proc getCircleBoxSizes*( weight: float32 = 0.0, width = float32.high(), height = float32.high(), + innerShadow = false, ): tuple[maxRadius, sideSize, totalSize, padding, inner: int] = result.maxRadius = 0 for r in radii: @@ -85,7 +86,10 @@ proc getCircleBoxSizes*( let padding = max(spread + blur, result.maxRadius) result.padding = padding - result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) + if innerShadow: + result.sideSize = min(result.maxRadius + padding, min(bw, bh)).max(ww) + else: + result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) result.totalSize = 3*result.sidesize + 3*padding result.inner = 3*result.sideSize diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 55e393cc0..3cbdfaba5 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -184,7 +184,12 @@ proc fillRoundedRectWithShadowSdf*[R]( radii = clampRadii(radii, rect) shadowBlur = shadowBlur.round().float32 shadowSpread = shadowSpread.round().float32 - cbs = getCircleBoxSizes(radii, blur = shadowBlur, spread = shadowSpread, weight = 0.0, width = rect.w, height = rect.h) + cbs = getCircleBoxSizes(radii, blur = shadowBlur, + spread = shadowSpread, + weight = 0.0, + width = rect.w, + height = rect.h, + innerShadow = innerShadow) maxRadius = cbs.maxRadius shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow, radii) wh = vec2(cbs.inner.float32, cbs.inner.float32) From d0562cb361c2fb91ea63b1346a6da1758d13d6d2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 17:10:24 -0600 Subject: [PATCH 061/225] update sdfy --- figuro.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/figuro.nimble b/figuro.nimble index 6625a84df..4048e5f53 100644 --- a/figuro.nimble +++ b/figuro.nimble @@ -15,7 +15,7 @@ requires "bumpy" requires "pretty" requires "stew == 0.2.0" requires "chronicles >= 0.10.3" -requires "https://github.com/elcritch/sdfy >= 0.7.6" +requires "https://github.com/elcritch/sdfy >= 0.7.7" requires "supersnappy >= 2.1.3" requires "variant >= 0.2.12" requires "opengl >= 1.2.6" From f5b7913519fa9f1094dbd812d790ba563c7c8c6e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 19:16:54 -0600 Subject: [PATCH 062/225] fix inset shadow insets - sse --- tests/tbutton.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tbutton.nim b/tests/tbutton.nim index f615992b9..26fe0b38f 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -52,7 +52,7 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 30'ux, 30'pp, 30'pp fill css"#2B9F2B" - # border 5'ui, css"red" + border 5'ui, css"darkgreen" corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From 68cf9e7c3a24a78206750de32ffd011388f25a37 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 19:31:37 -0600 Subject: [PATCH 063/225] fix inset shadow insets - sse --- src/figuro/renderer/utils/drawshadows.nim | 154 +--------------------- tests/tbutton.nim | 4 +- 2 files changed, 7 insertions(+), 151 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3cbdfaba5..7cdca8c55 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -15,152 +15,6 @@ import ./drawutils var shadowCache: Table[Hash, Image] = initTable[Hash, Image]() -proc fillRoundedRectWithShadow*[R]( - ctx: R, - rect: Rect, - radii: array[DirectionCorners, float32], - shadowX, shadowY, shadowBlur, shadowSpread: float32, - shadowColor: Color, - innerShadow = false, -) = - ## Draws a rounded rectangle with a shadow underneath using 9-patch technique - ## The shadow is drawn with padding around the main rectangle - if rect.w <= 0 or rect.h <= 0: - return - - # First, draw the shadow - # Generate shadow key for caching - proc getShadowKey(blur: float32, spread: float32, radius: float32, innerShadow: bool): Hash = - hash((7723, (blur * 1).int, (spread * 1).int, (radius * 1).int, innerShadow)) - - let - radii = clampRadii(radii, rect) - radiusLimit = max(radii) - # maxRadius = radiusLimit - shadowBlurSize = shadowBlur - shadowSpread = shadowSpread - shadowKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) - - let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, shadowBlur, shadowSpread, 0.0, rect.w, rect.h) - - var ninePatchHashes: array[8, Hash] - for i in 0..7: - ninePatchHashes[i] = shadowKey !& i - - # Check if we've already generated this shadow - let shadowKeyBase = shadowKey !& 0 - # let newSize = max(shadowBlur.int + shadowSpread.int + maxRadius.int, 2) - let newSize = totalSize - - if shadowKeyBase notin ctx.entries: - var shadowImg: Image = - if innerShadow: - let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) - # Generate shadow image - if mainKey notin shadowCache: - echo "generating main shadow image: ", mainKey, " blur: ", shadowBlurSize.round(2), " spread: ", shadowSpread.round(2), " radius: ", radiusLimit.round(2), " ", innerShadow - let mainImg = generateCircleBox( - radii = radii, - offset = vec2(0, 0), - spread = shadowSpread, - blur = shadowBlur, - stroked = true, - lineWidth = 1.0, - innerShadow = true, - outerShadow = false, - innerShadowBorder = true, - outerShadowFill = true, - ) - # mainImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & ".png") - shadowCache[mainKey] = mainImg - mainImg - else: - shadowCache[mainKey] - else: - let mainKey = getShadowKey(shadowBlurSize, shadowSpread, radiusLimit, innerShadow) - if mainKey notin shadowCache: - let mainImg = generateCircleBox( - radii = radii, - offset = vec2(0, 0), - spread = shadowSpread, - blur = shadowBlurSize, - stroked = false, - lineWidth = 1.0, - outerShadow = true, - innerShadow = false, - innerShadowBorder = true, - outerShadowFill = false, - ) - # mainImg.writeFile("examples/renderer-shadowImage-" & $innerShadow & ".png") - shadowCache[mainKey] = mainImg - mainImg - else: - shadowCache[mainKey] - - if shadowImg.width != newSize or shadowImg.height != newSize: - shadowImg = shadowImg.resize(newSize, newSize) - - # Slice it into 9-patch pieces - let patches = sliceToNinePatch(shadowImg) - - # Store each piece in the atlas - let patchArray = [ - patches.topLeft, patches.topRight, - patches.bottomLeft, patches.bottomRight, - patches.top, patches.right, - patches.bottom, patches.left - ] - - for i in 0..7: - ninePatchHashes[i] = shadowKey !& i - ctx.putImage(ninePatchHashes[i], patchArray[i]) - - var - # totalPadding = int(shadowBlur+shadowSpread) - 1 - totalPadding = padding.int - corner = totalPadding.float32 + inner.float32/2 + 1 - - let - sbox = rect( - rect.x - totalPadding.float32 + shadowX, - rect.y - totalPadding.float32 + shadowY, - rect.w + 2 * totalPadding.float32, - rect.h + 2 * totalPadding.float32 - ) - halfW = sbox.w / 2 - halfH = sbox.h / 2 - centerX = sbox.x + halfW - centerY = sbox.y + halfH - - # Draw the corners - let - topLeft = rect(sbox.x, sbox.y, corner, corner) - topRight = rect(sbox.x + sbox.w - corner, sbox.y, corner, corner) - bottomLeft = rect(sbox.x, sbox.y + sbox.h - corner, corner, corner) - bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) - - # Draw corners - ctx.drawImageAdj(ninePatchHashes[0], topLeft.xy, shadowColor, topLeft.wh) - ctx.drawImageAdj(ninePatchHashes[1], topRight.xy, shadowColor, topRight.wh) - ctx.drawImageAdj(ninePatchHashes[2], bottomLeft.xy, shadowColor, bottomLeft.wh) - ctx.drawImageAdj(ninePatchHashes[3], bottomRight.xy, shadowColor, bottomRight.wh) - - # Draw edges - # Top edge (stretched horizontally) - let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) - let rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor*1.0, rightEdge.wh) - let bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor*1.0, bottomEdge.wh) - let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor*1.0, leftEdge.wh) - - # Center (stretched both ways) - let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) - if not innerShadow: - ctx.drawRect(center, shadowColor) - proc fillRoundedRectWithShadowSdf*[R]( ctx: R, rect: Rect, @@ -208,6 +62,8 @@ proc fillRoundedRectWithShadowSdf*[R]( let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) var shadowImg = newImage(newSize, newSize) + let wh = if innerShadow: vec2(cbs.inner.float32 - 2*shadowSpread, cbs.inner.float32 - 2*shadowSpread) else: vec2(cbs.inner.float32, cbs.inner.float32) + let spread = if innerShadow: 0.0 else: shadowSpread let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow drawSdfShape( @@ -218,10 +74,10 @@ proc fillRoundedRectWithShadowSdf*[R]( pos = whiteColor, neg = whiteColor, factor = shadowBlur, - spread = shadowSpread, + spread = spread, mode = mode) - # echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius + shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 26fe0b38f..d6b4bdd33 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -20,7 +20,7 @@ type proc initialize*(self: Main) {.slot.} = for kd in FadeKinds: self.toggles[kd] = true - self.fades[kd] = Fader(minMax: 0.01..22.0, + self.fades[kd] = Fader(minMax: 0.0..34.0, inTimeMs: 1400, outTimeMs: 1400) self.fades[FkTopLeft] = Fader(minMax: 2.0..8.0, inTimeMs: 1400, outTimeMs: 1400) @@ -50,7 +50,7 @@ proc draw*(self: Main) {.slot.} = self.toggles[this.state] = not self.toggles[this.state] Button[int] as "btn": - box 40'ux, 30'ux, 30'pp, 30'pp + box 50'ux, 40'ux, 30'pp, 30'pp fill css"#2B9F2B" border 5'ui, css"darkgreen" corners topLeft = self.fades[FkTopLeft].amount.UiScalar, From 07cdb6eb02a37f3fea9101c45fec56d90b95a987 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 19:36:02 -0600 Subject: [PATCH 064/225] fix inset shadow insets - sse --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 7cdca8c55..a20583fc2 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -76,8 +76,8 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius - shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius, " -rTL:", radii[dcTopLeft], " -rTR:", radii[dcTopRight], " -rBL:", radii[dcBottomLeft], " -rBR:", radii[dcBottomRight] + # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) From ad6ba5ae8a53335c1441f33c6cac04fcc400b35d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 20:39:51 -0600 Subject: [PATCH 065/225] css update --- tests/twidget.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/twidget.css b/tests/twidget.css index 39a0ba905..2d679b7d9 100644 --- a/tests/twidget.css +++ b/tests/twidget.css @@ -14,7 +14,7 @@ Dropdown { TextButton { border-radius: 10px; - box-shadow: 2px 2px 1px 1px rgba(0, 0, 0, 0.2); + box-shadow: 3px 4px 4px -3px rgba(0, 0, 0, 0.30); box-shadow: 2px 2px 6px 0px rgba(255, 255, 255, 0.07) inset; } From b5144aad308aa38704a2da5eb79e98af23c598f2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 11 Jun 2025 20:40:07 -0600 Subject: [PATCH 066/225] renderer update --- src/figuro/renderer/opengl/renderer.nim | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 9f954ac42..9b54e8163 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -262,11 +262,14 @@ proc render( ctx.renderBoxes(node) ifrender node.kind == nkRectangle: - # ctx.beginMask() - # ctx.drawMasks(node) - # ctx.endMask() - ctx.renderInnerShadows(node) - # ctx.popMask() + if NfClipContent notin node.flags: + ctx.beginMask() + ctx.drawMasks(node) + ctx.endMask() + ctx.renderInnerShadows(node) + ctx.popMask() + else: + ctx.renderInnerShadows(node) # restores the opengl context back to the parent node's (see above) ctx.restoreTransform() From 1742676f63eccb5b6c229156bb34d271a316605e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 15 Jun 2025 22:11:16 -0600 Subject: [PATCH 067/225] updates --- .github/workflows/build-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index b2c3252b9..dc9b0dadc 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -30,7 +30,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble + nimble install nimble@0.18.4 nim -v nimble -v From 7e5d159ef48c1142b1f7af7ec417a3f908368943 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 15 Jun 2025 22:12:00 -0600 Subject: [PATCH 068/225] updates --- .github/workflows/build-full.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-full.yml b/.github/workflows/build-full.yml index 12453c8d4..5f0b3914a 100644 --- a/.github/workflows/build-full.yml +++ b/.github/workflows/build-full.yml @@ -33,7 +33,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble + nimble install nimble@0.18.4 nim -v nimble -v From 99427cfd7e9ff2ea5984acafa12b3cff5b0d7fe9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 15 Jun 2025 22:15:01 -0600 Subject: [PATCH 069/225] updates --- src/figuro/renderer/utils/drawshadows.nim | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index a20583fc2..acdc8c7ce 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -84,10 +84,14 @@ proc fillRoundedRectWithShadowSdf*[R]( # Store each piece in the atlas let patchArray = [ - patches.topLeft, patches.topRight, - patches.bottomLeft, patches.bottomRight, - patches.top, patches.right, - patches.bottom, patches.left + patches.topLeft, + patches.topRight, + patches.bottomLeft, + patches.bottomRight, + patches.top, + patches.right, + patches.bottom, + patches.left, ] for i in 0..7: @@ -95,7 +99,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.putImage(ninePatchHashes[i], patchArray[i]) # patchArray[0].writeFile("tests/renderer-shadowImage-topleft-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") - # if innerShadow: # echo "making inner shadow", " top left hash: ", ninePatchHashes[0], " shadow keybase: ", shadowKeyBase From 00e201138d974baa4d11f0f60713ac7663b06310 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 15 Jun 2025 22:45:13 -0600 Subject: [PATCH 070/225] refactor to enum loops --- src/figuro/renderer/utils/drawshadows.nim | 87 ++++++++++++++--------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index acdc8c7ce..e24e168df 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -32,7 +32,12 @@ proc fillRoundedRectWithShadowSdf*[R]( # Generate shadow key for caching proc getShadowKey(blur: float32, spread: float32, innerShadow: bool, radii: array[DirectionCorners, float32]): Hash = result = hash((7723, blur.int, spread.int, innerShadow)) - result = result !& radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int + + proc getShadowKey(shadowKey: Hash, radii: array[DirectionCorners, float32], corner: DirectionCorners): Hash = + result = shadowKey !& hash(2474431) !& hash(radii[corner].int) !& hash(corner.int) + + proc getShadowKey(shadowKey: Hash, radii: array[Directions, float32], side: Directions): Hash = + result = shadowKey !& hash(971767) !& hash(side.int) let radii = clampRadii(radii, rect) @@ -48,16 +53,19 @@ proc fillRoundedRectWithShadowSdf*[R]( shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow, radii) wh = vec2(cbs.inner.float32, cbs.inner.float32) - var ninePatchHashes: array[8, Hash] - for i in 0..7: - ninePatchHashes[i] = shadowKey !& i + var cornerHashes: array[DirectionCorners, Hash] + for corner in DirectionCorners: + cornerHashes[corner] = getShadowKey(shadowKey, radii, corner) - # Check if we've already generated this shadow - let shadowKeyBase = shadowKey !& 0 - # let newSize = max(shadowBlur.int + shadowSpread.int + maxRadius.int, 2) + var sideHashes: array[Directions, Hash] + for side in Directions: + sideHashes[side] = getShadowKey(shadowKey, radii, side) + + # use the left side of the shadow key to check if we've already generated this shadow let newSize = cbs.totalSize + let shadowKeyLeft = getShadowKey(shadowKey, radii, dLeft) - if shadowKeyBase notin ctx.entries: + if shadowKeyLeft notin ctx.entries: const whiteColor = rgba(255, 255, 255, 255) let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) @@ -81,22 +89,31 @@ proc fillRoundedRectWithShadowSdf*[R]( # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) - - # Store each piece in the atlas - let patchArray = [ - patches.topLeft, - patches.topRight, - patches.bottomLeft, - patches.bottomRight, - patches.top, - patches.right, - patches.bottom, - patches.left, + let cornerArray = [ + dcTopLeft: patches.topLeft, + dcTopRight: patches.topRight, + dcBottomRight: patches.bottomRight, + dcBottomLeft: patches.bottomLeft, ] + let sideArray = [ + dTop: patches.top, + dRight: patches.right, + dBottom: patches.bottom, + dLeft: patches.left, + ] + + var radiisDone: array[DirectionCorners, float32] = [NaN.float32, NaN.float32, NaN.float32, NaN.float32] + for corner in DirectionCorners: + let cornerHash = getShadowKey(shadowKey, radii, corner) + ctx.putImage(cornerHash, cornerArray[corner]) + # if radii[corner] notin radiisDone: + # let cornerHash = getShadowKey(shadowKey, radii, corner) + # ctx.putImage(cornerHash, patchArray[corner]) + # radiisDone[corner] = radii[corner] - for i in 0..7: - ninePatchHashes[i] = shadowKey !& i - ctx.putImage(ninePatchHashes[i], patchArray[i]) + for side in Directions: + let sideHash = getShadowKey(shadowKey, radii, side) + ctx.putImage(sideHash, sideArray[side]) # patchArray[0].writeFile("tests/renderer-shadowImage-topleft-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # if innerShadow: @@ -127,21 +144,23 @@ proc fillRoundedRectWithShadowSdf*[R]( bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) # Draw corners - ctx.drawImageAdj(ninePatchHashes[0], topLeft.xy, shadowColor, topLeft.wh) - ctx.drawImageAdj(ninePatchHashes[1], topRight.xy, shadowColor, topRight.wh) - ctx.drawImageAdj(ninePatchHashes[2], bottomLeft.xy, shadowColor, bottomLeft.wh) - ctx.drawImageAdj(ninePatchHashes[3], bottomRight.xy, shadowColor, bottomRight.wh) + ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) + ctx.drawImageAdj(cornerHashes[dcTopRight], topRight.xy, shadowColor, topRight.wh) + ctx.drawImageAdj(cornerHashes[dcBottomLeft], bottomLeft.xy, shadowColor, bottomLeft.wh) + ctx.drawImageAdj(cornerHashes[dcBottomRight], bottomRight.xy, shadowColor, bottomRight.wh) # Draw edges # Top edge (stretched horizontally) - let topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[4], topEdge.xy, shadowColor, topEdge.wh) - let rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[5], rightEdge.xy, shadowColor, rightEdge.wh) - let bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) - ctx.drawImageAdj(ninePatchHashes[6], bottomEdge.xy, shadowColor, bottomEdge.wh) - let leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) - ctx.drawImageAdj(ninePatchHashes[7], leftEdge.xy, shadowColor, leftEdge.wh) + let + topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) + rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) + bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) + leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) + + ctx.drawImageAdj(sideHashes[dTop], topEdge.xy, shadowColor, topEdge.wh) + ctx.drawImageAdj(sideHashes[dRight], rightEdge.xy, shadowColor, rightEdge.wh) + ctx.drawImageAdj(sideHashes[dBottom], bottomEdge.xy, shadowColor, bottomEdge.wh) + ctx.drawImageAdj(sideHashes[dLeft], leftEdge.xy, shadowColor, leftEdge.wh) # Center (stretched both ways) if not innerShadow: From d68c95ee142587f48aa39d2c8ea0f385509f126f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 15 Jun 2025 23:40:54 -0600 Subject: [PATCH 071/225] change to non-transform offset --- src/figuro/renderer/opengl/renderer.nim | 59 ++++++++++++----------- src/figuro/renderer/utils/drawextras.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 55 +++++++++++++++------ tests/tbutton.nim | 6 +-- 4 files changed, 76 insertions(+), 46 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 9b54e8163..9b562c25f 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -90,13 +90,13 @@ macro postRender() = proc drawMasks(ctx: Context, node: Node) = if node.cornerRadius != [0'f32, 0'f32, 0'f32, 0'f32]: ctx.drawRoundedRect( - rect(0, 0, node.screenBox.w, node.screenBox.h), + node.screenBox, rgba(255, 0, 0, 255).color, node.cornerRadius, ) else: ctx.drawRect( - rect(0, 0, node.screenBox.w, node.screenBox.h), rgba(255, 0, 0, 255).color + node.screenBox, rgba(255, 0, 0, 255).color ) proc renderDropShadows(ctx: Context, node: Node) = @@ -120,7 +120,7 @@ proc renderDropShadows(ctx: Context, node: Node) = ctx.drawRoundedRect(rect = box, color = color, radius = node.cornerRadius) else: ctx.fillRoundedRectWithShadowSdf( - rect = node.screenBox.atXY(0'f32, 0'f32), + rect = node.screenBox, radii = node.cornerRadius, shadowX = shadow.x, shadowY = shadow.y, @@ -145,7 +145,7 @@ proc renderInnerShadows(ctx: Context, node: Node) = let blurAmt = shadow.blur / n.toFloat for i in 0 .. n: let blur: float32 = i.toFloat() * blurAmt - var box = node.screenBox.atXY(x = 0'f32, y = 0'f32) + var box = node.screenBox # var box = node.screenBox.atXY(x = shadow.x, y = shadow.y) if shadow.x >= 0'f32: box.w += shadow.x @@ -162,9 +162,8 @@ proc renderInnerShadows(ctx: Context, node: Node) = radius = node.cornerRadius - blur, ) else: - var rect = node.screenBox.atXY(0'f32, 0'f32) ctx.fillRoundedRectWithShadowSdf( - rect = node.screenBox.atXY(0'f32, 0'f32), + rect = node.screenBox, radii = node.cornerRadius, shadowX = shadow.x, shadowY = shadow.y, @@ -176,26 +175,27 @@ proc renderInnerShadows(ctx: Context, node: Node) = proc renderBoxes(ctx: Context, node: Node) = ## drawing boxes for rectangles + if node.fill.a > 0'f32: if node.cornerRadius != [0'f32, 0'f32, 0'f32, 0'f32]: discard ctx.drawRoundedRect( - rect = node.screenBox.atXY(0'f32, 0'f32), + rect = node.screenBox, color = node.fill, radii = node.cornerRadius, ) else: - ctx.drawRect(node.screenBox.atXY(0'f32, 0'f32), node.fill) + ctx.drawRect(node.screenBox, node.fill) if node.highlight.a > 0'f32: if node.cornerRadius != [0'f32, 0'f32, 0'f32, 0'f32]: ctx.drawRoundedRect( - rect = node.screenBox.atXY(0'f32, 0'f32), + rect = node.screenBox, color = node.highlight, radii = node.cornerRadius, ) else: - ctx.drawRect(node.screenBox.atXY(0'f32, 0'f32), node.highlight) + ctx.drawRect(node.screenBox, node.highlight) if node.image.id.int != 0: let size = vec2(node.screenBox.w, node.screenBox.h) @@ -204,7 +204,7 @@ proc renderBoxes(ctx: Context, node: Node) = if node.stroke.color.a > 0 and node.stroke.weight > 0: ctx.drawRoundedRect( - rect = node.screenBox.atXY(0'f32, 0'f32), + rect = node.screenBox, color = node.stroke.color, radii = node.cornerRadius, weight = node.stroke.weight, @@ -233,8 +233,8 @@ proc render( # setup the opengl context to match the current node size and position - ctx.saveTransform() - ctx.translate(node.screenBox.xy) + # ctx.saveTransform() + # ctx.translate(node.screenBox.xy) # handle node rotation ifrender node.rotation != 0: @@ -246,33 +246,36 @@ proc render( ctx.renderDropShadows(node) # handle clipping children content based on this node - ifrender NfClipContent in node.flags: - ctx.beginMask() - ctx.drawMasks(node) - ctx.endMask() - finally: - ctx.popMask() + # ifrender NfClipContent in node.flags: + # ctx.beginMask() + # ctx.drawMasks(node) + # ctx.endMask() + # finally: + # ctx.popMask() ifrender true: if node.kind == nkText: + ctx.saveTransform() + ctx.translate(node.screenBox.xy) ctx.renderText(node) + ctx.restoreTransform() elif node.kind == nkDrawable: ctx.renderDrawable(node) elif node.kind == nkRectangle: ctx.renderBoxes(node) ifrender node.kind == nkRectangle: - if NfClipContent notin node.flags: - ctx.beginMask() - ctx.drawMasks(node) - ctx.endMask() - ctx.renderInnerShadows(node) - ctx.popMask() - else: - ctx.renderInnerShadows(node) + # if NfClipContent notin node.flags: + # ctx.beginMask() + # ctx.drawMasks(node) + # ctx.endMask() + # ctx.renderInnerShadows(node) + # ctx.popMask() + # else: + ctx.renderInnerShadows(node) # restores the opengl context back to the parent node's (see above) - ctx.restoreTransform() + # ctx.restoreTransform() for childIdx in childIndex(nodes, nodeIdx): ctx.render(nodes, childIdx, nodeIdx) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 851034bd1..bd5cc1762 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -73,7 +73,7 @@ proc drawRoundedRect*[R]( block: let fill = rgba(255, 255, 255, 255) let clear = rgba(0, 0, 0, 0) - var center = vec2(rect.x + rw, rect.y + rh) + var center = vec2(rw, rh) let wh = vec2(2*rw+1, 2*rh+1) # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index e24e168df..a73e15209 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -34,7 +34,7 @@ proc fillRoundedRectWithShadowSdf*[R]( result = hash((7723, blur.int, spread.int, innerShadow)) proc getShadowKey(shadowKey: Hash, radii: array[DirectionCorners, float32], corner: DirectionCorners): Hash = - result = shadowKey !& hash(2474431) !& hash(radii[corner].int) !& hash(corner.int) + result = shadowKey !& hash(2474431) !& hash(radii[corner].int) proc getShadowKey(shadowKey: Hash, radii: array[Directions, float32], side: Directions): Hash = result = shadowKey !& hash(971767) !& hash(side.int) @@ -104,12 +104,21 @@ proc fillRoundedRectWithShadowSdf*[R]( var radiisDone: array[DirectionCorners, float32] = [NaN.float32, NaN.float32, NaN.float32, NaN.float32] for corner in DirectionCorners: - let cornerHash = getShadowKey(shadowKey, radii, corner) - ctx.putImage(cornerHash, cornerArray[corner]) - # if radii[corner] notin radiisDone: - # let cornerHash = getShadowKey(shadowKey, radii, corner) - # ctx.putImage(cornerHash, patchArray[corner]) - # radiisDone[corner] = radii[corner] + if radii[corner] notin radiisDone: + let cornerHash = getShadowKey(shadowKey, radii, corner) + let image = cornerArray[corner] + case corner: + of dcTopLeft: + discard + of dcTopRight: + image.flipHorizontal() + of dcBottomRight: + image.flipVertical() + of dcBottomLeft: + image.flipHorizontal() + image.flipVertical() + ctx.putImage(cornerHash, image) + radiisDone[corner] = radii[corner] for side in Directions: let sideHash = getShadowKey(shadowKey, radii, side) @@ -138,17 +147,35 @@ proc fillRoundedRectWithShadowSdf*[R]( # Draw the corners let + zero = vec2(0, 0) topLeft = rect(sbox.x, sbox.y, corner, corner) topRight = rect(sbox.x + sbox.w - corner, sbox.y, corner, corner) bottomLeft = rect(sbox.x, sbox.y + sbox.h - corner, corner, corner) bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) # Draw corners + ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) - ctx.drawImageAdj(cornerHashes[dcTopRight], topRight.xy, shadowColor, topRight.wh) - ctx.drawImageAdj(cornerHashes[dcBottomLeft], bottomLeft.xy, shadowColor, bottomLeft.wh) - ctx.drawImageAdj(cornerHashes[dcBottomRight], bottomRight.xy, shadowColor, bottomRight.wh) - + + ctx.saveTransform() + ctx.translate(vec2(-topRight.w, topRight.h)) + ctx.rotate(-Pi/2) + # ctx.translate(-topRight.xy) + ctx.drawImageAdj(cornerHashes[dcTopRight], zero, shadowColor, topRight.wh) + ctx.restoreTransform() + + ctx.saveTransform() + # ctx.rotate(Pi/2) + ctx.translate(bottomLeft.xy) + ctx.drawImageAdj(cornerHashes[dcBottomLeft], zero, shadowColor, bottomLeft.wh) + ctx.restoreTransform() + + ctx.saveTransform() + # ctx.rotate(Pi/2) + ctx.translate(bottomRight.xy) + ctx.drawImageAdj(cornerHashes[dcBottomRight], zero, shadowColor, bottomRight.wh) + ctx.restoreTransform() + # Draw edges # Top edge (stretched horizontally) let @@ -163,6 +190,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(sideHashes[dLeft], leftEdge.xy, shadowColor, leftEdge.wh) # Center (stretched both ways) - if not innerShadow: - let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) - ctx.drawRect(center, shadowColor) \ No newline at end of file + # if not innerShadow: + # let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) + # ctx.drawRect(center, shadowColor) \ No newline at end of file diff --git a/tests/tbutton.nim b/tests/tbutton.nim index d6b4bdd33..432bfa565 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -50,9 +50,9 @@ proc draw*(self: Main) {.slot.} = self.toggles[this.state] = not self.toggles[this.state] Button[int] as "btn": - box 50'ux, 40'ux, 30'pp, 30'pp - fill css"#2B9F2B" - border 5'ui, css"darkgreen" + box 20'pp, 20'pp, 30'pp, 30'pp + fill css"#2B9F2B" * 0.5 + border 5'ui, css"darkgreen" * 0.5 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From f21025d82de1afb33b5d7d0d88542349906c049e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:10:55 -0600 Subject: [PATCH 072/225] reuse sides --- src/figuro/renderer/opengl/renderer.nim | 2 ++ src/figuro/renderer/utils/drawshadows.nim | 11 ++++++----- tests/tbutton.nim | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 9b562c25f..394348bbd 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -134,6 +134,8 @@ proc renderInnerShadows(ctx: Context, node: Node) = ## drawing poor man's inner shadows ## this is even more incorrect than drop shadows, but it's something ## and I don't actually want to think today ;) + if true: + return let shadow = node.shadow[InnerShadow] if shadow.blur <= 0.0 and shadow.spread <= 0.0: return diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index a73e15209..6b2b3d1b4 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -30,8 +30,8 @@ proc fillRoundedRectWithShadowSdf*[R]( # First, draw the shadow # Generate shadow key for caching - proc getShadowKey(blur: float32, spread: float32, innerShadow: bool, radii: array[DirectionCorners, float32]): Hash = - result = hash((7723, blur.int, spread.int, innerShadow)) + proc getShadowKey(blur: float32, spread: float32, totalSize: int, innerShadow: bool, radii: array[DirectionCorners, float32]): Hash = + result = hash((7723, blur.int, spread.int, innerShadow, totalSize)) proc getShadowKey(shadowKey: Hash, radii: array[DirectionCorners, float32], corner: DirectionCorners): Hash = result = shadowKey !& hash(2474431) !& hash(radii[corner].int) @@ -50,7 +50,7 @@ proc fillRoundedRectWithShadowSdf*[R]( height = rect.h, innerShadow = innerShadow) maxRadius = cbs.maxRadius - shadowKey = getShadowKey(shadowBlur, shadowSpread, innerShadow, radii) + shadowKey = getShadowKey(shadowBlur, shadowSpread, cbs.totalSize, innerShadow, radii) wh = vec2(cbs.inner.float32, cbs.inner.float32) var cornerHashes: array[DirectionCorners, Hash] @@ -158,9 +158,10 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) ctx.saveTransform() - ctx.translate(vec2(-topRight.w, topRight.h)) + # ctx.translate(vec2(+topRight.w/2, topRight.h/2)) + ctx.translate(topRight.xy + topRight.wh / 2) ctx.rotate(-Pi/2) - # ctx.translate(-topRight.xy) + ctx.translate(-topRight.wh / 2) ctx.drawImageAdj(cornerHashes[dcTopRight], zero, shadowColor, topRight.wh) ctx.restoreTransform() diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 432bfa565..c5ad17f0e 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -66,14 +66,14 @@ proc draw*(self: Main) {.slot.} = blur: self.fades[FkBlur].amount.UiScalar, spread: self.fades[FkSpread].amount.UiScalar, x: self.fades[FkX].amount.UiScalar, y: self.fades[FkY].amount.UiScalar, - color: Color(r: 1.0, g: 0.0, b: 0.0, a: 0.99)) + color: Color(r: 1.0, g: 0.0, b: 0.0, a: 0.4)) when true: this.shadow[InnerShadow] = Shadow( blur: self.fades[FkBlur].amount.UiScalar, spread: self.fades[FkSpread].amount.UiScalar, x: self.fades[FkX].amount.UiScalar, y: self.fades[FkY].amount.UiScalar, - color: Color(r: 0.0, g: 0.0, b: 1.0, a: 0.99)) + color: Color(r: 0.0, g: 0.0, b: 1.0, a: 0.4)) Text.new "btnText": size 100'pp, 100'pp From 24893e6d326b4dd34c1bf43f7b3dcd63060a0f14 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:12:48 -0600 Subject: [PATCH 073/225] reuse sides --- src/figuro/renderer/utils/drawshadows.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 6b2b3d1b4..96349289c 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -166,8 +166,9 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.restoreTransform() ctx.saveTransform() - # ctx.rotate(Pi/2) - ctx.translate(bottomLeft.xy) + ctx.translate(bottomLeft.xy + bottomLeft.wh / 2) + ctx.rotate(Pi/2) + ctx.translate(-bottomLeft.wh / 2) ctx.drawImageAdj(cornerHashes[dcBottomLeft], zero, shadowColor, bottomLeft.wh) ctx.restoreTransform() From c0611d951eec728d9c1e529ca55e5ce77a201db9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:14:10 -0600 Subject: [PATCH 074/225] reuse sides --- src/figuro/renderer/utils/drawshadows.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 96349289c..b6d625962 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -173,8 +173,9 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.restoreTransform() ctx.saveTransform() - # ctx.rotate(Pi/2) - ctx.translate(bottomRight.xy) + ctx.translate(bottomRight.xy + bottomRight.wh / 2) + ctx.rotate(Pi) + ctx.translate(-bottomRight.wh / 2) ctx.drawImageAdj(cornerHashes[dcBottomRight], zero, shadowColor, bottomRight.wh) ctx.restoreTransform() From 43dd36ab17744c8d2c6d509070a1ee51ff9c1ffb Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:15:11 -0600 Subject: [PATCH 075/225] reuse sides --- src/figuro/renderer/utils/drawshadows.nim | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index b6d625962..2b3844f46 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -102,10 +102,9 @@ proc fillRoundedRectWithShadowSdf*[R]( dLeft: patches.left, ] - var radiisDone: array[DirectionCorners, float32] = [NaN.float32, NaN.float32, NaN.float32, NaN.float32] for corner in DirectionCorners: - if radii[corner] notin radiisDone: - let cornerHash = getShadowKey(shadowKey, radii, corner) + let cornerHash = cornerHashes[corner] + if cornerHash notin ctx.entries: let image = cornerArray[corner] case corner: of dcTopLeft: @@ -118,7 +117,6 @@ proc fillRoundedRectWithShadowSdf*[R]( image.flipHorizontal() image.flipVertical() ctx.putImage(cornerHash, image) - radiisDone[corner] = radii[corner] for side in Directions: let sideHash = getShadowKey(shadowKey, radii, side) From b73d0d0a418f9d0d2b273e95aeaaf372ea40f0f8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:22:30 -0600 Subject: [PATCH 076/225] reuse sides --- src/figuro/renderer/utils/drawshadows.nim | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 2b3844f46..58ff046a8 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -64,8 +64,14 @@ proc fillRoundedRectWithShadowSdf*[R]( # use the left side of the shadow key to check if we've already generated this shadow let newSize = cbs.totalSize let shadowKeyLeft = getShadowKey(shadowKey, radii, dLeft) + var missingAnyCorner = false + for corner in DirectionCorners: + if cornerHashes[corner] notin ctx.entries: + missingAnyCorner = true + break - if shadowKeyLeft notin ctx.entries: + if shadowKeyLeft notin ctx.entries or missingAnyCorner: + echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius, " -rTL:", radii[dcTopLeft], " -rTR:", radii[dcTopRight], " -rBL:", radii[dcBottomLeft], " -rBR:", radii[dcBottomRight] const whiteColor = rgba(255, 255, 255, 255) let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) @@ -112,9 +118,9 @@ proc fillRoundedRectWithShadowSdf*[R]( of dcTopRight: image.flipHorizontal() of dcBottomRight: + image.flipHorizontal() image.flipVertical() of dcBottomLeft: - image.flipHorizontal() image.flipVertical() ctx.putImage(cornerHash, image) From 15005e118f71d0aa409e2bcb5370929ea64d781a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:39:59 -0600 Subject: [PATCH 077/225] reuse sides --- examples/innerShadow.nim | 218 ---------------------- src/figuro/renderer/utils/drawshadows.nim | 1 + 2 files changed, 1 insertion(+), 218 deletions(-) delete mode 100644 examples/innerShadow.nim diff --git a/examples/innerShadow.nim b/examples/innerShadow.nim deleted file mode 100644 index 2cb704cfd..000000000 --- a/examples/innerShadow.nim +++ /dev/null @@ -1,218 +0,0 @@ -import pixie, pixie/simd - -proc delta*(image: Image) {.hasSimd, raises: [].} = - ## Inverts all of the colors and alpha. - for i in 0 ..< image.data.len: - var rgbx = image.data[i] - let r = (rgbx.r != 0).uint8 - rgbx.a = (255-rgbx.g) * r - rgbx.r = (255) * r - rgbx.g = (255) * r - rgbx.b = (255) * r - image.data[i] = rgbx - - # Inverting rgbx(50, 100, 150, 200) becomes rgbx(205, 155, 105, 55). This - # is not a valid premultiplied alpha color. - # We need to convert back to premultiplied alpha after inverting. - # image.data.toPremultipliedAlpha() -proc drawCircle(ctx: Context, center, radius: float, lineWidth: float, stroke: bool, color: ColorRGBA) = - ctx.strokeStyle = color - ctx.fillStyle = color - ctx.lineCap = SquareCap - ctx.lineWidth = lineWidth - ctx.circle(center, center, radius) - if stroke: - ctx.stroke() - else: - ctx.fill() - -proc gaussianFunction*(x: float, mean: float = 0.0, stdDev: float = 1.0): float = - ## Creates a Gaussian (normal) distribution function - ## - ## Parameters: - ## mean: The mean (μ) of the distribution - ## stdDev: The standard deviation (σ) of the distribution - ## - ## Returns: - ## A function that takes an x value and returns the probability density - - # Constant factors for the Gaussian formula - let factor = 1.0 / (stdDev * sqrt(2.0 * PI)) - let exponentFactor = -1.0 / (2.0 * stdDev * stdDev) - - # Return a closure that calculates the Gaussian probability density - # Calculate (x - mean)² - let deviation = x - mean - let deviationSquared = deviation * deviation - - # Calculate e^(-((x-mean)²)/(2σ²)) - let exponent = deviationSquared * exponentFactor - - # Return the complete formula: (1/(σ√(2π))) * e^(-((x-mean)²)/(2σ²)) - result = factor * exp(exponent) - -proc generateCircle(radius: int, offset: Vec2, - spread: float32, blur: float32, - lineWidth: float32 = 0'f32, - stroked: bool = true, - fillStyle: ColorRGBA = rgba(255, 255, 255, 255), - shadowColor: ColorRGBA = rgba(0, 0, 0, 255), - innerShadow = false, - innerShadowBorder = false, - ): Image = - let sz = 2*radius - let radius = radius.toFloat - let center = radius.float32 - - let circle = newImage(sz, sz) - let ctxCircle = newContext(circle) - drawCircle(ctxCircle, radius, radius - lineWidth/2, lineWidth, true, fillStyle) - - var image = newImage(sz, sz) - - # if innerShadow: - # let shadow = circle.shadow( - # offset = offset, - # spread = spread, - # blur = blur, - # color = shadowColor) - # image.draw(shadow) - - image.draw(circle) - - if innerShadow: - let circleInner = newImage(sz, sz) - circleInner.fill(rgba(255, 255, 255, 255)) - - let circleSolid = newImage(sz, sz) - let ctx = newContext(circleSolid) - ctx.fillStyle = rgba(255, 255, 255, 255) - ctx.circle(radius, radius, radius-2*lineWidth) - ctx.fill() - - circleInner.draw(circleSolid, blendMode = SubtractMaskBlend) - - let innerRadius = radius/2 - let cnt = radius*2 - for i in 0..cnt.int: - block: - let i = i.float32 - let cl = newImage(sz, sz) - let ctxCl = newContext(cl) - # let fs = rgba(255, 255, 255, uint8(170*(1-sin(i/cnt*PI/2)))) - let fs = rgba(255, 255, 255, uint8((255*gaussianFunction(i/cnt*PI/2, mean = -0.3, stdDev = 0.49)))) - let radius = radius-2*lineWidth - i/cnt*(radius-innerRadius) - # let lw = 1.float32 * (1-i/cnt) - let lw = 1.float32 - # echo "circleInner: ", i, " fs: ", fs, " radius: ", radius - drawCircle(ctxCl, center = center, radius = radius, lineWidth = lw, stroke = true, color = fs) - image.draw(cl) - image.draw(circle) - image.draw(circleInner) - return image - -proc sliceToNinePatch*(img: Image): tuple[ - topLeft, topRight, bottomLeft, bottomRight: Image, - top, right, bottom, left: Image -] = - ## Slices an image into 8 pieces for a 9-patch style UI renderer. - ## The ninth piece (center) is not included as it's typically transparent or filled separately. - ## Returns the four corners and four edges as separate images. - - let - width = img.width - height = img.height - halfW = width div 2 - halfH = height div 2 - - # Create the corner images - using the actual corner size or half the image size, whichever is smaller - let - actualCornerW = halfW - actualCornerH = halfH - - # Four corners - let - topLeft = img.subImage(0, 0, halfW, halfH) - topRight = img.subImage(width - halfW, 0, halfW, halfH) - bottomLeft = img.subImage(0, height - halfH, halfW, halfH) - bottomRight = img.subImage(width - halfW, height - halfH, halfW, halfH) - - # Four edges (1 pixel wide for sides, full width/height for top/bottom) - # Each edge goes from the center point to the edge - let - centerX = width div 2 - centerY = height div 2 - - # Top edge: from center to top edge, 1px wide - top = img.subImage(centerX, 0, 1, centerY) - # Right edge: from center to right edge, 1px high - right = img.subImage(centerX, centerY, width - centerX, 1) - # Bottom edge: from center to bottom edge, 1px wide - bottom = img.subImage(centerX, centerY, 1, height - centerY) - # Left edge: from left edge to center, 1px high - left = img.subImage(0, centerY, centerX, 1) - - var - ftop = newImage(4, top.height) - fbottom = newImage(4, bottom.height) - fright = newImage(right.width, 4) - fleft = newImage(left.width, 4) - - for i in 0..3: - ftop.draw(top, translate(vec2(i.float32, 0))) - fbottom.draw(bottom, translate(vec2(i.float32, 0))) - fright.draw(right, translate(vec2(0, i.float32))) - fleft.draw(left, translate(vec2(0, i.float32))) - - result = ( - topLeft: topLeft, - topRight: topRight, - bottomLeft: bottomLeft, - bottomRight: bottomRight, - top: ftop, - right: fright, - bottom: fbottom, - left: fleft - ) - -# Example usage: -when true: - let circleImage = generateCircle( - radius = 100, - stroked = true, - offset = vec2(0, 0), - spread = 20.0, - blur = 40.0, - lineWidth = 10.0, - fillStyle = rgba(255, 255, 255, 255), - shadowColor = rgba(255, 255, 255, 255), - innerShadow = false, - innerShadowBorder = false, - ) - circleImage.writeFile("examples/circle.png") - -# Example usage: -let shadowImage = generateCircle( - radius = 100, - stroked = true, - offset = vec2(0, 0), - spread = 20.0, - blur = 40.0, - lineWidth = 10.0, - fillStyle = rgba(255, 255, 255, 255), - shadowColor = rgba(255, 255, 255, 255), - innerShadow = true, - innerShadowBorder = true, -) -shadowImage.writeFile("examples/innerShadow.png") - -# Example of slicing the shadow image into a 9-patch -let ninePatch = sliceToNinePatch(shadowImage) -# ninePatch.topLeft.writeFile("examples/shadow_top_left.png") -# ninePatch.topRight.writeFile("examples/shadow_top_right.png") -# ninePatch.bottomLeft.writeFile("examples/shadow_bottom_left.png") -# ninePatch.bottomRight.writeFile("examples/shadow_bottom_right.png") -# ninePatch.top.writeFile("examples/shadow_top.png") -# ninePatch.right.writeFile("examples/shadow_right.png") -# ninePatch.bottom.writeFile("examples/shadow_bottom.png") -# ninePatch.left.writeFile("examples/shadow_left.png") \ No newline at end of file diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 58ff046a8..7f09ef751 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -95,6 +95,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) + let cornerArray = [ dcTopLeft: patches.topLeft, dcTopRight: patches.topRight, From 0042264cb8a89c4a3294d0995982178f011424e2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:41:21 -0600 Subject: [PATCH 078/225] reuse sides --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 7f09ef751..06353adc2 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -34,10 +34,10 @@ proc fillRoundedRectWithShadowSdf*[R]( result = hash((7723, blur.int, spread.int, innerShadow, totalSize)) proc getShadowKey(shadowKey: Hash, radii: array[DirectionCorners, float32], corner: DirectionCorners): Hash = - result = shadowKey !& hash(2474431) !& hash(radii[corner].int) + result = hash((shadowKey, 2474431, int(radii[corner]))) proc getShadowKey(shadowKey: Hash, radii: array[Directions, float32], side: Directions): Hash = - result = shadowKey !& hash(971767) !& hash(side.int) + result = hash((shadowKey, 971767, int(side))) let radii = clampRadii(radii, rect) From 052adaa8cb1f5f4cc43dfcff3aa87d4d78efe7cd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:56:12 -0600 Subject: [PATCH 079/225] reuse sides --- src/figuro/renderer/utils/drawshadows.nim | 5 +++++ src/figuro/renderer/utils/drawutils.nim | 5 +++-- src/figuro/ui/apis.nim | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 06353adc2..14493a29f 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -123,6 +123,9 @@ proc fillRoundedRectWithShadowSdf*[R]( image.flipVertical() of dcBottomLeft: image.flipVertical() + + if not innerShadow: + echo "putting corner: ", corner, " size: ", newSize, " hash: ", cornerHash, " radius: ", radii[corner] ctx.putImage(cornerHash, image) for side in Directions: @@ -159,6 +162,8 @@ proc fillRoundedRectWithShadowSdf*[R]( bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) # Draw corners + echo "cornerHashes: ", " tL: ", cornerHashes[dcTopLeft], " tR: ", cornerHashes[dcTopRight], " bL: ", cornerHashes[dcBottomLeft], " bR: ", cornerHashes[dcBottomRight] + echo "cornerRadius: ", " tL: ", radii[dcTopLeft], " tR: ", radii[dcTopRight], " bL: ", radii[dcBottomLeft], " bR: ", radii[dcBottomRight] ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 812f1e5f9..d8a968533 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -18,6 +18,7 @@ proc hash(radii: array[DirectionCorners, float32]): Hash = result = result !& hash(r) proc clampRadii*(radii: array[DirectionCorners, float32], rect: Rect): array[DirectionCorners, float32] = + let maxRadius = min(rect.w / 2, rect.h / 2) result = radii - for r in result.mitems(): - r = max(1.0, min(r, min(rect.w / 2, rect.h / 2))).round() + for corner in DirectionCorners: + result[corner] = max(1.0, min(radii[corner], maxRadius)).round() diff --git a/src/figuro/ui/apis.nim b/src/figuro/ui/apis.nim index 9ad7fe24e..00a3a0df1 100644 --- a/src/figuro/ui/apis.nim +++ b/src/figuro/ui/apis.nim @@ -230,7 +230,7 @@ template cornerRadius*(radius: array[DirectionCorners, Constraint]) {.thisWrappe template corners*(topLeft = 0'ui, topRight = 0'ui, bottomLeft = 0'ui, bottomRight = 0'ui) = ## Sets corner radii - cornerRadius(this, [topLeft, topRight, bottomLeft, bottomRight]) + cornerRadius(this, [dcTopLeft: topLeft, dcTopRight: topRight, dcBottomRight: bottomRight, dcBottomLeft: bottomLeft]) template cornerRadius*(radius: UiScalar) {.thisWrapper.} ## Sets all radius of all 4 corners. @@ -240,7 +240,7 @@ template cornerRadius*(radius: Constraint) {.thisWrapper.} template corners*(topLeft = 0'ux, topRight = 0'ux, bottomLeft = 0'ux, bottomRight = 0'ux) = ## Sets corner radii - cornerRadius(this, [topLeft, topRight, bottomLeft, bottomRight]) + cornerRadius(this, [dcTopLeft: topLeft, dcTopRight: topRight, dcBottomRight: bottomRight, dcBottomLeft: bottomLeft]) ## --------------------------------------------- ## Fidget Text APIs From 2d3bd67cf50e7a23f131a5d0e27a5b7667093638 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:59:05 -0600 Subject: [PATCH 080/225] reuse sides --- src/figuro/renderer/utils/drawextras.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index bd5cc1762..7ad9be900 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -46,14 +46,14 @@ proc drawRoundedRect*[R]( let w = rect.w.ceil() h = rect.h.ceil() - # radii = clampRadii(radii, rect) + radii = clampRadii(radii, rect) # maxRadius = max(radii) cbs = getCircleBoxSizes(radii, 0.0, 0.0, weight, w, h) maxRadius = cbs.maxRadius rw = cbs.sideSize.float32 rh = cbs.sideSize.float32 - let rhash = radii[dcTopLeft].int !& radii[dcTopRight].int !& radii[dcBottomLeft].int !& radii[dcBottomRight].int + let rhash = hash((int(radii[dcTopLeft]), int(radii[dcTopRight]), int(radii[dcBottomRight]), int(radii[dcBottomLeft]))) let hash = hash((6217, int(rw * 1), int(rh * 1), int(weight * 1), int(cbs.sideSize * 1), doStroke, outerShadowFill)) !& rhash block drawCorners: From c1ccd1af5bc9aff0c0bed74a41b7707b91063cc9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 00:59:57 -0600 Subject: [PATCH 081/225] reuse sides --- src/figuro/renderer/utils/drawextras.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 7ad9be900..8abd54f4b 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -118,8 +118,8 @@ proc drawRoundedRect*[R]( offsets = [ dcTopLeft: vec2(0, 0), dcTopRight: vec2(w - rw, 0), - dcBottomRight: vec2(w - rw, h - rh), - dcBottomLeft: vec2(0, h - rh), + dcBottomRight: vec2(0, h - rh), + dcBottomLeft: vec2(w - rw, h - rh), ] for corner in DirectionCorners: From fe4b7df9ca2025dfdcb0b53ee951332b62c9320a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:06:41 -0600 Subject: [PATCH 082/225] reuse sides --- src/figuro/renderer/utils/drawextras.nim | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 8abd54f4b..3142e5e22 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -57,12 +57,12 @@ proc drawRoundedRect*[R]( let hash = hash((6217, int(rw * 1), int(rh * 1), int(weight * 1), int(cbs.sideSize * 1), doStroke, outerShadowFill)) !& rhash block drawCorners: - var hashes: array[DirectionCorners, Hash] - for quadrant in DirectionCorners: - let qhash = hash !& hash(41) !& quadrant.int - hashes[quadrant] = qhash + var cornerHashes: array[DirectionCorners, Hash] + for corner in DirectionCorners: + let qhash = hash !& hash(41) !& corner.int + cornerHashes[corner] = qhash - if not ctx.hasImage(toKey(hashes[dcTopRight])): + if not ctx.hasImage(toKey(cornerHashes[dcTopRight])): let circle = when defined(figuroNoSDF): if doStroke: @@ -102,31 +102,31 @@ proc drawRoundedRect*[R]( let patches = sliceToNinePatch(circle) # Store each piece in the atlas - let patchArray = [ + let cornerImages = [ dcTopLeft: patches.topLeft, dcTopRight: patches.topRight, dcBottomRight: patches.bottomRight, dcBottomLeft: patches.bottomLeft, ] - for quadrant in DirectionCorners: - let img = patchArray[quadrant] - ctx.addImage(toKey(hashes[quadrant]), img) + for corner in DirectionCorners: + let img = cornerImages[corner] + ctx.addImage(toKey(cornerHashes[corner]), img) let xy = rect.xy offsets = [ dcTopLeft: vec2(0, 0), dcTopRight: vec2(w - rw, 0), - dcBottomRight: vec2(0, h - rh), - dcBottomLeft: vec2(w - rw, h - rh), + dcBottomRight: vec2(w - rw, h - rh), + dcBottomLeft: vec2(0, h - rh), ] for corner in DirectionCorners: let pt = ceil(xy + offsets[corner]) - ctx.drawImage(toKey(hashes[corner]), pt, color) + ctx.drawImage(toKey(cornerHashes[corner]), pt, color) block drawEdgeBoxes: let From 414df902cc1a418abcbf67edabd651f40f0b2c88 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:24:23 -0600 Subject: [PATCH 083/225] change corners order --- examples/circlebox.nim | 303 ---------------------- examples/corners.nim | 103 -------- src/figuro/common/nodes/basics.nim | 2 +- src/figuro/renderer/opengl/renderer.nim | 3 + src/figuro/renderer/utils/drawextras.nim | 10 +- src/figuro/renderer/utils/drawshadows.nim | 2 +- src/figuro/ui/apis.nim | 4 +- 7 files changed, 12 insertions(+), 415 deletions(-) delete mode 100644 examples/circlebox.nim delete mode 100644 examples/corners.nim diff --git a/examples/circlebox.nim b/examples/circlebox.nim deleted file mode 100644 index e57d44ed5..000000000 --- a/examples/circlebox.nim +++ /dev/null @@ -1,303 +0,0 @@ -import pixie, pixie/simd - - -type - Directions* = enum - dTop - dRight - dBottom - dLeft - - DirectionCorners* = enum - dcTopLeft - dcTopRight - dcBottomRight - dcBottomLeft - - -proc generateCircleBox*( - radii: array[DirectionCorners, float32], - offset = vec2(0, 0), - spread: float32 = 0.0'f32, - blur: float32 = 0.0'f32, - stroked: bool = true, - filled: bool = true, - lineWidth: float32 = 0.0'f32, - fillStyle: ColorRGBA = rgba(255, 255, 255, 255), - shadowColor: ColorRGBA = rgba(255, 255, 255, 255), - outerShadow = true, - innerShadow = true, - innerShadowBorder = true, - outerShadowFill = false, -): Image = - var maxRadius = 0.0 - for r in radii: - maxRadius = max(maxRadius, r) - - # Additional size for spread and blur - let padding = (spread.int + blur.int) - let lw = lineWidth.ceil() - let totalSize = max(2*maxRadius.ceil().int + 2*padding, 10+2*padding) - - # Create a canvas large enough to contain the box with all effects - let img = newImage(totalSize, totalSize) - let ctx = newContext(img) - - # Calculate the inner box dimensions - let innerWidth = (totalSize - padding * 2).float32 - let innerHeight = (totalSize - padding * 2).float32 - - # Create a path for the rounded rectangle with the given dimensions and corner radii - proc createRoundedRectPath( - width, height: float32, - radii: array[DirectionCorners, float32], - padding: float32, - lw: float32 - ): pixie.Path = - # Start at top right after the corner radius - let hlw = lw / 2.0 - let padding = padding + hlw - let width = width - lw - let height = height - lw - - result = newPath() - let topRight = vec2(width - radii[dcTopRight], 0) - result.moveTo(topRight + vec2(padding, padding)) - - # Top right corner - let trControl = vec2(width, 0) - result.quadraticCurveTo( - trControl + vec2(padding, padding), - vec2(width, radii[dcTopRight]) + vec2(padding, padding) - ) - - # Right side - result.lineTo(vec2(width, height - radii[dcBottomRight]) + vec2(padding, padding)) - - # Bottom right corner - let brControl = vec2(width, height) - result.quadraticCurveTo( - brControl + vec2(padding, padding), - vec2(width - radii[dcBottomRight], height) + vec2(padding, padding) - ) - - # Bottom side - result.lineTo(vec2(radii[dcBottomLeft], height) + vec2(padding, padding)) - - # Bottom left corner - let blControl = vec2(0, height) - result.quadraticCurveTo( - blControl + vec2(padding, padding), - vec2(0, height - radii[dcBottomLeft]) + vec2(padding, padding) - ) - - # Left side - result.lineTo(vec2(0, radii[dcTopLeft]) + vec2(padding, padding)) - - # Top left corner - let tlControl = vec2(0, 0) - result.quadraticCurveTo( - tlControl + vec2(padding, padding), - vec2(radii[dcTopLeft], 0) + vec2(padding, padding) - ) - - # Close the path - result.lineTo(topRight + vec2(padding, padding)) - - # Create the path for our rounded rectangle - let path = createRoundedRectPath(innerWidth, innerHeight, radii, padding.float32, lw) - - # Draw the box - if stroked: - ctx.strokeStyle = fillStyle - ctx.lineWidth = lineWidth - ctx.stroke(path) - - if filled: - ctx.fillStyle = fillStyle - ctx.fill(path) - - # Apply inner shadow if requested - if innerShadow or outerShadow or outerShadowFill: - let shadow = img.shadow( - offset = offset, - spread = spread, - blur = blur, - color = shadowColor - ) - - let spath = createRoundedRectPath(innerWidth, innerHeight, radii, padding.float32, lw) - - let combined = newImage(totalSize, totalSize) - let ctx = newContext(combined) - if innerShadow: - ctx.saveLayer() - ctx.clip(spath, EvenOdd) - ctx.drawImage(shadow, pos = vec2(0, 0)) - ctx.restore() - if outerShadowFill: - let spath = spath.copy() - spath.rect(0, 0, totalSize.float32, totalSize.float32) - ctx.saveLayer() - ctx.clip(spath, EvenOdd) - ctx.fillStyle = fillStyle - ctx.rect(0, 0, totalSize.float32, totalSize.float32) - ctx.fill() - ctx.restore() - if outerShadow: - let spath = spath.copy() - spath.rect(0, 0, totalSize.float32, totalSize.float32) - ctx.saveLayer() - ctx.clip(spath, EvenOdd) - ctx.drawImage(shadow, pos = vec2(0, 0)) - ctx.restore() - if innerShadowBorder: - ctx.drawImage(img, pos = vec2(0, 0)) - return combined - else: - return img - -let imgA = generateCircleBox( - radii = [0'f32, 20'f32, 40'f32, 10'f32], # Different radius for each corner - offset = vec2(0, 0), - spread = 1.0'f32, - blur = 10.0'f32, - stroked = true, - lineWidth = 2.0, - outerShadow = false, - innerShadow = false, -) - -imgA.writeFile("examples/circlebox-asymmetric.png") - -let imgAstroke = generateCircleBox( - radii = [0'f32, 20'f32, 40'f32, 10'f32], # Different radius for each corner - offset = vec2(0, 0), - spread = 1.0'f32, - blur = 10.0'f32, - stroked = true, - filled = true, - lineWidth = 2.0, - outerShadow = false, - innerShadow = false, -) - -imgAstroke.writeFile("examples/circlebox-asymmetric-stroke.png") - -let imgAnostroke = generateCircleBox( - radii = [30'f32, 20'f32, 40'f32, 10'f32], # Different radius for each corner - offset = vec2(0, 0), - spread = 1.0'f32, - blur = 10.0'f32, - stroked = false, - lineWidth = 0.0, - outerShadow = false, - innerShadow = false, -) - -imgAnostroke.writeFile("examples/circlebox-asymmetric-nostroke.png") - -let imgAfillshadow = generateCircleBox( - radii = [30'f32, 20'f32, 40'f32, 10'f32], # Different radius for each corner - offset = vec2(0, 0), - spread = 20.0'f32, - blur = 20.0'f32, - stroked = false, - lineWidth = 0.0, - outerShadow = true, - innerShadow = false, - innerShadowBorder = true, - outerShadowFill = false, -) - -imgAfillshadow.writeFile("examples/circlebox-asymmetric-fill-shadow.png") - - -let imgB = generateCircleBox( - radii = [1'f32, 1'f32, 1'f32, 1'f32], # Different radius for each corner - offset = vec2(0, 0), - spread = 0.0'f32, - blur = 10.0'f32, - stroked = false, - lineWidth = 2.0, - outerShadow = true, - innerShadow = false, - innerShadowBorder = true, -) - -imgB.writeFile("examples/circlebox-symmetric.png") - -# Only inner shadow example -let imgC = generateCircleBox( - radii = [30'f32, 30'f32, 30'f32, 30'f32], - offset = vec2(0, 0), - spread = 1.0'f32, - blur = 10.0'f32, - stroked = true, - lineWidth = 2.0, - outerShadow = false, - innerShadow = true, - innerShadowBorder = false, -) - -imgC.writeFile("examples/circlebox-inner-only.png") - -# Only outer shadow example -let imgD = generateCircleBox( - radii = [30'f32, 30'f32, 30'f32, 30'f32], - offset = vec2(2, 2), - spread = 1.0'f32, - blur = 10.0'f32, - stroked = true, - lineWidth = 2.0, - outerShadow = true, - innerShadow = false, - innerShadowBorder = false, -) - -imgD.writeFile("examples/circlebox-outer-only.png") - -# Only outer shadow example -let imgE = generateCircleBox( - radii = [30'f32, 30'f32, 30'f32, 30'f32], - offset = vec2(0, 0), - spread = 1.0'f32, - blur = 10.0'f32, - stroked = true, - lineWidth = 2.0, - outerShadow = true, - innerShadow = true, - innerShadowBorder = false, -) - -imgE.writeFile("examples/circlebox-outer-inner.png") - -let imgF = generateCircleBox( - radii = [30'f32, 30'f32, 30'f32, 30'f32], - offset = vec2(0, 0), - spread = 1.0'f32, - blur = 10.0'f32, - stroked = true, - lineWidth = 2.0, - outerShadow = true, - innerShadow = true, - innerShadowBorder = false, - outerShadowFill = true, -) - -imgF.writeFile("examples/circlebox-inner-and-fill-outer.png") - -let imgG = generateCircleBox( - radii = [10'f32, 10'f32, 10'f32, 10'f32], - offset = vec2(0, 0), - spread = 0.0'f32, - blur = 5.0'f32, - stroked = true, - lineWidth = 2.0, - outerShadow = false, - innerShadow = true, - innerShadowBorder = true, - outerShadowFill = true, -) - -imgG.writeFile("examples/circlebox-inner-and-fill-outer-0radius.png") diff --git a/examples/corners.nim b/examples/corners.nim deleted file mode 100644 index ebe9a1420..000000000 --- a/examples/corners.nim +++ /dev/null @@ -1,103 +0,0 @@ -import pixie, pixie/simd - -type - DirectionCorners* = enum - dcTopLeft - dcTopRight - dcBottomRight - dcBottomLeft - -proc generateCorner( - radius: int, - quadrant: DirectionCorners, - stroked: bool, - lineWidth: float32 = 0'f32, - fillStyle = rgba(255, 255, 255, 255), - innerShadow = false, - shadowColor = rgba(255, 0, 0, 255), - offset = vec2(0, 0), - spread = 0.0, - blur = 0.0, -): Image = - const s = 4.0 / 3.0 * (sqrt(2.0) - 1.0) - let - x = radius.toFloat - y = radius.toFloat - r = radius.toFloat - lineWidth - - tl = vec2(0, 0) - tr = vec2(x, 0) - bl = vec2(0, y) - br = vec2(x, y) - trc = tr + vec2(0, r * s) - blc = bl + vec2(r * s, 0) - - template drawImpl(ctx: untyped, doStroke: bool, lineWidth: float32) = - let path = newPath() - if doStroke: - let bl = vec2(0, y - lineWidth / 2) - let tr = vec2(x - lineWidth / 2, 0) - path.moveTo(bl) - path.bezierCurveTo(blc, trc, tr) - else: - path.moveTo(tr) - path.lineTo(tl) - path.lineTo(bl) - path.bezierCurveTo(blc, trc, tr) - - case quadrant - of dcTopLeft: # TL - ctx.rotate(180 * PI / 180) - ctx.translate(-br) - of dcTopRight: # TR - ctx.rotate(270 * PI / 180) - ctx.translate(-tr) - of dcBottomLeft: # BL - ctx.rotate(90 * PI / 180) - ctx.translate(-bl) - of dcBottomRight: # BR - discard - - if doStroke: - ctx.stroke(path) - else: - ctx.fill(path) - - let corner = newImage(radius, radius) - - let ctx2 = newContext(corner) - ctx2.fillStyle = fillStyle - ctx2.strokeStyle = fillStyle - ctx2.lineCap = SquareCap - ctx2.lineWidth = lineWidth - drawImpl(ctx2, doStroke = stroked, lineWidth = lineWidth) - - let image = newImage(radius, radius) - - if innerShadow: - let shadow = corner.shadow( - offset = offset, - spread = spread, - blur = blur, - color = shadowColor - ) - image.draw(shadow) - - image.draw(corner) - - if innerShadow: - let circleSolid = newImage(radius, radius) - let ctx3 = newContext(circleSolid) - ctx3.fillStyle = fillStyle - drawImpl(ctx3, doStroke = false, lineWidth = lineWidth) - image.draw(circleSolid, blendMode = MaskBlend) - - result = image - - -for i in DirectionCorners: - let img = generateCorner(30, i, stroked = true, - lineWidth = 3, innerShadow = true, - spread = 1, blur = 10, - ) - img.writeFile("examples/corner" & $i & ".png") diff --git a/src/figuro/common/nodes/basics.nim b/src/figuro/common/nodes/basics.nim index 02d6bd9e1..619d7fbab 100644 --- a/src/figuro/common/nodes/basics.nim +++ b/src/figuro/common/nodes/basics.nim @@ -24,8 +24,8 @@ type DirectionCorners* = enum dcTopLeft dcTopRight - dcBottomRight dcBottomLeft + dcBottomRight NodeKind* = enum ## Different types of nodes. diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 394348bbd..eea91d047 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -240,9 +240,12 @@ proc render( # handle node rotation ifrender node.rotation != 0: + ctx.saveTransform() ctx.translate(node.screenBox.wh / 2) ctx.rotate(node.rotation / 180 * PI) ctx.translate(-node.screenBox.wh / 2) + finally: + ctx.restoreTransform() ifrender node.kind == nkRectangle: ctx.renderDropShadows(node) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 3142e5e22..643ce56c8 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -59,7 +59,7 @@ proc drawRoundedRect*[R]( block drawCorners: var cornerHashes: array[DirectionCorners, Hash] for corner in DirectionCorners: - let qhash = hash !& hash(41) !& corner.int + let qhash = hash((hash, 41, corner.int)) cornerHashes[corner] = qhash if not ctx.hasImage(toKey(cornerHashes[dcTopRight])): @@ -102,11 +102,11 @@ proc drawRoundedRect*[R]( let patches = sliceToNinePatch(circle) # Store each piece in the atlas - let cornerImages = [ + let cornerImages: array[DirectionCorners, Image] = [ dcTopLeft: patches.topLeft, dcTopRight: patches.topRight, - dcBottomRight: patches.bottomRight, dcBottomLeft: patches.bottomLeft, + dcBottomRight: patches.bottomRight, ] for corner in DirectionCorners: @@ -115,11 +115,11 @@ proc drawRoundedRect*[R]( let xy = rect.xy - offsets = [ + offsets: array[DirectionCorners, Vec2] = [ dcTopLeft: vec2(0, 0), dcTopRight: vec2(w - rw, 0), - dcBottomRight: vec2(w - rw, h - rh), dcBottomLeft: vec2(0, h - rh), + dcBottomRight: vec2(w - rw, h - rh), ] for corner in DirectionCorners: diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 14493a29f..6576061e0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -99,8 +99,8 @@ proc fillRoundedRectWithShadowSdf*[R]( let cornerArray = [ dcTopLeft: patches.topLeft, dcTopRight: patches.topRight, - dcBottomRight: patches.bottomRight, dcBottomLeft: patches.bottomLeft, + dcBottomRight: patches.bottomRight, ] let sideArray = [ dTop: patches.top, diff --git a/src/figuro/ui/apis.nim b/src/figuro/ui/apis.nim index 00a3a0df1..72f85a680 100644 --- a/src/figuro/ui/apis.nim +++ b/src/figuro/ui/apis.nim @@ -230,7 +230,7 @@ template cornerRadius*(radius: array[DirectionCorners, Constraint]) {.thisWrappe template corners*(topLeft = 0'ui, topRight = 0'ui, bottomLeft = 0'ui, bottomRight = 0'ui) = ## Sets corner radii - cornerRadius(this, [dcTopLeft: topLeft, dcTopRight: topRight, dcBottomRight: bottomRight, dcBottomLeft: bottomLeft]) + cornerRadius(this, [dcTopLeft: topLeft, dcTopRight: topRight, dcBottomLeft: bottomLeft, dcBottomRight: bottomRight]) template cornerRadius*(radius: UiScalar) {.thisWrapper.} ## Sets all radius of all 4 corners. @@ -240,7 +240,7 @@ template cornerRadius*(radius: Constraint) {.thisWrapper.} template corners*(topLeft = 0'ux, topRight = 0'ux, bottomLeft = 0'ux, bottomRight = 0'ux) = ## Sets corner radii - cornerRadius(this, [dcTopLeft: topLeft, dcTopRight: topRight, dcBottomRight: bottomRight, dcBottomLeft: bottomLeft]) + cornerRadius(this, [dcTopLeft: topLeft, dcTopRight: topRight, dcBottomLeft: bottomLeft, dcBottomRight: bottomRight]) ## --------------------------------------------- ## Fidget Text APIs From 53111f50c2202117dc3060d367a4503ab9908eac Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:25:19 -0600 Subject: [PATCH 084/225] change corners order --- src/figuro/renderer/utils/drawshadows.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 6576061e0..5c9ef66c4 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -165,6 +165,7 @@ proc fillRoundedRectWithShadowSdf*[R]( echo "cornerHashes: ", " tL: ", cornerHashes[dcTopLeft], " tR: ", cornerHashes[dcTopRight], " bL: ", cornerHashes[dcBottomLeft], " bR: ", cornerHashes[dcBottomRight] echo "cornerRadius: ", " tL: ", radii[dcTopLeft], " tR: ", radii[dcTopRight], " bL: ", radii[dcBottomLeft], " bR: ", radii[dcBottomRight] + ctx.saveTransform() ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) ctx.saveTransform() @@ -188,6 +189,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(-bottomRight.wh / 2) ctx.drawImageAdj(cornerHashes[dcBottomRight], zero, shadowColor, bottomRight.wh) ctx.restoreTransform() + ctx.restoreTransform() # Draw edges # Top edge (stretched horizontally) From 6af424c457f3cf0a0df6f2b3878bd9543e3cc11a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:29:48 -0600 Subject: [PATCH 085/225] change corners order --- src/figuro/renderer/utils/drawextras.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 643ce56c8..9a65140f3 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -76,7 +76,7 @@ proc drawRoundedRect*[R]( var center = vec2(rw, rh) let wh = vec2(2*rw+1, 2*rh+1) # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) - let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) + let corners = vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) let circle = newImage(int(2*rw), int(2*rh)) # echo "drawing circle: ", doStroke, " sz:", rect.w, "x", rect.h, " ", rw, "x", rh, " weight: ", weight, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")", " rhash: ", rhash, " " if doStroke: diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 5c9ef66c4..89dd14cf6 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -74,7 +74,7 @@ proc fillRoundedRectWithShadowSdf*[R]( echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius, " -rTL:", radii[dcTopLeft], " -rTR:", radii[dcTopRight], " -rBL:", radii[dcBottomLeft], " -rBR:", radii[dcBottomRight] const whiteColor = rgba(255, 255, 255, 255) let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) - let corners = vec4(radii[dcBottomLeft], radii[dcTopRight], radii[dcBottomRight], radii[dcTopLeft]) + let corners = vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) var shadowImg = newImage(newSize, newSize) let wh = if innerShadow: vec2(cbs.inner.float32 - 2*shadowSpread, cbs.inner.float32 - 2*shadowSpread) else: vec2(cbs.inner.float32, cbs.inner.float32) let spread = if innerShadow: 0.0 else: shadowSpread From ba02d690b8adce3b9e3996019b6061b009fc60ea Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:33:32 -0600 Subject: [PATCH 086/225] change corners order --- src/figuro/renderer/utils/drawextras.nim | 6 ++++-- src/figuro/renderer/utils/drawshadows.nim | 11 +---------- tests/tbutton.nim | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 9a65140f3..4962a43b8 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -13,6 +13,9 @@ import pkg/sdfy import ../utils/boxes import ./drawutils +proc cornersToSdfRadii*(radii: array[DirectionCorners, float32]): Vec4 = + vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) + proc drawOuterBox*[R](ctx: R, rect: Rect, padding: float32, color: Color) = var obox = rect @@ -75,8 +78,7 @@ proc drawRoundedRect*[R]( let clear = rgba(0, 0, 0, 0) var center = vec2(rw, rh) let wh = vec2(2*rw+1, 2*rh+1) - # let corners = vec4(radii[dcTopRight], radii[dcBottomRight], radii[dcBottomLeft], radii[dcTopLeft]) - let corners = vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) + let corners = radii.cornersToSdfRadii() let circle = newImage(int(2*rw), int(2*rh)) # echo "drawing circle: ", doStroke, " sz:", rect.w, "x", rect.h, " ", rw, "x", rh, " weight: ", weight, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")", " rhash: ", rhash, " " if doStroke: diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 89dd14cf6..dd0a75053 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -71,10 +71,9 @@ proc fillRoundedRectWithShadowSdf*[R]( break if shadowKeyLeft notin ctx.entries or missingAnyCorner: - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius, " -rTL:", radii[dcTopLeft], " -rTR:", radii[dcTopRight], " -rBL:", radii[dcBottomLeft], " -rBR:", radii[dcBottomRight] + let corners = radii.cornersToSdfRadii() const whiteColor = rgba(255, 255, 255, 255) let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) - let corners = vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) var shadowImg = newImage(newSize, newSize) let wh = if innerShadow: vec2(cbs.inner.float32 - 2*shadowSpread, cbs.inner.float32 - 2*shadowSpread) else: vec2(cbs.inner.float32, cbs.inner.float32) let spread = if innerShadow: 0.0 else: shadowSpread @@ -90,8 +89,6 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) - echo "drawing shadow: ", innerShadow, " sz:", rect.w, "x", rect.h, " total:", cbs.totalSize, " inner:", cbs.inner, " padding:", cbs.padding, " side:", cbs.sideSize, " blur: ", shadowBlur, " spread: ", shadowSpread, " maxr:", maxRadius, " -rTL:", radii[dcTopLeft], " -rTR:", radii[dcTopRight], " -rBL:", radii[dcBottomLeft], " -rBR:", radii[dcBottomRight] - # shadowImg.writeFile("tests/renderer-shadowImage-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) @@ -124,8 +121,6 @@ proc fillRoundedRectWithShadowSdf*[R]( of dcBottomLeft: image.flipVertical() - if not innerShadow: - echo "putting corner: ", corner, " size: ", newSize, " hash: ", cornerHash, " radius: ", radii[corner] ctx.putImage(cornerHash, image) for side in Directions: @@ -162,10 +157,7 @@ proc fillRoundedRectWithShadowSdf*[R]( bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) # Draw corners - echo "cornerHashes: ", " tL: ", cornerHashes[dcTopLeft], " tR: ", cornerHashes[dcTopRight], " bL: ", cornerHashes[dcBottomLeft], " bR: ", cornerHashes[dcBottomRight] - echo "cornerRadius: ", " tL: ", radii[dcTopLeft], " tR: ", radii[dcTopRight], " bL: ", radii[dcBottomLeft], " bR: ", radii[dcBottomRight] - ctx.saveTransform() ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) ctx.saveTransform() @@ -189,7 +181,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(-bottomRight.wh / 2) ctx.drawImageAdj(cornerHashes[dcBottomRight], zero, shadowColor, bottomRight.wh) ctx.restoreTransform() - ctx.restoreTransform() # Draw edges # Top edge (stretched horizontally) diff --git a/tests/tbutton.nim b/tests/tbutton.nim index c5ad17f0e..718c2e11a 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -20,7 +20,7 @@ type proc initialize*(self: Main) {.slot.} = for kd in FadeKinds: self.toggles[kd] = true - self.fades[kd] = Fader(minMax: 0.0..34.0, + self.fades[kd] = Fader(minMax: 1.0..34.0, inTimeMs: 1400, outTimeMs: 1400) self.fades[FkTopLeft] = Fader(minMax: 2.0..8.0, inTimeMs: 1400, outTimeMs: 1400) From 9ee6a8a778abcca120be771d5dceaa144806490f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:36:38 -0600 Subject: [PATCH 087/225] change corners order --- src/figuro/renderer/utils/drawshadows.nim | 2 +- tests/tbutton.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index dd0a75053..b6a050f39 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -133,7 +133,7 @@ proc fillRoundedRectWithShadowSdf*[R]( var totalPadding = cbs.padding.int - corner = totalPadding.float32 + cbs.sideSize.float32 + 1 + corner = totalPadding.float32 + cbs.inner.float32 # corner = totalPadding.float32 + 1 let diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 718c2e11a..5443746d5 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -20,7 +20,7 @@ type proc initialize*(self: Main) {.slot.} = for kd in FadeKinds: self.toggles[kd] = true - self.fades[kd] = Fader(minMax: 1.0..34.0, + self.fades[kd] = Fader(minMax: 0.1..34.0, inTimeMs: 1400, outTimeMs: 1400) self.fades[FkTopLeft] = Fader(minMax: 2.0..8.0, inTimeMs: 1400, outTimeMs: 1400) From 1f4839fe5f15fd99a2620b730cfca1028ec8f38f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:40:56 -0600 Subject: [PATCH 088/225] change corners order --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index b6a050f39..991b10a13 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -132,8 +132,8 @@ proc fillRoundedRectWithShadowSdf*[R]( # echo "making inner shadow", " top left hash: ", ninePatchHashes[0], " shadow keybase: ", shadowKeyBase var - totalPadding = cbs.padding.int - corner = totalPadding.float32 + cbs.inner.float32 + totalPadding = (cbs.totalSize.float32 - cbs.inner.float32) / 2 + corner = totalPadding.float32 + cbs.inner.float32 / 2 # corner = totalPadding.float32 + 1 let From b7f94c08f6d5f580330ca9aeb4d06910208c2931 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:41:12 -0600 Subject: [PATCH 089/225] cleanup --- src/figuro/renderer/utils/drawshadows.nim | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 991b10a13..417bf2947 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -127,14 +127,9 @@ proc fillRoundedRectWithShadowSdf*[R]( let sideHash = getShadowKey(shadowKey, radii, side) ctx.putImage(sideHash, sideArray[side]) - # patchArray[0].writeFile("tests/renderer-shadowImage-topleft-" & $innerShadow & "-maxr" & $maxRadius & "-totalsz" & $cbs.totalSize & "-sidesz" & $cbs.sideSize & "-blur" & $shadowBlur & "-spread" & $shadowSpread & "-rTL" & $radii[dcTopLeft] & "-rTR" & $radii[dcTopRight] & "-rBL" & $radii[dcBottomLeft] & "-rBR" & $radii[dcBottomRight] & ".png") - # if innerShadow: - # echo "making inner shadow", " top left hash: ", ninePatchHashes[0], " shadow keybase: ", shadowKeyBase - var totalPadding = (cbs.totalSize.float32 - cbs.inner.float32) / 2 corner = totalPadding.float32 + cbs.inner.float32 / 2 - # corner = totalPadding.float32 + 1 let sbox = rect( From 40abdb37fa124f1fdf46c3a0029ad43b316ff865 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:41:20 -0600 Subject: [PATCH 090/225] cleanup --- src/figuro/renderer/utils/drawshadows.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 417bf2947..7fcd4bbea 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -156,7 +156,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) ctx.saveTransform() - # ctx.translate(vec2(+topRight.w/2, topRight.h/2)) ctx.translate(topRight.xy + topRight.wh / 2) ctx.rotate(-Pi/2) ctx.translate(-topRight.wh / 2) From 13be31d8adb37fd984fdb7086814d6602d7d5358 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:42:44 -0600 Subject: [PATCH 091/225] cleanup --- src/figuro/renderer/utils/drawshadows.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 7fcd4bbea..360475186 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -153,7 +153,10 @@ proc fillRoundedRectWithShadowSdf*[R]( # Draw corners - ctx.drawImageAdj(cornerHashes[dcTopLeft], topLeft.xy, shadowColor, topLeft.wh) + ctx.saveTransform() + ctx.translate(topLeft.xy) + ctx.drawImageAdj(cornerHashes[dcTopLeft], zero, shadowColor, topLeft.wh) + ctx.restoreTransform() ctx.saveTransform() ctx.translate(topRight.xy + topRight.wh / 2) From 9fa5f14ab7528c2c3a1bc22a6c83c3c742d2c5f7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:46:23 -0600 Subject: [PATCH 092/225] cleanup --- src/figuro/renderer/openglBackend.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 9fc27829c..08ab4a79e 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 3072 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 360475186..b58e2288a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -193,6 +193,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(sideHashes[dLeft], leftEdge.xy, shadowColor, leftEdge.wh) # Center (stretched both ways) - # if not innerShadow: - # let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) - # ctx.drawRect(center, shadowColor) \ No newline at end of file + if not innerShadow: + let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) + ctx.drawRect(center, shadowColor) \ No newline at end of file From de2ab96bd042496ad519e80b36fb3f99b3b4734f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 01:50:46 -0600 Subject: [PATCH 093/225] cleanup --- src/figuro/renderer/opengl/renderer.nim | 28 ++++++++++++------------- tests/tbutton.nim | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index eea91d047..c0035a7ec 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -251,12 +251,12 @@ proc render( ctx.renderDropShadows(node) # handle clipping children content based on this node - # ifrender NfClipContent in node.flags: - # ctx.beginMask() - # ctx.drawMasks(node) - # ctx.endMask() - # finally: - # ctx.popMask() + ifrender NfClipContent in node.flags: + ctx.beginMask() + ctx.drawMasks(node) + ctx.endMask() + finally: + ctx.popMask() ifrender true: if node.kind == nkText: @@ -270,14 +270,14 @@ proc render( ctx.renderBoxes(node) ifrender node.kind == nkRectangle: - # if NfClipContent notin node.flags: - # ctx.beginMask() - # ctx.drawMasks(node) - # ctx.endMask() - # ctx.renderInnerShadows(node) - # ctx.popMask() - # else: - ctx.renderInnerShadows(node) + if NfClipContent notin node.flags: + ctx.beginMask() + ctx.drawMasks(node) + ctx.endMask() + ctx.renderInnerShadows(node) + ctx.popMask() + else: + ctx.renderInnerShadows(node) # restores the opengl context back to the parent node's (see above) # ctx.restoreTransform() diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 5443746d5..2c4749813 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -50,7 +50,7 @@ proc draw*(self: Main) {.slot.} = self.toggles[this.state] = not self.toggles[this.state] Button[int] as "btn": - box 20'pp, 20'pp, 30'pp, 30'pp + box 40'ux, 40'ux, 30'pp, 30'pp fill css"#2B9F2B" * 0.5 border 5'ui, css"darkgreen" * 0.5 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, From ef8d36e44abb1b5210b98324603ec1c901ef7147 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:02:51 -0600 Subject: [PATCH 094/225] cleanup --- src/figuro/renderer/utils/drawextras.nim | 75 +++++++++++++++++------ src/figuro/renderer/utils/drawshadows.nim | 8 +-- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 4962a43b8..fe4f85829 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -56,16 +56,21 @@ proc drawRoundedRect*[R]( rw = cbs.sideSize.float32 rh = cbs.sideSize.float32 - let rhash = hash((int(radii[dcTopLeft]), int(radii[dcTopRight]), int(radii[dcBottomRight]), int(radii[dcBottomLeft]))) - let hash = hash((6217, int(rw * 1), int(rh * 1), int(weight * 1), int(cbs.sideSize * 1), doStroke, outerShadowFill)) !& rhash - + # let rhash = hash((int(radii[dcTopLeft]), int(radii[dcTopRight]), int(radii[dcBottomRight]), int(radii[dcBottomLeft]))) + let hash = hash((6217, int(rw * 1), int(rh * 1), int(weight * 1), int(cbs.sideSize * 1), doStroke, outerShadowFill)) block drawCorners: var cornerHashes: array[DirectionCorners, Hash] for corner in DirectionCorners: - let qhash = hash((hash, 41, corner.int)) + let qhash = hash((hash, 41, int(radii[corner]))) cornerHashes[corner] = qhash - if not ctx.hasImage(toKey(cornerHashes[dcTopRight])): + var missingAnyCorner = false + for corner in DirectionCorners: + if cornerHashes[corner] notin ctx.entries: + missingAnyCorner = true + break + + if missingAnyCorner: let circle = when defined(figuroNoSDF): if doStroke: @@ -112,23 +117,55 @@ proc drawRoundedRect*[R]( ] for corner in DirectionCorners: - let img = cornerImages[corner] - ctx.addImage(toKey(cornerHashes[corner]), img) + let cornerHash = cornerHashes[corner] + if cornerHash notin ctx.entries: + let image = cornerImages[corner] + case corner: + of dcTopLeft: + discard + of dcTopRight: + image.flipHorizontal() + of dcBottomRight: + image.flipHorizontal() + image.flipVertical() + of dcBottomLeft: + image.flipVertical() + ctx.addImage(toKey(cornerHash), image) let xy = rect.xy - offsets: array[DirectionCorners, Vec2] = [ - dcTopLeft: vec2(0, 0), - dcTopRight: vec2(w - rw, 0), - dcBottomLeft: vec2(0, h - rh), - dcBottomRight: vec2(w - rw, h - rh), - ] - - for corner in DirectionCorners: - let - pt = ceil(xy + offsets[corner]) - - ctx.drawImage(toKey(cornerHashes[corner]), pt, color) + zero = vec2(0, 0) + cornerSize = vec2(rw, rh) + topLeft = xy + vec2(0, 0) + topRight = xy + vec2(w - rw, 0) + bottomLeft = xy + vec2(0, h - rh) + bottomRight = xy + vec2(w - rw, h - rh) + + ctx.saveTransform() + ctx.translate(topLeft) + ctx.drawImage(cornerHashes[dcTopLeft], zero, color) + ctx.restoreTransform() + + ctx.saveTransform() + ctx.translate(topRight + cornerSize / 2) + ctx.rotate(-Pi/2) + ctx.translate(-cornerSize / 2) + ctx.drawImage(cornerHashes[dcTopRight], zero, color) + ctx.restoreTransform() + + ctx.saveTransform() + ctx.translate(bottomLeft + cornerSize / 2) + ctx.rotate(Pi/2) + ctx.translate(-cornerSize / 2) + ctx.drawImage(cornerHashes[dcBottomLeft], zero, color) + ctx.restoreTransform() + + ctx.saveTransform() + ctx.translate(bottomRight + cornerSize / 2) + ctx.rotate(Pi) + ctx.translate(-cornerSize / 2) + ctx.drawImage(cornerHashes[dcBottomRight], zero, color) + ctx.restoreTransform() block drawEdgeBoxes: let diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index b58e2288a..59c6d5924 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -93,13 +93,13 @@ proc fillRoundedRectWithShadowSdf*[R]( # Slice it into 9-patch pieces let patches = sliceToNinePatch(shadowImg) - let cornerArray = [ + let cornerImages = [ dcTopLeft: patches.topLeft, dcTopRight: patches.topRight, dcBottomLeft: patches.bottomLeft, dcBottomRight: patches.bottomRight, ] - let sideArray = [ + let sideImages = [ dTop: patches.top, dRight: patches.right, dBottom: patches.bottom, @@ -109,7 +109,7 @@ proc fillRoundedRectWithShadowSdf*[R]( for corner in DirectionCorners: let cornerHash = cornerHashes[corner] if cornerHash notin ctx.entries: - let image = cornerArray[corner] + let image = cornerImages[corner] case corner: of dcTopLeft: discard @@ -125,7 +125,7 @@ proc fillRoundedRectWithShadowSdf*[R]( for side in Directions: let sideHash = getShadowKey(shadowKey, radii, side) - ctx.putImage(sideHash, sideArray[side]) + ctx.putImage(sideHash, sideImages[side]) var totalPadding = (cbs.totalSize.float32 - cbs.inner.float32) / 2 From 007ede061233913b34c8a7fcdd8a9aed02a1e45f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:04:34 -0600 Subject: [PATCH 095/225] cleanup --- src/figuro/renderer/utils/drawextras.nim | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index fe4f85829..4488649ba 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -53,11 +53,11 @@ proc drawRoundedRect*[R]( # maxRadius = max(radii) cbs = getCircleBoxSizes(radii, 0.0, 0.0, weight, w, h) maxRadius = cbs.maxRadius - rw = cbs.sideSize.float32 - rh = cbs.sideSize.float32 + bw = cbs.sideSize.float32 + bh = cbs.sideSize.float32 # let rhash = hash((int(radii[dcTopLeft]), int(radii[dcTopRight]), int(radii[dcBottomRight]), int(radii[dcBottomLeft]))) - let hash = hash((6217, int(rw * 1), int(rh * 1), int(weight * 1), int(cbs.sideSize * 1), doStroke, outerShadowFill)) + let hash = hash((6217, int(bw), int(bh), int(weight), int(cbs.sideSize), doStroke, outerShadowFill)) block drawCorners: var cornerHashes: array[DirectionCorners, Hash] for corner in DirectionCorners: @@ -81,10 +81,10 @@ proc drawRoundedRect*[R]( block: let fill = rgba(255, 255, 255, 255) let clear = rgba(0, 0, 0, 0) - var center = vec2(rw, rh) - let wh = vec2(2*rw+1, 2*rh+1) + var center = vec2(bw, bh) + let wh = vec2(2*bw+1, 2*bh+1) let corners = radii.cornersToSdfRadii() - let circle = newImage(int(2*rw), int(2*rh)) + let circle = newImage(int(2*bw), int(2*bh)) # echo "drawing circle: ", doStroke, " sz:", rect.w, "x", rect.h, " ", rw, "x", rh, " weight: ", weight, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")", " rhash: ", rhash, " " if doStroke: drawSdfShape(circle, @@ -135,11 +135,11 @@ proc drawRoundedRect*[R]( let xy = rect.xy zero = vec2(0, 0) - cornerSize = vec2(rw, rh) + cornerSize = vec2(bw, bh) topLeft = xy + vec2(0, 0) - topRight = xy + vec2(w - rw, 0) - bottomLeft = xy + vec2(0, h - rh) - bottomRight = xy + vec2(w - rw, h - rh) + topRight = xy + vec2(w - bw, 0) + bottomLeft = xy + vec2(0, h - bh) + bottomRight = xy + vec2(w - bw, h - bh) ctx.saveTransform() ctx.translate(topLeft) @@ -171,16 +171,16 @@ proc drawRoundedRect*[R]( let ww = if doStroke: weight else: cbs.sideSize.float32 # ww = cbs.sideSize.float32 - rrw = if doStroke: w - weight else: w - rw - rrh = if doStroke: h - weight else: h - rh - wrw = w - 2 * rw - hrh = h - 2 * rh + rrw = if doStroke: w - weight else: w - bw + rrh = if doStroke: h - weight else: h - bh + wrw = w - 2 * bw + hrh = h - 2 * bh if not doStroke: - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rh), wrw, hrh), color) + ctx.drawRect(rect(ceil(rect.x + bw), ceil(rect.y + bh), wrw, hrh), color) - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y), wrw, ww), color) - ctx.drawRect(rect(ceil(rect.x + rw), ceil(rect.y + rrh), wrw, ww), color) + ctx.drawRect(rect(ceil(rect.x + bw), ceil(rect.y), wrw, ww), color) + ctx.drawRect(rect(ceil(rect.x + bw), ceil(rect.y + rrh), wrw, ww), color) - ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + rh), ww, hrh), color) - ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + rh), ww, hrh), color) + ctx.drawRect(rect(ceil(rect.x), ceil(rect.y + bh), ww, hrh), color) + ctx.drawRect(rect(ceil(rect.x + rrw), ceil(rect.y + bh), ww, hrh), color) From 8e7292ecd81f20265bf91df532119b9b94014707 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:04:58 -0600 Subject: [PATCH 096/225] cleanup --- src/figuro/renderer/utils/drawextras.nim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 4488649ba..42d76f562 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -56,8 +56,8 @@ proc drawRoundedRect*[R]( bw = cbs.sideSize.float32 bh = cbs.sideSize.float32 - # let rhash = hash((int(radii[dcTopLeft]), int(radii[dcTopRight]), int(radii[dcBottomRight]), int(radii[dcBottomLeft]))) let hash = hash((6217, int(bw), int(bh), int(weight), int(cbs.sideSize), doStroke, outerShadowFill)) + block drawCorners: var cornerHashes: array[DirectionCorners, Hash] for corner in DirectionCorners: @@ -85,7 +85,6 @@ proc drawRoundedRect*[R]( let wh = vec2(2*bw+1, 2*bh+1) let corners = radii.cornersToSdfRadii() let circle = newImage(int(2*bw), int(2*bh)) - # echo "drawing circle: ", doStroke, " sz:", rect.w, "x", rect.h, " ", rw, "x", rh, " weight: ", weight, " r(", radii[dcTopLeft], ",", radii[dcTopRight], ",", radii[dcBottomLeft], ",", radii[dcBottomRight], ")", " rhash: ", rhash, " " if doStroke: drawSdfShape(circle, center = center, @@ -104,7 +103,6 @@ proc drawRoundedRect*[R]( pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - # circle.writeFile("tests/circlebox-" & "stroke-" & $doStroke & "-rect" & $rw & "x" & $rh & "-mr" & $maxRadius & ".png") circle let patches = sliceToNinePatch(circle) From fce0fd33331887737f959eb09f77ffb816c3aa41 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:09:25 -0600 Subject: [PATCH 097/225] cleanup --- src/figuro/renderer/utils/drawextras.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 42d76f562..f0ea6ac42 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -61,12 +61,12 @@ proc drawRoundedRect*[R]( block drawCorners: var cornerHashes: array[DirectionCorners, Hash] for corner in DirectionCorners: - let qhash = hash((hash, 41, int(radii[corner]))) - cornerHashes[corner] = qhash + cornerHashes[corner] = hash((hash, 41, int(radii[corner]))) var missingAnyCorner = false for corner in DirectionCorners: if cornerHashes[corner] notin ctx.entries: + echo "missing corner: ", corner, " hash: ", cornerHashes[corner] missingAnyCorner = true break @@ -128,7 +128,7 @@ proc drawRoundedRect*[R]( image.flipVertical() of dcBottomLeft: image.flipVertical() - ctx.addImage(toKey(cornerHash), image) + ctx.putImage(toKey(cornerHash), image) let xy = rect.xy From 5b2accb049a5def968e92487a2214be56acf287c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:11:42 -0600 Subject: [PATCH 098/225] cleanup --- src/figuro/renderer/utils/drawextras.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index f0ea6ac42..eb3028e23 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -50,13 +50,12 @@ proc drawRoundedRect*[R]( w = rect.w.ceil() h = rect.h.ceil() radii = clampRadii(radii, rect) - # maxRadius = max(radii) cbs = getCircleBoxSizes(radii, 0.0, 0.0, weight, w, h) maxRadius = cbs.maxRadius bw = cbs.sideSize.float32 bh = cbs.sideSize.float32 - let hash = hash((6217, int(bw), int(bh), int(weight), int(cbs.sideSize), doStroke, outerShadowFill)) + let hash = hash((6217, int(cbs.sideSize), int(cbs.maxRadius), int(weight), doStroke, outerShadowFill)) block drawCorners: var cornerHashes: array[DirectionCorners, Hash] From 03f9c9fed40da28806f800c5e9c0296909eccfd4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:14:09 -0600 Subject: [PATCH 099/225] cleanup --- src/figuro/renderer/utils/drawutils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index d8a968533..8918e8eae 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -21,4 +21,4 @@ proc clampRadii*(radii: array[DirectionCorners, float32], rect: Rect): array[Dir let maxRadius = min(rect.w / 2, rect.h / 2) result = radii for corner in DirectionCorners: - result[corner] = max(1.0, min(radii[corner], maxRadius)).round() + result[corner] = max(1.0, min(radii[corner], maxRadius)).ceil() From 8e2c8175ea296e9432910f87e12fed1b088037ce Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:17:59 -0600 Subject: [PATCH 100/225] cleanup --- src/figuro/renderer/utils/drawextras.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index eb3028e23..c99b34de8 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -65,7 +65,7 @@ proc drawRoundedRect*[R]( var missingAnyCorner = false for corner in DirectionCorners: if cornerHashes[corner] notin ctx.entries: - echo "missing corner: ", corner, " hash: ", cornerHashes[corner] + echo "missing corner: ", corner, " hash: ", cornerHashes[corner], " radius: ", radii[corner], " sideSize: ", cbs.sideSize, " maxRadius: ", cbs.maxRadius, " weight: ", weight, " doStroke: ", doStroke, " outerShadowFill: ", outerShadowFill missingAnyCorner = true break From 824e739ac85a6f6ee69f30f1c258bcbac167d1b5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:20:01 -0600 Subject: [PATCH 101/225] cleanup --- src/figuro/renderer/utils/drawextras.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index c99b34de8..4761fe68e 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -65,7 +65,7 @@ proc drawRoundedRect*[R]( var missingAnyCorner = false for corner in DirectionCorners: if cornerHashes[corner] notin ctx.entries: - echo "missing corner: ", corner, " hash: ", cornerHashes[corner], " radius: ", radii[corner], " sideSize: ", cbs.sideSize, " maxRadius: ", cbs.maxRadius, " weight: ", weight, " doStroke: ", doStroke, " outerShadowFill: ", outerShadowFill + # echo "missing corner: ", corner, " hash: ", cornerHashes[corner], " radius: ", radii[corner], " sideSize: ", cbs.sideSize, " maxRadius: ", cbs.maxRadius, " weight: ", weight, " doStroke: ", doStroke, " outerShadowFill: ", outerShadowFill missingAnyCorner = true break From ed3d98dcac1219973d3fb1e762455d062a3941c0 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 02:24:39 -0600 Subject: [PATCH 102/225] cleanup --- src/figuro/renderer/utils/boxes.nim | 12 ++++++------ src/figuro/renderer/utils/drawutils.nim | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/boxes.nim index 1349b133a..2873a0464 100644 --- a/src/figuro/renderer/utils/boxes.nim +++ b/src/figuro/renderer/utils/boxes.nim @@ -77,12 +77,12 @@ proc getCircleBoxSizes*( ): tuple[maxRadius, sideSize, totalSize, padding, inner: int] = result.maxRadius = 0 for r in radii: - result.maxRadius = max(result.maxRadius, r.ceil().int) - let ww = int(1.5*weight.ceil()) - let bw = width.ceil().int - let bh = height.ceil().int - let blur = blur.ceil().int - let spread = spread.ceil().int + result.maxRadius = max(result.maxRadius, r.round().int) + let ww = int(1.5*weight.round()) + let bw = width.round().int + let bh = height.round().int + let blur = blur.round().int + let spread = spread.round().int let padding = max(spread + blur, result.maxRadius) result.padding = padding diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 8918e8eae..d8a968533 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -21,4 +21,4 @@ proc clampRadii*(radii: array[DirectionCorners, float32], rect: Rect): array[Dir let maxRadius = min(rect.w / 2, rect.h / 2) result = radii for corner in DirectionCorners: - result[corner] = max(1.0, min(radii[corner], maxRadius)).ceil() + result[corner] = max(1.0, min(radii[corner], maxRadius)).round() From 89f21bea4fed97e95695cebfe03409a191c2bef9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 16 Jun 2025 11:34:30 -0600 Subject: [PATCH 103/225] cleanup --- .github/workflows/build-full.yml | 2 +- .github/workflows/build-pr.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-full.yml b/.github/workflows/build-full.yml index 5f0b3914a..eaad98c49 100644 --- a/.github/workflows/build-full.yml +++ b/.github/workflows/build-full.yml @@ -33,7 +33,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble@0.18.4 + nimble install nimble@0.18.2 nim -v nimble -v diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index dc9b0dadc..f2db852f2 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -30,7 +30,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble@0.18.4 + nimble install nimble@0.18.2 nim -v nimble -v From 8fe23ae6130fe22723a60918c95b8149971205c7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:02:02 -0600 Subject: [PATCH 104/225] rename --- src/figuro/renderer/utils/{boxes.nim => drawboxes.nim} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/figuro/renderer/utils/{boxes.nim => drawboxes.nim} (100%) diff --git a/src/figuro/renderer/utils/boxes.nim b/src/figuro/renderer/utils/drawboxes.nim similarity index 100% rename from src/figuro/renderer/utils/boxes.nim rename to src/figuro/renderer/utils/drawboxes.nim From 6affc33883a05407179217c5a5d9aa5016095ac1 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:03:04 -0600 Subject: [PATCH 105/225] rename --- src/figuro/renderer/utils/drawboxes.nim | 392 ++++++++++------------- src/figuro/renderer/utils/drawextras.nim | 392 +++++++++++++---------- 2 files changed, 392 insertions(+), 392 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 2873a0464..964369d21 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -3,232 +3,168 @@ import pkg/chroma import ../../common/nodes/basics -proc sliceToNinePatch*(img: Image): tuple[ - topLeft, topRight, bottomLeft, bottomRight: Image, - top, right, bottom, left: Image -] = - ## Slices an image into 8 pieces for a 9-patch style UI renderer. - ## The ninth piece (center) is not included as it's typically transparent or filled separately. - ## Returns the four corners and four edges as separate images. - - let - width = img.width - height = img.height - halfW = width div 2 - halfH = height div 2 - - # echo "sliceToNinePatch: ", width, "x", height, " halfW: ", halfW, " halfH: ", halfH - - # Create the corner images - using the actual corner size or half the image size, whichever is smaller - let - actualCornerW = halfW - actualCornerH = halfH - - # Four corners - let - topLeft = img.subImage(0, 0, halfW, halfH) - topRight = img.subImage(width - halfW, 0, halfW, halfH) - bottomLeft = img.subImage(0, height - halfH, halfW, halfH) - bottomRight = img.subImage(width - halfW, height - halfH, halfW, halfH) - - # Four edges (1 pixel wide for sides, full width/height for top/bottom) - # Each edge goes from the center point to the edge - let - centerX = width div 2 - centerY = height div 2 - - top = img.subImage(centerX, 0, 1, centerY) - right = img.subImage(centerX, centerY, width - centerX, 1) - bottom = img.subImage(centerX, centerY, 1, height - centerY) - left = img.subImage(0, centerY, centerX, 1) - - var - n = 8 - ftop = newImage(n, top.height) - fbottom = newImage(n, bottom.height) - fright = newImage(right.width, n) - fleft = newImage(left.width, n) - - for i in 0.. Date: Tue, 17 Jun 2025 01:06:30 -0600 Subject: [PATCH 106/225] refactor --- src/figuro/renderer/opengl/glcontext.nim | 2 +- src/figuro/renderer/opengl/renderer.nim | 1 + src/figuro/renderer/utils/drawboxes.nim | 3 +++ src/figuro/renderer/utils/drawextras.nim | 31 ---------------------- src/figuro/renderer/utils/drawshadows.nim | 2 +- src/figuro/renderer/utils/drawutils.nim | 32 +++++++++++++++++++++-- 6 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/figuro/renderer/opengl/glcontext.nim b/src/figuro/renderer/opengl/glcontext.nim index 014c7b8c4..31c0765d1 100644 --- a/src/figuro/renderer/opengl/glcontext.nim +++ b/src/figuro/renderer/opengl/glcontext.nim @@ -7,8 +7,8 @@ import pixie/simd import pkg/chronicles import ../../commons -import ../utils/boxes import ../utils/drawextras +import ../utils/drawboxes import ../utils/drawshadows export drawextras diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index c0035a7ec..f2567c16e 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -11,6 +11,7 @@ import ../../common/nodes/uinodes import ../utils/glutils import ../utils/baserenderer import ../utils/drawshadows +import ../utils/drawboxes import glcommons, glcontext import std/locks diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 964369d21..710ddbb84 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -1,7 +1,10 @@ import pkg/pixie import pkg/chroma +import pkg/sdfy import ../../common/nodes/basics +import ./drawutils +import ./drawextras proc drawOuterBox*[R](ctx: R, rect: Rect, padding: float32, color: Color) = diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index 1e8825fbc..c08876020 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -10,12 +10,8 @@ import pkg/chronicles import pkg/pixie import pkg/sdfy -import ../utils/boxes import ./drawutils -proc cornersToSdfRadii*(radii: array[DirectionCorners, float32]): Vec4 = - vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) - proc sliceToNinePatch*(img: Image): tuple[ topLeft, topRight, bottomLeft, bottomRight: Image, top, right, bottom, left: Image @@ -79,33 +75,6 @@ proc sliceToNinePatch*(img: Image): tuple[ left: fleft ) -proc getCircleBoxSizes*( - radii: array[DirectionCorners, float32], - blur: float32, - spread: float32, - weight: float32 = 0.0, - width = float32.high(), - height = float32.high(), - innerShadow = false, -): tuple[maxRadius, sideSize, totalSize, padding, inner: int] = - result.maxRadius = 0 - for r in radii: - result.maxRadius = max(result.maxRadius, r.round().int) - let ww = int(1.5*weight.round()) - let bw = width.round().int - let bh = height.round().int - let blur = blur.round().int - let spread = spread.round().int - let padding = max(spread + blur, result.maxRadius) - - result.padding = padding - if innerShadow: - result.sideSize = min(result.maxRadius + padding, min(bw, bh)).max(ww) - else: - result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) - result.totalSize = 3*result.sidesize + 3*padding - result.inner = 3*result.sideSize - proc generateCircleBox*( radii: array[DirectionCorners, float32], offset = vec2(0, 0), diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 59c6d5924..159e4ec32 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -10,7 +10,7 @@ import pkg/chronicles import pkg/pixie import pkg/sdfy -import ../utils/boxes +import ../utils/drawextras import ./drawutils var shadowCache: Table[Hash, Image] = initTable[Hash, Image]() diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index d8a968533..48c895ab6 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -7,8 +7,6 @@ import pkg/chroma import pkg/sigils import pkg/chronicles -import ../utils/boxes - proc hash(v: Vec2): Hash = hash((v.x, v.y)) @@ -22,3 +20,33 @@ proc clampRadii*(radii: array[DirectionCorners, float32], rect: Rect): array[Dir result = radii for corner in DirectionCorners: result[corner] = max(1.0, min(radii[corner], maxRadius)).round() + +proc cornersToSdfRadii*(radii: array[DirectionCorners, float32]): Vec4 = + vec4(radii[dcBottomRight], radii[dcTopRight], radii[dcBottomLeft], radii[dcTopLeft]) + +proc getCircleBoxSizes*( + radii: array[DirectionCorners, float32], + blur: float32, + spread: float32, + weight: float32 = 0.0, + width = float32.high(), + height = float32.high(), + innerShadow = false, +): tuple[maxRadius, sideSize, totalSize, padding, inner: int] = + result.maxRadius = 0 + for r in radii: + result.maxRadius = max(result.maxRadius, r.round().int) + let ww = int(1.5*weight.round()) + let bw = width.round().int + let bh = height.round().int + let blur = blur.round().int + let spread = spread.round().int + let padding = max(spread + blur, result.maxRadius) + + result.padding = padding + if innerShadow: + result.sideSize = min(result.maxRadius + padding, min(bw, bh)).max(ww) + else: + result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) + result.totalSize = 3*result.sidesize + 3*padding + result.inner = 3*result.sideSize From 1de329cfb07fd9b8a1d054d3032e577d7ca989f9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:06:43 -0600 Subject: [PATCH 107/225] refactor --- src/figuro/renderer/utils/drawextras.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index c08876020..c290c9f9e 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -8,7 +8,6 @@ import pkg/chroma import pkg/sigils import pkg/chronicles import pkg/pixie -import pkg/sdfy import ./drawutils From e088be660d61e6c850b5bf3a74041bd747fe095e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:12:16 -0600 Subject: [PATCH 108/225] refactor --- src/figuro/renderer/utils/drawutils.nim | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 48c895ab6..c06b5ca9d 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -50,3 +50,26 @@ proc getCircleBoxSizes*( result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) result.totalSize = 3*result.sidesize + 3*padding result.inner = 3*result.sideSize + +proc roundedBoxCornerSizes*( + radii: array[DirectionCorners, float32], + blur: float32, + spread: float32, + weight: float32 = 0.0, + width = float32.high(), + height = float32.high(), + innerShadow = false, +): array[DirectionCorners, tuple[corner, side, padding: int]] = + let ww = int(1.5*weight.round()) + let bw = width.round().int + let bh = height.round().int + + let padding = spread + 1.5 * blur + let sideSize = + if innerShadow: + min(result.maxRadius + padding, min(bw, bh)).max(ww) + else: + min(result.maxRadius, min(bw, bh)).max(ww) + + for corner in DirectionCorners: + result[corner] = (corner, sideSize, padding) From 441b99c7609838fb4d06e04a9cf63c8638623963 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:14:14 -0600 Subject: [PATCH 109/225] refactor --- src/figuro/renderer/utils/drawutils.nim | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index c06b5ca9d..170fc6b10 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -59,17 +59,22 @@ proc roundedBoxCornerSizes*( width = float32.high(), height = float32.high(), innerShadow = false, -): array[DirectionCorners, tuple[corner, side, padding: int]] = +): array[DirectionCorners, tuple[corner, side, padding, sideSize, inner, totalSize: int]] = let ww = int(1.5*weight.round()) let bw = width.round().int let bh = height.round().int + var maxRadius = 0 + for r in radii: + maxRadius = max(maxRadius, r.round().int) let padding = spread + 1.5 * blur let sideSize = if innerShadow: - min(result.maxRadius + padding, min(bw, bh)).max(ww) + min(maxRadius + padding, min(bw, bh)).max(ww) else: - min(result.maxRadius, min(bw, bh)).max(ww) + min(maxRadius, min(bw, bh)).max(ww) + let totalSize = 3*sideSize + 3*padding + let inner = 3*sideSize for corner in DirectionCorners: - result[corner] = (corner, sideSize, padding) + result[corner] = (corner, sideSize, padding, sideSize, inner, totalSize) From 9ad9d6fc12966bfef90ba9502f121f90a2756c2d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:17:40 -0600 Subject: [PATCH 110/225] refactor --- src/figuro/renderer/utils/drawutils.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 170fc6b10..d510f7eb3 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -59,7 +59,7 @@ proc roundedBoxCornerSizes*( width = float32.high(), height = float32.high(), innerShadow = false, -): array[DirectionCorners, tuple[corner, side, padding, sideSize, inner, totalSize: int]] = +): array[DirectionCorners, tuple[dim, side, padding, sideSize, inner, totalSize: int]] = let ww = int(1.5*weight.round()) let bw = width.round().int let bh = height.round().int @@ -67,7 +67,7 @@ proc roundedBoxCornerSizes*( for r in radii: maxRadius = max(maxRadius, r.round().int) - let padding = spread + 1.5 * blur + let padding = int(round(spread + 1.5 * blur)) let sideSize = if innerShadow: min(maxRadius + padding, min(bw, bh)).max(ww) @@ -77,4 +77,5 @@ proc roundedBoxCornerSizes*( let inner = 3*sideSize for corner in DirectionCorners: - result[corner] = (corner, sideSize, padding, sideSize, inner, totalSize) + let dim = max(int(round(radii[corner])), ww) + 1 + result[corner] = (dim, sideSize, padding, sideSize, inner, totalSize) From dcfece5b64c3b31cb0b65311a95b2e1a84067fac Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:18:59 -0600 Subject: [PATCH 111/225] refactor --- src/figuro/renderer/utils/drawboxes.nim | 57 +++++++++++-------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 710ddbb84..92630a769 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -60,39 +60,32 @@ proc drawRoundedRect*[R]( break if missingAnyCorner: - let circle = - when defined(figuroNoSDF): - if doStroke: - generateCircleBox(radii, stroked = true, lineWidth = weight, outerShadowFill = outerShadowFill) - else: - generateCircleBox(radii, stroked = false, lineWidth = weight) + let circle = block: + let fill = rgba(255, 255, 255, 255) + let clear = rgba(0, 0, 0, 0) + var center = vec2(bw, bh) + let wh = vec2(2*bw+1, 2*bh+1) + let corners = radii.cornersToSdfRadii() + let circle = newImage(int(2*bw), int(2*bh)) + if doStroke: + drawSdfShape(circle, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = fill.to(ColorRGBA), + neg = clear.to(ColorRGBA), + factor = weight + 0.5, + spread = 0.0, + mode = sdfModeAnnular) else: - block: - let fill = rgba(255, 255, 255, 255) - let clear = rgba(0, 0, 0, 0) - var center = vec2(bw, bh) - let wh = vec2(2*bw+1, 2*bh+1) - let corners = radii.cornersToSdfRadii() - let circle = newImage(int(2*bw), int(2*bh)) - if doStroke: - drawSdfShape(circle, - center = center, - wh = wh, - params = RoundedBoxParams(r: corners), - pos = fill.to(ColorRGBA), - neg = clear.to(ColorRGBA), - factor = weight + 0.5, - spread = 0.0, - mode = sdfModeAnnular) - else: - drawSdfShape(circle, - center = center, - wh = wh, - params = RoundedBoxParams(r: corners), - pos = fill.to(ColorRGBA), - neg = clear.to(ColorRGBA), - mode = sdfModeClipAA) - circle + drawSdfShape(circle, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = fill.to(ColorRGBA), + neg = clear.to(ColorRGBA), + mode = sdfModeClipAA) + circle let patches = sliceToNinePatch(circle) # Store each piece in the atlas From d54489f223705ecfd5d39a626578af6a9d7a4e21 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:20:02 -0600 Subject: [PATCH 112/225] refactor --- src/figuro/renderer/utils/drawboxes.nim | 51 ++++++++++++------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 92630a769..d1cd3b050 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -60,32 +60,31 @@ proc drawRoundedRect*[R]( break if missingAnyCorner: - let circle = block: - let fill = rgba(255, 255, 255, 255) - let clear = rgba(0, 0, 0, 0) - var center = vec2(bw, bh) - let wh = vec2(2*bw+1, 2*bh+1) - let corners = radii.cornersToSdfRadii() - let circle = newImage(int(2*bw), int(2*bh)) - if doStroke: - drawSdfShape(circle, - center = center, - wh = wh, - params = RoundedBoxParams(r: corners), - pos = fill.to(ColorRGBA), - neg = clear.to(ColorRGBA), - factor = weight + 0.5, - spread = 0.0, - mode = sdfModeAnnular) - else: - drawSdfShape(circle, - center = center, - wh = wh, - params = RoundedBoxParams(r: corners), - pos = fill.to(ColorRGBA), - neg = clear.to(ColorRGBA), - mode = sdfModeClipAA) - circle + let fill = rgba(255, 255, 255, 255) + let clear = rgba(0, 0, 0, 0) + var center = vec2(bw, bh) + let wh = vec2(2*bw+1, 2*bh+1) + let corners = radii.cornersToSdfRadii() + var circle = newImage(int(2*bw), int(2*bh)) + + if doStroke: + drawSdfShape(circle, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = fill.to(ColorRGBA), + neg = clear.to(ColorRGBA), + factor = weight + 0.5, + spread = 0.0, + mode = sdfModeAnnular) + else: + drawSdfShape(circle, + center = center, + wh = wh, + params = RoundedBoxParams(r: corners), + pos = fill.to(ColorRGBA), + neg = clear.to(ColorRGBA), + mode = sdfModeClipAA) let patches = sliceToNinePatch(circle) # Store each piece in the atlas From a17fb474bf6bc19488289de27191948aec0c46e7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:22:25 -0600 Subject: [PATCH 113/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 46 +++++++++---------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index d1cd3b050..6a46d47b3 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -52,14 +52,10 @@ proc drawRoundedRect*[R]( for corner in DirectionCorners: cornerHashes[corner] = hash((hash, 41, int(radii[corner]))) - var missingAnyCorner = false for corner in DirectionCorners: - if cornerHashes[corner] notin ctx.entries: - # echo "missing corner: ", corner, " hash: ", cornerHashes[corner], " radius: ", radii[corner], " sideSize: ", cbs.sideSize, " maxRadius: ", cbs.maxRadius, " weight: ", weight, " doStroke: ", doStroke, " outerShadowFill: ", outerShadowFill - missingAnyCorner = true - break + if cornerHashes[corner] in ctx.entries: + continue - if missingAnyCorner: let fill = rgba(255, 255, 255, 255) let clear = rgba(0, 0, 0, 0) var center = vec2(bw, bh) @@ -86,30 +82,20 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - let patches = sliceToNinePatch(circle) - # Store each piece in the atlas - let cornerImages: array[DirectionCorners, Image] = [ - dcTopLeft: patches.topLeft, - dcTopRight: patches.topRight, - dcBottomLeft: patches.bottomLeft, - dcBottomRight: patches.bottomRight, - ] - - for corner in DirectionCorners: - let cornerHash = cornerHashes[corner] - if cornerHash notin ctx.entries: - let image = cornerImages[corner] - case corner: - of dcTopLeft: - discard - of dcTopRight: - image.flipHorizontal() - of dcBottomRight: - image.flipHorizontal() - image.flipVertical() - of dcBottomLeft: - image.flipVertical() - ctx.putImage(toKey(cornerHash), image) + let cornerHash = cornerHashes[corner] + if cornerHash notin ctx.entries: + let image = cornerImages[corner] + case corner: + of dcTopLeft: + discard + of dcTopRight: + image.flipHorizontal() + of dcBottomRight: + image.flipHorizontal() + image.flipVertical() + of dcBottomLeft: + image.flipVertical() + ctx.putImage(toKey(cornerHash), image) let xy = rect.xy From dda5935763de588dde501b932a0275e070582419 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:27:41 -0600 Subject: [PATCH 114/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 21 ++++------------- src/figuro/renderer/utils/drawutils.nim | 30 +++++-------------------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 6a46d47b3..b2724b931 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -61,10 +61,10 @@ proc drawRoundedRect*[R]( var center = vec2(bw, bh) let wh = vec2(2*bw+1, 2*bh+1) let corners = radii.cornersToSdfRadii() - var circle = newImage(int(2*bw), int(2*bh)) + var image = newImage(int(2*bw), int(2*bh)) if doStroke: - drawSdfShape(circle, + drawSdfShape(image, center = center, wh = wh, params = RoundedBoxParams(r: corners), @@ -74,7 +74,7 @@ proc drawRoundedRect*[R]( spread = 0.0, mode = sdfModeAnnular) else: - drawSdfShape(circle, + drawSdfShape(image, center = center, wh = wh, params = RoundedBoxParams(r: corners), @@ -82,20 +82,7 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - let cornerHash = cornerHashes[corner] - if cornerHash notin ctx.entries: - let image = cornerImages[corner] - case corner: - of dcTopLeft: - discard - of dcTopRight: - image.flipHorizontal() - of dcBottomRight: - image.flipHorizontal() - image.flipVertical() - of dcBottomLeft: - image.flipVertical() - ctx.putImage(toKey(cornerHash), image) + ctx.putImage(toKey(cornerHashes[corner]), image) let xy = rect.xy diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index d510f7eb3..db5464f4e 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -32,7 +32,7 @@ proc getCircleBoxSizes*( width = float32.high(), height = float32.high(), innerShadow = false, -): tuple[maxRadius, sideSize, totalSize, padding, inner: int] = +): tuple[maxRadius, sideSize, totalSize, padding, inner, weightSize: int] = result.maxRadius = 0 for r in radii: result.maxRadius = max(result.maxRadius, r.round().int) @@ -50,32 +50,14 @@ proc getCircleBoxSizes*( result.sideSize = min(result.maxRadius, min(bw, bh)).max(ww) result.totalSize = 3*result.sidesize + 3*padding result.inner = 3*result.sideSize + result.weightSize = ww proc roundedBoxCornerSizes*( radii: array[DirectionCorners, float32], - blur: float32, - spread: float32, - weight: float32 = 0.0, - width = float32.high(), - height = float32.high(), - innerShadow = false, -): array[DirectionCorners, tuple[dim, side, padding, sideSize, inner, totalSize: int]] = - let ww = int(1.5*weight.round()) - let bw = width.round().int - let bh = height.round().int - var maxRadius = 0 - for r in radii: - maxRadius = max(maxRadius, r.round().int) - - let padding = int(round(spread + 1.5 * blur)) - let sideSize = - if innerShadow: - min(maxRadius + padding, min(bw, bh)).max(ww) - else: - min(maxRadius, min(bw, bh)).max(ww) - let totalSize = 3*sideSize + 3*padding - let inner = 3*sideSize + cbs: tuple[maxRadius, sideSize, totalSize, padding, inner, weightSize: int], +): array[DirectionCorners, tuple[dim, sideDelta: int]] = + let ww = cbs.weightSize for corner in DirectionCorners: let dim = max(int(round(radii[corner])), ww) + 1 - result[corner] = (dim, sideSize, padding, sideSize, inner, totalSize) + result[corner] = (dim, cbs.sideSize - dim) From db61a24bbd029c39d541274c6ab890cf698a9980 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:33:07 -0600 Subject: [PATCH 115/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 1 + src/figuro/renderer/utils/drawutils.nim | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index b2724b931..163a3a169 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -46,6 +46,7 @@ proc drawRoundedRect*[R]( bh = cbs.sideSize.float32 let hash = hash((6217, int(cbs.sideSize), int(cbs.maxRadius), int(weight), doStroke, outerShadowFill)) + let cornerCbs = cbs.roundedBoxCornerSizes(radii) block drawCorners: var cornerHashes: array[DirectionCorners, Hash] diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index db5464f4e..3753ec3dc 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -53,11 +53,13 @@ proc getCircleBoxSizes*( result.weightSize = ww proc roundedBoxCornerSizes*( - radii: array[DirectionCorners, float32], cbs: tuple[maxRadius, sideSize, totalSize, padding, inner, weightSize: int], -): array[DirectionCorners, tuple[dim, sideDelta: int]] = + radii: array[DirectionCorners, float32], +): array[DirectionCorners, tuple[sideSize, inner, sideDelta, center: int]] = let ww = cbs.weightSize for corner in DirectionCorners: let dim = max(int(round(radii[corner])), ww) + 1 - result[corner] = (dim, cbs.sideSize - dim) + let sideSize = int(round(1.5*cbs.padding.float32)) + dim + let center = int(round(1.5*cbs.padding.float32)) + result[corner] = (sideSize, dim, sideSize - dim, center) From dc2ba133e1c17b47f412dcb45cef78c2bc99922e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:36:15 -0600 Subject: [PATCH 116/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 18 +++++++++--------- src/figuro/renderer/utils/drawutils.nim | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 163a3a169..a6c400fcd 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -53,21 +53,21 @@ proc drawRoundedRect*[R]( for corner in DirectionCorners: cornerHashes[corner] = hash((hash, 41, int(radii[corner]))) + let fill = rgba(255, 255, 255, 255) + let clear = rgba(0, 0, 0, 0) + for corner in DirectionCorners: if cornerHashes[corner] in ctx.entries: continue - let fill = rgba(255, 255, 255, 255) - let clear = rgba(0, 0, 0, 0) - var center = vec2(bw, bh) - let wh = vec2(2*bw+1, 2*bh+1) - let corners = radii.cornersToSdfRadii() var image = newImage(int(2*bw), int(2*bh)) + let cornerCbs = cornerCbs[corner] + let corners = [cornerCbs.radius, cornerCbs.radius, cornerCbs.radius, cornerCbs.radius] if doStroke: drawSdfShape(image, - center = center, - wh = wh, + center = vec2(cornerCbs.center, cornerCbs.center), + wh = vec2(cornerCbs.sideSize, cornerCbs.sideSize), params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), @@ -76,8 +76,8 @@ proc drawRoundedRect*[R]( mode = sdfModeAnnular) else: drawSdfShape(image, - center = center, - wh = wh, + center = vec2(cornerCbs.center, cornerCbs.center), + wh = vec2(cornerCbs.sideSize, cornerCbs.sideSize), params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 3753ec3dc..9d5c6d6bf 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -55,11 +55,11 @@ proc getCircleBoxSizes*( proc roundedBoxCornerSizes*( cbs: tuple[maxRadius, sideSize, totalSize, padding, inner, weightSize: int], radii: array[DirectionCorners, float32], -): array[DirectionCorners, tuple[sideSize, inner, sideDelta, center: int]] = +): array[DirectionCorners, tuple[radius, sideSize, inner, sideDelta, center: int]] = let ww = cbs.weightSize for corner in DirectionCorners: let dim = max(int(round(radii[corner])), ww) + 1 let sideSize = int(round(1.5*cbs.padding.float32)) + dim let center = int(round(1.5*cbs.padding.float32)) - result[corner] = (sideSize, dim, sideSize - dim, center) + result[corner] = (int(round(radii[corner])), sideSize, dim, sideSize - dim, center) From 36b7aaf8c5cdf1588bc78b2a949a9b46ac522c64 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:36:51 -0600 Subject: [PATCH 117/225] trying independently generated corners --- src/figuro/renderer/utils/drawextras.nim | 140 ----------------------- 1 file changed, 140 deletions(-) diff --git a/src/figuro/renderer/utils/drawextras.nim b/src/figuro/renderer/utils/drawextras.nim index c290c9f9e..15fcd15b5 100644 --- a/src/figuro/renderer/utils/drawextras.nim +++ b/src/figuro/renderer/utils/drawextras.nim @@ -73,143 +73,3 @@ proc sliceToNinePatch*(img: Image): tuple[ bottom: fbottom, left: fleft ) - -proc generateCircleBox*( - radii: array[DirectionCorners, float32], - offset = vec2(0, 0), - spread: float32 = 0.0'f32, - blur: float32 = 0.0'f32, - stroked: bool = true, - lineWidth: float32 = 0.0'f32, - fillStyle: ColorRGBA = rgba(255, 255, 255, 255), - shadowColor: ColorRGBA = rgba(255, 255, 255, 255), - outerShadow = true, - innerShadow = true, - innerShadowBorder = true, - outerShadowFill = false, -): Image = - - # Additional size for spread and blur - let lw = lineWidth.ceil() - let (maxRadius, sideSize, totalSize, padding, inner) = getCircleBoxSizes(radii, blur, spread, lineWidth) - - # Create a canvas large enough to contain the box with all effects - let img = newImage(totalSize, totalSize) - let bxy = newContext(img) - - # Calculate the inner box dimensions - let innerWidth = inner.float32 - let innerHeight = inner.float32 - - # Create a path for the rounded rectangle with the given dimensions and corner radii - proc createRoundedRectPath( - width, height: float32, - radii: array[DirectionCorners, float32], - padding: float32, - lw: float32 - ): pixie.Path = - # Start at top right after the corner radius - let hlw = lw / 2.0 - let padding = padding + hlw - let width = width - lw - let height = height - lw - - result = newPath() - let topRight = vec2(width - radii[dcTopRight], 0) - result.moveTo(topRight + vec2(padding, padding)) - - # Top right corner - let trControl = vec2(width, 0) - result.quadraticCurveTo( - trControl + vec2(padding, padding), - vec2(width, radii[dcTopRight]) + vec2(padding, padding) - ) - - # Right side - result.lineTo(vec2(width, height - radii[dcBottomRight]) + vec2(padding, padding)) - - # Bottom right corner - let brControl = vec2(width, height) - result.quadraticCurveTo( - brControl + vec2(padding, padding), - vec2(width - radii[dcBottomRight], height) + vec2(padding, padding) - ) - - # Bottom side - result.lineTo(vec2(radii[dcBottomLeft], height) + vec2(padding, padding)) - - # Bottom left corner - let blControl = vec2(0, height) - result.quadraticCurveTo( - blControl + vec2(padding, padding), - vec2(0, height - radii[dcBottomLeft]) + vec2(padding, padding) - ) - - # Left side - result.lineTo(vec2(0, radii[dcTopLeft]) + vec2(padding, padding)) - - # Top left corner - let tlControl = vec2(0, 0) - result.quadraticCurveTo( - tlControl + vec2(padding, padding), - vec2(radii[dcTopLeft], 0) + vec2(padding, padding) - ) - - # Close the path - result.lineTo(topRight + vec2(padding, padding)) - - # Create the path for our rounded rectangle - let path = createRoundedRectPath(innerWidth, innerHeight, radii, padding.float32, lw) - - # Draw the box - if stroked: - bxy.strokeStyle = fillStyle - bxy.lineWidth = lineWidth - bxy.stroke(path) - else: - bxy.fillStyle = fillStyle - bxy.fill(path) - - # Apply inner shadow if requested - if innerShadow or outerShadow or outerShadowFill: - let spath = createRoundedRectPath(innerWidth, innerHeight, radii, padding.float32, lw) - - let ctxImg = newContext(img) - if outerShadowFill: - let spath = spath.copy() - spath.rect(0, 0, totalSize.float32, totalSize.float32) - ctxImg.saveLayer() - ctxImg.clip(spath, EvenOdd) - ctxImg.fillStyle = fillStyle - ctxImg.rect(0, 0, totalSize.float32, totalSize.float32) - ctxImg.fill() - ctxImg.restore() - - let shadow = img.shadow( - offset = offset, - spread = spread, - blur = blur, - color = shadowColor - ) - - let combined = newImage(totalSize, totalSize) - let bxy = newContext(combined) - if innerShadow: - bxy.saveLayer() - bxy.clip(spath, EvenOdd) - bxy.drawImage(shadow, pos = vec2(0, 0)) - bxy.drawImage(shadow, pos = vec2(0, 0)) - bxy.drawImage(shadow, pos = vec2(0, 0)) - bxy.restore() - if outerShadow: - let spath = spath.copy() - spath.rect(0, 0, totalSize.float32, totalSize.float32) - bxy.saveLayer() - bxy.clip(spath, EvenOdd) - bxy.drawImage(shadow, pos = vec2(0, 0)) - bxy.restore() - if innerShadowBorder: - bxy.drawImage(img, pos = vec2(0, 0)) - return combined - else: - return img From bfc5bc9e1ecb7f4e29c19ffebc14288f7a8c7e75 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:37:24 -0600 Subject: [PATCH 118/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index a6c400fcd..1652f7311 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -66,8 +66,8 @@ proc drawRoundedRect*[R]( if doStroke: drawSdfShape(image, - center = vec2(cornerCbs.center, cornerCbs.center), - wh = vec2(cornerCbs.sideSize, cornerCbs.sideSize), + center = vec2(cornerCbs.center.float32, cornerCbs.center.float32), + wh = vec2(cornerCbs.sideSize.float32, cornerCbs.sideSize.float32), params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), @@ -76,8 +76,8 @@ proc drawRoundedRect*[R]( mode = sdfModeAnnular) else: drawSdfShape(image, - center = vec2(cornerCbs.center, cornerCbs.center), - wh = vec2(cornerCbs.sideSize, cornerCbs.sideSize), + center = vec2(cornerCbs.center.float32, cornerCbs.center.float32), + wh = vec2(cornerCbs.sideSize.float32, cornerCbs.sideSize.float32), params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), From ad32afd8fff6f03a02e360361f63210affdce3a8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:38:14 -0600 Subject: [PATCH 119/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 1652f7311..2cae5aa38 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -62,7 +62,7 @@ proc drawRoundedRect*[R]( var image = newImage(int(2*bw), int(2*bh)) let cornerCbs = cornerCbs[corner] - let corners = [cornerCbs.radius, cornerCbs.radius, cornerCbs.radius, cornerCbs.radius] + let corners = vec4(cornerCbs.radius.float32) if doStroke: drawSdfShape(image, From 1af9900eca3a5191542bda5be0cab9c5b2dd9ffa Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:41:54 -0600 Subject: [PATCH 120/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 2cae5aa38..2ef7e260e 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -83,6 +83,9 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) + let msg = "corner-" & $corner & "-" & $cornerCbs.sideSize & "-" & $cornerCbs.center & "-" & $cornerCbs.radius & "-" & $weight & "-" & $doStroke & "-" & $outerShadowFill + echo "generating corner: ", msg + image.writeFile("tests/" & msg & ".png") ctx.putImage(toKey(cornerHashes[corner]), image) let From 156a045d4abd420f569dd3d0263d75948eef4763 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:46:12 -0600 Subject: [PATCH 121/225] trying independently generated corners --- src/figuro/renderer/utils/drawboxes.nim | 8 ++++---- src/figuro/renderer/utils/drawutils.nim | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 2ef7e260e..9669d9e2c 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -60,14 +60,14 @@ proc drawRoundedRect*[R]( if cornerHashes[corner] in ctx.entries: continue - var image = newImage(int(2*bw), int(2*bh)) let cornerCbs = cornerCbs[corner] let corners = vec4(cornerCbs.radius.float32) + var image = newImage(cornerCbs.sideSize, cornerCbs.sideSize) if doStroke: drawSdfShape(image, center = vec2(cornerCbs.center.float32, cornerCbs.center.float32), - wh = vec2(cornerCbs.sideSize.float32, cornerCbs.sideSize.float32), + wh = vec2(2*cornerCbs.sideSize.float32, 2*cornerCbs.sideSize.float32), params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), @@ -83,9 +83,9 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - let msg = "corner-" & $corner & "-" & $cornerCbs.sideSize & "-" & $cornerCbs.center & "-" & $cornerCbs.radius & "-" & $weight & "-" & $doStroke & "-" & $outerShadowFill + let msg = "corner-" & $corner & "-sideSize" & $cornerCbs.sideSize & "-center" & $cornerCbs.center & "-radius" & $cornerCbs.radius & "-weight" & $weight & "-doStroke" & $doStroke & "-outerShadowFill" & $outerShadowFill echo "generating corner: ", msg - image.writeFile("tests/" & msg & ".png") + image.writeFile("examples/" & msg & ".png") ctx.putImage(toKey(cornerHashes[corner]), image) let diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 9d5c6d6bf..2fb30c31c 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -61,5 +61,5 @@ proc roundedBoxCornerSizes*( for corner in DirectionCorners: let dim = max(int(round(radii[corner])), ww) + 1 let sideSize = int(round(1.5*cbs.padding.float32)) + dim - let center = int(round(1.5*cbs.padding.float32)) + let center = sideSize - 1 result[corner] = (int(round(radii[corner])), sideSize, dim, sideSize - dim, center) From 03a23e901fd1b9c845cdc984380404e92e4da38a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:49:10 -0600 Subject: [PATCH 122/225] trying independently generated corners --- src/figuro/renderer/utils/drawutils.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 2fb30c31c..18d9e6360 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -59,7 +59,7 @@ proc roundedBoxCornerSizes*( let ww = cbs.weightSize for corner in DirectionCorners: - let dim = max(int(round(radii[corner])), ww) + 1 + let dim = max(int(round(radii[corner])), ww) let sideSize = int(round(1.5*cbs.padding.float32)) + dim - let center = sideSize - 1 + let center = sideSize result[corner] = (int(round(radii[corner])), sideSize, dim, sideSize - dim, center) From 71bd8f699874677fc4f972d4f841b49750bedf8f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 01:55:19 -0600 Subject: [PATCH 123/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 7 ++++--- src/figuro/renderer/utils/drawutils.nim | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 9669d9e2c..f67cea957 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -63,11 +63,12 @@ proc drawRoundedRect*[R]( let cornerCbs = cornerCbs[corner] let corners = vec4(cornerCbs.radius.float32) var image = newImage(cornerCbs.sideSize, cornerCbs.sideSize) + let wh = vec2(2*cornerCbs.sideSize.float32, 2*cornerCbs.sideSize.float32) if doStroke: drawSdfShape(image, center = vec2(cornerCbs.center.float32, cornerCbs.center.float32), - wh = vec2(2*cornerCbs.sideSize.float32, 2*cornerCbs.sideSize.float32), + wh = wh, params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), @@ -77,13 +78,13 @@ proc drawRoundedRect*[R]( else: drawSdfShape(image, center = vec2(cornerCbs.center.float32, cornerCbs.center.float32), - wh = vec2(cornerCbs.sideSize.float32, cornerCbs.sideSize.float32), + wh = wh, params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - let msg = "corner-" & $corner & "-sideSize" & $cornerCbs.sideSize & "-center" & $cornerCbs.center & "-radius" & $cornerCbs.radius & "-weight" & $weight & "-doStroke" & $doStroke & "-outerShadowFill" & $outerShadowFill + let msg = "corner-" & $corner & "-sideSize" & $cornerCbs.sideSize & "-wh" & $wh.x & "-padding" & $cbs.padding & "-center" & $cornerCbs.center & "-radius" & $cornerCbs.radius & "-weight" & $weight & "-doStroke" & $doStroke & "-outerShadowFill" & $outerShadowFill echo "generating corner: ", msg image.writeFile("examples/" & msg & ".png") ctx.putImage(toKey(cornerHashes[corner]), image) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 18d9e6360..402600956 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -41,7 +41,8 @@ proc getCircleBoxSizes*( let bh = height.round().int let blur = blur.round().int let spread = spread.round().int - let padding = max(spread + blur, result.maxRadius) + # let padding = max(spread + blur, result.maxRadius) + let padding = spread + blur result.padding = padding if innerShadow: From cbe1a100d333d42c3cfabfac89d72fea2fdb42b4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 02:23:31 -0600 Subject: [PATCH 124/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index f67cea957..5c2266b44 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -45,7 +45,8 @@ proc drawRoundedRect*[R]( bw = cbs.sideSize.float32 bh = cbs.sideSize.float32 - let hash = hash((6217, int(cbs.sideSize), int(cbs.maxRadius), int(weight), doStroke, outerShadowFill)) + # let hash = hash((6217, int(cbs.sideSize), int(cbs.maxRadius), int(weight), doStroke, outerShadowFill)) + let hash = hash((6217, doStroke, outerShadowFill, cbs.padding, cbs.weightSize)) let cornerCbs = cbs.roundedBoxCornerSizes(radii) block drawCorners: @@ -84,9 +85,20 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - let msg = "corner-" & $corner & "-sideSize" & $cornerCbs.sideSize & "-wh" & $wh.x & "-padding" & $cbs.padding & "-center" & $cornerCbs.center & "-radius" & $cornerCbs.radius & "-weight" & $weight & "-doStroke" & $doStroke & "-outerShadowFill" & $outerShadowFill - echo "generating corner: ", msg - image.writeFile("examples/" & msg & ".png") + if doStroke: + var msg = "corner" + msg &= "-weight" & $weight + msg &= "-radius" & $cornerCbs.radius + msg &= "-sideSize" & $cornerCbs.sideSize + msg &= "-wh" & $wh.x + msg &= "-padding" & $cbs.padding + msg &= "-center" & $cornerCbs.center + msg &= "-doStroke" & (if doStroke: "true" else: "false") + msg &= "-outerShadowFill" & (if outerShadowFill: "true" else: "false") + msg &= "-corner-" & $corner + msg &= "-hash" & $cast[uint](int(cornerHashes[corner])) + echo "generating corner: ", msg + image.writeFile("examples/" & msg & ".png") ctx.putImage(toKey(cornerHashes[corner]), image) let From d9918a5ec23ee8acea9c51ee3ac0d28183d40bcf Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 02:39:38 -0600 Subject: [PATCH 125/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 33 +++++++++++++++++++------ 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 5c2266b44..82bfce1b0 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -22,6 +22,15 @@ proc drawOuterBox*[R](ctx: R, rect: Rect, padding: float32, color: Color) = ctx.drawRect(rectBottom, color) ctx.drawRect(rectRight, color) +proc toHex*(h: Hash): string = + const HexChars = "0123456789ABCDEF" + result = newString(sizeof(Hash) * 2) + var h = h + for i in countdown(result.high, 0): + result[i] = HexChars[h and 0xF] + h = h shr 4 + + proc drawRoundedRect*[R]( ctx: R, rect: Rect, @@ -73,7 +82,7 @@ proc drawRoundedRect*[R]( params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), neg = clear.to(ColorRGBA), - factor = weight + 0.5, + factor = cbs.weightSize.float32, spread = 0.0, mode = sdfModeAnnular) else: @@ -96,7 +105,7 @@ proc drawRoundedRect*[R]( msg &= "-doStroke" & (if doStroke: "true" else: "false") msg &= "-outerShadowFill" & (if outerShadowFill: "true" else: "false") msg &= "-corner-" & $corner - msg &= "-hash" & $cast[uint](int(cornerHashes[corner])) + msg &= "-hash" & toHex(cornerHashes[corner]) echo "generating corner: ", msg image.writeFile("examples/" & msg & ".png") ctx.putImage(toKey(cornerHashes[corner]), image) @@ -110,29 +119,37 @@ proc drawRoundedRect*[R]( bottomLeft = xy + vec2(0, h - bh) bottomRight = xy + vec2(w - bw, h - bh) + tlCornerSize = vec2(cornerCbs[dcTopLeft].sideSize.float32, cornerCbs[dcTopLeft].sideSize.float32) + trCornerSize = vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32) + blCornerSize = vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32) + brCornerSize = vec2(cornerCbs[dcBottomRight].sideSize.float32, cornerCbs[dcBottomRight].sideSize.float32) + + if doStroke: + echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize + ctx.saveTransform() ctx.translate(topLeft) ctx.drawImage(cornerHashes[dcTopLeft], zero, color) ctx.restoreTransform() ctx.saveTransform() - ctx.translate(topRight + cornerSize / 2) + ctx.translate(topRight + trCornerSize / 2) ctx.rotate(-Pi/2) - ctx.translate(-cornerSize / 2) + ctx.translate(-trCornerSize / 2) ctx.drawImage(cornerHashes[dcTopRight], zero, color) ctx.restoreTransform() ctx.saveTransform() - ctx.translate(bottomLeft + cornerSize / 2) + ctx.translate(bottomLeft + blCornerSize / 2) ctx.rotate(Pi/2) - ctx.translate(-cornerSize / 2) + ctx.translate(-blCornerSize / 2) ctx.drawImage(cornerHashes[dcBottomLeft], zero, color) ctx.restoreTransform() ctx.saveTransform() - ctx.translate(bottomRight + cornerSize / 2) + ctx.translate(bottomRight + brCornerSize / 2) ctx.rotate(Pi) - ctx.translate(-cornerSize / 2) + ctx.translate(-brCornerSize / 2) ctx.drawImage(cornerHashes[dcBottomRight], zero, color) ctx.restoreTransform() From 12a25e7c4a6c29d474cee35b74535474283f2438 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 02:46:41 -0600 Subject: [PATCH 126/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 3 ++- tests/tbutton.nim | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 82bfce1b0..89c5c2fa1 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -140,10 +140,11 @@ proc drawRoundedRect*[R]( ctx.restoreTransform() ctx.saveTransform() + # ctx.translate(bottomLeft) ctx.translate(bottomLeft + blCornerSize / 2) ctx.rotate(Pi/2) ctx.translate(-blCornerSize / 2) - ctx.drawImage(cornerHashes[dcBottomLeft], zero, color) + ctx.drawImage(cornerHashes[dcBottomLeft], zero, rgba(0, 0, 0, 255).to(Color)) ctx.restoreTransform() ctx.saveTransform() diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 2c4749813..8c1e71dfc 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -51,8 +51,8 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 40'ux, 30'pp, 30'pp - fill css"#2B9F2B" * 0.5 - border 5'ui, css"darkgreen" * 0.5 + fill css"#2B9F2B" * 0.3 + border 5'ui, css"darkgreen" * 0.2 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From a684fbec39d790e52a77f539db86eda075d9d8bb Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 02:59:05 -0600 Subject: [PATCH 127/225] perfect corners same radii --- src/figuro/renderer/opengl/renderer.nim | 32 ++++++++++++------------- src/figuro/renderer/utils/drawboxes.nim | 20 +++++++++------- tests/tbutton.nim | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index f2567c16e..0df8289ee 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -251,13 +251,13 @@ proc render( ifrender node.kind == nkRectangle: ctx.renderDropShadows(node) - # handle clipping children content based on this node - ifrender NfClipContent in node.flags: - ctx.beginMask() - ctx.drawMasks(node) - ctx.endMask() - finally: - ctx.popMask() + # # handle clipping children content based on this node + # ifrender NfClipContent in node.flags: + # ctx.beginMask() + # ctx.drawMasks(node) + # ctx.endMask() + # finally: + # ctx.popMask() ifrender true: if node.kind == nkText: @@ -270,15 +270,15 @@ proc render( elif node.kind == nkRectangle: ctx.renderBoxes(node) - ifrender node.kind == nkRectangle: - if NfClipContent notin node.flags: - ctx.beginMask() - ctx.drawMasks(node) - ctx.endMask() - ctx.renderInnerShadows(node) - ctx.popMask() - else: - ctx.renderInnerShadows(node) + # ifrender node.kind == nkRectangle: + # if NfClipContent notin node.flags: + # ctx.beginMask() + # ctx.drawMasks(node) + # ctx.endMask() + # ctx.renderInnerShadows(node) + # ctx.popMask() + # else: + # ctx.renderInnerShadows(node) # restores the opengl context back to the parent node's (see above) # ctx.restoreTransform() diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 89c5c2fa1..0d8af8ffd 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -115,28 +115,31 @@ proc drawRoundedRect*[R]( zero = vec2(0, 0) cornerSize = vec2(bw, bh) topLeft = xy + vec2(0, 0) - topRight = xy + vec2(w - bw, 0) - bottomLeft = xy + vec2(0, h - bh) - bottomRight = xy + vec2(w - bw, h - bh) + topRight = xy + vec2(w - bw + cornerCbs[dcTopRight].sideDelta.float32, 0) + bottomLeft = xy + vec2(0, h - bh + cornerCbs[dcBottomLeft].sideDelta.float32) + bottomRight = xy + vec2(w - bw + cornerCbs[dcBottomRight].sideDelta.float32, + h - bh + cornerCbs[dcBottomRight].sideDelta.float32) tlCornerSize = vec2(cornerCbs[dcTopLeft].sideSize.float32, cornerCbs[dcTopLeft].sideSize.float32) trCornerSize = vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32) blCornerSize = vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32) brCornerSize = vec2(cornerCbs[dcBottomRight].sideSize.float32, cornerCbs[dcBottomRight].sideSize.float32) + darkGrey = rgba(50, 50, 50, 255).to(Color) + if doStroke: - echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize + echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize & " blPos: " & $(bottomLeft + blCornerSize / 2) ctx.saveTransform() ctx.translate(topLeft) - ctx.drawImage(cornerHashes[dcTopLeft], zero, color) + ctx.drawImage(cornerHashes[dcTopLeft], zero, darkGrey) ctx.restoreTransform() ctx.saveTransform() ctx.translate(topRight + trCornerSize / 2) ctx.rotate(-Pi/2) ctx.translate(-trCornerSize / 2) - ctx.drawImage(cornerHashes[dcTopRight], zero, color) + ctx.drawImage(cornerHashes[dcTopRight], zero, darkGrey) ctx.restoreTransform() ctx.saveTransform() @@ -144,14 +147,15 @@ proc drawRoundedRect*[R]( ctx.translate(bottomLeft + blCornerSize / 2) ctx.rotate(Pi/2) ctx.translate(-blCornerSize / 2) - ctx.drawImage(cornerHashes[dcBottomLeft], zero, rgba(0, 0, 0, 255).to(Color)) + ctx.drawImage(cornerHashes[dcBottomLeft], zero, darkGrey) + # ctx.drawImage(cornerHashes[dcBottomLeft], zero, rgba(0, 0, 0, 255).to(Color)) ctx.restoreTransform() ctx.saveTransform() ctx.translate(bottomRight + brCornerSize / 2) ctx.rotate(Pi) ctx.translate(-brCornerSize / 2) - ctx.drawImage(cornerHashes[dcBottomRight], zero, color) + ctx.drawImage(cornerHashes[dcBottomRight], zero, darkGrey) ctx.restoreTransform() block drawEdgeBoxes: diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 8c1e71dfc..c0f039850 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -52,7 +52,7 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 40'ux, 30'pp, 30'pp fill css"#2B9F2B" * 0.3 - border 5'ui, css"darkgreen" * 0.2 + # border 5'ui, css"darkgreen" * 0.2 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From d7b5ad7688054eb521964df8a6b8fbc7471fa313 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:09:23 -0600 Subject: [PATCH 128/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 0d8af8ffd..79160e141 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -94,8 +94,9 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - if doStroke: + if cornerCbs.radius != 40: var msg = "corner" + msg &= (if doStroke: "-stroke" else: "-noStroke") msg &= "-weight" & $weight msg &= "-radius" & $cornerCbs.radius msg &= "-sideSize" & $cornerCbs.sideSize @@ -127,8 +128,8 @@ proc drawRoundedRect*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) - if doStroke: - echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize & " blPos: " & $(bottomLeft + blCornerSize / 2) + if cornerCbs[dcBottomLeft].radius != 40: + echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize & " blPos: " & $(bottomLeft + blCornerSize / 2) & " doStroke: " & $doStroke ctx.saveTransform() ctx.translate(topLeft) From e7a93b8517583a51d5e00ee7691ee1140c7bf057 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:12:15 -0600 Subject: [PATCH 129/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 79160e141..85ca8a0c8 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -94,7 +94,7 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - if cornerCbs.radius != 40: + if color.a != 1.0: var msg = "corner" msg &= (if doStroke: "-stroke" else: "-noStroke") msg &= "-weight" & $weight @@ -128,8 +128,8 @@ proc drawRoundedRect*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) - if cornerCbs[dcBottomLeft].radius != 40: - echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize & " blPos: " & $(bottomLeft + blCornerSize / 2) & " doStroke: " & $doStroke + if color.a != 1.0: + echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " color: " & $color & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize & " blPos: " & $(bottomLeft + blCornerSize / 2) & " doStroke: " & $doStroke ctx.saveTransform() ctx.translate(topLeft) From 1285f3a98a0e569f7a1635c1e57f7b5066672a92 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:19:49 -0600 Subject: [PATCH 130/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 2 +- src/figuro/renderer/utils/drawutils.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 85ca8a0c8..e6a97c040 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -129,7 +129,7 @@ proc drawRoundedRect*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) if color.a != 1.0: - echo "drawing corners: ", "BL: " & toHex(cornerHashes[dcBottomLeft]) & " color: " & $color & " hasImage: " & $ctx.hasImage(cornerHashes[dcBottomLeft]) & " cornerSize: " & $blCornerSize & " blPos: " & $(bottomLeft + blCornerSize / 2) & " doStroke: " & $doStroke + 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 ctx.saveTransform() ctx.translate(topLeft) diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 402600956..fc058aaca 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -63,4 +63,4 @@ proc roundedBoxCornerSizes*( let dim = max(int(round(radii[corner])), ww) let sideSize = int(round(1.5*cbs.padding.float32)) + dim let center = sideSize - result[corner] = (int(round(radii[corner])), sideSize, dim, sideSize - dim, center) + result[corner] = (int(round(radii[corner])), sideSize, dim, cbs.sideSize - dim, center) From 191347393244377e66eab001bc0364892d82fa9f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:21:34 -0600 Subject: [PATCH 131/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index e6a97c040..525ebe345 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -121,7 +121,7 @@ proc drawRoundedRect*[R]( bottomRight = xy + vec2(w - bw + cornerCbs[dcBottomRight].sideDelta.float32, h - bh + cornerCbs[dcBottomRight].sideDelta.float32) - tlCornerSize = vec2(cornerCbs[dcTopLeft].sideSize.float32, cornerCbs[dcTopLeft].sideSize.float32) + tlCornerSize = vec2(0.0, 0.0) trCornerSize = vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32) blCornerSize = vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32) brCornerSize = vec2(cornerCbs[dcBottomRight].sideSize.float32, cornerCbs[dcBottomRight].sideSize.float32) @@ -132,8 +132,9 @@ proc drawRoundedRect*[R]( 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 ctx.saveTransform() - ctx.translate(topLeft) + ctx.translate(topLeft + tlCornerSize / 2) ctx.drawImage(cornerHashes[dcTopLeft], zero, darkGrey) + ctx.translate(-tlCornerSize / 2) ctx.restoreTransform() ctx.saveTransform() From f8cda48d32ef72e5f371d25e00946ab925562b10 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:26:54 -0600 Subject: [PATCH 132/225] perfect corners same radii --- src/figuro/renderer/utils/drawboxes.nim | 89 ++++++++++++++----------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 525ebe345..c3a3347e0 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -115,50 +115,59 @@ proc drawRoundedRect*[R]( xy = rect.xy zero = vec2(0, 0) cornerSize = vec2(bw, bh) - topLeft = xy + vec2(0, 0) - topRight = xy + vec2(w - bw + cornerCbs[dcTopRight].sideDelta.float32, 0) - bottomLeft = xy + vec2(0, h - bh + cornerCbs[dcBottomLeft].sideDelta.float32) - bottomRight = xy + vec2(w - bw + cornerCbs[dcBottomRight].sideDelta.float32, - h - bh + cornerCbs[dcBottomRight].sideDelta.float32) - tlCornerSize = vec2(0.0, 0.0) - trCornerSize = vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32) - blCornerSize = vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32) - brCornerSize = vec2(cornerCbs[dcBottomRight].sideSize.float32, cornerCbs[dcBottomRight].sideSize.float32) + cpos = [ + dcTopLeft: xy + vec2(0, 0), + dcTopRight: xy + vec2(w - bw + cornerCbs[dcTopRight].sideDelta.float32, 0), + dcBottomLeft: xy + vec2(0, h - bh + cornerCbs[dcBottomLeft].sideDelta.float32), + dcBottomRight: xy + vec2(w - bw + cornerCbs[dcBottomRight].sideDelta.float32, + h - bh + cornerCbs[dcBottomRight].sideDelta.float32) + ] + + csizes = [ + dcTopLeft: vec2(0.0, 0.0), + dcTopRight: vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32), + dcBottomLeft: vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32), + dcBottomRight: vec2(cornerCbs[dcBottomRight].sideSize.float32, cornerCbs[dcBottomRight].sideSize.float32) + ] darkGrey = rgba(50, 50, 50, 255).to(Color) - if color.a != 1.0: - 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 - - ctx.saveTransform() - ctx.translate(topLeft + tlCornerSize / 2) - ctx.drawImage(cornerHashes[dcTopLeft], zero, darkGrey) - ctx.translate(-tlCornerSize / 2) - ctx.restoreTransform() - - ctx.saveTransform() - ctx.translate(topRight + trCornerSize / 2) - ctx.rotate(-Pi/2) - ctx.translate(-trCornerSize / 2) - ctx.drawImage(cornerHashes[dcTopRight], zero, darkGrey) - ctx.restoreTransform() - - ctx.saveTransform() - # ctx.translate(bottomLeft) - ctx.translate(bottomLeft + blCornerSize / 2) - ctx.rotate(Pi/2) - ctx.translate(-blCornerSize / 2) - ctx.drawImage(cornerHashes[dcBottomLeft], zero, darkGrey) - # ctx.drawImage(cornerHashes[dcBottomLeft], zero, rgba(0, 0, 0, 255).to(Color)) - ctx.restoreTransform() - - ctx.saveTransform() - ctx.translate(bottomRight + brCornerSize / 2) - ctx.rotate(Pi) - ctx.translate(-brCornerSize / 2) - ctx.drawImage(cornerHashes[dcBottomRight], zero, darkGrey) - ctx.restoreTransform() + angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: Pi] + + # if color.a != 1.0: + # 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 + + for corner in DirectionCorners: + ctx.saveTransform() + ctx.translate(cpos[corner] + csizes[corner] / 2) + ctx.rotate(angles[corner]) + ctx.translate(-csizes[corner] / 2) + ctx.drawImage(cornerHashes[corner], zero, darkGrey) + ctx.restoreTransform() + + # ctx.saveTransform() + # ctx.translate(topRight + trCornerSize / 2) + # ctx.rotate(-Pi/2) + # ctx.translate(-trCornerSize / 2) + # ctx.drawImage(cornerHashes[dcTopRight], zero, darkGrey) + # ctx.restoreTransform() + + # ctx.saveTransform() + # # ctx.translate(bottomLeft) + # ctx.translate(bottomLeft + blCornerSize / 2) + # ctx.rotate(Pi/2) + # ctx.translate(-blCornerSize / 2) + # ctx.drawImage(cornerHashes[dcBottomLeft], zero, darkGrey) + # # ctx.drawImage(cornerHashes[dcBottomLeft], zero, rgba(0, 0, 0, 255).to(Color)) + # ctx.restoreTransform() + + # ctx.saveTransform() + # ctx.translate(bottomRight + brCornerSize / 2) + # ctx.rotate(Pi) + # ctx.translate(-brCornerSize / 2) + # ctx.drawImage(cornerHashes[dcBottomRight], zero, darkGrey) + # ctx.restoreTransform() block drawEdgeBoxes: let From ee4ccf63c0187ff37bdbc1a17fa59a7281abb25d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:27:08 -0600 Subject: [PATCH 133/225] change to loop --- src/figuro/renderer/utils/drawboxes.nim | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index c3a3347e0..90eb7f478 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -146,29 +146,6 @@ proc drawRoundedRect*[R]( ctx.drawImage(cornerHashes[corner], zero, darkGrey) ctx.restoreTransform() - # ctx.saveTransform() - # ctx.translate(topRight + trCornerSize / 2) - # ctx.rotate(-Pi/2) - # ctx.translate(-trCornerSize / 2) - # ctx.drawImage(cornerHashes[dcTopRight], zero, darkGrey) - # ctx.restoreTransform() - - # ctx.saveTransform() - # # ctx.translate(bottomLeft) - # ctx.translate(bottomLeft + blCornerSize / 2) - # ctx.rotate(Pi/2) - # ctx.translate(-blCornerSize / 2) - # ctx.drawImage(cornerHashes[dcBottomLeft], zero, darkGrey) - # # ctx.drawImage(cornerHashes[dcBottomLeft], zero, rgba(0, 0, 0, 255).to(Color)) - # ctx.restoreTransform() - - # ctx.saveTransform() - # ctx.translate(bottomRight + brCornerSize / 2) - # ctx.rotate(Pi) - # ctx.translate(-brCornerSize / 2) - # ctx.drawImage(cornerHashes[dcBottomRight], zero, darkGrey) - # ctx.restoreTransform() - block drawEdgeBoxes: let ww = if doStroke: weight else: cbs.sideSize.float32 From fb2df93b5933e194f760db830c25dc6d1eca947b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:36:10 -0600 Subject: [PATCH 134/225] change to loop --- src/figuro/renderer/utils/drawboxes.nim | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 90eb7f478..5247cf87b 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -118,10 +118,16 @@ proc drawRoundedRect*[R]( cpos = [ dcTopLeft: xy + vec2(0, 0), - dcTopRight: xy + vec2(w - bw + cornerCbs[dcTopRight].sideDelta.float32, 0), - dcBottomLeft: xy + vec2(0, h - bh + cornerCbs[dcBottomLeft].sideDelta.float32), - dcBottomRight: xy + vec2(w - bw + cornerCbs[dcBottomRight].sideDelta.float32, - h - bh + cornerCbs[dcBottomRight].sideDelta.float32) + dcTopRight: xy + vec2(w - bw, 0), + dcBottomLeft: xy + vec2(0, h - bh), + dcBottomRight: xy + vec2(w - bw, h - bh) + ] + + coffset = [ + dcTopLeft: vec2(0, 0), + dcTopRight: vec2(cornerCbs[dcTopRight].sideDelta.float32, 0), + dcBottomLeft: vec2(0, cornerCbs[dcBottomLeft].sideDelta.float32), + dcBottomRight: vec2(cornerCbs[dcBottomRight].sideDelta.float32, cornerCbs[dcBottomRight].sideDelta.float32) ] csizes = [ @@ -140,12 +146,17 @@ proc drawRoundedRect*[R]( for corner in DirectionCorners: ctx.saveTransform() - ctx.translate(cpos[corner] + csizes[corner] / 2) + ctx.translate(cpos[corner] + coffset[corner] + csizes[corner] / 2) ctx.rotate(angles[corner]) ctx.translate(-csizes[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, darkGrey) ctx.restoreTransform() + if cornerCbs[corner].sideDelta > 0: + let inner = cornerCbs[corner].inner.float32 + let sideDelta = cornerCbs[corner].sideDelta.float32 + ctx.drawRect(rect(cpos[corner].x, cpos[corner].y, inner, sideDelta), color) + block drawEdgeBoxes: let ww = if doStroke: weight else: cbs.sideSize.float32 From 0e81adcaa16181c8709899c2e7730b66806eac8f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:42:15 -0600 Subject: [PATCH 135/225] change to loop --- src/figuro/renderer/utils/drawboxes.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 5247cf87b..c22a1c826 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -150,12 +150,13 @@ proc drawRoundedRect*[R]( ctx.rotate(angles[corner]) ctx.translate(-csizes[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, darkGrey) - ctx.restoreTransform() if cornerCbs[corner].sideDelta > 0: let inner = cornerCbs[corner].inner.float32 let sideDelta = cornerCbs[corner].sideDelta.float32 - ctx.drawRect(rect(cpos[corner].x, cpos[corner].y, inner, sideDelta), color) + ctx.drawRect(rect(0, inner, inner, sideDelta), color) + + ctx.restoreTransform() block drawEdgeBoxes: let From 650e6950761c55db806aa3b96ee0258367c33a3f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:46:04 -0600 Subject: [PATCH 136/225] change to loop --- src/figuro/renderer/utils/drawboxes.nim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index c22a1c826..6381c8e92 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -94,7 +94,7 @@ proc drawRoundedRect*[R]( neg = clear.to(ColorRGBA), mode = sdfModeClipAA) - if color.a != 1.0: + if color.a != 1.0 and false: var msg = "corner" msg &= (if doStroke: "-stroke" else: "-noStroke") msg &= "-weight" & $weight @@ -154,7 +154,12 @@ proc drawRoundedRect*[R]( if cornerCbs[corner].sideDelta > 0: let inner = cornerCbs[corner].inner.float32 let sideDelta = cornerCbs[corner].sideDelta.float32 + let sideSize = cornerCbs[corner].sideSize.float32 + # inner patch left, right, and then center ctx.drawRect(rect(0, inner, inner, sideDelta), color) + ctx.drawRect(rect(inner, 0, sideDelta, sideSize), color) + # we could do two boxes, but this matches our shadow needs + ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), color) ctx.restoreTransform() From 5c8378e34098088b6435ab7158c01ee5a9922050 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:56:39 -0600 Subject: [PATCH 137/225] change to loop --- src/figuro/renderer/openglBackend.nim | 2 +- src/figuro/renderer/utils/drawboxes.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 08ab4a79e..346f77bd0 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 1024 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 6381c8e92..8ff63b285 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -149,7 +149,7 @@ proc drawRoundedRect*[R]( ctx.translate(cpos[corner] + coffset[corner] + csizes[corner] / 2) ctx.rotate(angles[corner]) ctx.translate(-csizes[corner] / 2) - ctx.drawImage(cornerHashes[corner], zero, darkGrey) + ctx.drawImage(cornerHashes[corner], zero, color) if cornerCbs[corner].sideDelta > 0: let inner = cornerCbs[corner].inner.float32 From 3d285eaf58da0e159cfca26ee86f6742332ba06a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 03:56:55 -0600 Subject: [PATCH 138/225] change to loop --- src/figuro/renderer/openglBackend.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 346f77bd0..08ab4a79e 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 1024 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) From f3c5bbd3a80234c8bb1df02f8ba04da6ab1e5123 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 21:29:55 -0600 Subject: [PATCH 139/225] fixing 21 patch setup --- src/figuro/renderer/utils/drawboxes.nim | 13 +++++++++---- src/figuro/renderer/utils/drawutils.nim | 2 +- tests/tbutton.nim | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 8ff63b285..3d69a15ab 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -109,6 +109,7 @@ proc drawRoundedRect*[R]( msg &= "-hash" & toHex(cornerHashes[corner]) echo "generating corner: ", msg image.writeFile("examples/" & msg & ".png") + ctx.putImage(toKey(cornerHashes[corner]), image) let @@ -156,10 +157,14 @@ proc drawRoundedRect*[R]( let sideDelta = cornerCbs[corner].sideDelta.float32 let sideSize = cornerCbs[corner].sideSize.float32 # inner patch left, right, and then center - ctx.drawRect(rect(0, inner, inner, sideDelta), color) - ctx.drawRect(rect(inner, 0, sideDelta, sideSize), color) - # we could do two boxes, but this matches our shadow needs - ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), color) + if doStroke: + ctx.drawRect(rect(0, inner, cbs.weightSize.float32, sideDelta), color) + ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) + else: + ctx.drawRect(rect(0, inner, inner, sideDelta), color) + ctx.drawRect(rect(inner, 0, sideDelta, sideSize), color) + # we could do two boxes, but this matches our shadow needs + ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), color) ctx.restoreTransform() diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index fc058aaca..70286b85f 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -36,7 +36,7 @@ proc getCircleBoxSizes*( result.maxRadius = 0 for r in radii: result.maxRadius = max(result.maxRadius, r.round().int) - let ww = int(1.5*weight.round()) + let ww = int(weight.round()) let bw = width.round().int let bh = height.round().int let blur = blur.round().int diff --git a/tests/tbutton.nim b/tests/tbutton.nim index c0f039850..8c1e71dfc 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -52,7 +52,7 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 40'ux, 30'pp, 30'pp fill css"#2B9F2B" * 0.3 - # border 5'ui, css"darkgreen" * 0.2 + border 5'ui, css"darkgreen" * 0.2 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From b0bb357d20a7f2bc2d79ef3ab61cd61f0208c159 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 21:45:17 -0600 Subject: [PATCH 140/225] shadow patch21 setup --- src/figuro/renderer/utils/drawboxes.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 260 ++++++++++------------ 2 files changed, 115 insertions(+), 147 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 3d69a15ab..5b40d58a5 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -77,7 +77,7 @@ proc drawRoundedRect*[R]( if doStroke: drawSdfShape(image, - center = vec2(cornerCbs.center.float32, cornerCbs.center.float32), + center = vec2(cornerCbs.center.float32), wh = wh, params = RoundedBoxParams(r: corners), pos = fill.to(ColorRGBA), diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 159e4ec32..ba0aba739 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -30,15 +30,6 @@ proc fillRoundedRectWithShadowSdf*[R]( # First, draw the shadow # Generate shadow key for caching - proc getShadowKey(blur: float32, spread: float32, totalSize: int, innerShadow: bool, radii: array[DirectionCorners, float32]): Hash = - result = hash((7723, blur.int, spread.int, innerShadow, totalSize)) - - proc getShadowKey(shadowKey: Hash, radii: array[DirectionCorners, float32], corner: DirectionCorners): Hash = - result = hash((shadowKey, 2474431, int(radii[corner]))) - - proc getShadowKey(shadowKey: Hash, radii: array[Directions, float32], side: Directions): Hash = - result = hash((shadowKey, 971767, int(side))) - let radii = clampRadii(radii, rect) shadowBlur = shadowBlur.round().float32 @@ -50,149 +41,126 @@ proc fillRoundedRectWithShadowSdf*[R]( height = rect.h, innerShadow = innerShadow) maxRadius = cbs.maxRadius - shadowKey = getShadowKey(shadowBlur, shadowSpread, cbs.totalSize, innerShadow, radii) wh = vec2(cbs.inner.float32, cbs.inner.float32) + + shadowKey = hash((7723, shadowBlur.int, shadowSpread.int, innerShadow)) - var cornerHashes: array[DirectionCorners, Hash] - for corner in DirectionCorners: - cornerHashes[corner] = getShadowKey(shadowKey, radii, corner) + let cornerCbs = cbs.roundedBoxCornerSizes(radii) var sideHashes: array[Directions, Hash] for side in Directions: - sideHashes[side] = getShadowKey(shadowKey, radii, side) - - # use the left side of the shadow key to check if we've already generated this shadow - let newSize = cbs.totalSize - let shadowKeyLeft = getShadowKey(shadowKey, radii, dLeft) - var missingAnyCorner = false - for corner in DirectionCorners: - if cornerHashes[corner] notin ctx.entries: - missingAnyCorner = true - break - - if shadowKeyLeft notin ctx.entries or missingAnyCorner: - let corners = radii.cornersToSdfRadii() + sideHashes[side] = hash((shadowKey, 971767, int(side))) + + block drawCorners: + var cornerHashes: array[DirectionCorners, Hash] + for corner in DirectionCorners: + cornerHashes[corner] = hash((shadowKey, 2474431, int(radii[corner]))) + + # use the left side of the shadow key to check if we've already generated this shadow const whiteColor = rgba(255, 255, 255, 255) - let center = vec2(cbs.totalSize.float32/2, cbs.totalSize.float32/2) - var shadowImg = newImage(newSize, newSize) - let wh = if innerShadow: vec2(cbs.inner.float32 - 2*shadowSpread, cbs.inner.float32 - 2*shadowSpread) else: vec2(cbs.inner.float32, cbs.inner.float32) - let spread = if innerShadow: 0.0 else: shadowSpread - - let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow - drawSdfShape( - shadowImg, - center = center, - wh = wh, - params = RoundedBoxParams(r: corners), - pos = whiteColor, - neg = whiteColor, - factor = shadowBlur, - spread = spread, - mode = mode) - - # Slice it into 9-patch pieces - let patches = sliceToNinePatch(shadowImg) - - let cornerImages = [ - dcTopLeft: patches.topLeft, - dcTopRight: patches.topRight, - dcBottomLeft: patches.bottomLeft, - dcBottomRight: patches.bottomRight, - ] - let sideImages = [ - dTop: patches.top, - dRight: patches.right, - dBottom: patches.bottom, - dLeft: patches.left, - ] for corner in DirectionCorners: - let cornerHash = cornerHashes[corner] - if cornerHash notin ctx.entries: - let image = cornerImages[corner] - case corner: - of dcTopLeft: + if cornerHashes[corner] in ctx.entries: + continue + + let corners = vec4(cornerCbs[corner].radius.float32) + var shadowImg = newImage(cornerCbs.sideSize, cornerCbs.sideSize) + let wh = vec2(2*cornerCbs.sideSize.float32, 2*cornerCbs.sideSize.float32) + + let spread = if innerShadow: 0.0 else: shadowSpread + let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow + + drawSdfShape(shadowImg, + center = vec2(cornerCbs.center.float32), + wh = wh, + params = RoundedBoxParams(r: corners), + pos = whiteColor, + neg = whiteColor, + factor = shadowBlur, + spread = spread, + mode = mode) + + ctx.putImage(cornerHashes[corner], shadowImg) + + var + totalPadding = (cbs.totalSize.float32 - cbs.inner.float32) / 2 + corner = totalPadding.float32 + cbs.inner.float32 / 2 + + let + xy = rect.xy + bw = cornerCbs[dcTopLeft].sideSize.float32 + bh = cornerCbs[dcTopLeft].sideSize.float32 + zero = vec2(0, 0) + cornerSize = vec2(bw, bh) + + cpos = [ + dcTopLeft: xy + vec2(0, 0), + dcTopRight: xy + vec2(w - bw, 0), + dcBottomLeft: xy + vec2(0, h - bh), + dcBottomRight: xy + vec2(w - bw, h - bh) + ] + + coffset = [ + dcTopLeft: vec2(0, 0), + dcTopRight: vec2(cornerCbs[dcTopRight].sideDelta.float32, 0), + dcBottomLeft: vec2(0, cornerCbs[dcBottomLeft].sideDelta.float32), + dcBottomRight: vec2(cornerCbs[dcBottomRight].sideDelta.float32, cornerCbs[dcBottomRight].sideDelta.float32) + ] + + csizes = [ + dcTopLeft: vec2(0.0, 0.0), + dcTopRight: vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32), + dcBottomLeft: vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32), + dcBottomRight: vec2(cornerCbs[dcBottomRight].sideSize.float32, cornerCbs[dcBottomRight].sideSize.float32) + ] + + darkGrey = rgba(50, 50, 50, 255).to(Color) + + angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: Pi] + + # if color.a != 1.0: + # 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 + + for corner in DirectionCorners: + ctx.saveTransform() + ctx.translate(cpos[corner] + coffset[corner] + csizes[corner] / 2) + ctx.rotate(angles[corner]) + ctx.translate(-csizes[corner] / 2) + ctx.drawImage(cornerHashes[corner], zero, color) + + if cornerCbs[corner].sideDelta > 0: + let inner = cornerCbs[corner].inner.float32 + let sideDelta = cornerCbs[corner].sideDelta.float32 + let sideSize = cornerCbs[corner].sideSize.float32 + # inner patch left, right, and then center + if innerShadow: discard - of dcTopRight: - image.flipHorizontal() - of dcBottomRight: - image.flipHorizontal() - image.flipVertical() - of dcBottomLeft: - image.flipVertical() - - ctx.putImage(cornerHash, image) - - for side in Directions: - let sideHash = getShadowKey(shadowKey, radii, side) - ctx.putImage(sideHash, sideImages[side]) - - var - totalPadding = (cbs.totalSize.float32 - cbs.inner.float32) / 2 - corner = totalPadding.float32 + cbs.inner.float32 / 2 - - let - sbox = rect( - rect.x - totalPadding.float32 + shadowX, - rect.y - totalPadding.float32 + shadowY, - rect.w + 2 * totalPadding.float32, - rect.h + 2 * totalPadding.float32 - ) - halfW = sbox.w / 2 - halfH = sbox.h / 2 - centerX = sbox.x + halfW - centerY = sbox.y + halfH - - # Draw the corners - let - zero = vec2(0, 0) - topLeft = rect(sbox.x, sbox.y, corner, corner) - topRight = rect(sbox.x + sbox.w - corner, sbox.y, corner, corner) - bottomLeft = rect(sbox.x, sbox.y + sbox.h - corner, corner, corner) - bottomRight = rect(sbox.x + sbox.w - corner, sbox.y + sbox.h - corner, corner, corner) - - # Draw corners - - ctx.saveTransform() - ctx.translate(topLeft.xy) - ctx.drawImageAdj(cornerHashes[dcTopLeft], zero, shadowColor, topLeft.wh) - ctx.restoreTransform() - - ctx.saveTransform() - ctx.translate(topRight.xy + topRight.wh / 2) - ctx.rotate(-Pi/2) - ctx.translate(-topRight.wh / 2) - ctx.drawImageAdj(cornerHashes[dcTopRight], zero, shadowColor, topRight.wh) - ctx.restoreTransform() - - ctx.saveTransform() - ctx.translate(bottomLeft.xy + bottomLeft.wh / 2) - ctx.rotate(Pi/2) - ctx.translate(-bottomLeft.wh / 2) - ctx.drawImageAdj(cornerHashes[dcBottomLeft], zero, shadowColor, bottomLeft.wh) - ctx.restoreTransform() - - ctx.saveTransform() - ctx.translate(bottomRight.xy + bottomRight.wh / 2) - ctx.rotate(Pi) - ctx.translate(-bottomRight.wh / 2) - ctx.drawImageAdj(cornerHashes[dcBottomRight], zero, shadowColor, bottomRight.wh) - ctx.restoreTransform() - - # Draw edges - # Top edge (stretched horizontally) - let - topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) - rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) - bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) - leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) - - ctx.drawImageAdj(sideHashes[dTop], topEdge.xy, shadowColor, topEdge.wh) - ctx.drawImageAdj(sideHashes[dRight], rightEdge.xy, shadowColor, rightEdge.wh) - ctx.drawImageAdj(sideHashes[dBottom], bottomEdge.xy, shadowColor, bottomEdge.wh) - ctx.drawImageAdj(sideHashes[dLeft], leftEdge.xy, shadowColor, leftEdge.wh) - - # Center (stretched both ways) - if not innerShadow: - let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) - ctx.drawRect(center, shadowColor) \ No newline at end of file + # ctx.drawRect(rect(0, inner, cbs.weightSize.float32, sideDelta), color) + # ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) + else: + ctx.drawRect(rect(0, inner, inner, sideDelta), color) + ctx.drawRect(rect(inner, 0, sideDelta, sideSize), color) + # we could do two boxes, but this matches our shadow needs + ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), color) + + ctx.restoreTransform() + + block drawEdges: + discard + # # Draw edges + # # Top edge (stretched horizontally) + # let + # topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) + # rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) + # bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) + # leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) + + # ctx.drawImageAdj(sideHashes[dTop], topEdge.xy, shadowColor, topEdge.wh) + # ctx.drawImageAdj(sideHashes[dRight], rightEdge.xy, shadowColor, rightEdge.wh) + # ctx.drawImageAdj(sideHashes[dBottom], bottomEdge.xy, shadowColor, bottomEdge.wh) + # ctx.drawImageAdj(sideHashes[dLeft], leftEdge.xy, shadowColor, leftEdge.wh) + + # # Center (stretched both ways) + # if not innerShadow: + # let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) + # ctx.drawRect(center, shadowColor) \ No newline at end of file From f2ba1d5489c52903e95d1eba5994b011bfc2e30f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 21:54:03 -0600 Subject: [PATCH 141/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 40 ++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index ba0aba739..ab9118c05 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -31,6 +31,8 @@ proc fillRoundedRectWithShadowSdf*[R]( # First, draw the shadow # Generate shadow key for caching let + w = rect.w.ceil() + h = rect.h.ceil() radii = clampRadii(radii, rect) shadowBlur = shadowBlur.round().float32 shadowSpread = shadowSpread.round().float32 @@ -42,6 +44,8 @@ proc fillRoundedRectWithShadowSdf*[R]( innerShadow = innerShadow) maxRadius = cbs.maxRadius wh = vec2(cbs.inner.float32, cbs.inner.float32) + bw = cbs.sideSize.float32 + bh = cbs.sideSize.float32 shadowKey = hash((7723, shadowBlur.int, shadowSpread.int, innerShadow)) @@ -63,7 +67,8 @@ proc fillRoundedRectWithShadowSdf*[R]( if cornerHashes[corner] in ctx.entries: continue - let corners = vec4(cornerCbs[corner].radius.float32) + let cornerCbs = cornerCbs[corner] + let corners = vec4(cornerCbs.radius.float32) var shadowImg = newImage(cornerCbs.sideSize, cornerCbs.sideSize) let wh = vec2(2*cornerCbs.sideSize.float32, 2*cornerCbs.sideSize.float32) @@ -80,6 +85,20 @@ proc fillRoundedRectWithShadowSdf*[R]( spread = spread, mode = mode) + if true: + var msg = "shadow" + msg &= (if innerShadow: "inner" else: "outer") + msg &= "-weight" & $shadowBlur + msg &= "-radius" & $cornerCbs.radius + msg &= "-sideSize" & $cornerCbs.sideSize + msg &= "-wh" & $wh.x + msg &= "-padding" & $cbs.padding + msg &= "-center" & $cornerCbs.center + msg &= "-corner-" & $corner + msg &= "-hash" & toHex(cornerHashes[corner]) + echo "generating shadow: ", msg + shadowImg.writeFile("examples/" & msg & ".png") + ctx.putImage(cornerHashes[corner], shadowImg) var @@ -88,16 +107,15 @@ proc fillRoundedRectWithShadowSdf*[R]( let xy = rect.xy - bw = cornerCbs[dcTopLeft].sideSize.float32 - bh = cornerCbs[dcTopLeft].sideSize.float32 zero = vec2(0, 0) cornerSize = vec2(bw, bh) + padding = cbs.padding.float32 cpos = [ - dcTopLeft: xy + vec2(0, 0), - dcTopRight: xy + vec2(w - bw, 0), - dcBottomLeft: xy + vec2(0, h - bh), - dcBottomRight: xy + vec2(w - bw, h - bh) + dcTopLeft: xy + vec2(0, 0) + vec2(-padding, -padding), + dcTopRight: xy + vec2(w - bw, 0) + vec2(padding, -padding), + dcBottomLeft: xy + vec2(0, h - bh) + vec2(-padding, padding), + dcBottomRight: xy + vec2(w - bw, h - bh) + vec2(padding, padding) ] coffset = [ @@ -126,7 +144,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(cpos[corner] + coffset[corner] + csizes[corner] / 2) ctx.rotate(angles[corner]) ctx.translate(-csizes[corner] / 2) - ctx.drawImage(cornerHashes[corner], zero, color) + ctx.drawImage(cornerHashes[corner], zero, shadowColor) if cornerCbs[corner].sideDelta > 0: let inner = cornerCbs[corner].inner.float32 @@ -138,10 +156,10 @@ proc fillRoundedRectWithShadowSdf*[R]( # ctx.drawRect(rect(0, inner, cbs.weightSize.float32, sideDelta), color) # ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) else: - ctx.drawRect(rect(0, inner, inner, sideDelta), color) - ctx.drawRect(rect(inner, 0, sideDelta, sideSize), color) + ctx.drawRect(rect(0, inner, inner, sideDelta), shadowColor) + ctx.drawRect(rect(inner, 0, sideDelta, sideSize), shadowColor) # we could do two boxes, but this matches our shadow needs - ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), color) + ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) ctx.restoreTransform() From 2791657dbc47c6eebcab928de6d6062dcddb628d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:01:30 -0600 Subject: [PATCH 142/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 17 +++++++++-------- src/figuro/renderer/utils/drawutils.nim | 6 +++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index ab9118c05..2e102092d 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -110,19 +110,20 @@ proc fillRoundedRectWithShadowSdf*[R]( zero = vec2(0, 0) cornerSize = vec2(bw, bh) padding = cbs.padding.float32 + paddingOffset = 1.5*cbs.padding.float32 cpos = [ - dcTopLeft: xy + vec2(0, 0) + vec2(-padding, -padding), - dcTopRight: xy + vec2(w - bw, 0) + vec2(padding, -padding), - dcBottomLeft: xy + vec2(0, h - bh) + vec2(-padding, padding), - dcBottomRight: xy + vec2(w - bw, h - bh) + vec2(padding, padding) + dcTopLeft: xy + vec2(0, 0), + dcTopRight: xy + vec2(w - bw, 0), + dcBottomLeft: xy + vec2(0, h - bh), + dcBottomRight: xy + vec2(w - bw, h - bh) ] coffset = [ - dcTopLeft: vec2(0, 0), - dcTopRight: vec2(cornerCbs[dcTopRight].sideDelta.float32, 0), - dcBottomLeft: vec2(0, cornerCbs[dcBottomLeft].sideDelta.float32), - dcBottomRight: vec2(cornerCbs[dcBottomRight].sideDelta.float32, cornerCbs[dcBottomRight].sideDelta.float32) + dcTopLeft: vec2(-paddingOffset, -paddingOffset), + dcTopRight: vec2(paddingOffset, -paddingOffset), + dcBottomLeft: vec2(-paddingOffset, paddingOffset), + dcBottomRight: vec2(paddingOffset, paddingOffset) ] csizes = [ diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 70286b85f..605343f21 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -63,4 +63,8 @@ proc roundedBoxCornerSizes*( let dim = max(int(round(radii[corner])), ww) let sideSize = int(round(1.5*cbs.padding.float32)) + dim let center = sideSize - result[corner] = (int(round(radii[corner])), sideSize, dim, cbs.sideSize - dim, center) + result[corner] = (radius: int(round(radii[corner])), + sideSize: sideSize, + inner: dim, + sideDelta: cbs.sideSize - dim, + center: center) From a36092235df57f333796e0308e50bfa820c9ff1d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:09:23 -0600 Subject: [PATCH 143/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 2e102092d..202c9e2e5 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -119,12 +119,18 @@ proc fillRoundedRectWithShadowSdf*[R]( dcBottomRight: xy + vec2(w - bw, h - bh) ] - coffset = [ + cpad = [ dcTopLeft: vec2(-paddingOffset, -paddingOffset), dcTopRight: vec2(paddingOffset, -paddingOffset), dcBottomLeft: vec2(-paddingOffset, paddingOffset), dcBottomRight: vec2(paddingOffset, paddingOffset) ] + coffset = [ + dcTopLeft: vec2(-paddingOffset, -paddingOffset), + dcTopRight: vec2(0, -paddingOffset), + dcBottomLeft: vec2(-paddingOffset, 0), + dcBottomRight: vec2(0, 0) + ] csizes = [ dcTopLeft: vec2(0.0, 0.0), @@ -147,7 +153,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(-csizes[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, shadowColor) - if cornerCbs[corner].sideDelta > 0: + if false and cornerCbs[corner].sideDelta > 0: let inner = cornerCbs[corner].inner.float32 let sideDelta = cornerCbs[corner].sideDelta.float32 let sideSize = cornerCbs[corner].sideSize.float32 From 6b2cc5a2f92d4d67b743a6ac2507fcaf47d2650b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:09:37 -0600 Subject: [PATCH 144/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 202c9e2e5..be4c2ad00 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -125,6 +125,7 @@ proc fillRoundedRectWithShadowSdf*[R]( dcBottomLeft: vec2(-paddingOffset, paddingOffset), dcBottomRight: vec2(paddingOffset, paddingOffset) ] + coffset = [ dcTopLeft: vec2(-paddingOffset, -paddingOffset), dcTopRight: vec2(0, -paddingOffset), From 2af1d86103f3206b4bb55bf86887a7042cbed4b2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:14:56 -0600 Subject: [PATCH 145/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 9 +-------- src/figuro/renderer/utils/drawutils.nim | 7 ++++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index be4c2ad00..15aedac6a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -110,7 +110,7 @@ proc fillRoundedRectWithShadowSdf*[R]( zero = vec2(0, 0) cornerSize = vec2(bw, bh) padding = cbs.padding.float32 - paddingOffset = 1.5*cbs.padding.float32 + paddingOffset = cbs.paddingOffset.float32 cpos = [ dcTopLeft: xy + vec2(0, 0), @@ -119,13 +119,6 @@ proc fillRoundedRectWithShadowSdf*[R]( dcBottomRight: xy + vec2(w - bw, h - bh) ] - cpad = [ - dcTopLeft: vec2(-paddingOffset, -paddingOffset), - dcTopRight: vec2(paddingOffset, -paddingOffset), - dcBottomLeft: vec2(-paddingOffset, paddingOffset), - dcBottomRight: vec2(paddingOffset, paddingOffset) - ] - coffset = [ dcTopLeft: vec2(-paddingOffset, -paddingOffset), dcTopRight: vec2(0, -paddingOffset), diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 605343f21..02de9d5c7 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -32,7 +32,7 @@ proc getCircleBoxSizes*( width = float32.high(), height = float32.high(), innerShadow = false, -): tuple[maxRadius, sideSize, totalSize, padding, inner, weightSize: int] = +): tuple[maxRadius, sideSize, totalSize, padding, paddingOffset, inner, weightSize: int] = result.maxRadius = 0 for r in radii: result.maxRadius = max(result.maxRadius, r.round().int) @@ -45,6 +45,7 @@ proc getCircleBoxSizes*( let padding = spread + blur result.padding = padding + result.paddingOffset = int(round(1.5*padding.float32)) if innerShadow: result.sideSize = min(result.maxRadius + padding, min(bw, bh)).max(ww) else: @@ -54,14 +55,14 @@ proc getCircleBoxSizes*( result.weightSize = ww proc roundedBoxCornerSizes*( - cbs: tuple[maxRadius, sideSize, totalSize, padding, inner, weightSize: int], + cbs: tuple[maxRadius, sideSize, totalSize, padding, paddingOffset, inner, weightSize: int], radii: array[DirectionCorners, float32], ): array[DirectionCorners, tuple[radius, sideSize, inner, sideDelta, center: int]] = let ww = cbs.weightSize for corner in DirectionCorners: let dim = max(int(round(radii[corner])), ww) - let sideSize = int(round(1.5*cbs.padding.float32)) + dim + let sideSize = cbs.paddingOffset + dim let center = sideSize result[corner] = (radius: int(round(radii[corner])), sideSize: sideSize, From 1e3a88f67b159248ab62b738e77771b9344d8211 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:21:00 -0600 Subject: [PATCH 146/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 15aedac6a..9da1af1ae 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -70,7 +70,7 @@ proc fillRoundedRectWithShadowSdf*[R]( let cornerCbs = cornerCbs[corner] let corners = vec4(cornerCbs.radius.float32) var shadowImg = newImage(cornerCbs.sideSize, cornerCbs.sideSize) - let wh = vec2(2*cornerCbs.sideSize.float32, 2*cornerCbs.sideSize.float32) + let wh = vec2(2*cornerCbs.inner.float32, 2*cornerCbs.inner.float32) let spread = if innerShadow: 0.0 else: shadowSpread let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow From cecdf4ddc1eb3dc611a9b010a278a4d4fb9bedef Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:30:14 -0600 Subject: [PATCH 147/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 9da1af1ae..6345a643c 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -114,9 +114,10 @@ proc fillRoundedRectWithShadowSdf*[R]( cpos = [ dcTopLeft: xy + vec2(0, 0), - dcTopRight: xy + vec2(w - bw, 0), - dcBottomLeft: xy + vec2(0, h - bh), - dcBottomRight: xy + vec2(w - bw, h - bh) + dcTopRight: xy + vec2(w - cornerCbs[dcTopRight].inner.float32, 0), + dcBottomLeft: xy + vec2(0, h - cornerCbs[dcBottomLeft].inner.float32), + dcBottomRight: xy + vec2(w - cornerCbs[dcBottomRight].inner.float32, + h - cornerCbs[dcBottomRight].inner.float32) ] coffset = [ From 0cbcc780f5081dd1293bda75cdf4ed144a877d79 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:38:09 -0600 Subject: [PATCH 148/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 36 ++++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 6345a643c..5c5d4cd6c 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -53,7 +53,7 @@ proc fillRoundedRectWithShadowSdf*[R]( var sideHashes: array[Directions, Hash] for side in Directions: - sideHashes[side] = hash((shadowKey, 971767, int(side))) + sideHashes[side] = hash((shadowKey, 971767, int(cbs.padding))) block drawCorners: var cornerHashes: array[DirectionCorners, Hash] @@ -84,22 +84,42 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) + ctx.putImage(cornerHashes[corner], shadowImg) + + for side in Directions: + if sideHashes[side] in ctx.entries: + continue + + let corners = vec4(0) + var shadowImg = newImage(cbs.paddingOffset, 4) + let wh = vec2(12, 12) + + let spread = if innerShadow: 0.0 else: shadowSpread + let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow + + drawSdfShape(shadowImg, + center = vec2(cbs.paddingOffset.float32, 6), + wh = wh, + params = RoundedBoxParams(r: corners), + pos = whiteColor, + neg = whiteColor, + factor = shadowBlur, + spread = spread, + mode = mode) if true: - var msg = "shadow" + var msg = "shadow-side" msg &= (if innerShadow: "inner" else: "outer") msg &= "-weight" & $shadowBlur - msg &= "-radius" & $cornerCbs.radius - msg &= "-sideSize" & $cornerCbs.sideSize + msg &= "-sideSize" & $cbs.sideSize msg &= "-wh" & $wh.x msg &= "-padding" & $cbs.padding - msg &= "-center" & $cornerCbs.center - msg &= "-corner-" & $corner - msg &= "-hash" & toHex(cornerHashes[corner]) + msg &= "-side-" & $side + msg &= "-hash" & toHex(sideHashes[side]) echo "generating shadow: ", msg shadowImg.writeFile("examples/" & msg & ".png") - ctx.putImage(cornerHashes[corner], shadowImg) + ctx.putImage(sideHashes[side], shadowImg) var totalPadding = (cbs.totalSize.float32 - cbs.inner.float32) / 2 From 807ad2d619e406bd5f9857c1606a91d5c0de9dd9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:49:55 -0600 Subject: [PATCH 149/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 51 +++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 5c5d4cd6c..4e303f60d 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -187,9 +187,54 @@ proc fillRoundedRectWithShadowSdf*[R]( block drawEdges: discard - # # Draw edges - # # Top edge (stretched horizontally) + # Draw edges + # Top edge (stretched horizontally) + + let + corner = cbs.maxRadius.float32 + xy = rect.xy + zero = vec2(0, 0) + cornerSize = vec2(bw, bh) + padding = cbs.padding.float32 + paddingOffset = cbs.paddingOffset.float32 + + cpos = [ + dLeft: xy + vec2(0, 0), + dRight: xy + vec2(w, 0), + dBottom: xy + vec2(0, h), + dTop: xy + vec2(w, h) + ] + + coffset = [ + dLeft: vec2(paddingOffset, h - 2*corner), + dRight: vec2(paddingOffset, h - 2*corner), + dBottom: vec2(w - 2*corner, paddingOffset), + dTop: vec2(w - 2*corner, paddingOffset) + ] + + csizes = [ + dLeft: vec2(paddingOffset, h - 2*corner), + dRight: vec2(paddingOffset, h - 2*corner), + dBottom: vec2(w - 2*corner, paddingOffset), + dTop: vec2(w - 2*corner, paddingOffset) + ] + + angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: Pi] + + # if color.a != 1.0: + # 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 + + for side in Directions: + ctx.saveTransform() + ctx.translate(cpos[side] + coffset[side] + csizes[side] / 2) + ctx.rotate(angles[side]) + ctx.translate(-csizes[side] / 2) + ctx.drawImage(sideHashes[side], zero, shadowColor) + ctx.restoreTransform() # let + # paddingOffset = cbs.paddingOffset.float32 + # corner = cbs.paddingOffset.float32 + # sbox = rect(-paddingOffset, -paddingOffset, w + paddingOffset, h + paddingOffset) # topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) # rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) # bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) @@ -200,7 +245,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # ctx.drawImageAdj(sideHashes[dBottom], bottomEdge.xy, shadowColor, bottomEdge.wh) # ctx.drawImageAdj(sideHashes[dLeft], leftEdge.xy, shadowColor, leftEdge.wh) - # # Center (stretched both ways) + # Center (stretched both ways) # if not innerShadow: # let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) # ctx.drawRect(center, shadowColor) \ No newline at end of file From 64766d019c819c106d290202bdc3e15dc5347788 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:51:27 -0600 Subject: [PATCH 150/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 4e303f60d..3dff11f9a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -198,39 +198,40 @@ proc fillRoundedRectWithShadowSdf*[R]( padding = cbs.padding.float32 paddingOffset = cbs.paddingOffset.float32 - cpos = [ + spos = [ dLeft: xy + vec2(0, 0), dRight: xy + vec2(w, 0), dBottom: xy + vec2(0, h), dTop: xy + vec2(w, h) ] - coffset = [ + soffset = [ dLeft: vec2(paddingOffset, h - 2*corner), dRight: vec2(paddingOffset, h - 2*corner), dBottom: vec2(w - 2*corner, paddingOffset), dTop: vec2(w - 2*corner, paddingOffset) ] - csizes = [ + ssizes = [ dLeft: vec2(paddingOffset, h - 2*corner), dRight: vec2(paddingOffset, h - 2*corner), dBottom: vec2(w - 2*corner, paddingOffset), dTop: vec2(w - 2*corner, paddingOffset) ] - angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: Pi] + sangles = [dLeft: 0.0, dRight: -Pi/2, dBottom: Pi/2, dTop: Pi] # if color.a != 1.0: # 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 for side in Directions: ctx.saveTransform() - ctx.translate(cpos[side] + coffset[side] + csizes[side] / 2) - ctx.rotate(angles[side]) - ctx.translate(-csizes[side] / 2) + ctx.translate(spos[side] + soffset[side] + ssizes[side] / 2) + ctx.rotate(sangles[side]) + ctx.translate(-ssizes[side] / 2) ctx.drawImage(sideHashes[side], zero, shadowColor) ctx.restoreTransform() + # let # paddingOffset = cbs.paddingOffset.float32 # corner = cbs.paddingOffset.float32 From 03b216e5d351e9efe1572b59e7b2edf89a554287 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:54:52 -0600 Subject: [PATCH 151/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3dff11f9a..3b553ce38 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -186,10 +186,8 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.restoreTransform() block drawEdges: - discard # Draw edges # Top edge (stretched horizontally) - let corner = cbs.maxRadius.float32 xy = rect.xy @@ -199,27 +197,28 @@ proc fillRoundedRectWithShadowSdf*[R]( paddingOffset = cbs.paddingOffset.float32 spos = [ - dLeft: xy + vec2(0, 0), + dTop: xy + vec2(w, h), dRight: xy + vec2(w, 0), dBottom: xy + vec2(0, h), - dTop: xy + vec2(w, h) + dLeft: xy + vec2(0, 0) ] soffset = [ - dLeft: vec2(paddingOffset, h - 2*corner), + dTop: vec2(w - 2*corner, paddingOffset), dRight: vec2(paddingOffset, h - 2*corner), dBottom: vec2(w - 2*corner, paddingOffset), - dTop: vec2(w - 2*corner, paddingOffset) + dLeft: vec2(paddingOffset, h - 2*corner) ] ssizes = [ - dLeft: vec2(paddingOffset, h - 2*corner), + dTop: vec2(w - 2*corner, paddingOffset), dRight: vec2(paddingOffset, h - 2*corner), dBottom: vec2(w - 2*corner, paddingOffset), - dTop: vec2(w - 2*corner, paddingOffset) + dLeft: vec2(paddingOffset, h - 2*corner) ] - sangles = [dLeft: 0.0, dRight: -Pi/2, dBottom: Pi/2, dTop: Pi] + # sangles = [dLeft: 0.0, dRight: -Pi/2, dBottom: Pi/2, dTop: Pi] + sangles = [dTop: Pi, dRight: Pi/2, dBottom: 0.0, dLeft: -Pi/2] # if color.a != 1.0: # 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 From 6b9a2ace93ce232bcaae292000caeb5ad5b6e3a8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 22:57:20 -0600 Subject: [PATCH 152/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3b553ce38..57a494a47 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -197,17 +197,10 @@ proc fillRoundedRectWithShadowSdf*[R]( paddingOffset = cbs.paddingOffset.float32 spos = [ - dTop: xy + vec2(w, h), - dRight: xy + vec2(w, 0), - dBottom: xy + vec2(0, h), - dLeft: xy + vec2(0, 0) - ] - - soffset = [ - dTop: vec2(w - 2*corner, paddingOffset), - dRight: vec2(paddingOffset, h - 2*corner), - dBottom: vec2(w - 2*corner, paddingOffset), - dLeft: vec2(paddingOffset, h - 2*corner) + dTop: xy + vec2(corner, -paddingOffset), + dRight: xy + vec2(paddingOffset, corner), + dBottom: xy + vec2(corner, paddingOffset), + dLeft: xy + vec2(-paddingOffset, corner) ] ssizes = [ @@ -225,10 +218,10 @@ proc fillRoundedRectWithShadowSdf*[R]( for side in Directions: ctx.saveTransform() - ctx.translate(spos[side] + soffset[side] + ssizes[side] / 2) + ctx.translate(spos[side] + ssizes[side] / 2) ctx.rotate(sangles[side]) ctx.translate(-ssizes[side] / 2) - ctx.drawImage(sideHashes[side], zero, shadowColor) + ctx.drawImageAdj(sideHashes[side], zero, shadowColor, ssizes[side]) ctx.restoreTransform() # let From b940a04b7f528cceb2aaefe19fdfa529f329abbe Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:01:34 -0600 Subject: [PATCH 153/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 71 ++++++++++++----------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 57a494a47..aab3005a0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -160,6 +160,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # if color.a != 1.0: # 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 + let sides = [dcTopLeft: dTop, dcTopRight: dRight, dcBottomLeft: dBottom, dcBottomRight: dLeft] for corner in DirectionCorners: ctx.saveTransform() @@ -183,46 +184,48 @@ proc fillRoundedRectWithShadowSdf*[R]( # we could do two boxes, but this matches our shadow needs ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) + ctx.drawImage(sideHashes[sides[corner]], vec2(csizes[corner].x, 0), darkGrey) ctx.restoreTransform() block drawEdges: + discard # Draw edges # Top edge (stretched horizontally) - let - corner = cbs.maxRadius.float32 - xy = rect.xy - zero = vec2(0, 0) - cornerSize = vec2(bw, bh) - padding = cbs.padding.float32 - paddingOffset = cbs.paddingOffset.float32 - - spos = [ - dTop: xy + vec2(corner, -paddingOffset), - dRight: xy + vec2(paddingOffset, corner), - dBottom: xy + vec2(corner, paddingOffset), - dLeft: xy + vec2(-paddingOffset, corner) - ] - - ssizes = [ - dTop: vec2(w - 2*corner, paddingOffset), - dRight: vec2(paddingOffset, h - 2*corner), - dBottom: vec2(w - 2*corner, paddingOffset), - dLeft: vec2(paddingOffset, h - 2*corner) - ] - - # sangles = [dLeft: 0.0, dRight: -Pi/2, dBottom: Pi/2, dTop: Pi] - sangles = [dTop: Pi, dRight: Pi/2, dBottom: 0.0, dLeft: -Pi/2] - - # if color.a != 1.0: - # 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 + # let + # corner = cbs.maxRadius.float32 + # xy = rect.xy + # zero = vec2(0, 0) + # cornerSize = vec2(bw, bh) + # padding = cbs.padding.float32 + # paddingOffset = cbs.paddingOffset.float32 - for side in Directions: - ctx.saveTransform() - ctx.translate(spos[side] + ssizes[side] / 2) - ctx.rotate(sangles[side]) - ctx.translate(-ssizes[side] / 2) - ctx.drawImageAdj(sideHashes[side], zero, shadowColor, ssizes[side]) - ctx.restoreTransform() + # spos = [ + # dTop: xy + vec2(corner, -paddingOffset), + # dRight: xy + vec2(paddingOffset, corner), + # dBottom: xy + vec2(corner, paddingOffset), + # dLeft: xy + vec2(-paddingOffset, corner) + # ] + + # ssizes = [ + # dTop: vec2(w - 2*corner, paddingOffset), + # dRight: vec2(paddingOffset, h - 2*corner), + # dBottom: vec2(w - 2*corner, paddingOffset), + # dLeft: vec2(paddingOffset, h - 2*corner) + # ] + + # # sangles = [dLeft: 0.0, dRight: -Pi/2, dBottom: Pi/2, dTop: Pi] + # sangles = [dTop: Pi, dRight: Pi/2, dBottom: 0.0, dLeft: -Pi/2] + + # # if color.a != 1.0: + # # 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 + + # for side in Directions: + # ctx.saveTransform() + # ctx.translate(spos[side] + ssizes[side] / 2) + # ctx.rotate(sangles[side]) + # ctx.translate(-ssizes[side] / 2) + # ctx.drawImageAdj(sideHashes[side], zero, shadowColor, ssizes[side]) + # ctx.restoreTransform() # let # paddingOffset = cbs.paddingOffset.float32 From 93b27a378ce9c4e5483755cd79545fbaaea26c79 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:02:38 -0600 Subject: [PATCH 154/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index aab3005a0..41dc9e756 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -160,7 +160,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # if color.a != 1.0: # 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 - let sides = [dcTopLeft: dTop, dcTopRight: dRight, dcBottomLeft: dBottom, dcBottomRight: dLeft] + let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] for corner in DirectionCorners: ctx.saveTransform() From 250c1249e9eaaba9a9a09a21978448fa0686f9d3 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:06:30 -0600 Subject: [PATCH 155/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 41dc9e756..76e07377f 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -48,7 +48,10 @@ proc fillRoundedRectWithShadowSdf*[R]( bh = cbs.sideSize.float32 shadowKey = hash((7723, shadowBlur.int, shadowSpread.int, innerShadow)) - + + if cbs.paddingOffset == 0: + return + let cornerCbs = cbs.roundedBoxCornerSizes(radii) var sideHashes: array[Directions, Hash] @@ -87,7 +90,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.putImage(cornerHashes[corner], shadowImg) for side in Directions: - if sideHashes[side] in ctx.entries: + if sideHashes[side] in ctx.entries or cbs.paddingOffset == 0: continue let corners = vec4(0) @@ -184,7 +187,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # we could do two boxes, but this matches our shadow needs ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) - ctx.drawImage(sideHashes[sides[corner]], vec2(csizes[corner].x, 0), darkGrey) + ctx.drawImage(sideHashes[sides[corner]], vec2(0, -csizes[corner].x), darkGrey) ctx.restoreTransform() block drawEdges: From 4caa58ecf763c779b16457a4c6fc581a54a81749 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:09:31 -0600 Subject: [PATCH 156/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 76e07377f..b0a556303 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -187,7 +187,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # we could do two boxes, but this matches our shadow needs ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) - ctx.drawImage(sideHashes[sides[corner]], vec2(0, -csizes[corner].x), darkGrey) + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, csizes[corner].x), darkGrey, vec2(paddingOffset, h - 2*cbs.maxRadius.float32)) ctx.restoreTransform() block drawEdges: From e7e2ee0e41c6ec3b693139dd2e1ae2c0300a78d5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:41:09 -0600 Subject: [PATCH 157/225] shadow patch21 setup --- src/figuro/renderer/utils/drawboxes.nim | 6 +++--- src/figuro/renderer/utils/drawshadows.nim | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 5b40d58a5..2df940c38 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -131,7 +131,7 @@ proc drawRoundedRect*[R]( dcBottomRight: vec2(cornerCbs[dcBottomRight].sideDelta.float32, cornerCbs[dcBottomRight].sideDelta.float32) ] - csizes = [ + ccenter = [ dcTopLeft: vec2(0.0, 0.0), dcTopRight: vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32), dcBottomLeft: vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32), @@ -147,9 +147,9 @@ proc drawRoundedRect*[R]( for corner in DirectionCorners: ctx.saveTransform() - ctx.translate(cpos[corner] + coffset[corner] + csizes[corner] / 2) + ctx.translate(cpos[corner] + coffset[corner] + ccenter[corner] / 2) ctx.rotate(angles[corner]) - ctx.translate(-csizes[corner] / 2) + ctx.translate(-ccenter[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, color) if cornerCbs[corner].sideDelta > 0: diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index b0a556303..d2f1c4bf0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -150,7 +150,7 @@ proc fillRoundedRectWithShadowSdf*[R]( dcBottomRight: vec2(0, 0) ] - csizes = [ + ccenter = [ dcTopLeft: vec2(0.0, 0.0), dcTopRight: vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32), dcBottomLeft: vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32), @@ -158,6 +158,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ] darkGrey = rgba(50, 50, 50, 255).to(Color) + black = rgba(0, 0, 0, 255).to(Color) angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: Pi] @@ -167,9 +168,9 @@ proc fillRoundedRectWithShadowSdf*[R]( for corner in DirectionCorners: ctx.saveTransform() - ctx.translate(cpos[corner] + coffset[corner] + csizes[corner] / 2) + ctx.translate(cpos[corner] + coffset[corner] + ccenter[corner] / 2) ctx.rotate(angles[corner]) - ctx.translate(-csizes[corner] / 2) + ctx.translate(-ccenter[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, shadowColor) if false and cornerCbs[corner].sideDelta > 0: @@ -187,7 +188,9 @@ proc fillRoundedRectWithShadowSdf*[R]( # we could do two boxes, but this matches our shadow needs ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) - ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, csizes[corner].x), darkGrey, vec2(paddingOffset, h - 2*cbs.maxRadius.float32)) + let sideDim = if sides[corner] in [dTop, dBottom]: w else: h + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), + darkGrey, vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32)) ctx.restoreTransform() block drawEdges: From 3d48a117d8a524ba8bd22e2b4714e578733c832a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:53:16 -0600 Subject: [PATCH 158/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index d2f1c4bf0..be2533387 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -165,6 +165,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # if color.a != 1.0: # 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 let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] + let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcBottomRight, dcBottomLeft: dcTopLeft, dcBottomRight: dcTopRight] for corner in DirectionCorners: ctx.saveTransform() @@ -189,8 +190,11 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) let sideDim = if sides[corner] in [dTop, dBottom]: w else: h - ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), - darkGrey, vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32)) + let sideSize = cornerCbs[corner].sideSize.float32 + let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) + let prevSideAdj = (cbs.maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, sideSize), + darkGrey, vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj)) ctx.restoreTransform() block drawEdges: From 3cb6ff2e65363c26d4326e9eafb753e5e431e42b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:54:32 -0600 Subject: [PATCH 159/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index be2533387..b1c5b30a0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -165,7 +165,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # if color.a != 1.0: # 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 let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] - let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcBottomRight, dcBottomLeft: dcTopLeft, dcBottomRight: dcTopRight] + let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] for corner in DirectionCorners: ctx.saveTransform() From fee01f9ade03bc1c4304f1487ce02f8877bbf86e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 17 Jun 2025 23:57:25 -0600 Subject: [PATCH 160/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index b1c5b30a0..07ca4139a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -190,11 +190,10 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) let sideDim = if sides[corner] in [dTop, dBottom]: w else: h - let sideSize = cornerCbs[corner].sideSize.float32 let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) let prevSideAdj = (cbs.maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) - ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, sideSize), - darkGrey, vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj)) + let sideSize = vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, sideSize) ctx.restoreTransform() block drawEdges: From 5906ddc9bdb86c7d66093a96da763a91587081f8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:01:54 -0600 Subject: [PATCH 161/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 07ca4139a..6c95fb0ba 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -192,7 +192,7 @@ proc fillRoundedRectWithShadowSdf*[R]( let sideDim = if sides[corner] in [dTop, dBottom]: w else: h let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) let prevSideAdj = (cbs.maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) - let sideSize = vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) + let sideSize = vec2(paddingOffset / 2, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, sideSize) ctx.restoreTransform() From 03167f631f23fb8ec24fe492bc6c84a3be0d41a5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:10:36 -0600 Subject: [PATCH 162/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- src/figuro/renderer/utils/drawutils.nim | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 6c95fb0ba..fa7ff13bd 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -101,7 +101,7 @@ proc fillRoundedRectWithShadowSdf*[R]( let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow drawSdfShape(shadowImg, - center = vec2(cbs.paddingOffset.float32, 6), + center = vec2(cbs.paddingOffset.float32, 2), wh = wh, params = RoundedBoxParams(r: corners), pos = whiteColor, @@ -192,7 +192,7 @@ proc fillRoundedRectWithShadowSdf*[R]( let sideDim = if sides[corner] in [dTop, dBottom]: w else: h let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) let prevSideAdj = (cbs.maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) - let sideSize = vec2(paddingOffset / 2, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) + let sideSize = vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, sideSize) ctx.restoreTransform() diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 02de9d5c7..99ec2ac81 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -39,13 +39,13 @@ proc getCircleBoxSizes*( let ww = int(weight.round()) let bw = width.round().int let bh = height.round().int - let blur = blur.round().int + let blur = round(1.5*blur).int let spread = spread.round().int # let padding = max(spread + blur, result.maxRadius) let padding = spread + blur result.padding = padding - result.paddingOffset = int(round(1.5*padding.float32)) + result.paddingOffset = result.padding if innerShadow: result.sideSize = min(result.maxRadius + padding, min(bw, bh)).max(ww) else: From 69bdfa34457e029ed9e1642ef7e854387d9139b7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:15:56 -0600 Subject: [PATCH 163/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index fa7ff13bd..c8825b937 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -125,8 +125,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.putImage(sideHashes[side], shadowImg) var - totalPadding = (cbs.totalSize.float32 - cbs.inner.float32) / 2 - corner = totalPadding.float32 + cbs.inner.float32 / 2 + corner = cbs.sideSize.float32 let xy = rect.xy From 741b5ac7db6905963fd002b1ee02c9d9a630492e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:22:09 -0600 Subject: [PATCH 164/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 66 +---------------------- 1 file changed, 2 insertions(+), 64 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index c8825b937..9dc8e089c 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -95,7 +95,7 @@ proc fillRoundedRectWithShadowSdf*[R]( let corners = vec4(0) var shadowImg = newImage(cbs.paddingOffset, 4) - let wh = vec2(12, 12) + let wh = vec2(1, 12) let spread = if innerShadow: 0.0 else: shadowSpread let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow @@ -124,9 +124,6 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.putImage(sideHashes[side], shadowImg) - var - corner = cbs.sideSize.float32 - let xy = rect.xy zero = vec2(0, 0) @@ -150,7 +147,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ] ccenter = [ - dcTopLeft: vec2(0.0, 0.0), + dcTopLeft: vec2(cornerCbs[dcTopLeft].sideSize.float32, cornerCbs[dcTopLeft].sideSize.float32), dcTopRight: vec2(cornerCbs[dcTopRight].sideSize.float32, cornerCbs[dcTopRight].sideSize.float32), dcBottomLeft: vec2(cornerCbs[dcBottomLeft].sideSize.float32, cornerCbs[dcBottomLeft].sideSize.float32), dcBottomRight: vec2(cornerCbs[dcBottomRight].sideSize.float32, cornerCbs[dcBottomRight].sideSize.float32) @@ -194,62 +191,3 @@ proc fillRoundedRectWithShadowSdf*[R]( let sideSize = vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, sideSize) ctx.restoreTransform() - - block drawEdges: - discard - # Draw edges - # Top edge (stretched horizontally) - # let - # corner = cbs.maxRadius.float32 - # xy = rect.xy - # zero = vec2(0, 0) - # cornerSize = vec2(bw, bh) - # padding = cbs.padding.float32 - # paddingOffset = cbs.paddingOffset.float32 - - # spos = [ - # dTop: xy + vec2(corner, -paddingOffset), - # dRight: xy + vec2(paddingOffset, corner), - # dBottom: xy + vec2(corner, paddingOffset), - # dLeft: xy + vec2(-paddingOffset, corner) - # ] - - # ssizes = [ - # dTop: vec2(w - 2*corner, paddingOffset), - # dRight: vec2(paddingOffset, h - 2*corner), - # dBottom: vec2(w - 2*corner, paddingOffset), - # dLeft: vec2(paddingOffset, h - 2*corner) - # ] - - # # sangles = [dLeft: 0.0, dRight: -Pi/2, dBottom: Pi/2, dTop: Pi] - # sangles = [dTop: Pi, dRight: Pi/2, dBottom: 0.0, dLeft: -Pi/2] - - # # if color.a != 1.0: - # # 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 - - # for side in Directions: - # ctx.saveTransform() - # ctx.translate(spos[side] + ssizes[side] / 2) - # ctx.rotate(sangles[side]) - # ctx.translate(-ssizes[side] / 2) - # ctx.drawImageAdj(sideHashes[side], zero, shadowColor, ssizes[side]) - # ctx.restoreTransform() - - # let - # paddingOffset = cbs.paddingOffset.float32 - # corner = cbs.paddingOffset.float32 - # sbox = rect(-paddingOffset, -paddingOffset, w + paddingOffset, h + paddingOffset) - # topEdge = rect(sbox.x + corner, sbox.y, sbox.w - 2 * corner, corner) - # rightEdge = rect( sbox.x + sbox.w - corner, sbox.y + corner, corner, sbox.h - 2 * corner) - # bottomEdge = rect( sbox.x + corner, sbox.y + sbox.h - corner, sbox.w - 2 * corner, corner) - # leftEdge = rect( sbox.x, sbox.y + corner, corner, sbox.h - 2 * corner) - - # ctx.drawImageAdj(sideHashes[dTop], topEdge.xy, shadowColor, topEdge.wh) - # ctx.drawImageAdj(sideHashes[dRight], rightEdge.xy, shadowColor, rightEdge.wh) - # ctx.drawImageAdj(sideHashes[dBottom], bottomEdge.xy, shadowColor, bottomEdge.wh) - # ctx.drawImageAdj(sideHashes[dLeft], leftEdge.xy, shadowColor, leftEdge.wh) - - # Center (stretched both ways) - # if not innerShadow: - # let center = rect(sbox.x + corner, sbox.y + corner, sbox.w - 2 * corner, sbox.h - 2 * corner) - # ctx.drawRect(center, shadowColor) \ No newline at end of file From 4f819f69051aa2d9074893355e8c0793aed2fceb Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:23:19 -0600 Subject: [PATCH 165/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 9dc8e089c..44c9aedce 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -120,7 +120,7 @@ proc fillRoundedRectWithShadowSdf*[R]( msg &= "-side-" & $side msg &= "-hash" & toHex(sideHashes[side]) echo "generating shadow: ", msg - shadowImg.writeFile("examples/" & msg & ".png") + # shadowImg.writeFile("examples/" & msg & ".png") ctx.putImage(sideHashes[side], shadowImg) From 7f95bffc3f5d8e1d5abf275d4de8e604129b2241 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:35:57 -0600 Subject: [PATCH 166/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 44c9aedce..862d214df 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -109,19 +109,6 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) - - if true: - var msg = "shadow-side" - msg &= (if innerShadow: "inner" else: "outer") - msg &= "-weight" & $shadowBlur - msg &= "-sideSize" & $cbs.sideSize - msg &= "-wh" & $wh.x - msg &= "-padding" & $cbs.padding - msg &= "-side-" & $side - msg &= "-hash" & toHex(sideHashes[side]) - echo "generating shadow: ", msg - # shadowImg.writeFile("examples/" & msg & ".png") - ctx.putImage(sideHashes[side], shadowImg) let @@ -158,8 +145,6 @@ proc fillRoundedRectWithShadowSdf*[R]( angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: Pi] - # if color.a != 1.0: - # 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 let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] @@ -170,7 +155,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(-ccenter[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, shadowColor) - if false and cornerCbs[corner].sideDelta > 0: + if cornerCbs[corner].sideDelta > 0: let inner = cornerCbs[corner].inner.float32 let sideDelta = cornerCbs[corner].sideDelta.float32 let sideSize = cornerCbs[corner].sideSize.float32 @@ -181,9 +166,9 @@ proc fillRoundedRectWithShadowSdf*[R]( # ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) else: ctx.drawRect(rect(0, inner, inner, sideDelta), shadowColor) - ctx.drawRect(rect(inner, 0, sideDelta, sideSize), shadowColor) + ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), darkGrey) # we could do two boxes, but this matches our shadow needs - ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) + # ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) let sideDim = if sides[corner] in [dTop, dBottom]: w else: h let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) From e3fd1f2f632b30990f0147ba89af7e127358b284 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:39:36 -0600 Subject: [PATCH 167/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 862d214df..2c5582237 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -155,24 +155,25 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(-ccenter[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, shadowColor) + let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) + let inner = cornerCbs[corner].inner.float32 + let sideDelta = cornerCbs[corner].sideDelta.float32 + let sideSize = cornerCbs[corner].sideSize.float32 + if cornerCbs[corner].sideDelta > 0: - let inner = cornerCbs[corner].inner.float32 - let sideDelta = cornerCbs[corner].sideDelta.float32 - let sideSize = cornerCbs[corner].sideSize.float32 # inner patch left, right, and then center if innerShadow: discard # ctx.drawRect(rect(0, inner, cbs.weightSize.float32, sideDelta), color) # ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) else: - ctx.drawRect(rect(0, inner, inner, sideDelta), shadowColor) ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), darkGrey) + ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), darkGrey) # we could do two boxes, but this matches our shadow needs # ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) - let sideDim = if sides[corner] in [dTop, dBottom]: w else: h - let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) + let borderDim = if sides[corner] in [dTop, dBottom]: w else: h let prevSideAdj = (cbs.maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) - let sideSize = vec2(paddingOffset, sideDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) - ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, sideSize) + let borderSize = vec2(paddingOffset, borderDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() From 24c4f4b0fcaedd0e9fc2e14a7a5e466dae974b25 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:45:34 -0600 Subject: [PATCH 168/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 2c5582237..68f4ed4c0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -167,8 +167,8 @@ proc fillRoundedRectWithShadowSdf*[R]( # ctx.drawRect(rect(0, inner, cbs.weightSize.float32, sideDelta), color) # ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) else: - ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), darkGrey) - ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), darkGrey) + ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) + ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) # we could do two boxes, but this matches our shadow needs # ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) From 9de873c64000784b6670e3a1e142509bf9d038c4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 00:55:04 -0600 Subject: [PATCH 169/225] shadow patch21 setup --- src/figuro/renderer/utils/drawshadows.nim | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 68f4ed4c0..dad6425e4 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -155,7 +155,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(-ccenter[corner] / 2) ctx.drawImage(cornerHashes[corner], zero, shadowColor) - let sideAdj = (cbs.maxRadius.float32 - cornerCbs[corner].inner.float32) + let sideAdj = (maxRadius.float32 - cornerCbs[corner].inner.float32) let inner = cornerCbs[corner].inner.float32 let sideDelta = cornerCbs[corner].sideDelta.float32 let sideSize = cornerCbs[corner].sideSize.float32 @@ -173,7 +173,12 @@ proc fillRoundedRectWithShadowSdf*[R]( # ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) let borderDim = if sides[corner] in [dTop, dBottom]: w else: h - let prevSideAdj = (cbs.maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) - let borderSize = vec2(paddingOffset, borderDim - 2*cbs.maxRadius.float32 + sideAdj + prevSideAdj) + let prevSideAdj = (maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) + let borderSize = vec2(paddingOffset, borderDim - 2*maxRadius.float32 + sideAdj + prevSideAdj) ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() + + ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + + ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 7496c94afa3b189bdd6341b6765bd344746589c9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:08:01 -0600 Subject: [PATCH 170/225] shadow patch21 setup --- src/figuro/renderer/opengl/glcontext.nim | 11 +++++++---- src/figuro/renderer/utils/drawshadows.nim | 6 ++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/opengl/glcontext.nim b/src/figuro/renderer/opengl/glcontext.nim index 31c0765d1..2a0cfbd80 100644 --- a/src/figuro/renderer/opengl/glcontext.nim +++ b/src/figuro/renderer/opengl/glcontext.nim @@ -16,6 +16,9 @@ export drawextras logScope: scope = "opengl" +proc round*(v: Vec2): Vec2 = + vec2(round(v.x), round(v.y)) + const quadLimit = 10_921 type Context* = ref object @@ -390,10 +393,10 @@ proc drawUvRect(ctx: Context, at, to: Vec2, uvAt, uvTo: Vec2, color: Color) = let posQuad = [ - ceil(ctx.mat * vec2(at.x, to.y)), - ceil(ctx.mat * vec2(to.x, to.y)), - ceil(ctx.mat * vec2(to.x, at.y)), - ceil(ctx.mat * vec2(at.x, at.y)), + round(ctx.mat * vec2(at.x, to.y)), + round(ctx.mat * vec2(to.x, to.y)), + round(ctx.mat * vec2(to.x, at.y)), + round(ctx.mat * vec2(at.x, at.y)), ] uvQuad = [ vec2(uvAt.x, uvTo.y), diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index dad6425e4..ac2203356 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -150,9 +150,9 @@ proc fillRoundedRectWithShadowSdf*[R]( for corner in DirectionCorners: ctx.saveTransform() - ctx.translate(cpos[corner] + coffset[corner] + ccenter[corner] / 2) + ctx.translate(ceil(cpos[corner] + coffset[corner] + ccenter[corner] / 2)) ctx.rotate(angles[corner]) - ctx.translate(-ccenter[corner] / 2) + ctx.translate(ceil(-ccenter[corner] / 2)) ctx.drawImage(cornerHashes[corner], zero, shadowColor) let sideAdj = (maxRadius.float32 - cornerCbs[corner].inner.float32) @@ -169,8 +169,6 @@ proc fillRoundedRectWithShadowSdf*[R]( else: ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) - # we could do two boxes, but this matches our shadow needs - # ctx.drawRect(rect(inner, inner, sideDelta, sideDelta), shadowColor) let borderDim = if sides[corner] in [dTop, dBottom]: w else: h let prevSideAdj = (maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) From 3028b8f8ed4cada41a52e44ba6fb5efc8a9a2bd4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:09:34 -0600 Subject: [PATCH 171/225] shadow patch21 setup --- .github/workflows/build-full.yml | 2 +- .github/workflows/build-pr.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-full.yml b/.github/workflows/build-full.yml index eaad98c49..5f0b3914a 100644 --- a/.github/workflows/build-full.yml +++ b/.github/workflows/build-full.yml @@ -33,7 +33,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble@0.18.2 + nimble install nimble@0.18.4 nim -v nimble -v diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index f2db852f2..dc9b0dadc 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -30,7 +30,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble@0.18.2 + nimble install nimble@0.18.4 nim -v nimble -v From f606993bac487f0afcd390f1fb95c9309f7e1230 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:11:28 -0600 Subject: [PATCH 172/225] shadow patch21 setup --- .github/workflows/build-full.yml | 2 +- .github/workflows/build-pr.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-full.yml b/.github/workflows/build-full.yml index 5f0b3914a..eaad98c49 100644 --- a/.github/workflows/build-full.yml +++ b/.github/workflows/build-full.yml @@ -33,7 +33,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble@0.18.4 + nimble install nimble@0.18.2 nim -v nimble -v diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index dc9b0dadc..f2db852f2 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -30,7 +30,7 @@ jobs: - name: Install Nimble run: | - nimble install nimble@0.18.4 + nimble install nimble@0.18.2 nim -v nimble -v From 5ba84c972b7c6a1ae9a996d047ee3bbc5573adcd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:13:36 -0600 Subject: [PATCH 173/225] shadow patch21 setup --- .github/workflows/build-full.yml | 4 ++-- .github/workflows/build-pr.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-full.yml b/.github/workflows/build-full.yml index eaad98c49..3651c6200 100644 --- a/.github/workflows/build-full.yml +++ b/.github/workflows/build-full.yml @@ -17,8 +17,6 @@ jobs: - macOS-latest - windows-latest steps: - - uses: actions/checkout@v1 - - name: Cache packages uses: actions/cache@v3 with: @@ -37,6 +35,8 @@ jobs: nim -v nimble -v + - uses: actions/checkout@v1 + - name: Install Deps run: | # sync deps diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index f2db852f2..141a82d52 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -14,8 +14,6 @@ jobs: os: - ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: Cache packages uses: actions/cache@v3 with: @@ -34,6 +32,8 @@ jobs: nim -v nimble -v + - uses: actions/checkout@v1 + - name: Install Deps run: | # new atlas workspace From 2ebcfedfc0ef1569ec878377b7062eb19e69c490 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:15:45 -0600 Subject: [PATCH 174/225] shadow patch21 setup --- .github/workflows/build-full.yml | 14 +++++++------- .github/workflows/build-pr.yml | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-full.yml b/.github/workflows/build-full.yml index 3651c6200..bfc3553d6 100644 --- a/.github/workflows/build-full.yml +++ b/.github/workflows/build-full.yml @@ -17,11 +17,13 @@ jobs: - macOS-latest - windows-latest steps: - - name: Cache packages - uses: actions/cache@v3 - with: - path: ~/.nimble - key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} + - uses: actions/checkout@v1 + + # - name: Cache packages + # uses: actions/cache@v3 + # with: + # path: ~/.nimble + # key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} - uses: iffy/install-nim@v4 with: @@ -35,8 +37,6 @@ jobs: nim -v nimble -v - - uses: actions/checkout@v1 - - name: Install Deps run: | # sync deps diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 141a82d52..537e278f7 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -14,11 +14,13 @@ jobs: os: - ubuntu-latest steps: - - name: Cache packages - uses: actions/cache@v3 - with: - path: ~/.nimble - key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} + - uses: actions/checkout@v1 + + # - name: Cache packages + # uses: actions/cache@v3 + # with: + # path: ~/.nimble + # key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} - uses: iffy/install-nim@v4 with: @@ -32,8 +34,6 @@ jobs: nim -v nimble -v - - uses: actions/checkout@v1 - - name: Install Deps run: | # new atlas workspace From d6eb0bd8c107db4c01047b4775a45fc5f24d6758 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:20:41 -0600 Subject: [PATCH 175/225] fix ci --- .github/workflows/build-full.yml | 11 ++++++----- .github/workflows/build-pr.yml | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-full.yml b/.github/workflows/build-full.yml index bfc3553d6..2f13b2f89 100644 --- a/.github/workflows/build-full.yml +++ b/.github/workflows/build-full.yml @@ -19,11 +19,12 @@ jobs: steps: - uses: actions/checkout@v1 - # - name: Cache packages - # uses: actions/cache@v3 - # with: - # path: ~/.nimble - # key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} + - name: Cache packages + if: matrix.nimversion != '2.0.14' + uses: actions/cache@v3 + with: + path: ~/.nimble + key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} - uses: iffy/install-nim@v4 with: diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 537e278f7..8fa1a4241 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -16,11 +16,12 @@ jobs: steps: - uses: actions/checkout@v1 - # - name: Cache packages - # uses: actions/cache@v3 - # with: - # path: ~/.nimble - # key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} + - name: Cache packages + if: matrix.nimversion != '2.0.14' + uses: actions/cache@v3 + with: + path: ~/.nimble + key: ${{ runner.os }}-${{ hashFiles('figuro.nimble') }} - uses: iffy/install-nim@v4 with: From 155541f7d763a473bcf1c861aa3dc792d6fa15a8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:22:48 -0600 Subject: [PATCH 176/225] re-add clips --- src/figuro/renderer/opengl/renderer.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 0df8289ee..a1cfe1e22 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -251,13 +251,13 @@ proc render( ifrender node.kind == nkRectangle: ctx.renderDropShadows(node) - # # handle clipping children content based on this node - # ifrender NfClipContent in node.flags: - # ctx.beginMask() - # ctx.drawMasks(node) - # ctx.endMask() - # finally: - # ctx.popMask() + # handle clipping children content based on this node + ifrender NfClipContent in node.flags: + ctx.beginMask() + ctx.drawMasks(node) + ctx.endMask() + finally: + ctx.popMask() ifrender true: if node.kind == nkText: From 240c9c829512e9afb8fc58c65c2dfef274b3d53b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 01:25:04 -0600 Subject: [PATCH 177/225] fixes --- src/figuro/renderer/opengl/renderer.nim | 18 +++++++++--------- tests/tbutton.nim | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index a1cfe1e22..f2567c16e 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -270,15 +270,15 @@ proc render( elif node.kind == nkRectangle: ctx.renderBoxes(node) - # ifrender node.kind == nkRectangle: - # if NfClipContent notin node.flags: - # ctx.beginMask() - # ctx.drawMasks(node) - # ctx.endMask() - # ctx.renderInnerShadows(node) - # ctx.popMask() - # else: - # ctx.renderInnerShadows(node) + ifrender node.kind == nkRectangle: + if NfClipContent notin node.flags: + ctx.beginMask() + ctx.drawMasks(node) + ctx.endMask() + ctx.renderInnerShadows(node) + ctx.popMask() + else: + ctx.renderInnerShadows(node) # restores the opengl context back to the parent node's (see above) # ctx.restoreTransform() diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 8c1e71dfc..3068b5725 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -51,8 +51,8 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 40'ux, 30'pp, 30'pp - fill css"#2B9F2B" * 0.3 - border 5'ui, css"darkgreen" * 0.2 + fill css"#2B9F2B" * 1.0 + border 5'ui, css"darkgreen" * 1.0 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From 7ffa3455247de14ef2390853421cae595e5568ab Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 02:04:10 -0600 Subject: [PATCH 178/225] fixes --- src/figuro/renderer/opengl/glcontext.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/opengl/glcontext.nim b/src/figuro/renderer/opengl/glcontext.nim index 2a0cfbd80..8f7a82e1c 100644 --- a/src/figuro/renderer/opengl/glcontext.nim +++ b/src/figuro/renderer/opengl/glcontext.nim @@ -393,10 +393,10 @@ proc drawUvRect(ctx: Context, at, to: Vec2, uvAt, uvTo: Vec2, color: Color) = let posQuad = [ - round(ctx.mat * vec2(at.x, to.y)), - round(ctx.mat * vec2(to.x, to.y)), - round(ctx.mat * vec2(to.x, at.y)), - round(ctx.mat * vec2(at.x, at.y)), + ceil(ctx.mat * vec2(at.x, to.y)), + ceil(ctx.mat * vec2(to.x, to.y)), + ceil(ctx.mat * vec2(to.x, at.y)), + ceil(ctx.mat * vec2(at.x, at.y)), ] uvQuad = [ vec2(uvAt.x, uvTo.y), From f0c2dbc396fe1ced627e6568fdf21294bd51005c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 02:20:43 -0600 Subject: [PATCH 179/225] fixes --- src/figuro/renderer/utils/drawshadows.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index ac2203356..521f1c795 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -72,12 +72,13 @@ proc fillRoundedRectWithShadowSdf*[R]( let cornerCbs = cornerCbs[corner] let corners = vec4(cornerCbs.radius.float32) - var shadowImg = newImage(cornerCbs.sideSize, cornerCbs.sideSize) let wh = vec2(2*cornerCbs.inner.float32, 2*cornerCbs.inner.float32) let spread = if innerShadow: 0.0 else: shadowSpread let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow + var shadowImg = newImage(cornerCbs.sideSize, cornerCbs.sideSize) + drawSdfShape(shadowImg, center = vec2(cornerCbs.center.float32), wh = wh, @@ -150,9 +151,9 @@ proc fillRoundedRectWithShadowSdf*[R]( for corner in DirectionCorners: ctx.saveTransform() - ctx.translate(ceil(cpos[corner] + coffset[corner] + ccenter[corner] / 2)) + ctx.translate(floor(cpos[corner] + coffset[corner] + ccenter[corner] / 2)) ctx.rotate(angles[corner]) - ctx.translate(ceil(-ccenter[corner] / 2)) + ctx.translate((-ccenter[corner] / 2)) ctx.drawImage(cornerHashes[corner], zero, shadowColor) let sideAdj = (maxRadius.float32 - cornerCbs[corner].inner.float32) From abfe22e083603374968d715c47c944f843c0664f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 02:21:10 -0600 Subject: [PATCH 180/225] fixes --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 521f1c795..0a7a92178 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -151,7 +151,7 @@ proc fillRoundedRectWithShadowSdf*[R]( for corner in DirectionCorners: ctx.saveTransform() - ctx.translate(floor(cpos[corner] + coffset[corner] + ccenter[corner] / 2)) + ctx.translate(floor(cpos[corner] + coffset[corner] + ccenter[corner] / 2)) # important, floor once here, not after ctx.rotate(angles[corner]) ctx.translate((-ccenter[corner] / 2)) ctx.drawImage(cornerHashes[corner], zero, shadowColor) From 515daf58bd5ccd812795e93c4ae8121214b0baee Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 02:23:41 -0600 Subject: [PATCH 181/225] fixes --- src/figuro/renderer/opengl/renderer.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index f2567c16e..affc2780d 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -135,8 +135,6 @@ proc renderInnerShadows(ctx: Context, node: Node) = ## drawing poor man's inner shadows ## this is even more incorrect than drop shadows, but it's something ## and I don't actually want to think today ;) - if true: - return let shadow = node.shadow[InnerShadow] if shadow.blur <= 0.0 and shadow.spread <= 0.0: return From 37b1c5963ef98fb32ae20093a0e3c9f98f4a3197 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 18 Jun 2025 02:26:46 -0600 Subject: [PATCH 182/225] fixes --- src/figuro/renderer/openglBackend.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 08ab4a79e..2cf4ba321 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 1792 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) From bc97857a56d6dbaf723e7bfb7f57e62b10a4cec4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 19 Jun 2025 01:16:16 -0600 Subject: [PATCH 183/225] fix prs --- src/figuro/renderer/utils/drawshadows.nim | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 0a7a92178..6a165f0e1 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -177,7 +177,9 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() - ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) - - ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + if innerShadow: + ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + else: + ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 3f583939febfe37902a96676ae23cfeeda6788e2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 19 Jun 2025 01:21:12 -0600 Subject: [PATCH 184/225] fix prs --- src/figuro/renderer/utils/drawshadows.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 6a165f0e1..764225a25 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -178,7 +178,13 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.restoreTransform() if innerShadow: - ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + # left and right side boxes + ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + + # top and bottom side boxes + ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) + ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y + h - maxRadius.float32, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) else: ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From b6ab4d3e54df0176f6c008709a2c8ebf40738b72 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 19 Jun 2025 01:22:30 -0600 Subject: [PATCH 185/225] fix prs --- src/figuro/renderer/opengl/renderer.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index affc2780d..a95754ab4 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -269,14 +269,14 @@ proc render( ctx.renderBoxes(node) ifrender node.kind == nkRectangle: - if NfClipContent notin node.flags: - ctx.beginMask() - ctx.drawMasks(node) - ctx.endMask() - ctx.renderInnerShadows(node) - ctx.popMask() - else: - ctx.renderInnerShadows(node) + # if NfClipContent notin node.flags: + # ctx.beginMask() + # ctx.drawMasks(node) + # ctx.endMask() + # ctx.renderInnerShadows(node) + # ctx.popMask() + # else: + ctx.renderInnerShadows(node) # restores the opengl context back to the parent node's (see above) # ctx.restoreTransform() From 0f0d0880a6f70ff2c4e54f9f4fdf7c4221d6cc30 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 19 Jun 2025 01:27:14 -0600 Subject: [PATCH 186/225] fix prs --- src/figuro/renderer/utils/drawshadows.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 764225a25..044be7ba8 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -88,6 +88,8 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) + if innerShadow: + shadowImg.writeFile("examples/shadow-" & $corner & "-radius" & $cornerCbs.radius & ".png") ctx.putImage(cornerHashes[corner], shadowImg) for side in Directions: From 56a5dd8e914fa13df903834f7feb3ab783131daf Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 19 Jun 2025 01:28:43 -0600 Subject: [PATCH 187/225] fix prs --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 044be7ba8..3e2c40f5e 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -74,7 +74,7 @@ proc fillRoundedRectWithShadowSdf*[R]( let corners = vec4(cornerCbs.radius.float32) let wh = vec2(2*cornerCbs.inner.float32, 2*cornerCbs.inner.float32) - let spread = if innerShadow: 0.0 else: shadowSpread + let spread = shadowSpread let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow var shadowImg = newImage(cornerCbs.sideSize, cornerCbs.sideSize) From e21eca4d0c5cb05b731837ac788ed54e1e917fc8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 01:09:06 -0600 Subject: [PATCH 188/225] fix tbutton --- src/figuro/renderer/utils/drawboxes.nim | 2 +- src/figuro/renderer/utils/drawshadows.nim | 2 +- src/figuro/renderer/utils/drawutils.nim | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawboxes.nim b/src/figuro/renderer/utils/drawboxes.nim index 2df940c38..ce7910229 100644 --- a/src/figuro/renderer/utils/drawboxes.nim +++ b/src/figuro/renderer/utils/drawboxes.nim @@ -56,7 +56,7 @@ proc drawRoundedRect*[R]( # let hash = hash((6217, int(cbs.sideSize), int(cbs.maxRadius), int(weight), doStroke, outerShadowFill)) let hash = hash((6217, doStroke, outerShadowFill, cbs.padding, cbs.weightSize)) - let cornerCbs = cbs.roundedBoxCornerSizes(radii) + let cornerCbs = cbs.roundedBoxCornerSizes(radii, innerShadow = false) block drawCorners: var cornerHashes: array[DirectionCorners, Hash] diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3e2c40f5e..85c5a6532 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -52,7 +52,7 @@ proc fillRoundedRectWithShadowSdf*[R]( if cbs.paddingOffset == 0: return - let cornerCbs = cbs.roundedBoxCornerSizes(radii) + let cornerCbs = cbs.roundedBoxCornerSizes(radii, innerShadow) var sideHashes: array[Directions, Hash] for side in Directions: diff --git a/src/figuro/renderer/utils/drawutils.nim b/src/figuro/renderer/utils/drawutils.nim index 99ec2ac81..ad31bf47c 100644 --- a/src/figuro/renderer/utils/drawutils.nim +++ b/src/figuro/renderer/utils/drawutils.nim @@ -57,11 +57,14 @@ proc getCircleBoxSizes*( proc roundedBoxCornerSizes*( cbs: tuple[maxRadius, sideSize, totalSize, padding, paddingOffset, inner, weightSize: int], radii: array[DirectionCorners, float32], + innerShadow: bool, ): array[DirectionCorners, tuple[radius, sideSize, inner, sideDelta, center: int]] = let ww = cbs.weightSize for corner in DirectionCorners: - let dim = max(int(round(radii[corner])), ww) + let dim = + if innerShadow: max(cbs.maxRadius, cbs.paddingOffset) + else: max(int(round(radii[corner])), ww) let sideSize = cbs.paddingOffset + dim let center = sideSize result[corner] = (radius: int(round(radii[corner])), From ea2cfcca98aa962dd987c84dbd0fc0edb669d0b7 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 01:10:06 -0600 Subject: [PATCH 189/225] fix tbutton --- src/figuro/renderer/utils/drawshadows.nim | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 85c5a6532..d71ce7e02 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -180,13 +180,14 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.restoreTransform() if innerShadow: + discard # left and right side boxes - ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - # top and bottom side boxes - ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) - ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y + h - maxRadius.float32, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) + # # top and bottom side boxes + # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) + # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y + h - maxRadius.float32, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) else: ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 88a1aa20aec9d28535d3dbc369bf4be776ecba35 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 01:15:17 -0600 Subject: [PATCH 190/225] fix tbutton --- src/figuro/renderer/utils/drawshadows.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index d71ce7e02..8f494234f 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -169,6 +169,8 @@ proc fillRoundedRectWithShadowSdf*[R]( discard # ctx.drawRect(rect(0, inner, cbs.weightSize.float32, sideDelta), color) # ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) + # ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) + # ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) else: ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) From 7d17ed9eb059ed01be6c5db4e6c6eeec8d0868e5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 01:24:14 -0600 Subject: [PATCH 191/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 8f494234f..d5aa4b00a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -56,7 +56,7 @@ proc fillRoundedRectWithShadowSdf*[R]( var sideHashes: array[Directions, Hash] for side in Directions: - sideHashes[side] = hash((shadowKey, 971767, int(cbs.padding))) + sideHashes[side] = hash((shadowKey, 971767, int(cbs.padding), int(cbs.sideSize))) block drawCorners: var cornerHashes: array[DirectionCorners, Hash] @@ -88,8 +88,8 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) - if innerShadow: - shadowImg.writeFile("examples/shadow-" & $corner & "-radius" & $cornerCbs.radius & ".png") + # if innerShadow: + # shadowImg.writeFile("examples/shadow-" & $corner & "-radius" & $cornerCbs.radius & ".png") ctx.putImage(cornerHashes[corner], shadowImg) for side in Directions: @@ -100,7 +100,7 @@ proc fillRoundedRectWithShadowSdf*[R]( var shadowImg = newImage(cbs.paddingOffset, 4) let wh = vec2(1, 12) - let spread = if innerShadow: 0.0 else: shadowSpread + let spread = shadowSpread let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow drawSdfShape(shadowImg, @@ -112,6 +112,9 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) + if innerShadow: + echo "SHADOW side: ", side, " paddingOffset: ", cbs.paddingOffset, " sideSize: ", cbs.sideSize + shadowImg.writeFile("examples/shadow-side-" & $side & "-paddingOffset" & $cbs.paddingOffset & "-sideSize" & $cbs.sideSize & ".png") ctx.putImage(sideHashes[side], shadowImg) let From 30ca101194e814d2dad05b236da34da24022a6d6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 01:36:50 -0600 Subject: [PATCH 192/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index d5aa4b00a..83d8eb3f7 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -181,7 +181,13 @@ proc fillRoundedRectWithShadowSdf*[R]( let borderDim = if sides[corner] in [dTop, dBottom]: w else: h let prevSideAdj = (maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) let borderSize = vec2(paddingOffset, borderDim - 2*maxRadius.float32 + sideAdj + prevSideAdj) - ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) + if innerShadow: + echo "SHADOW side: ", sides[corner], " paddingOffset: ", paddingOffset, " sideSize: ", cornerCbs[corner].sideSize, " borderSize: ", borderSize + # ctx.drawRect(rect(vec2(0, cornerCbs[corner].sideSize.float32), borderSize), shadowColor) + # ctx.drawRect(rect(vec2(paddingOffset, paddingOffset), borderSize), shadowColor) + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(paddingOffset, 2*paddingOffset), shadowColor, borderSize) + else: + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() if innerShadow: From beb16cf4aa63a0fdbc9cefc4fdce49e65a3cfe26 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 01:43:07 -0600 Subject: [PATCH 193/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 83d8eb3f7..598184791 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -102,9 +102,11 @@ proc fillRoundedRectWithShadowSdf*[R]( let spread = shadowSpread let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow + let center = if innerShadow: vec2(2*cbs.paddingOffset.float32, 2) else: vec2(cbs.paddingOffset.float32, 2) + # let mode = sdfModeDropShadow drawSdfShape(shadowImg, - center = vec2(cbs.paddingOffset.float32, 2), + center = center, wh = wh, params = RoundedBoxParams(r: corners), pos = whiteColor, From f65e4015d1145723fde80ba9321cae3e862934e8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:03:00 -0600 Subject: [PATCH 194/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 598184791..0cf2122e0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -101,9 +101,10 @@ proc fillRoundedRectWithShadowSdf*[R]( let wh = vec2(1, 12) let spread = shadowSpread - let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow - let center = if innerShadow: vec2(2*cbs.paddingOffset.float32, 2) else: vec2(cbs.paddingOffset.float32, 2) - # let mode = sdfModeDropShadow + # let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow + let center = if innerShadow: vec2(cbs.paddingOffset.float32-1, 2) else: vec2(cbs.paddingOffset.float32, 2) + let mode = sdfModeDropShadow + drawSdfShape(shadowImg, center = center, @@ -114,6 +115,8 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) + if innerShadow: + shadowImg.flipHorizontal() if innerShadow: echo "SHADOW side: ", side, " paddingOffset: ", cbs.paddingOffset, " sideSize: ", cbs.sideSize shadowImg.writeFile("examples/shadow-side-" & $side & "-paddingOffset" & $cbs.paddingOffset & "-sideSize" & $cbs.sideSize & ".png") From 3bd8a64b4cedb6d3a7e5196a50edea589f9c4b05 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:03:15 -0600 Subject: [PATCH 195/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 0cf2122e0..3151ea453 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -88,8 +88,6 @@ proc fillRoundedRectWithShadowSdf*[R]( factor = shadowBlur, spread = spread, mode = mode) - # if innerShadow: - # shadowImg.writeFile("examples/shadow-" & $corner & "-radius" & $cornerCbs.radius & ".png") ctx.putImage(cornerHashes[corner], shadowImg) for side in Directions: @@ -101,7 +99,6 @@ proc fillRoundedRectWithShadowSdf*[R]( let wh = vec2(1, 12) let spread = shadowSpread - # let mode = if innerShadow: sdfModeInsetShadow else: sdfModeDropShadow let center = if innerShadow: vec2(cbs.paddingOffset.float32-1, 2) else: vec2(cbs.paddingOffset.float32, 2) let mode = sdfModeDropShadow @@ -117,9 +114,6 @@ proc fillRoundedRectWithShadowSdf*[R]( mode = mode) if innerShadow: shadowImg.flipHorizontal() - if innerShadow: - echo "SHADOW side: ", side, " paddingOffset: ", cbs.paddingOffset, " sideSize: ", cbs.sideSize - shadowImg.writeFile("examples/shadow-side-" & $side & "-paddingOffset" & $cbs.paddingOffset & "-sideSize" & $cbs.sideSize & ".png") ctx.putImage(sideHashes[side], shadowImg) let From cc0a07c61ea5c5508fd58ff1511e6ce827febf21 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:04:12 -0600 Subject: [PATCH 196/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3151ea453..1a5f61393 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -181,9 +181,6 @@ proc fillRoundedRectWithShadowSdf*[R]( let prevSideAdj = (maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) let borderSize = vec2(paddingOffset, borderDim - 2*maxRadius.float32 + sideAdj + prevSideAdj) if innerShadow: - echo "SHADOW side: ", sides[corner], " paddingOffset: ", paddingOffset, " sideSize: ", cornerCbs[corner].sideSize, " borderSize: ", borderSize - # ctx.drawRect(rect(vec2(0, cornerCbs[corner].sideSize.float32), borderSize), shadowColor) - # ctx.drawRect(rect(vec2(paddingOffset, paddingOffset), borderSize), shadowColor) ctx.drawImageAdj(sideHashes[sides[corner]], vec2(paddingOffset, 2*paddingOffset), shadowColor, borderSize) else: ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) From b2814a811c2985d761ae4ec345bbd306eb7aeebf Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:04:46 -0600 Subject: [PATCH 197/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 1a5f61393..7dce6886a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -167,13 +167,7 @@ proc fillRoundedRectWithShadowSdf*[R]( if cornerCbs[corner].sideDelta > 0: # inner patch left, right, and then center - if innerShadow: - discard - # ctx.drawRect(rect(0, inner, cbs.weightSize.float32, sideDelta), color) - # ctx.drawRect(rect(inner, 0, sideDelta, cbs.weightSize.float32), color) - # ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) - # ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) - else: + if not innerShadow: ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) From dd9b7248b9231cb2c4809af5f53e9825f23bb407 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:06:44 -0600 Subject: [PATCH 198/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 7dce6886a..866cd4780 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -95,7 +95,7 @@ proc fillRoundedRectWithShadowSdf*[R]( continue let corners = vec4(0) - var shadowImg = newImage(cbs.paddingOffset, 4) + var shadowImg = newImage(cbs.paddingOffset, 3) let wh = vec2(1, 12) let spread = shadowSpread From f4cc331465cac65a06e9a7a6e72461f35273b322 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:12:20 -0600 Subject: [PATCH 199/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 866cd4780..93123b135 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -148,7 +148,7 @@ proc fillRoundedRectWithShadowSdf*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) black = rgba(0, 0, 0, 255).to(Color) - angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: Pi] + angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: -Pi] let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] From ce914100460ed0520231b1f64294f5ffeafa7df2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:16:11 -0600 Subject: [PATCH 200/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 93123b135..68e7d0c3d 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -1,5 +1,7 @@ # import glcommons import std/hashes +import std/fenv + import ../../commons import ../../common/nodes/render @@ -148,7 +150,7 @@ proc fillRoundedRectWithShadowSdf*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) black = rgba(0, 0, 0, 255).to(Color) - angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2, dcBottomRight: -Pi] + angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] From 5a0e3309b7dfd9d6315996a52d63fb5a9b95f55c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:16:25 -0600 Subject: [PATCH 201/225] fix inner --- src/figuro/renderer/openglBackend.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/openglBackend.nim b/src/figuro/renderer/openglBackend.nim index 2cf4ba321..08ab4a79e 100644 --- a/src/figuro/renderer/openglBackend.nim +++ b/src/figuro/renderer/openglBackend.nim @@ -27,7 +27,7 @@ export baserenderer proc createRenderer*[F](frame: WeakRef[F]): Renderer = - let atlasSize = 1792 shl (app.uiScale.round().toInt() + 1) + let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1) let window = newWindexWindow(frame) let renderer = newOpenGLRenderer(window, frame, atlasSize) From dd3d10c679e0c9e7338ce41dbf9d9083b21f0148 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:24:44 -0600 Subject: [PATCH 202/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 68e7d0c3d..bccfc2813 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -177,7 +177,7 @@ proc fillRoundedRectWithShadowSdf*[R]( let prevSideAdj = (maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) let borderSize = vec2(paddingOffset, borderDim - 2*maxRadius.float32 + sideAdj + prevSideAdj) if innerShadow: - ctx.drawImageAdj(sideHashes[sides[corner]], vec2(paddingOffset, 2*paddingOffset), shadowColor, borderSize) + ctx.drawImageAdj(sideHashes[sides[corner]], vec2(paddingOffset, paddingOffset+cornerCbs[prevCorner[corner]].inner.float32), shadowColor, borderSize) else: ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() From 8157ae63ecdb24b78348262df3a28af768aff3d6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:26:31 -0600 Subject: [PATCH 203/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index bccfc2813..96edb568b 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -29,7 +29,9 @@ proc fillRoundedRectWithShadowSdf*[R]( ## The shadow is drawn with padding around the main rectangle if rect.w <= 0 or rect.h <= 0: return - + + let rect = rect + rect(shadowX, shadowY, 0, 0) + # First, draw the shadow # Generate shadow key for caching let From d88e57ee13479d04bd2c45296c7640a7e343f1c5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:35:39 -0600 Subject: [PATCH 204/225] fix inner --- src/figuro/renderer/opengl/renderer.nim | 12 ++++++------ src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index a95754ab4..84529d826 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -250,12 +250,12 @@ proc render( ctx.renderDropShadows(node) # handle clipping children content based on this node - ifrender NfClipContent in node.flags: - ctx.beginMask() - ctx.drawMasks(node) - ctx.endMask() - finally: - ctx.popMask() + # ifrender NfClipContent in node.flags: + # ctx.beginMask() + # ctx.drawMasks(node) + # ctx.endMask() + # finally: + # ctx.popMask() ifrender true: if node.kind == nkText: diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 96edb568b..3c9e16d79 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -187,8 +187,8 @@ proc fillRoundedRectWithShadowSdf*[R]( if innerShadow: discard # left and right side boxes - # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + let shadowColor = rgba(255, 255, 255, 255).to(Color) + ctx.drawRect(rect(rect.x - paddingOffset.float32, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) # # top and bottom side boxes # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) From dfb95f1c18b4c3531282ae7b8c91531540afdbfa Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:36:36 -0600 Subject: [PATCH 205/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3c9e16d79..03fe0afcf 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -189,6 +189,7 @@ proc fillRoundedRectWithShadowSdf*[R]( # left and right side boxes let shadowColor = rgba(255, 255, 255, 255).to(Color) ctx.drawRect(rect(rect.x - paddingOffset.float32, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) + ctx.drawRect(rect(rect.x + w, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) # # top and bottom side boxes # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) From fbfa9db8b3908933d43774b0b76df069a7bf04ad Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:37:15 -0600 Subject: [PATCH 206/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 03fe0afcf..66602db50 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -191,6 +191,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawRect(rect(rect.x - paddingOffset.float32, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) ctx.drawRect(rect(rect.x + w, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) + ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y - paddingOffset.float32, w - 2*paddingOffset.float32, paddingOffset), shadowColor) # # top and bottom side boxes # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y + h - maxRadius.float32, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) From b1710384eccc712787c8dbdfebddc02da9976a96 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:39:33 -0600 Subject: [PATCH 207/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 66602db50..a621681f0 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -187,14 +187,12 @@ proc fillRoundedRectWithShadowSdf*[R]( if innerShadow: discard # left and right side boxes - let shadowColor = rgba(255, 255, 255, 255).to(Color) ctx.drawRect(rect(rect.x - paddingOffset.float32, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) ctx.drawRect(rect(rect.x + w, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) - ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y - paddingOffset.float32, w - 2*paddingOffset.float32, paddingOffset), shadowColor) # # top and bottom side boxes - # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) - # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y + h - maxRadius.float32, w - 2*maxRadius.float32, maxRadius.float32), shadowColor) + ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y - paddingOffset.float32, w - 2*paddingOffset.float32, paddingOffset), shadowColor) + ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y + h, w - 2*paddingOffset.float32, paddingOffset), shadowColor) else: ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 0afb8a49bb6b612436fd9e772d8a26d4e14b7df9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:47:12 -0600 Subject: [PATCH 208/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index a621681f0..fe638ecb1 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -169,11 +169,14 @@ proc fillRoundedRectWithShadowSdf*[R]( let sideDelta = cornerCbs[corner].sideDelta.float32 let sideSize = cornerCbs[corner].sideSize.float32 - if cornerCbs[corner].sideDelta > 0: - # inner patch left, right, and then center - if not innerShadow: - ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) - ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) + if innerShadow: + if sides[corner] in [dTop, dBottom]: + ctx.drawRect(rect(0, 2*paddingOffset.float32, paddingOffset.float32, w - 2*paddingOffset.float32), shadowColor) + else: + ctx.drawRect(rect(0, 2*paddingOffset.float32, paddingOffset.float32, h - 2*paddingOffset.float32), shadowColor) + if not innerShadow and cornerCbs[corner].sideDelta > 0: + ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) + ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) let borderDim = if sides[corner] in [dTop, dBottom]: w else: h let prevSideAdj = (maxRadius.float32 - cornerCbs[prevCorner[corner]].inner.float32) @@ -187,12 +190,12 @@ proc fillRoundedRectWithShadowSdf*[R]( if innerShadow: discard # left and right side boxes - ctx.drawRect(rect(rect.x - paddingOffset.float32, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) - ctx.drawRect(rect(rect.x + w, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) + # ctx.drawRect(rect(rect.x - paddingOffset.float32, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) + # ctx.drawRect(rect(rect.x + w, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) - # # top and bottom side boxes - ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y - paddingOffset.float32, w - 2*paddingOffset.float32, paddingOffset), shadowColor) - ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y + h, w - 2*paddingOffset.float32, paddingOffset), shadowColor) + # # # top and bottom side boxes + # ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y - paddingOffset.float32, w - 2*paddingOffset.float32, paddingOffset), shadowColor) + # ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y + h, w - 2*paddingOffset.float32, paddingOffset), shadowColor) else: ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 00e181816625fb6950d88775397335bd25d5f59e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:47:23 -0600 Subject: [PATCH 209/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index fe638ecb1..79a5802a6 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -174,7 +174,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawRect(rect(0, 2*paddingOffset.float32, paddingOffset.float32, w - 2*paddingOffset.float32), shadowColor) else: ctx.drawRect(rect(0, 2*paddingOffset.float32, paddingOffset.float32, h - 2*paddingOffset.float32), shadowColor) - if not innerShadow and cornerCbs[corner].sideDelta > 0: + elif cornerCbs[corner].sideDelta > 0: ctx.drawRect(rect(paddingOffset, paddingOffset + inner, inner, sideDelta), shadowColor) ctx.drawRect(rect(paddingOffset + inner, paddingOffset, sideDelta, cbs.maxRadius.float32), shadowColor) From afabad7a6e84fd39952da795897198082241ce07 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:47:38 -0600 Subject: [PATCH 210/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 79a5802a6..3bab5e94d 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -187,16 +187,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() - if innerShadow: - discard - # left and right side boxes - # ctx.drawRect(rect(rect.x - paddingOffset.float32, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) - # ctx.drawRect(rect(rect.x + w, rect.y + paddingOffset.float32, paddingOffset, h - 2*paddingOffset.float32), shadowColor) - - # # # top and bottom side boxes - # ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y - paddingOffset.float32, w - 2*paddingOffset.float32, paddingOffset), shadowColor) - # ctx.drawRect(rect(rect.x + paddingOffset.float32, rect.y + h, w - 2*paddingOffset.float32, paddingOffset), shadowColor) - else: + if not innerShadow: ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 6cb82e9070b3fda7055fda4a91e89c1f5dc05359 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:48:46 -0600 Subject: [PATCH 211/225] fix inner --- src/figuro/renderer/opengl/renderer.nim | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/figuro/renderer/opengl/renderer.nim b/src/figuro/renderer/opengl/renderer.nim index 84529d826..fc40f48f4 100644 --- a/src/figuro/renderer/opengl/renderer.nim +++ b/src/figuro/renderer/opengl/renderer.nim @@ -201,7 +201,7 @@ proc renderBoxes(ctx: Context, node: Node) = if node.image.id.int != 0: let size = vec2(node.screenBox.w, node.screenBox.h) if ctx.cacheImage(node.image.name, node.image.id.Hash): - ctx.drawImage(node.image.id.Hash, pos = vec2(0, 0), color = node.image.color, size = size) + ctx.drawImage(node.image.id.Hash, pos = node.screenBox.xy, color = node.image.color, size = size) if node.stroke.color.a > 0 and node.stroke.weight > 0: ctx.drawRoundedRect( @@ -250,12 +250,12 @@ proc render( ctx.renderDropShadows(node) # handle clipping children content based on this node - # ifrender NfClipContent in node.flags: - # ctx.beginMask() - # ctx.drawMasks(node) - # ctx.endMask() - # finally: - # ctx.popMask() + ifrender NfClipContent in node.flags: + ctx.beginMask() + ctx.drawMasks(node) + ctx.endMask() + finally: + ctx.popMask() ifrender true: if node.kind == nkText: @@ -269,14 +269,14 @@ proc render( ctx.renderBoxes(node) ifrender node.kind == nkRectangle: - # if NfClipContent notin node.flags: - # ctx.beginMask() - # ctx.drawMasks(node) - # ctx.endMask() - # ctx.renderInnerShadows(node) - # ctx.popMask() - # else: - ctx.renderInnerShadows(node) + if NfClipContent notin node.flags: + ctx.beginMask() + ctx.drawMasks(node) + ctx.endMask() + ctx.renderInnerShadows(node) + ctx.popMask() + else: + ctx.renderInnerShadows(node) # restores the opengl context back to the parent node's (see above) # ctx.restoreTransform() From 8c1202621b7116255e2062ec2d15a974aab0dd48 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:52:01 -0600 Subject: [PATCH 212/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3bab5e94d..d504b99c1 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -152,7 +152,7 @@ proc fillRoundedRectWithShadowSdf*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) black = rgba(0, 0, 0, 255).to(Color) - angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2, dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] + angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2 + epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] @@ -187,7 +187,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() - if not innerShadow: - ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) - ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # if not innerShadow: + # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From ca6d4d3e01ee87fe6e143dee6ec35681419adc35 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:52:55 -0600 Subject: [PATCH 213/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index d504b99c1..1b94df909 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -187,7 +187,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) ctx.restoreTransform() - # if not innerShadow: - # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) - # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + if not innerShadow: + ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 81383e2f329e87431d4b03c00b384555c06fa6f8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 02:55:37 -0600 Subject: [PATCH 214/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 1b94df909..59d00812a 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -152,7 +152,7 @@ proc fillRoundedRectWithShadowSdf*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) black = rgba(0, 0, 0, 255).to(Color) - angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2 + epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] + angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2 - epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] From 6398ca3831336aca55fd95e732295f8088523030 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:09:03 -0600 Subject: [PATCH 215/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 59d00812a..da050f569 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -185,9 +185,14 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.drawImageAdj(sideHashes[sides[corner]], vec2(paddingOffset, paddingOffset+cornerCbs[prevCorner[corner]].inner.float32), shadowColor, borderSize) else: ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) - ctx.restoreTransform() - if not innerShadow: - ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) - ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + if not innerShadow: + if sides[corner] in [dTop, dBottom]: + ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - maxRadius.float32, w - paddingOffset.float32), shadowColor) + else: + ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - maxRadius.float32, h - paddingOffset.float32), shadowColor) + ctx.restoreTransform() + # if not innerShadow and corner == dcTopLeft: + # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 68578c888437048c9f2c9bd9372f0ed0254a1818 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:09:09 -0600 Subject: [PATCH 216/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index da050f569..3174ef1df 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -192,7 +192,7 @@ proc fillRoundedRectWithShadowSdf*[R]( else: ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - maxRadius.float32, h - paddingOffset.float32), shadowColor) ctx.restoreTransform() - # if not innerShadow and corner == dcTopLeft: - # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) - # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # if not innerShadow and corner == dcTopLeft: + # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 22ef734b267cf231915f2e6bbec3ba4a3184ba02 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:13:49 -0600 Subject: [PATCH 217/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 3174ef1df..37fadf068 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -186,13 +186,13 @@ proc fillRoundedRectWithShadowSdf*[R]( else: ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) - if not innerShadow: - if sides[corner] in [dTop, dBottom]: - ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - maxRadius.float32, w - paddingOffset.float32), shadowColor) - else: - ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - maxRadius.float32, h - paddingOffset.float32), shadowColor) + # if not innerShadow: + # if sides[corner] in [dTop, dBottom]: + # ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - cornerCbs[prevCorner[corner]].inner.float32, w - paddingOffset.float32 + 1), shadowColor) + # # else: + # # ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - maxRadius.float32 + 1, h - paddingOffset.float32 + 1), shadowColor) ctx.restoreTransform() - # if not innerShadow and corner == dcTopLeft: - # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) - # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + if not innerShadow: + ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From 3ff6d0fa7b1719998a435af577a0ac003582e520 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:19:44 -0600 Subject: [PATCH 218/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 37fadf068..2bf46c630 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -186,13 +186,14 @@ proc fillRoundedRectWithShadowSdf*[R]( else: ctx.drawImageAdj(sideHashes[sides[corner]], vec2(0, cornerCbs[corner].sideSize.float32), shadowColor, borderSize) - # if not innerShadow: - # if sides[corner] in [dTop, dBottom]: - # ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - cornerCbs[prevCorner[corner]].inner.float32, w - paddingOffset.float32 + 1), shadowColor) - # # else: - # # ctx.drawRect(rect(paddingOffset, paddingOffset, paddingOffset - maxRadius.float32 + 1, h - paddingOffset.float32 + 1), shadowColor) + if not innerShadow and corner == dcTopLeft: + ctx.translate(vec2(paddingOffset.float32, paddingOffset.float32)) + ctx.drawRect(rect(maxRadius.float32 - 1, 0, w - 2*maxRadius.float32 + 2, h), shadowColor) + # ctx.drawRect(rect(0, maxRadius.float32, w, h - 2*maxRadius.float32), shadowColor) + # ctx.drawRect(rect(w - maxRadius.float32, maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + ctx.restoreTransform() - if not innerShadow: - ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) - ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # if not innerShadow: + # ctx.drawRect(rect(rect.x + maxRadius.float32, rect.y, w - 2*maxRadius.float32, h), shadowColor) + # ctx.drawRect(rect(rect.x, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + # ctx.drawRect(rect(rect.x + w - maxRadius.float32, rect.y + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) From ba69bcae26f972fd93b0884a79d231941bf9d3bd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:21:07 -0600 Subject: [PATCH 219/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 2bf46c630..a6209f5f2 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -152,7 +152,11 @@ proc fillRoundedRectWithShadowSdf*[R]( darkGrey = rgba(50, 50, 50, 255).to(Color) black = rgba(0, 0, 0, 255).to(Color) - angles = [dcTopLeft: 0.0, dcTopRight: -Pi/2 - epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] + angles = + if innerShadow: + [dcTopLeft: 0.0, dcTopRight: -Pi/2 - epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] + else: + [dcTopLeft: 0.0, dcTopRight: -Pi/2 - epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] @@ -189,8 +193,6 @@ proc fillRoundedRectWithShadowSdf*[R]( if not innerShadow and corner == dcTopLeft: ctx.translate(vec2(paddingOffset.float32, paddingOffset.float32)) ctx.drawRect(rect(maxRadius.float32 - 1, 0, w - 2*maxRadius.float32 + 2, h), shadowColor) - # ctx.drawRect(rect(0, maxRadius.float32, w, h - 2*maxRadius.float32), shadowColor) - # ctx.drawRect(rect(w - maxRadius.float32, maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) ctx.restoreTransform() # if not innerShadow: From 9b2bd7635059b0cd8f81dfe09f8b08221db587d0 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:25:24 -0600 Subject: [PATCH 220/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index a6209f5f2..561660bd5 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -156,7 +156,7 @@ proc fillRoundedRectWithShadowSdf*[R]( if innerShadow: [dcTopLeft: 0.0, dcTopRight: -Pi/2 - epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] else: - [dcTopLeft: 0.0, dcTopRight: -Pi/2 - epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi] + [dcTopLeft: 0.0, dcTopRight: -Pi/2 - epsilon(float32), dcBottomLeft: Pi/2 + epsilon(float32), dcBottomRight: -Pi + epsilon(float32)] let sides = [dcTopLeft: dLeft, dcTopRight: dTop, dcBottomLeft: dBottom, dcBottomRight: dRight] let prevCorner = [dcTopLeft: dcBottomLeft, dcTopRight: dcTopLeft, dcBottomLeft: dcBottomRight, dcBottomRight: dcTopRight] @@ -192,7 +192,8 @@ proc fillRoundedRectWithShadowSdf*[R]( if not innerShadow and corner == dcTopLeft: ctx.translate(vec2(paddingOffset.float32, paddingOffset.float32)) - ctx.drawRect(rect(maxRadius.float32 - 1, 0, w - 2*maxRadius.float32 + 2, h), shadowColor) + ctx.drawRect(rect(maxRadius.float32, 0, w - 2*maxRadius.float32 + 1, h), shadowColor) + ctx.drawRect(rect(0, 0 + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) ctx.restoreTransform() # if not innerShadow: From 4b5c710a32116ec4d2875060ddb08303b4574ed0 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:27:55 -0600 Subject: [PATCH 221/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index 561660bd5..b1cfe80cd 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -194,6 +194,7 @@ proc fillRoundedRectWithShadowSdf*[R]( ctx.translate(vec2(paddingOffset.float32, paddingOffset.float32)) ctx.drawRect(rect(maxRadius.float32, 0, w - 2*maxRadius.float32 + 1, h), shadowColor) ctx.drawRect(rect(0, 0 + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) + ctx.drawRect(rect(w - maxRadius.float32 + 1, 0 + maxRadius.float32, maxRadius.float32 - 1, h - 2*maxRadius.float32), shadowColor) ctx.restoreTransform() # if not innerShadow: From d7b1ed0d8d67ab72018d048333f7f89bd2ecfd6c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:34:23 -0600 Subject: [PATCH 222/225] fix inner --- src/figuro/renderer/utils/drawshadows.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/figuro/renderer/utils/drawshadows.nim b/src/figuro/renderer/utils/drawshadows.nim index b1cfe80cd..712d25d66 100644 --- a/src/figuro/renderer/utils/drawshadows.nim +++ b/src/figuro/renderer/utils/drawshadows.nim @@ -192,9 +192,9 @@ proc fillRoundedRectWithShadowSdf*[R]( if not innerShadow and corner == dcTopLeft: ctx.translate(vec2(paddingOffset.float32, paddingOffset.float32)) - ctx.drawRect(rect(maxRadius.float32, 0, w - 2*maxRadius.float32 + 1, h), shadowColor) + ctx.drawRect(rect(maxRadius.float32, 0, w - 2*maxRadius.float32, h), shadowColor) ctx.drawRect(rect(0, 0 + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) - ctx.drawRect(rect(w - maxRadius.float32 + 1, 0 + maxRadius.float32, maxRadius.float32 - 1, h - 2*maxRadius.float32), shadowColor) + ctx.drawRect(rect(w - maxRadius.float32, 0 + maxRadius.float32, maxRadius.float32, h - 2*maxRadius.float32), shadowColor) ctx.restoreTransform() # if not innerShadow: From e31860734410a227d6055ffb8735d27d296ca325 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:35:58 -0600 Subject: [PATCH 223/225] fix inner --- tests/tbutton.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 3068b5725..2ce875422 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -52,7 +52,7 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 40'ux, 30'pp, 30'pp fill css"#2B9F2B" * 1.0 - border 5'ui, css"darkgreen" * 1.0 + # border 5'ui, css"darkgreen" * 1.0 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From 18085ba940cb4fa1a9b9b090b0b5b4481d454cf3 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 03:41:06 -0600 Subject: [PATCH 224/225] fix inner --- tests/tbutton.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tbutton.nim b/tests/tbutton.nim index 2ce875422..3068b5725 100644 --- a/tests/tbutton.nim +++ b/tests/tbutton.nim @@ -52,7 +52,7 @@ proc draw*(self: Main) {.slot.} = Button[int] as "btn": box 40'ux, 40'ux, 30'pp, 30'pp fill css"#2B9F2B" * 1.0 - # border 5'ui, css"darkgreen" * 1.0 + border 5'ui, css"darkgreen" * 1.0 corners topLeft = self.fades[FkTopLeft].amount.UiScalar, topRight = self.fades[FkTopRight].amount.UiScalar, bottomLeft = self.fades[FkBottomLeft].amount.UiScalar, From 557b4a92c6651bf7e49d473b1bce28004639cbb4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 20 Jun 2025 04:15:23 -0600 Subject: [PATCH 225/225] fix inner --- figuro.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/figuro.nimble b/figuro.nimble index 535d4c75d..e827aa270 100644 --- a/figuro.nimble +++ b/figuro.nimble @@ -1,4 +1,4 @@ -version = "0.16.0" +version = "0.16.1" author = "Jaremy Creechley" description = "UI Engine for Nim" license = "MIT"