Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
@ -23,7 +23,7 @@ block:
|
||||||
a.fill(rgba(255, 255, 255, 255))
|
a.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
||||||
timeIt "pixie1":
|
timeIt "pixie1":
|
||||||
var p: pixie.Path
|
let p = newPath()
|
||||||
p.moveTo(0, 0)
|
p.moveTo(0, 0)
|
||||||
p.lineTo(1920, 0)
|
p.lineTo(1920, 0)
|
||||||
p.lineTo(1920, 1080)
|
p.lineTo(1920, 1080)
|
||||||
|
@ -56,7 +56,7 @@ block:
|
||||||
a.fill(rgba(255, 255, 255, 255))
|
a.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
||||||
timeIt "pixie2":
|
timeIt "pixie2":
|
||||||
var p: pixie.Path
|
let p = newPath()
|
||||||
p.moveTo(500, 240)
|
p.moveTo(500, 240)
|
||||||
p.lineTo(1500, 240)
|
p.lineTo(1500, 240)
|
||||||
p.lineTo(1920, 600)
|
p.lineTo(1920, 600)
|
||||||
|
@ -66,31 +66,31 @@ block:
|
||||||
|
|
||||||
# a.writeFile("pixie2.png")
|
# a.writeFile("pixie2.png")
|
||||||
|
|
||||||
block:
|
# block:
|
||||||
let
|
# let
|
||||||
a = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000)
|
# a = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000)
|
||||||
b = imageSurfaceCreate(FORMAT_ARGB32, 500, 500)
|
# b = imageSurfaceCreate(FORMAT_ARGB32, 500, 500)
|
||||||
ac = a.create()
|
# ac = a.create()
|
||||||
bc = b.create()
|
# bc = b.create()
|
||||||
|
|
||||||
ac.setSourceRgba(1, 0, 0, 1)
|
# ac.setSourceRgba(1, 0, 0, 1)
|
||||||
ac.newPath()
|
# ac.newPath()
|
||||||
ac.rectangle(0, 0, 1000, 1000)
|
# ac.rectangle(0, 0, 1000, 1000)
|
||||||
ac.fill()
|
# ac.fill()
|
||||||
|
|
||||||
bc.setSourceRgba(0, 1, 0, 1)
|
# bc.setSourceRgba(0, 1, 0, 1)
|
||||||
bc.newPath()
|
# bc.newPath()
|
||||||
bc.rectangle(0, 0, 500, 500)
|
# bc.rectangle(0, 0, 500, 500)
|
||||||
bc.fill()
|
# bc.fill()
|
||||||
|
|
||||||
let pattern = patternCreateForSurface(b)
|
# let pattern = patternCreateForSurface(b)
|
||||||
|
|
||||||
timeIt "a":
|
# timeIt "a":
|
||||||
ac.setSource(pattern)
|
# ac.setSource(pattern)
|
||||||
ac.save()
|
# ac.save()
|
||||||
ac.translate(25.2, 25.2)
|
# ac.translate(25.2, 25.2)
|
||||||
ac.rectangle(0, 0, 500, 500)
|
# ac.rectangle(0, 0, 500, 500)
|
||||||
ac.fill()
|
# ac.fill()
|
||||||
ac.restore()
|
# ac.restore()
|
||||||
|
|
||||||
discard a.writeToPng("a.png")
|
# discard a.writeToPng("a.png")
|
||||||
|
|
|
@ -34,9 +34,9 @@ type
|
||||||
bmSubtractMask ## Inverse mask
|
bmSubtractMask ## Inverse mask
|
||||||
bmExcludeMask
|
bmExcludeMask
|
||||||
|
|
||||||
Blender* = proc(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].}
|
Blender* = proc(backdrop, source: ColorRGBX): ColorRGBX {.gcsafe, raises: [].}
|
||||||
## Function signature returned by blender.
|
## Function signature returned by blender.
|
||||||
Masker* = proc(backdrop, source: uint8): uint8 {.raises: [].}
|
Masker* = proc(backdrop, source: uint8): uint8 {.gcsafe, raises: [].}
|
||||||
## Function signature returned by masker.
|
## Function signature returned by masker.
|
||||||
|
|
||||||
when defined(release):
|
when defined(release):
|
||||||
|
@ -507,9 +507,9 @@ when defined(amd64) and not defined(pixieNoSimd):
|
||||||
import nimsimd/sse2
|
import nimsimd/sse2
|
||||||
|
|
||||||
type
|
type
|
||||||
BlenderSimd* = proc(blackdrop, source: M128i): M128i {.raises: [].}
|
BlenderSimd* = proc(blackdrop, source: M128i): M128i {.gcsafe, raises: [].}
|
||||||
## Function signature returned by blenderSimd.
|
## Function signature returned by blenderSimd.
|
||||||
MaskerSimd* = proc(blackdrop, source: M128i): M128i {.raises: [].}
|
MaskerSimd* = proc(blackdrop, source: M128i): M128i {.gcsafe, raises: [].}
|
||||||
## Function signature returned by maskerSimd.
|
## Function signature returned by maskerSimd.
|
||||||
|
|
||||||
proc blendNormalSimd(backdrop, source: M128i): M128i =
|
proc blendNormalSimd(backdrop, source: M128i): M128i =
|
||||||
|
|
|
@ -35,12 +35,17 @@ type
|
||||||
|
|
||||||
SomePath* = Path | string
|
SomePath* = Path | string
|
||||||
|
|
||||||
|
PartitionEntry = object
|
||||||
|
atY, toY: float32
|
||||||
|
m, b: float32
|
||||||
|
winding: int16
|
||||||
|
|
||||||
Partitioning = object
|
Partitioning = object
|
||||||
partitions: seq[seq[(Segment, int16)]]
|
partitions: seq[seq[PartitionEntry]]
|
||||||
startY, partitionHeight: uint32
|
startY, partitionHeight: uint32
|
||||||
|
|
||||||
const
|
const
|
||||||
epsilon = 0.0001 * PI ## Tiny value used for some computations.
|
epsilon: float32 = 0.0001 * PI ## Tiny value used for some computations.
|
||||||
defaultMiterLimit*: float32 = 4
|
defaultMiterLimit*: float32 = 4
|
||||||
|
|
||||||
when defined(release):
|
when defined(release):
|
||||||
|
@ -1076,8 +1081,19 @@ proc partitionSegments(
|
||||||
result.partitionHeight = height.uint32 div numPartitions
|
result.partitionHeight = height.uint32 div numPartitions
|
||||||
|
|
||||||
for (segment, winding) in segments:
|
for (segment, winding) in segments:
|
||||||
|
var entry: PartitionEntry
|
||||||
|
entry.atY = segment.at.y
|
||||||
|
entry.toY = segment.to.y
|
||||||
|
entry.winding = winding
|
||||||
|
let d = segment.at.x - segment.to.x
|
||||||
|
if d == 0:
|
||||||
|
entry.b = segment.at.x # Leave m = 0, store the x we want in b
|
||||||
|
else:
|
||||||
|
entry.m = (segment.at.y - segment.to.y) / d
|
||||||
|
entry.b = segment.at.y - entry.m * segment.at.x
|
||||||
|
|
||||||
if result.partitionHeight == 0:
|
if result.partitionHeight == 0:
|
||||||
result.partitions[0].add((segment, winding))
|
result.partitions[0].add(entry)
|
||||||
else:
|
else:
|
||||||
var
|
var
|
||||||
atPartition = max(0, segment.at.y - result.startY.float32).uint32
|
atPartition = max(0, segment.at.y - result.startY.float32).uint32
|
||||||
|
@ -1087,7 +1103,7 @@ proc partitionSegments(
|
||||||
atPartition = clamp(atPartition, 0, result.partitions.high.uint32)
|
atPartition = clamp(atPartition, 0, result.partitions.high.uint32)
|
||||||
toPartition = clamp(toPartition, 0, result.partitions.high.uint32)
|
toPartition = clamp(toPartition, 0, result.partitions.high.uint32)
|
||||||
for i in atPartition .. toPartition:
|
for i in atPartition .. toPartition:
|
||||||
result.partitions[i].add((segment, winding))
|
result.partitions[i].add(entry)
|
||||||
|
|
||||||
proc getIndexForY(partitioning: Partitioning, y: int): uint32 {.inline.} =
|
proc getIndexForY(partitioning: Partitioning, y: int): uint32 {.inline.} =
|
||||||
if partitioning.partitionHeight == 0 or partitioning.partitions.len == 1:
|
if partitioning.partitionHeight == 0 or partitioning.partitions.len == 1:
|
||||||
|
@ -1191,31 +1207,29 @@ proc computeCoverages(
|
||||||
zeroMem(coverages[0].addr, coverages.len)
|
zeroMem(coverages[0].addr, coverages.len)
|
||||||
|
|
||||||
# Do scanlines for this row
|
# Do scanlines for this row
|
||||||
let partitionIndex = partitioning.getIndexForY(y)
|
let
|
||||||
|
partitionIndex = partitioning.getIndexForY(y)
|
||||||
|
partitionEntryCount = partitioning.partitions[partitionIndex].len
|
||||||
var yLine = y.float32 + initialOffset - offset
|
var yLine = y.float32 + initialOffset - offset
|
||||||
for m in 0 ..< quality:
|
for m in 0 ..< quality:
|
||||||
yLine += offset
|
yLine += offset
|
||||||
numHits = 0
|
numHits = 0
|
||||||
for i in 0 ..< partitioning.partitions[partitionIndex].len: # Perf
|
for i in 0 ..< partitionEntryCount: # Perf
|
||||||
let
|
let entry = partitioning.partitions[partitionIndex][i]
|
||||||
segment = partitioning.partitions[partitionIndex][i][0]
|
if entry.atY <= yLine and entry.toY >= yLine:
|
||||||
winding = partitioning.partitions[partitionIndex][i][1]
|
|
||||||
if segment.at.y <= yLine and segment.to.y >= yLine:
|
|
||||||
let x =
|
let x =
|
||||||
if segment.at.x - segment.to.x == 0:
|
if entry.m == 0:
|
||||||
segment.at.x
|
entry.b
|
||||||
else:
|
else:
|
||||||
let
|
(yLine - entry.b) / entry.m
|
||||||
m = (segment.at.y - segment.to.y) / (segment.at.x - segment.to.x)
|
|
||||||
b = segment.at.y - m * segment.at.x
|
|
||||||
(yLine - b) / m
|
|
||||||
|
|
||||||
if numHits == hits.len:
|
if numHits == hits.len:
|
||||||
hits.setLen(hits.len * 2)
|
hits.setLen(hits.len * 2)
|
||||||
hits[numHits] = (min(x, width), winding)
|
hits[numHits] = (min(x, width), entry.winding)
|
||||||
inc numHits
|
inc numHits
|
||||||
|
|
||||||
sort(hits, 0, numHits - 1)
|
if numHits > 0:
|
||||||
|
sort(hits, 0, numHits - 1)
|
||||||
|
|
||||||
if aa:
|
if aa:
|
||||||
for (prevAt, at, count) in hits.walk(numHits, windingRule, y, width):
|
for (prevAt, at, count) in hits.walk(numHits, windingRule, y, width):
|
||||||
|
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 260 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 280 KiB |
Before Width: | Height: | Size: 645 KiB After Width: | Height: | Size: 644 KiB |
Before Width: | Height: | Size: 783 KiB After Width: | Height: | Size: 783 KiB |
Before Width: | Height: | Size: 3.4 MiB After Width: | Height: | Size: 3.4 MiB |
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 358 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 610 KiB After Width: | Height: | Size: 610 KiB |
Before Width: | Height: | Size: 519 KiB After Width: | Height: | Size: 519 KiB |
Before Width: | Height: | Size: 3.9 MiB After Width: | Height: | Size: 3.9 MiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |