Fixing blends
This commit is contained in:
parent
ff0a69b9de
commit
1ee3d3902a
3 changed files with 69 additions and 26 deletions
|
@ -440,9 +440,9 @@ proc blendIntersectMask(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
|
||||
proc blendExcludeMask(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let a = max(backdrop.a, source.a).uint32 - min(backdrop.a, source.a)
|
||||
result.r = ((backdrop.r * a) div 255).uint8
|
||||
result.g = ((backdrop.g * a) div 255).uint8
|
||||
result.b = ((backdrop.b * a) div 255).uint8
|
||||
result.r = ((source.r * a) div 255).uint8
|
||||
result.g = ((source.g * a) div 255).uint8
|
||||
result.b = ((source.b * a) div 255).uint8
|
||||
result.a = a.uint8
|
||||
|
||||
proc blendOverwrite(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
|
|
|
@ -1226,6 +1226,14 @@ 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 fillCoverage(
|
||||
image: Image,
|
||||
rgbx: ColorRGBX,
|
||||
|
@ -1291,7 +1299,7 @@ proc fillCoverage(
|
|||
let blender = blendMode.blender()
|
||||
while x < image.width:
|
||||
let coverage = coverages[x]
|
||||
if coverage != 0:
|
||||
if coverage != 0 or blendMode == bmExcludeMask:
|
||||
if blendMode == bmNormal and coverage == 255 and rgbx.a == 255:
|
||||
# Skip blending
|
||||
image.setRgbaUnsafe(x, y, rgbx)
|
||||
|
@ -1309,17 +1317,7 @@ proc fillCoverage(
|
|||
inc x
|
||||
|
||||
if blendMode == bmMask:
|
||||
image.data.fillUnsafe(
|
||||
rgbx(0, 0, 0, 0),
|
||||
image.dataIndex(0, y),
|
||||
image.dataIndex(startX, y) - image.dataIndex(0, y)
|
||||
)
|
||||
# if x < image.width:
|
||||
# image.data.fillUnsafe(
|
||||
# rgbx(0, 0, 0, 0),
|
||||
# image.dataIndex(x, y),
|
||||
# image.dataIndex(image.width, y)
|
||||
# )
|
||||
image.clearUnsafe(0, y, startX, y)
|
||||
|
||||
proc fillCoverage(mask: Mask, startX, y: int, coverages: seq[uint8]) =
|
||||
var x = startX
|
||||
|
@ -1356,6 +1354,7 @@ proc fillHits(
|
|||
blendMode: BlendMode
|
||||
) =
|
||||
let blender = blendMode.blender()
|
||||
var x = 0
|
||||
for (prevAt, at, count) in hits.walk(numHits, windingRule, y, image.wh):
|
||||
let
|
||||
fillStart = prevAt.int
|
||||
|
@ -1364,7 +1363,7 @@ proc fillHits(
|
|||
if blendMode == bmNormal and rgbx.a == 255:
|
||||
fillUnsafe(image.data, rgbx, image.dataIndex(fillStart, y), fillLen)
|
||||
else:
|
||||
var x = fillStart
|
||||
x = fillStart
|
||||
when defined(amd64) and not defined(pixieNoSimd):
|
||||
if blendMode.hasSimdBlender():
|
||||
# When supported, SIMD blend as much as possible
|
||||
|
@ -1385,6 +1384,10 @@ proc fillHits(
|
|||
image.setRgbaUnsafe(x, y, blender(backdrop, rgbx))
|
||||
inc x
|
||||
|
||||
if blendMode == bmMask:
|
||||
image.clearUnsafe(0, y, startX, y)
|
||||
image.clearUnsafe(x, y, image.width, y)
|
||||
|
||||
proc fillHits(
|
||||
mask: Mask,
|
||||
startX, y: int,
|
||||
|
@ -1454,16 +1457,8 @@ proc fillShapes(
|
|||
)
|
||||
|
||||
if blendMode == bmMask:
|
||||
image.data.fillUnsafe(
|
||||
rgbx(0, 0, 0, 0),
|
||||
image.dataIndex(0, 0),
|
||||
image.dataIndex(0, startY)
|
||||
)
|
||||
image.data.fillUnsafe(
|
||||
rgbx(0, 0, 0, 0),
|
||||
image.dataIndex(0, pathHeight),
|
||||
image.dataIndex(0, image.height)
|
||||
)
|
||||
image.clearUnsafe(0, 0, 0, startY)
|
||||
image.clearUnsafe(0, pathHeight, 0, image.height)
|
||||
|
||||
proc fillShapes(mask: Mask, shapes: seq[seq[Vec2]], windingRule: WindingRule) =
|
||||
# Figure out the total bounds of all the shapes,
|
||||
|
|
|
@ -363,3 +363,51 @@ block:
|
|||
path = parsePath("L 0 0")
|
||||
image.fill(rgba(255, 255, 255, 255))
|
||||
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcSquare, ljMiter)
|
||||
|
||||
block:
|
||||
let image = newImage(100, 100)
|
||||
image.fillPath(
|
||||
"M 10 10 H 60 V 60 H 10 z",
|
||||
Paint(kind: pkSolid, color: rgbx(255, 0, 0, 255), blendMode: bmNormal)
|
||||
)
|
||||
image.fillPath(
|
||||
"M 30 30 H 80 V 80 H 30 z",
|
||||
Paint(kind: pkSolid, color: rgbx(0, 255, 0, 255), blendMode: bmExcludeMask)
|
||||
)
|
||||
image.writeFile("tests/images/paths/rectExcludeMask.png")
|
||||
|
||||
block:
|
||||
let image = newImage(100, 100)
|
||||
image.fillPath(
|
||||
"M 10.1 10.1 H 60.1 V 60.1 H 10.1 z",
|
||||
Paint(kind: pkSolid, color: rgbx(255, 0, 0, 255), blendMode: bmNormal)
|
||||
)
|
||||
image.fillPath(
|
||||
"M 30.1 30.1 H 80.1 V 80.1 H 30.1 z",
|
||||
Paint(kind: pkSolid, color: rgbx(0, 255, 0, 255), blendMode: bmExcludeMask)
|
||||
)
|
||||
image.writeFile("tests/images/paths/rectExcludeMaskAA.png")
|
||||
|
||||
block:
|
||||
let image = newImage(100, 100)
|
||||
image.fillPath(
|
||||
"M 10 10 H 60 V 60 H 10 z",
|
||||
Paint(kind: pkSolid, color: rgbx(255, 0, 0, 255), blendMode: bmNormal)
|
||||
)
|
||||
image.fillPath(
|
||||
"M 30 30 H 80 V 80 H 30 z",
|
||||
Paint(kind: pkSolid, color: rgbx(0, 255, 0, 255), blendMode: bmMask)
|
||||
)
|
||||
image.writeFile("tests/images/paths/rectMask.png")
|
||||
|
||||
block:
|
||||
let image = newImage(100, 100)
|
||||
image.fillPath(
|
||||
"M 10.1 10.1 H 60.1 V 60.1 H 10.1 z",
|
||||
Paint(kind: pkSolid, color: rgbx(255, 0, 0, 255), blendMode: bmNormal)
|
||||
)
|
||||
image.fillPath(
|
||||
"M 30.1 30.1 H 80.1 V 80.1 H 30.1 z",
|
||||
Paint(kind: pkSolid, color: rgbx(0, 255, 0, 255), blendMode: bmMask)
|
||||
)
|
||||
image.writeFile("tests/images/paths/rectMaskAA.png")
|
||||
|
|
Loading…
Reference in a new issue