Merge pull request #257 from guzba/master
changes noticed while working on bindings
This commit is contained in:
commit
0765c61c00
9 changed files with 52 additions and 67 deletions
|
@ -69,10 +69,6 @@ proc encodeMask*(mask: Mask, fileFormat: FileFormat): string =
|
||||||
else:
|
else:
|
||||||
raise newException(PixieError, "Unsupported file format")
|
raise newException(PixieError, "Unsupported file format")
|
||||||
|
|
||||||
proc writeFile*(image: Image, filePath: string, fileFormat: FileFormat) =
|
|
||||||
## Writes an image to a file.
|
|
||||||
writeFile(filePath, image.encodeImage(fileFormat))
|
|
||||||
|
|
||||||
proc writeFile*(image: Image, filePath: string) =
|
proc writeFile*(image: Image, filePath: string) =
|
||||||
## Writes an image to a file.
|
## Writes an image to a file.
|
||||||
let fileFormat = case splitFile(filePath).ext.toLowerAscii():
|
let fileFormat = case splitFile(filePath).ext.toLowerAscii():
|
||||||
|
@ -81,11 +77,7 @@ proc writeFile*(image: Image, filePath: string) =
|
||||||
of ".jpg", ".jpeg": ffJpg
|
of ".jpg", ".jpeg": ffJpg
|
||||||
else:
|
else:
|
||||||
raise newException(PixieError, "Unsupported file extension")
|
raise newException(PixieError, "Unsupported file extension")
|
||||||
image.writeFile(filePath, fileformat)
|
writeFile(filePath, image.encodeImage(fileFormat))
|
||||||
|
|
||||||
proc writeFile*(mask: Mask, filePath: string, fileFormat: FileFormat) =
|
|
||||||
## Writes an mask to a file.
|
|
||||||
writeFile(filePath, mask.encodeMask(fileFormat))
|
|
||||||
|
|
||||||
proc writeFile*(mask: Mask, filePath: string) =
|
proc writeFile*(mask: Mask, filePath: string) =
|
||||||
## Writes a mask to a file.
|
## Writes a mask to a file.
|
||||||
|
@ -95,7 +87,7 @@ proc writeFile*(mask: Mask, filePath: string) =
|
||||||
of ".jpg", ".jpeg": ffJpg
|
of ".jpg", ".jpeg": ffJpg
|
||||||
else:
|
else:
|
||||||
raise newException(PixieError, "Unsupported file extension")
|
raise newException(PixieError, "Unsupported file extension")
|
||||||
mask.writeFile(filePath, fileformat)
|
writeFile(filePath, mask.encodeMask(fileFormat))
|
||||||
|
|
||||||
proc fillRect*(
|
proc fillRect*(
|
||||||
mask: Mask,
|
mask: Mask,
|
||||||
|
|
|
@ -421,10 +421,8 @@ proc decodePng*(data: string): Image =
|
||||||
var pixels = decodeImageData(header, palette, transparency, imageData)
|
var pixels = decodeImageData(header, palette, transparency, imageData)
|
||||||
pixels.toPremultipliedAlpha()
|
pixels.toPremultipliedAlpha()
|
||||||
|
|
||||||
result = Image()
|
result = newImage(header.width, header.height)
|
||||||
result.width = header.width
|
copyMem(result.data[0].addr, pixels[0].addr, pixels.len * 4)
|
||||||
result.height = header.height
|
|
||||||
result.data = cast[seq[ColorRGBX]](pixels)
|
|
||||||
|
|
||||||
proc encodePng*(width, height, channels: int, data: pointer, len: int): string =
|
proc encodePng*(width, height, channels: int, data: pointer, len: int): string =
|
||||||
## Encodes the image data into the PNG file format.
|
## Encodes the image data into the PNG file format.
|
||||||
|
|
|
@ -71,6 +71,10 @@ proc `[]`*(image: Image, x, y: int): ColorRGBX {.inline.} =
|
||||||
if image.inside(x, y):
|
if image.inside(x, y):
|
||||||
return image.getRgbaUnsafe(x, y)
|
return image.getRgbaUnsafe(x, y)
|
||||||
|
|
||||||
|
proc getColor*(image: Image, x, y: int): Color =
|
||||||
|
## Gets a color at (x, y) or returns transparent black if outside of bounds.
|
||||||
|
image[x, y].color()
|
||||||
|
|
||||||
proc setRgbaUnsafe*(image: Image, x, y: int, color: SomeColor) {.inline.} =
|
proc setRgbaUnsafe*(image: Image, x, y: int, color: SomeColor) {.inline.} =
|
||||||
## Sets a color from (x, y) coordinates.
|
## Sets a color from (x, y) coordinates.
|
||||||
## * No bounds checking *
|
## * No bounds checking *
|
||||||
|
@ -83,6 +87,10 @@ proc `[]=`*(image: Image, x, y: int, color: SomeColor) {.inline.} =
|
||||||
if image.inside(x, y):
|
if image.inside(x, y):
|
||||||
image.setRgbaUnsafe(x, y, color.asRgbx())
|
image.setRgbaUnsafe(x, y, color.asRgbx())
|
||||||
|
|
||||||
|
proc setColor*(image: Image, x, y: int, color: Color) =
|
||||||
|
## Sets a color at (x, y) or does nothing if outside of bounds.
|
||||||
|
image[x, y] = color.rgbx()
|
||||||
|
|
||||||
proc fillUnsafe*(data: var seq[ColorRGBX], color: SomeColor, start, len: int) =
|
proc fillUnsafe*(data: var seq[ColorRGBX], color: SomeColor, start, len: int) =
|
||||||
## Fills the image data with the parameter color starting at index start and
|
## Fills the image data with the parameter color starting at index start and
|
||||||
## continuing for len indices.
|
## continuing for len indices.
|
||||||
|
@ -807,7 +815,7 @@ proc drawUber(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
|
||||||
zeroMem(a.data[a.dataIndex(xMax, y)].addr, 4 * (a.width - xMax))
|
zeroMem(a.data[a.dataIndex(xMax, y)].addr, 4 * (a.width - xMax))
|
||||||
|
|
||||||
proc draw*(
|
proc draw*(
|
||||||
a, b: Image, transform: Vec2 | Mat3 = vec2(), blendMode = bmNormal
|
a, b: Image, transform: Mat3 = mat3(), blendMode = bmNormal
|
||||||
) {.inline.} =
|
) {.inline.} =
|
||||||
## Draws one image onto another using matrix with color blending.
|
## Draws one image onto another using matrix with color blending.
|
||||||
when type(transform) is Vec2:
|
when type(transform) is Vec2:
|
||||||
|
@ -816,7 +824,7 @@ proc draw*(
|
||||||
a.drawUber(b, transform, blendMode)
|
a.drawUber(b, transform, blendMode)
|
||||||
|
|
||||||
proc draw*(
|
proc draw*(
|
||||||
a, b: Mask, transform: Vec2 | Mat3 = vec2(), blendMode = bmMask
|
a, b: Mask, transform: Mat3 = mat3(), blendMode = bmMask
|
||||||
) {.inline.} =
|
) {.inline.} =
|
||||||
## Draws a mask onto a mask using a matrix with color blending.
|
## Draws a mask onto a mask using a matrix with color blending.
|
||||||
when type(transform) is Vec2:
|
when type(transform) is Vec2:
|
||||||
|
@ -825,7 +833,7 @@ proc draw*(
|
||||||
a.drawUber(b, transform, blendMode)
|
a.drawUber(b, transform, blendMode)
|
||||||
|
|
||||||
proc draw*(
|
proc draw*(
|
||||||
image: Image, mask: Mask, transform: Vec2 | Mat3 = vec2(), blendMode = bmMask
|
image: Image, mask: Mask, transform: Mat3 = mat3(), blendMode = bmMask
|
||||||
) {.inline.} =
|
) {.inline.} =
|
||||||
## Draws a mask onto an image using a matrix with color blending.
|
## Draws a mask onto an image using a matrix with color blending.
|
||||||
when type(transform) is Vec2:
|
when type(transform) is Vec2:
|
||||||
|
@ -834,7 +842,7 @@ proc draw*(
|
||||||
image.drawUber(mask, transform, blendMode)
|
image.drawUber(mask, transform, blendMode)
|
||||||
|
|
||||||
proc draw*(
|
proc draw*(
|
||||||
mask: Mask, image: Image, transform: Vec2 | Mat3 = vec2(), blendMode = bmMask
|
mask: Mask, image: Image, transform: Mat3 = mat3(), blendMode = bmMask
|
||||||
) {.inline.} =
|
) {.inline.} =
|
||||||
## Draws a image onto a mask using a matrix with color blending.
|
## Draws a image onto a mask using a matrix with color blending.
|
||||||
when type(transform) is Vec2:
|
when type(transform) is Vec2:
|
||||||
|
@ -860,25 +868,14 @@ proc resize*(srcImage: Image, width, height: int): Image =
|
||||||
bmOverwrite
|
bmOverwrite
|
||||||
)
|
)
|
||||||
|
|
||||||
proc shift*(target: Image | Mask, offset: Vec2) =
|
|
||||||
## Shifts the target by offset.
|
|
||||||
if offset != vec2(0, 0):
|
|
||||||
let copy = target.copy() # Copy to read from
|
|
||||||
|
|
||||||
# Reset target for being drawn to
|
|
||||||
when type(target) is Image:
|
|
||||||
target.fill(rgbx(0, 0, 0, 0))
|
|
||||||
else:
|
|
||||||
target.fill(0)
|
|
||||||
|
|
||||||
target.draw(copy, offset, bmOverwrite) # Draw copy at offset
|
|
||||||
|
|
||||||
proc shadow*(
|
proc shadow*(
|
||||||
image: Image, offset: Vec2, spread, blur: float32, color: SomeColor
|
image: Image, offset: Vec2, spread, blur: float32, color: SomeColor
|
||||||
): Image =
|
): Image =
|
||||||
## Create a shadow of the image with the offset, spread and blur.
|
## Create a shadow of the image with the offset, spread and blur.
|
||||||
let mask = image.newMask()
|
let
|
||||||
mask.shift(offset)
|
mask = image.newMask()
|
||||||
|
shifted = newMask(mask.width, mask.height)
|
||||||
|
shifted.draw(mask, translate(offset), bmOverwrite)
|
||||||
mask.spread(spread)
|
mask.spread(spread)
|
||||||
mask.blur(blur)
|
mask.blur(blur)
|
||||||
result = newImage(mask.width, mask.height)
|
result = newImage(mask.width, mask.height)
|
||||||
|
|
|
@ -50,10 +50,14 @@ proc getValueUnsafe*(mask: Mask, x, y: int): uint8 {.inline.} =
|
||||||
result = mask.data[mask.width * y + x]
|
result = mask.data[mask.width * y + x]
|
||||||
|
|
||||||
proc `[]`*(mask: Mask, x, y: int): uint8 {.inline.} =
|
proc `[]`*(mask: Mask, x, y: int): uint8 {.inline.} =
|
||||||
## Gets a pixel at (x, y) or returns transparent black if outside of bounds.
|
## Gets a value at (x, y) or returns transparent black if outside of bounds.
|
||||||
if mask.inside(x, y):
|
if mask.inside(x, y):
|
||||||
return mask.getValueUnsafe(x, y)
|
return mask.getValueUnsafe(x, y)
|
||||||
|
|
||||||
|
proc getValue*(mask: Mask, x, y: int): uint8 {.inline.} =
|
||||||
|
## Gets a value at (x, y) or returns transparent black if outside of bounds.
|
||||||
|
mask[x, y]
|
||||||
|
|
||||||
proc setValueUnsafe*(mask: Mask, x, y: int, value: uint8) {.inline.} =
|
proc setValueUnsafe*(mask: Mask, x, y: int, value: uint8) {.inline.} =
|
||||||
## Sets a value from (x, y) coordinates.
|
## Sets a value from (x, y) coordinates.
|
||||||
## * No bounds checking *
|
## * No bounds checking *
|
||||||
|
@ -66,6 +70,10 @@ proc `[]=`*(mask: Mask, x, y: int, value: uint8) {.inline.} =
|
||||||
if mask.inside(x, y):
|
if mask.inside(x, y):
|
||||||
mask.setValueUnsafe(x, y, value)
|
mask.setValueUnsafe(x, y, value)
|
||||||
|
|
||||||
|
proc setValue*(mask: Mask, x, y: int, value: uint8) {.inline.} =
|
||||||
|
## Sets a value at (x, y) or does nothing if outside of bounds.
|
||||||
|
mask[x, y] = value
|
||||||
|
|
||||||
proc minifyBy2*(mask: Mask, power = 1): Mask =
|
proc minifyBy2*(mask: Mask, power = 1): Mask =
|
||||||
## Scales the mask down by an integer scale.
|
## Scales the mask down by an integer scale.
|
||||||
if power < 0:
|
if power < 0:
|
||||||
|
|
|
@ -25,8 +25,8 @@ type
|
||||||
|
|
||||||
ColorStop* = object
|
ColorStop* = object
|
||||||
## Color stop on a gradient curve.
|
## Color stop on a gradient curve.
|
||||||
color*: ColorRGBX ## Color of the stop
|
color*: ColorRGBX ## Color of the stop.
|
||||||
position*: float32 ## Gradient Stop position 0..1.
|
position*: float32 ## Gradient stop position 0..1.
|
||||||
|
|
||||||
SomePaint* = string | Paint | SomeColor
|
SomePaint* = string | Paint | SomeColor
|
||||||
|
|
||||||
|
@ -96,12 +96,9 @@ proc gradientPut(
|
||||||
color = color.applyOpacity(paint.opacity)
|
color = color.applyOpacity(paint.opacity)
|
||||||
image.setRgbaUnsafe(x, y, color.rgba.rgbx())
|
image.setRgbaUnsafe(x, y, color.rgba.rgbx())
|
||||||
|
|
||||||
proc fillGradientLinear*(image: Image, paint: Paint) =
|
proc fillGradientLinear(image: Image, paint: Paint) =
|
||||||
## Fills a linear gradient.
|
## Fills a linear gradient.
|
||||||
|
|
||||||
if paint.kind != pkGradientLinear:
|
|
||||||
raise newException(PixieError, "Paint kind must be " & $pkGradientLinear)
|
|
||||||
|
|
||||||
if paint.gradientHandlePositions.len != 2:
|
if paint.gradientHandlePositions.len != 2:
|
||||||
raise newException(PixieError, "Linear gradient requires 2 handles")
|
raise newException(PixieError, "Linear gradient requires 2 handles")
|
||||||
|
|
||||||
|
@ -121,12 +118,9 @@ proc fillGradientLinear*(image: Image, paint: Paint) =
|
||||||
t = toLineSpace(at, to, xy)
|
t = toLineSpace(at, to, xy)
|
||||||
image.gradientPut(paint, x, y, t, paint.gradientStops)
|
image.gradientPut(paint, x, y, t, paint.gradientStops)
|
||||||
|
|
||||||
proc fillGradientRadial*(image: Image, paint: Paint) =
|
proc fillGradientRadial(image: Image, paint: Paint) =
|
||||||
## Fills a radial gradient.
|
## Fills a radial gradient.
|
||||||
|
|
||||||
if paint.kind != pkGradientRadial:
|
|
||||||
raise newException(PixieError, "Paint kind must be " & $pkGradientRadial)
|
|
||||||
|
|
||||||
if paint.gradientHandlePositions.len != 3:
|
if paint.gradientHandlePositions.len != 3:
|
||||||
raise newException(PixieError, "Radial gradient requires 3 handles")
|
raise newException(PixieError, "Radial gradient requires 3 handles")
|
||||||
|
|
||||||
|
@ -155,12 +149,9 @@ proc fillGradientRadial*(image: Image, paint: Paint) =
|
||||||
t = (mat * xy).length()
|
t = (mat * xy).length()
|
||||||
image.gradientPut(paint, x, y, t, paint.gradientStops)
|
image.gradientPut(paint, x, y, t, paint.gradientStops)
|
||||||
|
|
||||||
proc fillGradientAngular*(image: Image, paint: Paint) =
|
proc fillGradientAngular(image: Image, paint: Paint) =
|
||||||
## Fills an angular gradient.
|
## Fills an angular gradient.
|
||||||
|
|
||||||
if paint.kind != pkGradientAngular:
|
|
||||||
raise newException(PixieError, "Paint kind must be " & $pkGradientAngular)
|
|
||||||
|
|
||||||
if paint.gradientHandlePositions.len != 3:
|
if paint.gradientHandlePositions.len != 3:
|
||||||
raise newException(PixieError, "Angular gradient requires 2 handles")
|
raise newException(PixieError, "Angular gradient requires 2 handles")
|
||||||
|
|
||||||
|
@ -182,3 +173,16 @@ proc fillGradientAngular*(image: Image, paint: Paint) =
|
||||||
angle = normalize(xy - center).angle()
|
angle = normalize(xy - center).angle()
|
||||||
t = (angle + gradientAngle + PI / 2).fixAngle() / 2 / PI + 0.5
|
t = (angle + gradientAngle + PI / 2).fixAngle() / 2 / PI + 0.5
|
||||||
image.gradientPut(paint, x, y, t, paint.gradientStops)
|
image.gradientPut(paint, x, y, t, paint.gradientStops)
|
||||||
|
|
||||||
|
proc fillGradient*(image: Image, paint: Paint) =
|
||||||
|
## Fills with the Paint gradient.
|
||||||
|
|
||||||
|
case paint.kind:
|
||||||
|
of pkGradientLinear:
|
||||||
|
image.fillGradientLinear(paint)
|
||||||
|
of pkGradientRadial:
|
||||||
|
image.fillGradientRadial(paint)
|
||||||
|
of pkGradientAngular:
|
||||||
|
image.fillGradientAngular(paint)
|
||||||
|
else:
|
||||||
|
raise newException(PixieError, "Paint must be a gradient")
|
||||||
|
|
|
@ -1813,12 +1813,8 @@ proc fillPath*(
|
||||||
fill.draw(paint.image, paint.imageMat)
|
fill.draw(paint.image, paint.imageMat)
|
||||||
of pkImageTiled:
|
of pkImageTiled:
|
||||||
fill.drawTiled(paint.image, paint.imageMat)
|
fill.drawTiled(paint.image, paint.imageMat)
|
||||||
of pkGradientLinear:
|
of pkGradientLinear, pkGradientRadial, pkGradientAngular:
|
||||||
fill.fillGradientLinear(paint)
|
fill.fillGradient(paint)
|
||||||
of pkGradientRadial:
|
|
||||||
fill.fillGradientRadial(paint)
|
|
||||||
of pkGradientAngular:
|
|
||||||
fill.fillGradientAngular(paint)
|
|
||||||
|
|
||||||
paint.opacity = savedOpacity
|
paint.opacity = savedOpacity
|
||||||
|
|
||||||
|
@ -1909,12 +1905,8 @@ proc strokePath*(
|
||||||
fill.draw(paint.image, paint.imageMat)
|
fill.draw(paint.image, paint.imageMat)
|
||||||
of pkImageTiled:
|
of pkImageTiled:
|
||||||
fill.drawTiled(paint.image, paint.imageMat)
|
fill.drawTiled(paint.image, paint.imageMat)
|
||||||
of pkGradientLinear:
|
of pkGradientLinear, pkGradientRadial, pkGradientAngular:
|
||||||
fill.fillGradientLinear(paint)
|
fill.fillGradient(paint)
|
||||||
of pkGradientRadial:
|
|
||||||
fill.fillGradientRadial(paint)
|
|
||||||
of pkGradientAngular:
|
|
||||||
fill.fillGradientAngular(paint)
|
|
||||||
|
|
||||||
paint.opacity = savedOpacity
|
paint.opacity = savedOpacity
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 163 B |
|
@ -43,7 +43,7 @@ block:
|
||||||
a.fill(rgba(255, 0, 0, 255))
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
b.fill(rgba(0, 255, 0, 255))
|
b.fill(rgba(0, 255, 0, 255))
|
||||||
|
|
||||||
a.draw(b, vec2(0, 0))
|
a.draw(b, translate(vec2(0, 0)))
|
||||||
|
|
||||||
a.writeFile("tests/images/flipped1.png")
|
a.writeFile("tests/images/flipped1.png")
|
||||||
a.flipVertical()
|
a.flipVertical()
|
||||||
|
|
|
@ -75,12 +75,6 @@ block:
|
||||||
a.draw(b)
|
a.draw(b)
|
||||||
writeFile("tests/images/masks/imageMaskedMask.png", a.encodePng())
|
writeFile("tests/images/masks/imageMaskedMask.png", a.encodePng())
|
||||||
|
|
||||||
block:
|
|
||||||
let a = newMask(100, 100)
|
|
||||||
a.fill(255)
|
|
||||||
a.shift(vec2(10, 10))
|
|
||||||
writeFile("tests/images/masks/shifted.png", a.encodePng())
|
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let path = newPath()
|
let path = newPath()
|
||||||
path.rect(40, 40, 20, 20)
|
path.rect(40, 40, 20, 20)
|
||||||
|
|
Loading…
Reference in a new issue