commit
4a9d1297db
13 changed files with 63 additions and 55 deletions
|
@ -24,7 +24,7 @@ var a = newImage(1000, 1000)
|
|||
a.fill(rgba(0, 0, 0, 255))
|
||||
|
||||
timeIt "pixie":
|
||||
var p: paths.Path
|
||||
var p: pixie.Path
|
||||
p.moveTo(0, 0)
|
||||
p.lineTo(500, 0)
|
||||
p.lineTo(500, 500)
|
||||
|
|
|
@ -492,7 +492,7 @@ proc decodeSvg*(data: string, width = 0, height = 0): Image =
|
|||
let
|
||||
bgra = pixels[result.dataIndex(x, y)]
|
||||
rgba = rgba(bgra[2], bgra[1], bgra[0], bgra[3])
|
||||
result.setRgbaUnsafe(x, y, rgba)
|
||||
result.setRgbaUnsafe(x, y, rgba.rgbx())
|
||||
except PixieError as e:
|
||||
raise e
|
||||
except:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
author = "Andre von Houck and Ryan Oldenburg"
|
||||
description = "Full-featured 2d graphics library for Nim."
|
||||
license = "MIT"
|
||||
|
@ -7,7 +7,7 @@ srcDir = "src"
|
|||
|
||||
requires "nim >= 1.2.6"
|
||||
requires "vmath >= 0.4.0"
|
||||
requires "chroma >= 0.2.3"
|
||||
requires "chroma >= 0.2.4"
|
||||
requires "zippy >= 0.3.5"
|
||||
requires "flatty >= 0.1.3"
|
||||
requires "nimsimd >= 1.0.0"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import bumpy, chroma, flatty/binny, os, pixie/blends, pixie/common,
|
||||
pixie/fileformats/bmp, pixie/fileformats/gif, pixie/fileformats/jpg, pixie/fileformats/png,
|
||||
pixie/fileformats/svg, pixie/images, pixie/masks, pixie/paints, pixie/paths, vmath
|
||||
pixie/fileformats/bmp, pixie/fileformats/gif, pixie/fileformats/jpg,
|
||||
pixie/fileformats/png, pixie/fileformats/svg, pixie/images, pixie/masks,
|
||||
pixie/paints, pixie/paths, vmath
|
||||
|
||||
export blends, bumpy, chroma, common, images, masks, paints, paths, vmath
|
||||
|
||||
|
@ -8,6 +9,14 @@ type
|
|||
FileFormat* = enum
|
||||
ffPng, ffBmp, ffJpg, ffGif
|
||||
|
||||
converter autoStraightAlpha*(c: ColorRGBX): ColorRGBA {.inline.} =
|
||||
## Convert a paremultiplied alpha RGBA to a straight alpha RGBA.
|
||||
c.rgba()
|
||||
|
||||
converter autoPremultipliedAlpha*(c: ColorRGBA): ColorRGBX {.inline.} =
|
||||
## Convert a straight alpha RGBA to a premultiplied alpha RGBA.
|
||||
c.rgbx()
|
||||
|
||||
proc decodeImage*(data: string | seq[uint8]): Image =
|
||||
## Loads an image from a memory.
|
||||
if data.len > 8 and data.readUint64(0) == cast[uint64](pngSignature):
|
||||
|
|
|
@ -221,8 +221,8 @@ proc blendMultiply(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
|
||||
proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let
|
||||
backdrop = backdrop.toStraightAlpha()
|
||||
source = source.toStraightAlpha()
|
||||
backdrop = backdrop.rgba()
|
||||
source = source.rgba()
|
||||
proc blend(backdrop, source: uint32): uint8 {.inline.} =
|
||||
if backdrop == 255:
|
||||
255.uint8
|
||||
|
@ -234,7 +234,7 @@ proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
blended.r = blend(backdrop.r, source.r)
|
||||
blended.g = blend(backdrop.g, source.g)
|
||||
blended.b = blend(backdrop.b, source.b)
|
||||
result = alphaFix(backdrop, source, blended).toPremultipliedAlpha()
|
||||
result = alphaFix(backdrop, source, blended).rgbx()
|
||||
|
||||
proc blendLighten(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
proc blend(
|
||||
|
@ -268,8 +268,8 @@ proc blendScreen(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
|
||||
proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let
|
||||
backdrop = backdrop.toStraightAlpha()
|
||||
source = source.toStraightAlpha()
|
||||
backdrop = backdrop.rgba()
|
||||
source = source.rgba()
|
||||
proc blend(backdrop, source: uint32): uint8 {.inline.} =
|
||||
if backdrop == 0:
|
||||
0.uint8
|
||||
|
@ -281,7 +281,7 @@ proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
blended.r = blend(backdrop.r, source.r)
|
||||
blended.g = blend(backdrop.g, source.g)
|
||||
blended.b = blend(backdrop.b, source.b)
|
||||
result = alphaFix(backdrop, source, blended).toPremultipliedAlpha()
|
||||
result = alphaFix(backdrop, source, blended).rgbx()
|
||||
|
||||
proc blendOverlay(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
result.r = hardLight(source.r, source.a, backdrop.r, backdrop.a)
|
||||
|
@ -298,8 +298,8 @@ proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
# ).uint8
|
||||
|
||||
let
|
||||
backdrop = backdrop.toStraightAlpha()
|
||||
source = source.toStraightAlpha()
|
||||
backdrop = backdrop.rgba()
|
||||
source = source.rgba()
|
||||
|
||||
var rgba: ColorRGBA
|
||||
when defined(amd64) and not defined(pixieNoSimd):
|
||||
|
@ -361,7 +361,7 @@ proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
blended = alphaFix(b, s, blended)
|
||||
rgba = blended.rgba
|
||||
|
||||
result = rgba
|
||||
result = rgba.rgbx()
|
||||
|
||||
proc blendHardLight(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
result.r = hardLight(backdrop.r, backdrop.a, source.r, source.a)
|
||||
|
@ -396,31 +396,31 @@ proc blendExclusion(backdrop, source: ColorRGBX): ColorRGBX =
|
|||
|
||||
proc blendColor(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let
|
||||
backdrop = backdrop.toStraightAlpha().color
|
||||
source = source.toStraightAlpha().color
|
||||
backdrop = backdrop.rgba().color
|
||||
source = source.rgba().color
|
||||
blended = SetLum(source, Lum(backdrop))
|
||||
result = alphaFix(backdrop, source, blended).rgba.toPremultipliedAlpha()
|
||||
result = alphaFix(backdrop, source, blended).rgba.rgbx()
|
||||
|
||||
proc blendLuminosity(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let
|
||||
backdrop = backdrop.toStraightAlpha().color
|
||||
source = source.toStraightAlpha().color
|
||||
backdrop = backdrop.rgba().color
|
||||
source = source.rgba().color
|
||||
blended = SetLum(backdrop, Lum(source))
|
||||
result = alphaFix(backdrop, source, blended).rgba.toPremultipliedAlpha()
|
||||
result = alphaFix(backdrop, source, blended).rgba.rgbx()
|
||||
|
||||
proc blendHue(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let
|
||||
backdrop = backdrop.toStraightAlpha().color
|
||||
source = source.toStraightAlpha().color
|
||||
backdrop = backdrop.rgba().color
|
||||
source = source.rgba().color
|
||||
blended = SetLum(SetSat(source, Sat(backdrop)), Lum(backdrop))
|
||||
result = alphaFix(backdrop, source, blended).rgba.toPremultipliedAlpha()
|
||||
result = alphaFix(backdrop, source, blended).rgba.rgbx()
|
||||
|
||||
proc blendSaturation(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let
|
||||
backdrop = backdrop.toStraightAlpha().color
|
||||
source = source.toStraightAlpha().color
|
||||
backdrop = backdrop.rgba().color
|
||||
source = source.rgba().color
|
||||
blended = SetLum(SetSat(backdrop, Sat(source)), Lum(backdrop))
|
||||
result = alphaFix(backdrop, source, blended).rgba.toPremultipliedAlpha()
|
||||
result = alphaFix(backdrop, source, blended).rgba.rgbx()
|
||||
|
||||
proc blendMask(backdrop, source: ColorRGBX): ColorRGBX =
|
||||
let k = source.a.uint32
|
||||
|
|
|
@ -46,7 +46,7 @@ proc decodeBmp*(data: string): Image =
|
|||
rgba.b = data.readUint8(offset + 0)
|
||||
rgba.a = 255
|
||||
offset += 3
|
||||
result[x, result.height - y - 1] = rgba
|
||||
result[x, result.height - y - 1] = rgba.rgbx()
|
||||
|
||||
proc decodeBmp*(data: seq[uint8]): Image {.inline.} =
|
||||
## Decodes bitmap data into an Image.
|
||||
|
@ -84,7 +84,7 @@ proc encodeBmp*(image: Image): string =
|
|||
|
||||
for y in 0 ..< image.height:
|
||||
for x in 0 ..< image.width:
|
||||
let rgba = image[x, image.height - y - 1].toStraightAlpha()
|
||||
let rgba = image[x, image.height - y - 1].rgba()
|
||||
result.addUint8(rgba.r)
|
||||
result.addUint8(rgba.g)
|
||||
result.addUint8(rgba.b)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import chroma, flatty/binny, pixie/common, pixie/images, math, zippy/bitstreams
|
||||
import chroma, flatty/binny, math, pixie/common, pixie/images, zippy/bitstreams
|
||||
|
||||
const gifSignatures* = @["GIF87a", "GIF89a"]
|
||||
|
||||
|
@ -158,7 +158,7 @@ proc decodeGif*(data: string): Image =
|
|||
# Convert color indexes into real colors.
|
||||
for j, idx in colorIndexes:
|
||||
if idx >= colors.len or j >= result.data.len: failInvalid()
|
||||
result.data[j] = colors[idx]
|
||||
result.data[j] = colors[idx].rgbx()
|
||||
|
||||
of 0x21: # Read EXTENSION block.
|
||||
# Skip over all extensions (mostly animation information).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import chroma, flatty/binny, math, pixie/common, pixie/images, pixie/masks,
|
||||
zippy, zippy/crc, pixie/internal
|
||||
import chroma, flatty/binny, math, pixie/common, pixie/images, pixie/internal,
|
||||
pixie/masks, zippy, zippy/crc
|
||||
|
||||
# See http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ const
|
|||
|
||||
type Ctx = object
|
||||
fillRule: WindingRule
|
||||
fill, stroke: ColorRGBA
|
||||
fill, stroke: ColorRGBX
|
||||
strokeWidth: float32
|
||||
strokeLineCap: LineCap
|
||||
strokeLineJoin: LineJoin
|
||||
|
@ -25,8 +25,8 @@ proc attrOrDefault(node: XmlNode, name, default: string): string =
|
|||
result = default
|
||||
|
||||
proc initCtx(): Ctx =
|
||||
result.fill = parseHtmlColor("black").rgba
|
||||
result.stroke = parseHtmlColor("black").rgba
|
||||
result.fill = parseHtmlColor("black").rgbx
|
||||
result.stroke = parseHtmlColor("black").rgbx
|
||||
result.strokeWidth = 1
|
||||
result.transform = mat3()
|
||||
|
||||
|
@ -79,18 +79,18 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx =
|
|||
if fill == "" or fill == "currentColor":
|
||||
discard # Inherit
|
||||
elif fill == "none":
|
||||
result.fill = ColorRGBA()
|
||||
result.fill = ColorRGBX()
|
||||
else:
|
||||
result.fill = parseHtmlColor(fill).rgba
|
||||
result.fill = parseHtmlColor(fill).rgbx
|
||||
|
||||
if stroke == "":
|
||||
discard # Inherit
|
||||
elif stroke == "currentColor":
|
||||
result.shouldStroke = true
|
||||
elif stroke == "none":
|
||||
result.stroke = ColorRGBA()
|
||||
result.stroke = ColorRGBX()
|
||||
else:
|
||||
result.stroke = parseHtmlColor(stroke).rgba
|
||||
result.stroke = parseHtmlColor(stroke).rgbx
|
||||
result.shouldStroke = true
|
||||
|
||||
if strokeWidth == "":
|
||||
|
@ -101,7 +101,7 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx =
|
|||
result.strokeWidth = parseFloat(strokeWidth)
|
||||
result.shouldStroke = true
|
||||
|
||||
if result.stroke == ColorRGBA() or result.strokeWidth <= 0:
|
||||
if result.stroke == ColorRGBX() or result.strokeWidth <= 0:
|
||||
result.shouldStroke = false
|
||||
|
||||
if strokeLineCap == "":
|
||||
|
@ -216,7 +216,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
d = node.attr("d")
|
||||
ctx = decodeCtx(ctxStack[^1], node)
|
||||
path = parsePath(d)
|
||||
if ctx.fill != ColorRGBA():
|
||||
if ctx.fill != ColorRGBX():
|
||||
img.fillPath(path, ctx.fill, ctx.transform, ctx.fillRule)
|
||||
if ctx.shouldStroke:
|
||||
img.strokePath(path, ctx.stroke, ctx.transform, ctx.strokeWidth)
|
||||
|
@ -234,7 +234,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
path.lineTo(x2, y2)
|
||||
path.closePath()
|
||||
|
||||
if ctx.fill != ColorRGBA():
|
||||
if ctx.fill != ColorRGBX():
|
||||
img.fillPath(path, ctx.fill, ctx.transform)
|
||||
if ctx.shouldStroke:
|
||||
img.strokePath(path, ctx.stroke, ctx.transform, ctx.strokeWidth)
|
||||
|
@ -270,7 +270,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
if node.tag == "polygon":
|
||||
path.closePath()
|
||||
|
||||
if ctx.fill != ColorRGBA():
|
||||
if ctx.fill != ColorRGBX():
|
||||
img.fillPath(path, ctx.fill, ctx.transform)
|
||||
if ctx.shouldStroke:
|
||||
img.strokePath(path, ctx.stroke, ctx.transform, ctx.strokeWidth)
|
||||
|
@ -308,7 +308,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
else:
|
||||
path.rect(x, y, width, height)
|
||||
|
||||
if ctx.fill != ColorRGBA():
|
||||
if ctx.fill != ColorRGBX():
|
||||
img.fillPath(path, ctx.fill, ctx.transform)
|
||||
if ctx.shouldStroke:
|
||||
img.strokePath(path, ctx.stroke, ctx.transform, ctx.strokeWidth)
|
||||
|
@ -330,7 +330,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
var path: Path
|
||||
path.ellipse(cx, cy, rx, ry)
|
||||
|
||||
if ctx.fill != ColorRGBA():
|
||||
if ctx.fill != ColorRGBX():
|
||||
img.fillPath(path, ctx.fill, ctx.transform)
|
||||
if ctx.shouldStroke:
|
||||
img.strokePath(path, ctx.stroke, ctx.transform, ctx.strokeWidth)
|
||||
|
|
|
@ -36,8 +36,7 @@ proc toLineSpace(at, to, point: Vec2): float32 =
|
|||
|
||||
proc gradientPut(image: Image, x, y: int, a: float32, stops: seq[ColorStop]) =
|
||||
## Put an gradient color based on the "a" - were are we related to a line.
|
||||
var
|
||||
index = -1
|
||||
var index = -1
|
||||
for i, stop in stops:
|
||||
if stop.position < a:
|
||||
index = i
|
||||
|
@ -59,7 +58,7 @@ proc gradientPut(image: Image, x, y: int, a: float32, stops: seq[ColorStop]) =
|
|||
gs2.color.color,
|
||||
(a - gs1.position) / (gs2.position - gs1.position)
|
||||
)
|
||||
image.setRgbaUnsafe(x, y, color.rgba.toPremultipliedAlpha())
|
||||
image.setRgbaUnsafe(x, y, color.rgba.rgbx())
|
||||
|
||||
proc fillLinearGradient*(
|
||||
image: Image,
|
||||
|
|
|
@ -24,8 +24,8 @@ timeIt "subImage":
|
|||
|
||||
reset()
|
||||
|
||||
# timeIt "superImage":
|
||||
# discard
|
||||
timeIt "superImage":
|
||||
keep image.superImage(-10, -10, 2580, 1460)
|
||||
|
||||
reset()
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import pixie/fileformats/gif, pixie
|
||||
import pixie, pixie/fileformats/gif
|
||||
|
||||
var img = decodeGIF(readFile("tests/images/gif/3x5.gif"))
|
||||
img.writeFile("tests/images/gif/3x5.png")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import chroma, pixie, vmath, pixie/internal
|
||||
import chroma, pixie, pixie/internal, vmath
|
||||
|
||||
block:
|
||||
let image = newImage(10, 10)
|
||||
|
|
Loading…
Reference in a new issue