From 5e4f291f7d89fdf8c7058ca401bbc692cbbd9d21 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Fri, 18 Jun 2021 20:40:47 -0500 Subject: [PATCH 1/2] add test --- tests/images/paths/maskRectExcludeMask.png | Bin 0 -> 208 bytes tests/images/paths/maskRectExcludeMaskAA.png | Bin 0 -> 237 bytes tests/images/paths/maskRectMask.png | Bin 0 -> 208 bytes tests/images/paths/maskRectMaskAA.png | Bin 0 -> 237 bytes tests/test_paths.nim | 24 +++++++++++++++++++ 5 files changed, 24 insertions(+) create mode 100644 tests/images/paths/maskRectExcludeMask.png create mode 100644 tests/images/paths/maskRectExcludeMaskAA.png create mode 100644 tests/images/paths/maskRectMask.png create mode 100644 tests/images/paths/maskRectMaskAA.png diff --git a/tests/images/paths/maskRectExcludeMask.png b/tests/images/paths/maskRectExcludeMask.png new file mode 100644 index 0000000000000000000000000000000000000000..d17c2b58aa780b1f92351364392363e16cc227db GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^DIm-NBp57Fi*Ar*{oZ=B|8P+(xaxIq58 z{`yq5@EngLN9WYWNL5{|)Oo;>q<197WAbaQkiQmJd#3ca+sHVcX`R7sC=QZ1F)8Nd zYz5x`Rmau)6rMRDBsz8q6f0UkS#@xZeD2xs+D9j5@7%@q-Sg4aug|VteR>sWz)jQe oinshrF3Z`3Ju6^=7zfs6p5WBGW6|%5=^&?iy85}Sb4q9e0P<8+iU0rr literal 0 HcmV?d00001 diff --git a/tests/images/paths/maskRectExcludeMaskAA.png b/tests/images/paths/maskRectExcludeMaskAA.png new file mode 100644 index 0000000000000000000000000000000000000000..64db8caee3aa76add4f09e80fd542cccb95b8c4b GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^DIm-NBp5kMwsqTc)BCO)N`Cn@$v z-&O7IcjhQoeC7m_G8Dh0dfnJU*yZ=Xg|>D=cjr29f(R$+9f|4KDF9M;Zo=#D|H|_} zE!4FvaKBY^w%8*qvDCFjEqmQMop5oG!V`Tl7x(Sg{WU$T!g1R}0l3aHt!EgnU)fnz RcLU^p22WQ%mvv4FO#p-WUP1r> literal 0 HcmV?d00001 diff --git a/tests/images/paths/maskRectMask.png b/tests/images/paths/maskRectMask.png new file mode 100644 index 0000000000000000000000000000000000000000..d17c2b58aa780b1f92351364392363e16cc227db GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^DIm-NBp57Fi*Ar*{oZ=B|8P+(xaxIq58 z{`yq5@EngLN9WYWNL5{|)Oo;>q<197WAbaQkiQmJd#3ca+sHVcX`R7sC=QZ1F)8Nd zYz5x`Rmau)6rMRDBsz8q6f0UkS#@xZeD2xs+D9j5@7%@q-Sg4aug|VteR>sWz)jQe oinshrF3Z`3Ju6^=7zfs6p5WBGW6|%5=^&?iy85}Sb4q9e0P<8+iU0rr literal 0 HcmV?d00001 diff --git a/tests/images/paths/maskRectMaskAA.png b/tests/images/paths/maskRectMaskAA.png new file mode 100644 index 0000000000000000000000000000000000000000..64db8caee3aa76add4f09e80fd542cccb95b8c4b GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^DIm-NBp5kMwsqTc)BCO)N`Cn@$v z-&O7IcjhQoeC7m_G8Dh0dfnJU*yZ=Xg|>D=cjr29f(R$+9f|4KDF9M;Zo=#D|H|_} zE!4FvaKBY^w%8*qvDCFjEqmQMop5oG!V`Tl7x(Sg{WU$T!g1R}0l3aHt!EgnU)fnz RcLU^p22WQ%mvv4FO#p-WUP1r> literal 0 HcmV?d00001 diff --git a/tests/test_paths.nim b/tests/test_paths.nim index e0b17e7..4f7894b 100644 --- a/tests/test_paths.nim +++ b/tests/test_paths.nim @@ -411,3 +411,27 @@ block: Paint(kind: pkSolid, color: rgbx(0, 255, 0, 255), blendMode: bmMask) ) image.writeFile("tests/images/paths/rectMaskAA.png") + +block: + let mask = newMask(100, 100) + mask.fillPath("M 10 10 H 60 V 60 H 10 z") + mask.fillPath("M 30 30 H 80 V 80 H 30 z")#, blendMode = bmExcludeMask) + writeFile("tests/images/paths/maskRectExcludeMask.png", mask.encodePng()) + +block: + let mask = newMask(100, 100) + mask.fillPath("M 10.1 10.1 H 60.1 V 60.1 H 10.1 z") + mask.fillPath("M 30.1 30.1 H 80.1 V 80.1 H 30.1 z")#, blendMode = bmExcludeMask) + writeFile("tests/images/paths/maskRectExcludeMaskAA.png", mask.encodePng()) + +block: + let mask = newMask(100, 100) + mask.fillPath("M 10 10 H 60 V 60 H 10 z") + mask.fillPath("M 30 30 H 80 V 80 H 30 z")#, blendMode = bmMask) + writeFile("tests/images/paths/maskRectMask.png", mask.encodePng()) + +block: + let mask = newMask(100, 100) + mask.fillPath("M 10.1 10.1 H 60.1 V 60.1 H 10.1 z") + mask.fillPath("M 30.1 30.1 H 80.1 V 80.1 H 30.1 z")#, blendMode = bmMask) + writeFile("tests/images/paths/maskRectMaskAA.png", mask.encodePng()) From a838de821ccc0931661416b8a3be470f1a4e79f0 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Fri, 18 Jun 2021 21:43:42 -0500 Subject: [PATCH 2/2] paths.nim masks take blendMode for masking, tests, fixes and etc --- pixie.nimble | 2 +- src/pixie/blends.nim | 14 +- src/pixie/paths.nim | 200 ++++++++++++------- tests/images/paths/maskRectExcludeMask.png | Bin 208 -> 232 bytes tests/images/paths/maskRectExcludeMaskAA.png | Bin 237 -> 269 bytes tests/images/paths/maskRectMask.png | Bin 208 -> 188 bytes tests/images/paths/maskRectMaskAA.png | Bin 237 -> 207 bytes tests/test_paths.nim | 8 +- 8 files changed, 142 insertions(+), 82 deletions(-) diff --git a/pixie.nimble b/pixie.nimble index 973ada1..01de21a 100644 --- a/pixie.nimble +++ b/pixie.nimble @@ -1,4 +1,4 @@ -version = "2.0.5" +version = "2.1.0" author = "Andre von Houck and Ryan Oldenburg" description = "Full-featured 2d graphics library for Nim." license = "MIT" diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 3fdd211..5e5b2c7 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -435,9 +435,6 @@ proc blendSubtractMask(backdrop, source: ColorRGBX): ColorRGBX = result.b = ((backdrop.b * a) div 255).uint8 result.a = a.uint8 -proc blendIntersectMask(backdrop, source: ColorRGBX): ColorRGBX = - blendMask(backdrop, source) - proc blendExcludeMask(backdrop, source: ColorRGBX): ColorRGBX = let a = max(backdrop.a, source.a).uint32 - min(backdrop.a, source.a) result.r = ((source.r * a) div 255).uint8 @@ -489,9 +486,6 @@ proc maskMask(backdrop, source: uint8): uint8 = proc maskSubtract(backdrop, source: uint8): uint8 = ((backdrop.uint32 * (255 - source)) div 255).uint8 -proc maskIntersect(backdrop, source: uint8): uint8 = - maskMask(backdrop, source) - proc maskExclude(backdrop, source: uint8): uint8 = max(backdrop, source) - min(backdrop, source) @@ -592,7 +586,7 @@ when defined(amd64) and not defined(pixieNoSimd): div255 = mm_set1_epi16(cast[int16](0x8081)) var - sourceEven = mm_slli_epi16(mm_andnot_si128(oddMask, source), 8) + sourceEven = mm_slli_epi16(source, 8) sourceOdd = mm_and_si128(source, oddMask) let @@ -600,7 +594,7 @@ when defined(amd64) and not defined(pixieNoSimd): oddK = mm_sub_epi16(v255high, sourceOdd) var - backdropEven = mm_slli_epi16(mm_andnot_si128(oddMask, backdrop), 8) + backdropEven = mm_slli_epi16(backdrop, 8) backdropOdd = mm_and_si128(backdrop, oddMask) # backdrop * k @@ -625,11 +619,11 @@ when defined(amd64) and not defined(pixieNoSimd): let oddMask = mm_set1_epi16(cast[int16](0xff00)) div255 = mm_set1_epi16(cast[int16](0x8081)) - sourceEven = mm_slli_epi16(mm_andnot_si128(oddMask, source), 8) + sourceEven = mm_slli_epi16(source, 8) sourceOdd = mm_and_si128(source, oddMask) var - backdropEven = mm_slli_epi16(mm_andnot_si128(oddMask, backdrop), 8) + backdropEven = mm_slli_epi16(backdrop, 8) backdropOdd = mm_and_si128(backdrop, oddMask) # backdrop * source diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index fbeccea..124dd5b 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -1137,10 +1137,12 @@ iterator walk( # between zero and nonzero (or the last hit) count += winding continue - if at > 0: - if shouldFill(windingRule, count): - yield (prevAt, at, count) - prevAt = at + if at <= 0: + count += winding + continue + if shouldFill(windingRule, count): + yield (prevAt, at, count) + prevAt = at count += winding when defined(pixieLeakCheck): @@ -1226,13 +1228,15 @@ proc computeCoverages( for j in i ..< fillStart + fillLen: coverages[j] += sampleCoverage -proc clearUnsafe(image: Image, startX, startY, toX, toY: int) = - ## From startXY to toXY, exclusive, toXY is not cleared. - image.data.fillUnsafe( - rgbx(0, 0, 0, 0), - image.dataIndex(startX, startY), - image.dataIndex(toX, toY) - image.dataIndex(startX, startY) - ) +proc clearUnsafe(target: Image | Mask, startX, startY, toX, toY: int) = + ## Clears data from [start, to). + let + start = target.dataIndex(startX, startY) + len = target.dataIndex(toX, toY) - start + when type(target) is Image: + target.data.fillUnsafe(rgbx(0, 0, 0, 0), start, len) + else: # target is Mask + target.data.fillUnsafe(0, start, len) proc fillCoverage( image: Image, @@ -1258,7 +1262,7 @@ proc fillCoverage( let index = image.dataIndex(x, y) eqZero = mm_cmpeq_epi16(coverage, mm_setzero_si128()) - if mm_movemask_epi8(eqZero) != 0xffff: + if mm_movemask_epi8(eqZero) != 0xffff: # or blendMode == bmExcludeMask: # If the coverages are not all zero if mm_movemask_epi8(mm_cmpeq_epi32(coverage, first32)) == 0xffff: # Coverages are all 255 @@ -1294,6 +1298,8 @@ proc fillCoverage( image.data[index].addr, blenderSimd(backdrop, source) ) + elif blendMode == bmMask: + mm_storeu_si128(image.data[index].addr, mm_setzero_si128()) x += 4 let blender = blendMode.blender() @@ -1319,31 +1325,45 @@ proc fillCoverage( if blendMode == bmMask: image.clearUnsafe(0, y, startX, y) -proc fillCoverage(mask: Mask, startX, y: int, coverages: seq[uint8]) = +proc fillCoverage( + mask: Mask, + startX, y: int, + coverages: seq[uint8], + blendMode: BlendMode +) = var x = startX when defined(amd64) and not defined(pixieNoSimd): - # When supported, SIMD blend as much as possible - let maskerSimd = bmNormal.maskerSimd() - for _ in countup(x, coverages.len - 16, 16): - let - coverage = mm_loadu_si128(coverages[x].unsafeAddr) - eqZero = mm_cmpeq_epi16(coverage, mm_setzero_si128()) - if mm_movemask_epi8(eqZero) != 0xffff: - # If the coverages are not all zero - let backdrop = mm_loadu_si128(mask.data[mask.dataIndex(x, y)].addr) - mm_storeu_si128( - mask.data[mask.dataIndex(x, y)].addr, - maskerSimd(backdrop, coverage) - ) - x += 16 + if blendMode.hasSimdMasker(): + let maskerSimd = blendMode.maskerSimd() + for _ in countup(x, coverages.len - 16, 16): + let + index = mask.dataIndex(x, y) + coverage = mm_loadu_si128(coverages[x].unsafeAddr) + eqZero = mm_cmpeq_epi16(coverage, mm_setzero_si128()) + if mm_movemask_epi8(eqZero) != 0xffff: # or blendMode == bmExcludeMask: + # If the coverages are not all zero + let backdrop = mm_loadu_si128(mask.data[index].addr) + mm_storeu_si128( + mask.data[index].addr, + maskerSimd(backdrop, coverage) + ) + elif blendMode == bmMask: + mm_storeu_si128(mask.data[index].addr, mm_setzero_si128()) + x += 16 + let masker = blendMode.masker() while x < mask.width: let coverage = coverages[x] - if coverage != 0: + if coverage != 0 or blendMode == bmExcludeMask: let backdrop = mask.getValueUnsafe(x, y) - mask.setValueUnsafe(x, y, blendAlpha(backdrop, coverage)) + mask.setValueUnsafe(x, y, masker(backdrop, coverage)) + elif blendMode == bmMask: + mask.setValueUnsafe(x, y, 0) inc x + if blendMode == bmMask: + mask.clearUnsafe(0, y, startX, y) + proc fillHits( image: Image, rgbx: ColorRGBX, @@ -1354,53 +1374,89 @@ proc fillHits( blendMode: BlendMode ) = let blender = blendMode.blender() - var x = 0 + var filledTo: int for (prevAt, at, count) in hits.walk(numHits, windingRule, y, image.wh): let fillStart = prevAt.int fillLen = at.int - fillStart - if fillLen > 0: - if blendMode == bmNormal and rgbx.a == 255: - fillUnsafe(image.data, rgbx, image.dataIndex(fillStart, y), fillLen) - else: - x = fillStart - when defined(amd64) and not defined(pixieNoSimd): - if blendMode.hasSimdBlender(): - # When supported, SIMD blend as much as possible - let - blenderSimd = blendMode.blenderSimd() - vColor = mm_set1_epi32(cast[int32](rgbx)) - for _ in countup(fillStart, fillLen - 16, 4): - let - index = image.dataIndex(x, y) - backdrop = mm_loadu_si128(image.data[index].addr) - mm_storeu_si128( - image.data[index].addr, - blenderSimd(backdrop, vColor) - ) - x += 4 - while x < fillStart + fillLen: - let backdrop = image.getRgbaUnsafe(x, y) - image.setRgbaUnsafe(x, y, blender(backdrop, rgbx)) - inc x + if fillLen <= 0: + continue + + filledTo = fillStart + fillLen + + if blendMode == bmNormal and rgbx.a == 255: + fillUnsafe(image.data, rgbx, image.dataIndex(fillStart, y), fillLen) + continue + + var x = fillStart + when defined(amd64) and not defined(pixieNoSimd): + if blendMode.hasSimdBlender(): + # When supported, SIMD blend as much as possible + let + blenderSimd = blendMode.blenderSimd() + vColor = mm_set1_epi32(cast[int32](rgbx)) + for _ in countup(fillStart, fillLen - 16, 4): + let + index = image.dataIndex(x, y) + backdrop = mm_loadu_si128(image.data[index].addr) + mm_storeu_si128( + image.data[index].addr, + blenderSimd(backdrop, vColor) + ) + x += 4 + + for x in x ..< fillStart + fillLen: + let backdrop = image.getRgbaUnsafe(x, y) + image.setRgbaUnsafe(x, y, blender(backdrop, rgbx)) if blendMode == bmMask: image.clearUnsafe(0, y, startX, y) - image.clearUnsafe(x, y, image.width, y) + image.clearUnsafe(filledTo, y, image.width, y) proc fillHits( mask: Mask, startX, y: int, hits: seq[(float32, int16)], numHits: int, - windingRule: WindingRule + windingRule: WindingRule, + blendMode: BlendMode ) = + let masker = blendMode.masker() + var filledTo: int for (prevAt, at, count) in hits.walk(numHits, windingRule, y, mask.wh): let fillStart = prevAt.int fillLen = at.int - fillStart - if fillLen > 0: + if fillLen <= 0: + continue + + filledTo = fillStart + fillLen + + if blendMode == bmNormal: fillUnsafe(mask.data, 255, mask.dataIndex(fillStart, y), fillLen) + continue + + var x = fillStart + when defined(amd64) and not defined(pixieNoSimd): + if blendMode.hasSimdMasker(): + let + maskerSimd = blendMode.maskerSimd() + vValue = mm_set1_epi8(cast[int8](255)) + for _ in countup(fillStart, fillLen - 16, 16): + let backdrop = mm_loadu_si128(mask.data[mask.dataIndex(x, y)].addr) + mm_storeu_si128( + mask.data[mask.dataIndex(x, y)].addr, + maskerSimd(backdrop, vValue) + ) + x += 16 + + for x in x ..< fillStart + fillLen: + let backdrop = mask.getValueUnsafe(x, y) + mask.setValueUnsafe(x, y, masker(backdrop, 255)) + + if blendMode == bmMask: + mask.clearUnsafe(0, y, startX, y) + mask.clearUnsafe(filledTo, y, mask.width, y) proc fillShapes( image: Image, @@ -1460,7 +1516,12 @@ proc fillShapes( image.clearUnsafe(0, 0, 0, startY) image.clearUnsafe(0, pathHeight, 0, image.height) -proc fillShapes(mask: Mask, shapes: seq[seq[Vec2]], windingRule: WindingRule) = +proc fillShapes( + mask: Mask, + shapes: seq[seq[Vec2]], + windingRule: WindingRule, + blendMode: BlendMode +) = # Figure out the total bounds of all the shapes, # rasterize only within the total bounds let @@ -1469,8 +1530,7 @@ proc fillShapes(mask: Mask, shapes: seq[seq[Vec2]], windingRule: WindingRule) = bounds = computePixelBounds(segments) startX = max(0, bounds.x.int) startY = max(0, bounds.y.int) - stopY = min(mask.height, (bounds.y + bounds.h).int) - pathHeight = stopY - startY + pathHeight = min(mask.height, (bounds.y + bounds.h).int) partitioning = partitionSegments(segments, startY, pathHeight) var @@ -1478,7 +1538,7 @@ proc fillShapes(mask: Mask, shapes: seq[seq[Vec2]], windingRule: WindingRule) = hits = newSeq[(float32, int16)](4) numHits: int - for y in startY ..< stopY: + for y in startY ..< pathHeight: computeCoverages( coverages, hits, @@ -1490,9 +1550,13 @@ proc fillShapes(mask: Mask, shapes: seq[seq[Vec2]], windingRule: WindingRule) = windingRule ) if aa: - mask.fillCoverage(startX, y, coverages) + mask.fillCoverage(startX, y, coverages, blendMode) else: - mask.fillHits(startX, y, hits, numHits, windingRule) + mask.fillHits(startX, y, hits, numHits, windingRule, blendMode) + + if blendMode == bmMask: + mask.clearUnsafe(0, 0, 0, startY) + mask.clearUnsafe(0, pathHeight, 0, mask.height) proc miterLimitToAngle*(limit: float32): float32 = ## Converts miter-limit-ratio to miter-limit-angle. @@ -1668,12 +1732,13 @@ proc fillPath*( mask: Mask, path: SomePath, transform: Vec2 | Mat3 = vec2(), - windingRule = wrNonZero + windingRule = wrNonZero, + blendMode = bmNormal ) = ## Fills a path. var shapes = parseSomePath(path, true, transform.pixelScale()) shapes.transform(transform) - mask.fillShapes(shapes, windingRule) + mask.fillShapes(shapes, windingRule, blendMode) proc fillPath*( image: Image, @@ -1721,7 +1786,8 @@ proc strokePath*( lineCap = lcButt, lineJoin = ljMiter, miterLimit = defaultMiterLimit, - dashes: seq[float32] = @[] + dashes: seq[float32] = @[], + blendMode = bmNormal ) = ## Strokes a path. var strokeShapes = strokeShapes( @@ -1733,7 +1799,7 @@ proc strokePath*( dashes ) strokeShapes.transform(transform) - mask.fillShapes(strokeShapes, wrNonZero) + mask.fillShapes(strokeShapes, wrNonZero, blendMode) proc strokePath*( image: Image, diff --git a/tests/images/paths/maskRectExcludeMask.png b/tests/images/paths/maskRectExcludeMask.png index d17c2b58aa780b1f92351364392363e16cc227db..145429c91cca41491fced6751571fa6b1ce81851 100644 GIT binary patch delta 204 zcmcb>_=0hQO8t6I7srqa#<$nb^0^vFustk(bZlqQq^K|I`KLM}&Tf95tPxu$U%-*1 zcO=GRa(4X6x6f9jov8Xe;gn*>PJv>@XHI8YXK+_)Uaz0+xx2~a$0Paqd@C=lQ;>Z) z;ZRKTmvte}q-Lysp1!nTE>DcQ?RC$GR+2mXs^ZsA-cs-X``fDhuJ?kgy3Wp3`Dhc& z=Lj;&P#k2{iRPG>`|YQ%d+|vAKVQ27#1@d$6Nd8-PJAqA*L=(X1fH&bF6*2UngAQi BV$A>m delta 180 zcmaFCc!6<(O8s`M1;7HOt z65}!XwN}Vqi>p0T`rB<}9M81Q;5HNoNt~Dz^K!NV@Bgaf>U|2&oDdQnI|Ygrt)Hwq zI7dGBYbP0l+XkK;=@tL diff --git a/tests/images/paths/maskRectExcludeMaskAA.png b/tests/images/paths/maskRectExcludeMaskAA.png index 64db8caee3aa76add4f09e80fd542cccb95b8c4b..c28291f98a2b75cb2381b29b0fa836b683bfaacd 100644 GIT binary patch delta 241 zcmVG+poq~)zeWVA+7@56>2dj33F0lP9o+cVNMFn zNyMBa|2ijw*xzr}uX$qMZY|tOpRajYcPSK!h-*^gol&8?BD!l5-DM#z%NKE}bH7gg rOKVJg9~7|=mxZ`2#AP8a3vpTAZ*46CnAGD900000NkvXXu0mjfu(xZW delta 209 zcmeBWddoOLrGAU2i(^OyE=m_{n2+-yZfCviWQ$Zfusz@FR5NPwh(st z{coYIozUI6&YK{@NqR?OI(7Pgg&ebxsLQ0P}5IUjP6A diff --git a/tests/images/paths/maskRectMask.png b/tests/images/paths/maskRectMask.png index d17c2b58aa780b1f92351364392363e16cc227db..2d7751c62afe51cee4d5e52f3f0bb803674b73c6 100644 GIT binary patch delta 160 zcmcb>xQB6qN`14Zi(^OyhCg{Pb;t9OpHjKej>$*ny1Yv% zP(NvB{c`D-H|~??u6d~1u@l1#kbtDqx09vJW;1Lvp1kkg%>V?Ru6{1-oD!M<&Vx$9 delta 180 zcmdnPc!6<(O8s`M1;7HOt z65}!XwN}Vqi>p0T`rB<}9M81Q;5HNoNt~Dz^K!NV@Bgaf>U|2&oDdQnI|Ygrt)Hwq zI7dGBYbP0l+XkK!_!fl diff --git a/tests/images/paths/maskRectMaskAA.png b/tests/images/paths/maskRectMaskAA.png index 64db8caee3aa76add4f09e80fd542cccb95b8c4b..079cbc5413a1e6b325206eefb6cbd2d846a6c824 100644 GIT binary patch delta 179 zcmaFMc%E^BO8qoX7srqa#<$lFa<&?Xum(O9|B$_vS=XT?xBOcIqf?oFw+gc&_uOCy zCTG1T=DZJ7J9Y{bD?W2N(>jCOP&`TRNX&`!qS)U-1^05VYVCYh|8mAzZ>3__ed~_Q zO}XRw#80SvQla`pYtK8L&upzNuT47kzbse1Hssii_UQ^hQ*_|QAek#U=`~}cNK9tB SSJhVrAnQ@-`VrI3xRJ}K->NxV>=Bk&>RO|gy>6XO wxHw4ViN2VN`}XVpnjTi+xb2|;Tzopr04R=Ipa1{> diff --git a/tests/test_paths.nim b/tests/test_paths.nim index 4f7894b..e3ab5ec 100644 --- a/tests/test_paths.nim +++ b/tests/test_paths.nim @@ -415,23 +415,23 @@ block: block: let mask = newMask(100, 100) mask.fillPath("M 10 10 H 60 V 60 H 10 z") - mask.fillPath("M 30 30 H 80 V 80 H 30 z")#, blendMode = bmExcludeMask) + mask.fillPath("M 30 30 H 80 V 80 H 30 z", blendMode = bmExcludeMask) writeFile("tests/images/paths/maskRectExcludeMask.png", mask.encodePng()) block: let mask = newMask(100, 100) mask.fillPath("M 10.1 10.1 H 60.1 V 60.1 H 10.1 z") - mask.fillPath("M 30.1 30.1 H 80.1 V 80.1 H 30.1 z")#, blendMode = bmExcludeMask) + mask.fillPath("M 30.1 30.1 H 80.1 V 80.1 H 30.1 z", blendMode = bmExcludeMask) writeFile("tests/images/paths/maskRectExcludeMaskAA.png", mask.encodePng()) block: let mask = newMask(100, 100) mask.fillPath("M 10 10 H 60 V 60 H 10 z") - mask.fillPath("M 30 30 H 80 V 80 H 30 z")#, blendMode = bmMask) + mask.fillPath("M 30 30 H 80 V 80 H 30 z", blendMode = bmMask) writeFile("tests/images/paths/maskRectMask.png", mask.encodePng()) block: let mask = newMask(100, 100) mask.fillPath("M 10.1 10.1 H 60.1 V 60.1 H 10.1 z") - mask.fillPath("M 30.1 30.1 H 80.1 V 80.1 H 30.1 z")#, blendMode = bmMask) + mask.fillPath("M 30.1 30.1 H 80.1 V 80.1 H 30.1 z", blendMode = bmMask) writeFile("tests/images/paths/maskRectMaskAA.png", mask.encodePng())