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

View file

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

View file

@ -33,5 +33,31 @@ timeIt "ceil":
reset()
timeIt "spread":
mask.spread(10)
block spread_1:
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)