Merge pull request #233 from guzba/master

spread >10x faster
This commit is contained in:
treeform 2021-06-19 21:18:24 -07:00 committed by GitHub
commit 75acaf0105
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 19 deletions

View file

@ -178,25 +178,35 @@ proc getValueSmooth*(mask: Mask, x, y: float32): uint8 =
proc spread*(mask: Mask, spread: float32) = proc spread*(mask: Mask, spread: float32) =
## Grows the mask by spread. ## Grows the mask by spread.
let spread = round(spread).int
if spread == 0: if spread == 0:
return return
if spread < 0: if spread < 0:
raise newException(PixieError, "Cannot apply negative spread") raise newException(PixieError, "Cannot apply negative spread")
let # Spread in the X direction. Store with dimensions swapped for reading later.
copy = mask.copy() let spreadX = newMask(mask.height, mask.width)
spread = round(spread).int
for y in 0 ..< mask.height: for y in 0 ..< mask.height:
for x in 0 ..< mask.width: for x in 0 ..< mask.width:
var maxValue: uint8 var maxValue: uint8
block blurBox: for xx in max(x - spread, 0) .. min(x + spread, mask.width - 1):
for by in max(y - spread, 0) .. min(y + spread, mask.height - 1): let value = mask.getValueUnsafe(xx, y)
for bx in max(x - spread, 0) .. min(x + spread, mask.width - 1): if value > maxValue:
let value = copy.getValueUnsafe(bx, by) maxValue = value
if value > maxValue: if maxValue == 255:
maxValue = value break
if maxValue == 255: spreadX.setValueUnsafe(y, x, maxValue)
break blurBox
# Spread in the Y direction and modify mask.
for y in 0 ..< mask.height:
for x in 0 ..< mask.width:
var maxValue: uint8
for yy in max(y - spread, 0) .. min(y + spread, mask.height - 1):
let value = spreadX.getValueUnsafe(yy, x)
if value > maxValue:
maxValue = value
if maxValue == 255:
break
mask.setValueUnsafe(x, y, maxValue) mask.setValueUnsafe(x, y, maxValue)
proc ceil*(mask: Mask) = proc ceil*(mask: Mask) =

View file

@ -1137,12 +1137,10 @@ iterator walk(
# between zero and nonzero (or the last hit) # between zero and nonzero (or the last hit)
count += winding count += winding
continue continue
if at <= 0: if at > 0:
count += winding if shouldFill(windingRule, count):
continue yield (prevAt, at, count)
if shouldFill(windingRule, count): prevAt = at
yield (prevAt, at, count)
prevAt = at
count += winding count += winding
when defined(pixieLeakCheck): when defined(pixieLeakCheck):

View file

@ -33,5 +33,31 @@ timeIt "ceil":
reset() reset()
timeIt "spread": block spread_1:
mask.spread(10) var p: Path
p.rect(500, 500, 500, 500)
timeIt "spread_1":
mask.fill(0)
mask.fillPath(p)
mask.spread(10)
block spread_2:
var p: Path
p.rect(500, 500, 1000, 1000)
timeIt "spread_2":
mask.fill(0)
mask.fillPath(p)
mask.spread(10)
block spread_3:
timeIt "spread_3":
mask.fill(255)
mask.spread(10)
block spread_4:
timeIt "spread_4":
mask.fill(0)
mask.setValueUnsafe(1000, 1000, 255)
mask.spread(10)