From 46cf47bdebbe5d26198f0855ac3453e46490a0b4 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Wed, 18 Aug 2021 22:50:22 -0500 Subject: [PATCH 1/2] prune some raises --- src/pixie/blends.nim | 94 ++++++++++++++-------------- src/pixie/contexts.nim | 18 ++---- src/pixie/fileformats/png.nim | 8 +-- src/pixie/fileformats/svg.nim | 14 ++--- src/pixie/fontformats/opentype.nim | 98 +++++++++++------------------- src/pixie/fontformats/svgfont.nim | 2 +- src/pixie/fonts.nim | 14 ++--- src/pixie/internal.nim | 12 ++-- src/pixie/paints.nim | 10 +-- src/pixie/paths.nim | 56 ++++++++--------- 10 files changed, 144 insertions(+), 182 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 8ef218c..9d96b25 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -42,10 +42,10 @@ type when defined(release): {.push checks: off.} -proc min(a, b: uint32): uint32 {.inline, raises: [].} = +proc min(a, b: uint32): uint32 {.inline.} = if a < b: a else: b -proc alphaFix(backdrop, source, mixed: ColorRGBA): ColorRGBA {.raises: [].} = +proc alphaFix(backdrop, source, mixed: ColorRGBA): ColorRGBA = ## After mixing an image, adjust its alpha value to be correct. let sa = source.a.uint32 @@ -68,7 +68,7 @@ proc alphaFix(backdrop, source, mixed: ColorRGBA): ColorRGBA {.raises: [].} = result.b = (b div a div 255).uint8 result.a = a.uint8 -proc alphaFix(backdrop, source, mixed: Color): Color {.raises: [].} = +proc alphaFix(backdrop, source, mixed: Color): Color = ## After mixing an image, adjust its alpha value to be correct. result.a = (source.a + backdrop.a * (1.0 - source.a)) if result.a == 0: @@ -87,16 +87,16 @@ proc alphaFix(backdrop, source, mixed: Color): Color {.raises: [].} = result.g /= result.a result.b /= result.a -proc blendAlpha*(backdrop, source: uint8): uint8 {.inline, raises: [].} = +proc blendAlpha*(backdrop, source: uint8): uint8 {.inline.} = ## Blends alphas of backdrop, source. source + ((backdrop.uint32 * (255 - source)) div 255).uint8 -proc screen(backdrop, source: uint32): uint8 {.inline, raises: [].} = +proc screen(backdrop, source: uint32): uint8 {.inline.} = ((backdrop + source).int32 - ((backdrop * source) div 255).int32).uint8 proc hardLight( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint32 -): uint8 {.inline, raises: [].} = +): uint8 {.inline.} = if sourceColor * 2 <= sourceAlpha: (( 2 * sourceColor * backdropColor + @@ -106,41 +106,41 @@ proc hardLight( else: screen(backdropColor, sourceColor) -proc softLight(backdrop, source: float32): float32 {.inline, raises: [].} = +proc softLight(backdrop, source: float32): float32 {.inline.} = ## Pegtop (1 - 2 * source) * backdrop ^ 2 + 2 * source * backdrop -proc `+`(c: Color, v: float32): Color {.inline, raises: [].} = +proc `+`(c: Color, v: float32): Color {.inline.} = result.r = c.r + v result.g = c.g + v result.b = c.b + v result.a = c.a + v -proc `+`(v: float32, c: Color): Color {.inline, raises: [].} = +proc `+`(v: float32, c: Color): Color {.inline.} = c + v -proc `*`(c: Color, v: float32): Color {.inline, raises: [].} = +proc `*`(c: Color, v: float32): Color {.inline.} = result.r = c.r * v result.g = c.g * v result.b = c.b * v result.a = c.a * v -proc `/`(c: Color, v: float32): Color {.inline, raises: [].} = +proc `/`(c: Color, v: float32): Color {.inline.} = result.r = c.r / v result.g = c.g / v result.b = c.b / v result.a = c.a / v -proc `-`(c: Color, v: float32): Color {.inline, raises: [].} = +proc `-`(c: Color, v: float32): Color {.inline.} = result.r = c.r - v result.g = c.g - v result.b = c.b - v result.a = c.a - v -proc Lum(C: Color): float32 {.inline, raises: [].} = +proc Lum(C: Color): float32 {.inline.} = 0.3 * C.r + 0.59 * C.g + 0.11 * C.b -proc ClipColor(C: var Color) {.inline, raises: [].} = +proc ClipColor(C: var Color) {.inline.} = let L = Lum(C) n = min([C.r, C.g, C.b]) @@ -150,22 +150,22 @@ proc ClipColor(C: var Color) {.inline, raises: [].} = if x > 1: C = L + (((C - L) * (1 - L)) / (x - L)) -proc SetLum(C: Color, l: float32): Color {.inline, raises: [].} = +proc SetLum(C: Color, l: float32): Color {.inline.} = let d = l - Lum(C) result.r = C.r + d result.g = C.g + d result.b = C.b + d ClipColor(result) -proc Sat(C: Color): float32 {.inline, raises: [].} = +proc Sat(C: Color): float32 {.inline.} = max([C.r, C.g, C.b]) - min([C.r, C.g, C.b]) -proc SetSat(C: Color, s: float32): Color {.inline, raises: [].} = +proc SetSat(C: Color, s: float32): Color {.inline.} = let satC = Sat(C) if satC > 0: result = (C - min([C.r, C.g, C.b])) * s / satC -proc blendNormal(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendNormal(backdrop, source: ColorRGBX): ColorRGBX = if backdrop.a == 0: return source if source.a == 255: @@ -179,7 +179,7 @@ proc blendNormal(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = result.b = source.b + ((backdrop.b.uint32 * k) div 255).uint8 result.a = blendAlpha(backdrop.a, source.a) -proc blendDarken(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendDarken(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -193,7 +193,7 @@ proc blendDarken(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = result.b = blend(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendMultiply(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendMultiply(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -218,7 +218,7 @@ proc blendMultiply(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = # result = alphaFix(backdrop, source, result) # result = result.toPremultipliedAlpha() -proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba() source = source.rgba() @@ -235,7 +235,7 @@ proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = blended.b = blend(backdrop.b, source.b) result = alphaFix(backdrop, source, blended).rgbx() -proc blendLighten(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendLighten(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -249,7 +249,7 @@ proc blendLighten(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = result.b = blend(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendScreen(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendScreen(backdrop, source: ColorRGBX): ColorRGBX = result.r = screen(backdrop.r, source.r) result.g = screen(backdrop.g, source.g) result.b = screen(backdrop.b, source.b) @@ -265,7 +265,7 @@ proc blendScreen(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = # result = alphaFix(backdrop, source, result) # result = result.toPremultipliedAlpha() -proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba() source = source.rgba() @@ -282,13 +282,13 @@ proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = blended.b = blend(backdrop.b, source.b) result = alphaFix(backdrop, source, blended).rgbx() -proc blendOverlay(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendOverlay(backdrop, source: ColorRGBX): ColorRGBX = result.r = hardLight(source.r, source.a, backdrop.r, backdrop.a) result.g = hardLight(source.g, source.a, backdrop.g, backdrop.a) result.b = hardLight(source.b, source.a, backdrop.b, backdrop.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX = # proc softLight(backdrop, source: int32): uint8 {.inline.} = # ## Pegtop # ( @@ -362,13 +362,13 @@ proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = result = rgba.rgbx() -proc blendHardLight(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendHardLight(backdrop, source: ColorRGBX): ColorRGBX = result.r = hardLight(backdrop.r, backdrop.a, source.r, source.a) result.g = hardLight(backdrop.g, backdrop.a, source.g, source.a) result.b = hardLight(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendDifference(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendDifference(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -384,7 +384,7 @@ proc blendDifference(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = result.b = blend(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendExclusion(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendExclusion(backdrop, source: ColorRGBX): ColorRGBX = proc blend(backdrop, source: uint32): uint8 {.inline.} = let v = (backdrop + source).int32 - ((2 * backdrop * source) div 255).int32 max(0, v).uint8 @@ -393,56 +393,56 @@ proc blendExclusion(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = result.b = blend(backdrop.b.uint32, source.b.uint32) result.a = blendAlpha(backdrop.a, source.a) -proc blendColor(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendColor(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(source, Lum(backdrop)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendLuminosity(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendLuminosity(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(backdrop, Lum(source)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendHue(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendHue(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(SetSat(source, Sat(backdrop)), Lum(backdrop)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendSaturation(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendSaturation(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(SetSat(backdrop, Sat(source)), Lum(backdrop)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendMask(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendMask(backdrop, source: ColorRGBX): ColorRGBX = let k = source.a.uint32 result.r = ((backdrop.r * k) div 255).uint8 result.g = ((backdrop.g * k) div 255).uint8 result.b = ((backdrop.b * k) div 255).uint8 result.a = ((backdrop.a * k) div 255).uint8 -proc blendSubtractMask(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendSubtractMask(backdrop, source: ColorRGBX): ColorRGBX = let a = (backdrop.a.uint32 * (255 - source.a)) div 255 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.a = a.uint8 -proc blendExcludeMask(backdrop, source: ColorRGBX): ColorRGBX {.raises: [].} = +proc blendExcludeMask(backdrop, source: ColorRGBX): ColorRGBX = let a = max(backdrop.a, source.a).uint32 - min(backdrop.a, source.a) 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 {.raises: [].} = +proc blendOverwrite(backdrop, source: ColorRGBX): ColorRGBX = source # proc blendWhite(backdrop, source: ColorRGBX): ColorRGBX = @@ -475,21 +475,21 @@ proc blender*(blendMode: BlendMode): Blender {.raises: [].} = of bmSubtractMask: blendSubtractMask of bmExcludeMask: blendExcludeMask -proc maskNormal(backdrop, source: uint8): uint8 {.raises: [].} = +proc maskNormal(backdrop, source: uint8): uint8 = ## Blending masks blendAlpha(backdrop, source) -proc maskMask(backdrop, source: uint8): uint8 {.raises: [].} = +proc maskMask(backdrop, source: uint8): uint8 = ## Masking masks ((backdrop.uint32 * source) div 255).uint8 -proc maskSubtract(backdrop, source: uint8): uint8 {.raises: [].} = +proc maskSubtract(backdrop, source: uint8): uint8 = ((backdrop.uint32 * (255 - source)) div 255).uint8 -proc maskExclude(backdrop, source: uint8): uint8 {.raises: [].} = +proc maskExclude(backdrop, source: uint8): uint8 = max(backdrop, source) - min(backdrop, source) -proc maskOverwrite(backdrop, source: uint8): uint8 {.raises: [].} = +proc maskOverwrite(backdrop, source: uint8): uint8 = source proc masker*(blendMode: BlendMode): Masker {.raises: [PixieError].} = @@ -512,7 +512,7 @@ when defined(amd64) and not defined(pixieNoSimd): MaskerSimd* = proc(blackdrop, source: M128i): M128i {.raises: [].} ## Function signature returned by maskerSimd. - proc blendNormalSimd(backdrop, source: M128i): M128i {.raises: [].} = + proc blendNormalSimd(backdrop, source: M128i): M128i = let alphaMask = mm_set1_epi32(cast[int32](0xff000000)) oddMask = mm_set1_epi16(cast[int16](0xff00)) @@ -541,7 +541,7 @@ when defined(amd64) and not defined(pixieNoSimd): mm_or_si128(backdropEven, mm_slli_epi16(backdropOdd, 8)) ) - proc blendMaskSimd(backdrop, source: M128i): M128i {.raises: [].} = + proc blendMaskSimd(backdrop, source: M128i): M128i = let alphaMask = mm_set1_epi32(cast[int32](0xff000000)) oddMask = mm_set1_epi16(cast[int16](0xff00)) @@ -562,7 +562,7 @@ when defined(amd64) and not defined(pixieNoSimd): mm_or_si128(backdropEven, mm_slli_epi16(backdropOdd, 8)) - proc blendOverwriteSimd(backdrop, source: M128i): M128i {.raises: [].} = + proc blendOverwriteSimd(backdrop, source: M128i): M128i = source proc blenderSimd*(blendMode: BlendMode): BlenderSimd {.raises: [PixieError].} = @@ -578,7 +578,7 @@ when defined(amd64) and not defined(pixieNoSimd): ## Is there a blend function for a given blend mode with SIMD support? blendMode in {bmNormal, bmMask, bmOverwrite} - proc maskNormalSimd(backdrop, source: M128i): M128i {.raises: [].} = + proc maskNormalSimd(backdrop, source: M128i): M128i = ## Blending masks let oddMask = mm_set1_epi16(cast[int16](0xff00)) @@ -615,7 +615,7 @@ when defined(amd64) and not defined(pixieNoSimd): mm_or_si128(blendedEven, mm_slli_epi16(blendedOdd, 8)) - proc maskMaskSimd(backdrop, source: M128i): M128i {.raises: [].} = + proc maskMaskSimd(backdrop, source: M128i): M128i = let oddMask = mm_set1_epi16(cast[int16](0xff00)) div255 = mm_set1_epi16(cast[int16](0x8081)) diff --git a/src/pixie/contexts.nim b/src/pixie/contexts.nim index 3269d8f..4d8fc55 100644 --- a/src/pixie/contexts.nim +++ b/src/pixie/contexts.nim @@ -63,7 +63,7 @@ proc newContext*(width, height: int): Context {.inline, raises: [PixieError].} = ## Create a new Context that will draw to a new image of width and height. newContext(newImage(width, height)) -proc state(ctx: Context): ContextState {.raises: [PixieError].} = +proc state(ctx: Context): ContextState = result.fillStyle = ctx.fillStyle result.strokeStyle = ctx.strokeStyle result.globalAlpha = ctx.globalAlpha @@ -130,9 +130,7 @@ proc restore*(ctx: Context) {.raises: [PixieError].} = else: # Otherwise draw to the root image ctx.image.draw(poppedLayer) -proc fill( - ctx: Context, image: Image, path: Path, windingRule: WindingRule -) {.raises: [PixieError].} = +proc fill(ctx: Context, image: Image, path: Path, windingRule: WindingRule) = var image = image if ctx.globalAlpha != 1: @@ -150,7 +148,7 @@ proc fill( ctx.layer.applyOpacity(ctx.globalAlpha) ctx.restore() -proc stroke(ctx: Context, image: Image, path: Path) {.raises: [PixieError].} = +proc stroke(ctx: Context, image: Image, path: Path) = var image = image if ctx.globalAlpha != 1: @@ -172,7 +170,7 @@ proc stroke(ctx: Context, image: Image, path: Path) {.raises: [PixieError].} = ctx.layer.applyOpacity(ctx.globalAlpha) ctx.restore() -proc newFont(ctx: Context): Font {.raises: [PixieError].} = +proc newFont(ctx: Context): Font = if ctx.font == "": raise newException(PixieError, "No font has been set on this Context") @@ -182,9 +180,7 @@ proc newFont(ctx: Context): Font {.raises: [PixieError].} = result = newFont(ctx.typefaces.getOrDefault(ctx.font, nil)) result.size = ctx.fontSize -proc fillText( - ctx: Context, image: Image, text: string, at: Vec2 -) {.raises: [PixieError].} = +proc fillText(ctx: Context, image: Image, text: string, at: Vec2) = let font = newFont(ctx) # Canvas positions text relative to the alphabetic baseline by default @@ -210,9 +206,7 @@ proc fillText( ctx.layer.applyOpacity(ctx.globalAlpha) ctx.restore() -proc strokeText( - ctx: Context, image: Image, text: string, at: Vec2 -) {.raises: [PixieError].} = +proc strokeText(ctx: Context, image: Image, text: string, at: Vec2) = let font = newFont(ctx) # Canvas positions text relative to the alphabetic baseline by default diff --git a/src/pixie/fileformats/png.nim b/src/pixie/fileformats/png.nim index 6e376db..b7e4bca 100644 --- a/src/pixie/fileformats/png.nim +++ b/src/pixie/fileformats/png.nim @@ -23,7 +23,7 @@ template failInvalid() = when defined(release): {.push checks: off.} -proc decodeHeader(data: string): PngHeader {.raises: [PixieError].} = +proc decodeHeader(data: string): PngHeader = result.width = data.readUint32(0).swap().int result.height = data.readUint32(4).swap().int result.bitDepth = data.readUint8(8) @@ -79,7 +79,7 @@ proc decodeHeader(data: string): PngHeader {.raises: [PixieError].} = if result.interlaceMethod != 0: raise newException(PixieError, "Interlaced PNG not yet supported") -proc decodePalette(data: string): seq[ColorRGB] {.raises: [PixieError].} = +proc decodePalette(data: string): seq[ColorRGB] = if data.len == 0 or data.len mod 3 != 0: failInvalid() @@ -90,7 +90,7 @@ proc decodePalette(data: string): seq[ColorRGB] {.raises: [PixieError].} = proc unfilter( uncompressed: string, height, rowBytes, bpp: int -): string {.raises: [].} = +): string = result.setLen(uncompressed.len - height) template uncompressedIdx(x, y: int): int = @@ -164,7 +164,7 @@ proc decodeImageData( header: PngHeader, palette: seq[ColorRGB], transparency, data: string -): seq[ColorRGBA] {.raises: [PixieError].} = +): seq[ColorRGBA] = result.setLen(header.width * header.height) let diff --git a/src/pixie/fileformats/svg.nim b/src/pixie/fileformats/svg.nim index b13f96a..8b8fa7f 100644 --- a/src/pixie/fileformats/svg.nim +++ b/src/pixie/fileformats/svg.nim @@ -33,12 +33,12 @@ type template failInvalid() = raise newException(PixieError, "Invalid SVG data") -proc attrOrDefault(node: XmlNode, name, default: string): string {.raises: [].} = +proc attrOrDefault(node: XmlNode, name, default: string): string = result = node.attr(name) if result.len == 0: result = default -proc initCtx(): Ctx {.raises: [PixieError].} = +proc initCtx(): Ctx = result.display = true try: result.fill = parseHtmlColor("black").rgbx @@ -317,7 +317,7 @@ proc decodeCtxInternal(inherited: Ctx, node: XmlNode): Ctx = else: failInvalidTransform(transform) -proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx {.raises: [PixieError].} = +proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx = try: decodeCtxInternal(inherited, node) except PixieError as e: @@ -326,14 +326,14 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx {.raises: [PixieError].} = let e = getCurrentException() raise newException(PixieError, e.msg, e) -proc fill(img: Image, ctx: Ctx, path: Path) {.inline, raises: [PixieError].} = +proc fill(img: Image, ctx: Ctx, path: Path) {.inline.} = if ctx.display and ctx.opacity > 0: let paint = newPaint(ctx.fill) if ctx.opacity != 1: paint.opacity = paint.opacity * ctx.opacity img.fillPath(path, paint, ctx.transform, ctx.fillRule) -proc stroke(img: Image, ctx: Ctx, path: Path) {.inline, raises: [PixieError].} = +proc stroke(img: Image, ctx: Ctx, path: Path) {.inline.} = if ctx.display and ctx.opacity > 0: let paint = newPaint(ctx.stroke) if ctx.opacity != 1: @@ -556,9 +556,7 @@ proc drawInternal(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) = else: raise newException(PixieError, "Unsupported SVG tag: " & node.tag) -proc draw( - img: Image, node: XmlNode, ctxStack: var seq[Ctx] -) {.raises: [PixieError].} = +proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) = try: drawInternal(img, node, ctxStack) except PixieError as e: diff --git a/src/pixie/fontformats/opentype.nim b/src/pixie/fontformats/opentype.nim index f6b4d33..6a0204d 100644 --- a/src/pixie/fontformats/opentype.nim +++ b/src/pixie/fontformats/opentype.nim @@ -341,27 +341,25 @@ template eofCheck(buf: string, readTo: int) = template failUnsupported() = raise newException(PixieError, "Unsupported font data") -proc readUint16Seq(buf: string, offset, len: int): seq[uint16] {.raises: [].} = +proc readUint16Seq(buf: string, offset, len: int): seq[uint16] = result = newSeq[uint16](len) for i in 0 ..< len: result[i] = buf.readUint16(offset + i * 2).swap() -proc readFixed32(buf: string, offset: int): float32 {.raises: [].} = +proc readFixed32(buf: string, offset: int): float32 = ## Packed 32-bit value with major and minor version numbers. ceil(buf.readInt32(offset).swap().float32 / 65536.0 * 100000.0) / 100000.0 -proc readFixed16(buf: string, offset: int): float32 {.raises: [].} = +proc readFixed16(buf: string, offset: int): float32 = ## Reads 16-bit signed fixed number with the low 14 bits of fraction (2.14). buf.readInt16(offset).swap().float32 / 16384.0 -proc readLongDateTime(buf: string, offset: int): float64 {.raises: [].} = +proc readLongDateTime(buf: string, offset: int): float64 = ## Date and time represented in number of seconds since 12:00 midnight, ## January 1, 1904, UTC. buf.readInt64(offset).swap().float64 - 2082844800 -proc parseCmapTable( - buf: string, offset: int -): CmapTable {.raises: [PixieError].} = +proc parseCmapTable(buf: string, offset: int): CmapTable = var i = offset buf.eofCheck(i + 4) @@ -456,9 +454,7 @@ proc parseCmapTable( # TODO implement other cmap platformIDs discard -proc parseHeadTable( - buf: string, offset: int -): HeadTable {.raises: [PixieError].} = +proc parseHeadTable(buf: string, offset: int): HeadTable = buf.eofCheck(offset + 54) result = HeadTable() @@ -487,9 +483,7 @@ proc parseHeadTable( if result.glyphDataFormat != 0: failUnsupported() -proc parseHheaTable( - buf: string, offset: int -): HheaTable {.raises: [PixieError].} = +proc parseHheaTable(buf: string, offset: int): HheaTable = buf.eofCheck(offset + 36) result = HheaTable() @@ -518,9 +512,7 @@ proc parseHheaTable( failUnsupported() result.numberOfHMetrics = buf.readUint16(offset + 34).swap() -proc parseMaxpTable( - buf: string, offset: int -): MaxpTable {.raises: [PixieError].} = +proc parseMaxpTable(buf: string, offset: int): MaxpTable = buf.eofCheck(offset + 32) result = MaxpTable() @@ -544,7 +536,7 @@ proc parseMaxpTable( proc parseHmtxTable( buf: string, offset: int, hhea: HheaTable, maxp: MaxpTable -): HmtxTable {.raises: [PixieError].} = +): HmtxTable = var i = offset let @@ -565,9 +557,7 @@ proc parseHmtxTable( result.leftSideBearings.add(buf.readInt16(i).swap()) i += 2 -proc parseNameTable( - buf: string, offset: int -): NameTable {.raises: [PixieError].} = +proc parseNameTable(buf: string, offset: int): NameTable = var i = offset buf.eofCheck(i + 6) @@ -593,9 +583,7 @@ proc parseNameTable( record.offset = buf.readUint16(i + 10).swap() i += 12 -proc parseOS2Table( - buf: string, offset: int -): OS2Table {.raises: [PixieError].} = +proc parseOS2Table(buf: string, offset: int): OS2Table = var i = offset buf.eofCheck(i + 78) @@ -659,7 +647,7 @@ proc parseOS2Table( proc parseLocaTable( buf: string, offset: int, head: HeadTable, maxp: MaxpTable -): LocaTable {.raises: [PixieError].} = +): LocaTable = var i = offset result = LocaTable() @@ -678,15 +666,13 @@ proc parseLocaTable( proc parseGlyfTable( buf: string, offset: int, loca: LocaTable -): GlyfTable {.raises: [].} = +): GlyfTable = result = GlyfTable() result.offsets.setLen(loca.offsets.len) for glyphId in 0 ..< loca.offsets.len: result.offsets[glyphId] = offset.uint32 + loca.offsets[glyphId] -proc parseKernTable( - buf: string, offset: int -): KernTable {.raises: [PixieError].} = +proc parseKernTable(buf: string, offset: int): KernTable = var i = offset buf.eofCheck(i + 2) @@ -748,9 +734,7 @@ proc parseKernTable( else: failUnsupported() -# proc parseLangSys( -# buf: string, offset: int -# ): LangSys {.raises: [PixieError].} = +# proc parseLangSys(buf: string, offset: int): LangSys = # var i = offset # buf.eofCheck(i + 6) @@ -838,16 +822,14 @@ proc parseKernTable( # result.featureRecords.add(featureRecord) # i += 6 -proc parseRangeRecord( - buf: string, offset: int -): RangeRecord {.raises: [PixieError].} = +proc parseRangeRecord(buf: string, offset: int): RangeRecord = buf.eofCheck(offset + 6) result.startGlyphID = buf.readUint16(offset + 0).swap() result.endGlyphID = buf.readUint16(offset + 2).swap() result.startCoverageIndex = buf.readUint16(offset + 4).swap() -proc parseCoverage(buf: string, offset: int): Coverage {.raises: [PixieError].} = +proc parseCoverage(buf: string, offset: int): Coverage = var i = offset buf.eofCheck(i + 4) @@ -885,7 +867,7 @@ proc parseCoverage(buf: string, offset: int): Coverage {.raises: [PixieError].} else: failUnsupported() -proc valueFormatSize(valueFormat: uint16): int {.raises: [].} = +proc valueFormatSize(valueFormat: uint16): int = # countSetBits(valueFormat) * 2 var n = valueFormat @@ -897,7 +879,7 @@ proc valueFormatSize(valueFormat: uint16): int {.raises: [].} = proc parseValueRecord( buf: string, offset: int, valueFormat: uint16 -): ValueRecord {.raises: [PixieError].} = +): ValueRecord = buf.eofCheck(offset + valueFormatSize(valueFormat)) var i = offset @@ -928,7 +910,7 @@ proc parseValueRecord( proc parsePairValueRecord( buf: string, offset: int, valueFormat1, valueFormat2: uint16 -): PairValueRecord {.raises: [PixieError].} = +): PairValueRecord = var i = offset buf.eofCheck(i + 2) @@ -942,7 +924,7 @@ proc parsePairValueRecord( proc parsePairSet( buf: string, offset: int, valueFormat1, valueFormat2: uint16 -): PairSet {.raises: [PixieError].} = +): PairSet = var i = offset buf.eofCheck(i + 2) @@ -961,7 +943,7 @@ proc parsePairSet( proc parseClass2Record( buf: string, offset: int, valueFormat1, valueFormat2: uint16 -): Class2Record {.raises: [PixieError].} = +): Class2Record = var i = offset buf.eofCheck( @@ -974,7 +956,7 @@ proc parseClass2Record( proc parseClass1Record( buf: string, offset: int, valueFormat1, valueFormat2, class2Count: uint16 -): Class1Record {.raises: [PixieError].} = +): Class1Record = var i = offset result.class2Records.setLen(class2Count.int) @@ -985,14 +967,14 @@ proc parseClass1Record( proc parseClassRangeRecord( buf: string, offset: int -): ClassRangeRecord {.raises: [PixieError].} = +): ClassRangeRecord = buf.eofCheck(offset + 6) result.startGlyphID = buf.readUint16(offset + 0).swap() result.endGlyphID = buf.readUint16(offset + 2).swap() result.class = buf.readUint16(offset + 4).swap() -proc parseClassDef(buf: string, offset: int): ClassDef {.raises: [PixieError].} = +proc parseClassDef(buf: string, offset: int): ClassDef = var i = offset buf.eofCheck(i + 2) @@ -1024,7 +1006,7 @@ proc parseClassDef(buf: string, offset: int): ClassDef {.raises: [PixieError].} else: failUnsupported() -proc parsePairPos(buf: string, offset: int): PairPos {.raises: [PixieError].} = +proc parsePairPos(buf: string, offset: int): PairPos = var i = offset buf.eofCheck(i + 4) @@ -1157,9 +1139,7 @@ proc parsePairPos(buf: string, offset: int): PairPos {.raises: [PixieError].} = else: failUnsupported() -proc parseLookup( - buf: string, offset: int, gpos: GposTable -): Lookup {.raises: [PixieError].} = +proc parseLookup(buf: string, offset: int, gpos: GposTable): Lookup = var i = offset buf.eofCheck(i + 6) @@ -1185,9 +1165,7 @@ proc parseLookup( pairPos.classPairAdjustments.len > 0: gpos.lookupList.pairPosTables.add(pairPos) -proc parseLookupList( - buf: string, offset: int, gpos: GposTable -): LookupList {.raises: [PixieError].} = +proc parseLookupList(buf: string, offset: int, gpos: GposTable): LookupList = var i = offset buf.eofCheck(i + 2) @@ -1202,9 +1180,7 @@ proc parseLookupList( for lookupOffset in result.lookupoffsets: result.lookups.add(parseLookup(buf, offset + lookupOffset.int, gpos)) -proc parseGposTable( - buf: string, offset: int -): GPOSTable {.raises: [PixieError].} = +proc parseGposTable(buf: string, offset: int): GPOSTable = var i = offset buf.eofCheck(i + 10) @@ -1235,9 +1211,7 @@ proc parseGposTable( result.lookupList = parseLookupList(buf, offset + result.lookupListOffset.int, result) -proc parsePostTable( - buf: string, offset: int -): PostTable {.raises: [PixieError].} = +proc parsePostTable(buf: string, offset: int): PostTable = buf.eofCheck(offset + 14) result = PostTable() @@ -1247,14 +1221,14 @@ proc parsePostTable( result.underlineThickness = buf.readInt16(offset + 10).swap() result.isFixedPitch = buf.readUint32(offset + 12).swap() -proc getGlyphId(opentype: OpenType, rune: Rune): uint16 {.inline, raises: [].} = +proc getGlyphId(opentype: OpenType, rune: Rune): uint16 = result = opentype.cmap.runeToGlyphId.getOrDefault(rune, 0) proc parseGlyph(opentype: OpenType, glyphId: uint16): Path {.raises: [PixieError].} proc parseGlyphPath( buf: string, offset, numberOfContours: int -): Path {.raises: [PixieError].} = +): Path = if numberOfContours < 0: raise newException(PixieError, "Glyph numberOfContours must be >= 0") @@ -1387,9 +1361,7 @@ proc parseGlyphPath( result.closePath() -proc parseCompositeGlyph( - opentype: OpenType, offset: int -): Path {.raises: [PixieError].} = +proc parseCompositeGlyph(opentype: OpenType, offset: int): Path = result = newPath() var @@ -1486,7 +1458,7 @@ proc parseCompositeGlyph( proc parseGlyph( opentype: OpenType, glyphId: uint16 -): Path {.raises: [PixieError].} = +): Path = if glyphId.int >= opentype.glyf.offsets.len: raise newException(PixieError, "Invalid glyph ID " & $glyphId) @@ -1516,7 +1488,7 @@ proc parseGlyph( proc parseGlyph( opentype: OpenType, rune: Rune -): Path {.inline, raises: [PixieError].} = +): Path {.inline.} = opentype.parseGlyph(opentype.getGlyphId(rune)) proc getGlyphPath*( diff --git a/src/pixie/fontformats/svgfont.nim b/src/pixie/fontformats/svgfont.nim index add3666..e6ab769 100644 --- a/src/pixie/fontformats/svgfont.nim +++ b/src/pixie/fontformats/svgfont.nim @@ -23,7 +23,7 @@ proc getKerningAdjustment*( template failInvalid() = raise newException(PixieError, "Invalid SVG font data") -proc parseFloat(node: XmlNode, attr: string): float32 {.raises: [PixieError].} = +proc parseFloat(node: XmlNode, attr: string): float32 = let value = node.attr(attr) if value.len == 0: raise newException(PixieError, "SVG font missing attr " & attr) diff --git a/src/pixie/fonts.nim b/src/pixie/fonts.nim index c171567..5055de9 100644 --- a/src/pixie/fonts.nim +++ b/src/pixie/fonts.nim @@ -76,19 +76,19 @@ proc lineHeight*(typeface: Typeface): float32 {.inline, raises: [].} = ## The default line height in font units. typeface.ascent - typeface.descent + typeface.lineGap -proc underlinePosition(typeface: Typeface): float32 {.raises: [].} = +proc underlinePosition(typeface: Typeface): float32 = if typeface.opentype != nil: result = typeface.opentype.post.underlinePosition.float32 -proc underlineThickness(typeface: Typeface): float32 {.raises: [].} = +proc underlineThickness(typeface: Typeface): float32 = if typeface.opentype != nil: result = typeface.opentype.post.underlineThickness.float32 -proc strikeoutPosition(typeface: Typeface): float32 {.raises: [].} = +proc strikeoutPosition(typeface: Typeface): float32 = if typeface.opentype != nil: result = typeface.opentype.os2.yStrikeoutPosition.float32 -proc strikeoutThickness(typeface: Typeface): float32 {.raises: [].} = +proc strikeoutThickness(typeface: Typeface): float32 = if typeface.opentype != nil: result = typeface.opentype.os2.yStrikeoutSize.float32 @@ -152,7 +152,7 @@ proc newSpan*(text: string, font: Font): Span {.raises: [].} = result.text = text result.font = font -proc convertTextCase(runes: var seq[Rune], textCase: TextCase) {.raises: [].} = +proc convertTextCase(runes: var seq[Rune], textCase: TextCase) = case textCase: of tcNormal: discard @@ -169,7 +169,7 @@ proc convertTextCase(runes: var seq[Rune], textCase: TextCase) {.raises: [].} = rune = rune.toUpper() prevRune = rune -proc canWrap(rune: Rune): bool {.inline, raises: [].} = +proc canWrap(rune: Rune): bool {.inline.} = rune == Rune(32) or rune.isWhiteSpace() proc typeset*( @@ -447,7 +447,7 @@ proc textUber( miterLimit = defaultMiterLimit, dashes: seq[float32] = @[], stroke: static[bool] = false -) {.raises: [PixieError].} = +) = var line: int for spanIndex, (start, stop) in arrangement.spans: let diff --git a/src/pixie/internal.nim b/src/pixie/internal.nim index ff8ff8e..0fe2894 100644 --- a/src/pixie/internal.nim +++ b/src/pixie/internal.nim @@ -3,7 +3,7 @@ import chroma, vmath when defined(amd64) and not defined(pixieNoSimd): import nimsimd/sse2 -proc gaussianKernel*(radius: int): seq[uint32] = +proc gaussianKernel*(radius: int): seq[uint32] {.raises: [].} = ## Compute lookup table for 1d Gaussian kernel. ## Values are [0, 255] * 1024. result.setLen(radius * 2 + 1) @@ -23,7 +23,7 @@ proc gaussianKernel*(radius: int): seq[uint32] = for i, f in floats: result[i] = round(f * 255 * 1024).uint32 -proc applyOpacity*(color: ColorRGBX, opacity: float32): ColorRGBX = +proc applyOpacity*(color: ColorRGBX, opacity: float32): ColorRGBX {.raises: [].} = if opacity == 0: rgbx(0, 0, 0, 0) else: @@ -35,7 +35,7 @@ proc applyOpacity*(color: ColorRGBX, opacity: float32): ColorRGBX = a = ((color.a * x) div 255).uint8 rgbx(r, g, b, a) -proc toStraightAlpha*(data: var seq[ColorRGBA | ColorRGBX]) = +proc toStraightAlpha*(data: var seq[ColorRGBA | ColorRGBX]) {.raises: [].} = ## Converts an image from premultiplied alpha to straight alpha. ## This is expensive for large images. for c in data.mitems: @@ -46,7 +46,7 @@ proc toStraightAlpha*(data: var seq[ColorRGBA | ColorRGBX]) = c.g = ((c.g.uint32 * multiplier) div 255).uint8 c.b = ((c.b.uint32 * multiplier) div 255).uint8 -proc toPremultipliedAlpha*(data: var seq[ColorRGBA | ColorRGBX]) = +proc toPremultipliedAlpha*(data: var seq[ColorRGBA | ColorRGBX]) {.raises: [].} = ## Converts an image to premultiplied alpha from straight alpha. var i: int when defined(amd64) and not defined(pixieNoSimd): @@ -94,7 +94,7 @@ proc toPremultipliedAlpha*(data: var seq[ColorRGBA | ColorRGBX]) = data[j] = c when defined(amd64) and not defined(pixieNoSimd): - proc packAlphaValues*(v: M128i): M128i {.inline.} = + proc packAlphaValues*(v: M128i): M128i {.inline, raises: [].} = ## Shuffle the alpha values for these 4 colors to the first 4 bytes result = mm_srli_epi32(v, 24) let @@ -105,7 +105,7 @@ when defined(amd64) and not defined(pixieNoSimd): result = mm_or_si128(mm_or_si128(result, i), mm_or_si128(j, k)) result = mm_and_si128(result, first32) - proc unpackAlphaValues*(v: M128i): M128i {.inline.} = + proc unpackAlphaValues*(v: M128i): M128i {.inline, raises: [].} = ## Unpack the first 32 bits into 4 rgba(0, 0, 0, value) let mask = cast[M128i]([uint8.high.uint64, 0]) diff --git a/src/pixie/paints.nim b/src/pixie/paints.nim index 7f3470a..ec6d3e4 100644 --- a/src/pixie/paints.nim +++ b/src/pixie/paints.nim @@ -64,7 +64,7 @@ converter parseSomePaint*( elif type(paint) is Paint: paint -proc toLineSpace(at, to, point: Vec2): float32 {.inline, raises: [].} = +proc toLineSpace(at, to, point: Vec2): float32 {.inline.} = ## Convert position on to where it would fall on a line between at and to. let d = to - at @@ -73,7 +73,7 @@ proc toLineSpace(at, to, point: Vec2): float32 {.inline, raises: [].} = proc gradientPut( image: Image, paint: Paint, x, y: int, t: float32, stops: seq[ColorStop] -) {.raises: [].} = +) = ## Put an gradient color based on `t` - where are we related to a line. var index = -1 for i, stop in stops: @@ -100,7 +100,7 @@ proc gradientPut( color.a *= paint.opacity image.setRgbaUnsafe(x, y, color.rgbx()) -proc fillGradientLinear(image: Image, paint: Paint) {.raises: [PixieError].} = +proc fillGradientLinear(image: Image, paint: Paint) = ## Fills a linear gradient. if paint.gradientHandlePositions.len != 2: @@ -122,7 +122,7 @@ proc fillGradientLinear(image: Image, paint: Paint) {.raises: [PixieError].} = t = toLineSpace(at, to, xy) image.gradientPut(paint, x, y, t, paint.gradientStops) -proc fillGradientRadial(image: Image, paint: Paint) {.raises: [PixieError].} = +proc fillGradientRadial(image: Image, paint: Paint) = ## Fills a radial gradient. if paint.gradientHandlePositions.len != 3: @@ -153,7 +153,7 @@ proc fillGradientRadial(image: Image, paint: Paint) {.raises: [PixieError].} = t = (mat * xy).length() image.gradientPut(paint, x, y, t, paint.gradientStops) -proc fillGradientAngular(image: Image, paint: Paint) {.raises: [PixieError].} = +proc fillGradientAngular(image: Image, paint: Paint) = ## Fills an angular gradient. if paint.gradientHandlePositions.len != 3: diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index e8bb547..d10be81 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -50,19 +50,19 @@ proc newPath*(): Path {.raises: [].} = ## Create a new Path. Path() -proc pixelScale(transform: Mat3): float32 {.raises: [].} = +proc pixelScale(transform: Mat3): float32 = ## What is the largest scale factor of this transform? max( vec2(transform[0, 0], transform[0, 1]).length, vec2(transform[1, 0], transform[1, 1]).length ) -proc isRelative(kind: PathCommandKind): bool {.inline, raises: [].} = +proc isRelative(kind: PathCommandKind): bool {.inline.} = kind in { RMove, RLine, TQuad, RTQuad, RHLine, RVLine, RCubic, RSCubic, RQuad, RArc } -proc parameterCount(kind: PathCommandKind): int {.raises: [].} = +proc parameterCount(kind: PathCommandKind): int = ## Returns number of parameters a path command has. case kind: of Close: 0 @@ -635,7 +635,7 @@ proc polygon*( proc commandsToShapes( path: Path, closeSubpaths = false, pixelScale: float32 = 1.0 -): seq[seq[Vec2]] {.raises: [PixieError].} = +): seq[seq[Vec2]] = ## Converts SVG-like commands to sequences of vectors. var start, at: Vec2 @@ -999,7 +999,7 @@ proc commandsToShapes( proc shapesToSegments( shapes: seq[seq[Vec2]] -): seq[(Segment, int16)] {.raises: [].} = +): seq[(Segment, int16)] = ## Converts the shapes into a set of filtered segments with winding value. for shape in shapes: for segment in shape.segments: @@ -1014,7 +1014,7 @@ proc shapesToSegments( result.add((segment, winding)) -proc requiresAntiAliasing(segments: seq[(Segment, int16)]): bool {.raises: [].} = +proc requiresAntiAliasing(segments: seq[(Segment, int16)]): bool = ## Returns true if the fill requires antialiasing. template hasFractional(v: float32): bool = @@ -1029,13 +1029,13 @@ proc requiresAntiAliasing(segments: seq[(Segment, int16)]): bool {.raises: [].} # AA is required if all segments are not vertical or have fractional > 0 return true -proc transform(shapes: var seq[seq[Vec2]], transform: Mat3) {.raises: [].} = +proc transform(shapes: var seq[seq[Vec2]], transform: Mat3) = if transform != mat3(): for shape in shapes.mitems: for vec in shape.mitems: vec = transform * vec -proc computeBounds(segments: seq[(Segment, int16)]): Rect {.raises: [].} = +proc computeBounds(segments: seq[(Segment, int16)]): Rect = ## Compute the bounds of the segments. var xMin = float32.high @@ -1067,7 +1067,7 @@ proc computeBounds*( proc partitionSegments( segments: seq[(Segment, int16)], top, height: int -): Partitioning {.raises: [].} = +): Partitioning = ## Puts segments into the height partitions they intersect with. let maxPartitions = max(1, height div 10).uint32 @@ -1091,9 +1091,7 @@ proc partitionSegments( for i in atPartition .. toPartition: result.partitions[i].add((segment, winding)) -proc getIndexForY( - partitioning: Partitioning, y: int -): uint32 {.inline, raises: [].} = +proc getIndexForY(partitioning: Partitioning, y: int): uint32 {.inline.} = if partitioning.partitionHeight == 0 or partitioning.partitions.len == 1: 0.uint32 else: @@ -1104,7 +1102,7 @@ proc getIndexForY( proc insertionSort( a: var seq[(float32, int16)], lo, hi: int -) {.inline, raises: [].} = +) {.inline.} = for i in lo + 1 .. hi: var j = i - 1 @@ -1114,7 +1112,7 @@ proc insertionSort( dec j dec k -proc sort(a: var seq[(float32, int16)], inl, inr: int) {.raises: [].} = +proc sort(a: var seq[(float32, int16)], inl, inr: int) = ## Quicksort + insertion sort, in-place and faster than standard lib sort. let n = inr - inl + 1 if n < 32: @@ -1138,7 +1136,7 @@ proc sort(a: var seq[(float32, int16)], inl, inr: int) {.raises: [].} = proc shouldFill( windingRule: WindingRule, count: int -): bool {.inline, raises: [].} = +): bool {.inline.} = ## Should we fill based on the current winding rule and count? case windingRule: of wrNonZero: @@ -1152,7 +1150,7 @@ iterator walk( windingRule: WindingRule, y: int, size: Vec2 -): (float32, float32, int32) {.raises: [].} = +): (float32, float32, int32) = var prevAt: float32 count: int32 @@ -1184,7 +1182,7 @@ proc computeCoverages( aa: bool, partitioning: Partitioning, windingRule: WindingRule -) {.inline, raises: [].} = +) {.inline.} = let quality = if aa: 5 else: 1 # Must divide 255 cleanly (1, 3, 5, 15, 17, 51, 85) sampleCoverage = (255 div quality).uint8 @@ -1256,7 +1254,7 @@ proc computeCoverages( proc clearUnsafe( target: Image | Mask, startX, startY, toX, toY: int -) {.raises: [].} = +) = ## Clears data from [start, to). if startX == target.width or startY == target.height: return @@ -1274,7 +1272,7 @@ proc fillCoverage( startX, y: int, coverages: seq[uint8], blendMode: BlendMode -) {.raises: [PixieError].} = +) = var x = startX when defined(amd64) and not defined(pixieNoSimd): if blendMode.hasSimdBlender(): @@ -1361,7 +1359,7 @@ proc fillCoverage( startX, y: int, coverages: seq[uint8], blendMode: BlendMode -) {.raises: [PixieError].} = +) = var x = startX when defined(amd64) and not defined(pixieNoSimd): if blendMode.hasSimdMasker(): @@ -1404,7 +1402,7 @@ proc fillHits( numHits: int, windingRule: WindingRule, blendMode: BlendMode -) {.raises: [PixieError].} = +) = let blender = blendMode.blender() var filledTo: int for (prevAt, at, count) in hits.walk(numHits, windingRule, y, image.wh): @@ -1452,7 +1450,7 @@ proc fillHits( numHits: int, windingRule: WindingRule, blendMode: BlendMode -) {.raises: [PixieError].} = +) = let masker = blendMode.masker() var filledTo: int for (prevAt, at, count) in hits.walk(numHits, windingRule, y, mask.wh): @@ -1496,7 +1494,7 @@ proc fillShapes( color: SomeColor, windingRule: WindingRule, blendMode: BlendMode -) {.raises: [PixieError].} = +) = # Figure out the total bounds of all the shapes, # rasterize only within the total bounds let @@ -1554,7 +1552,7 @@ proc fillShapes( shapes: seq[seq[Vec2]], windingRule: WindingRule, blendMode: BlendMode -) {.raises: [PixieError].} = +) = # Figure out the total bounds of all the shapes, # rasterize only within the total bounds let @@ -1592,11 +1590,11 @@ proc fillShapes( mask.clearUnsafe(0, 0, 0, startY) mask.clearUnsafe(0, pathHeight, 0, mask.height) -proc miterLimitToAngle*(limit: float32): float32 {.inline, raises: [].} = +proc miterLimitToAngle*(limit: float32): float32 {.inline.} = ## Converts miter-limit-ratio to miter-limit-angle. arcsin(1 / limit) * 2 -proc angleToMiterLimit*(angle: float32): float32 {.inline, raises: [].} = +proc angleToMiterLimit*(angle: float32): float32 {.inline.} = ## Converts miter-limit-angle to miter-limit-ratio. 1 / sin(angle / 2) @@ -1607,7 +1605,7 @@ proc strokeShapes( lineJoin: LineJoin, miterLimit: float32, dashes: seq[float32] -): seq[seq[Vec2]] {.raises: [PixieError].} = +): seq[seq[Vec2]] = if strokeWidth <= 0: return @@ -1743,7 +1741,7 @@ proc strokeShapes( proc parseSomePath( path: SomePath, closeSubpaths: bool, pixelScale: float32 = 1.0 -): seq[seq[Vec2]] {.inline, raises: [PixieError].} = +): seq[seq[Vec2]] {.inline.} = ## Given SomePath, parse it in different ways. when type(path) is string: parsePath(path).commandsToShapes(closeSubpaths, pixelScale) @@ -1908,7 +1906,7 @@ proc overlaps( shapes: seq[seq[Vec2]], test: Vec2, windingRule: WindingRule -): bool {.raises: [].} = +): bool = var hits: seq[(float32, int16)] let From f00860a9cc5d0459506f14edf37a1f7ed0dcdb6e Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Wed, 18 Aug 2021 22:53:04 -0500 Subject: [PATCH 2/2] morepretty --- src/pixie/blends.nim | 64 +++++++++++++++++++++--------------------- src/pixie/contexts.nim | 2 +- src/pixie/images.nim | 8 +++--- src/pixie/paths.nim | 4 +-- 4 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 9d96b25..6a3d2e0 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -45,7 +45,7 @@ when defined(release): proc min(a, b: uint32): uint32 {.inline.} = if a < b: a else: b -proc alphaFix(backdrop, source, mixed: ColorRGBA): ColorRGBA = +proc alphaFix(backdrop, source, mixed: ColorRGBA): ColorRGBA = ## After mixing an image, adjust its alpha value to be correct. let sa = source.a.uint32 @@ -68,7 +68,7 @@ proc alphaFix(backdrop, source, mixed: ColorRGBA): ColorRGBA = result.b = (b div a div 255).uint8 result.a = a.uint8 -proc alphaFix(backdrop, source, mixed: Color): Color = +proc alphaFix(backdrop, source, mixed: Color): Color = ## After mixing an image, adjust its alpha value to be correct. result.a = (source.a + backdrop.a * (1.0 - source.a)) if result.a == 0: @@ -165,7 +165,7 @@ proc SetSat(C: Color, s: float32): Color {.inline.} = if satC > 0: result = (C - min([C.r, C.g, C.b])) * s / satC -proc blendNormal(backdrop, source: ColorRGBX): ColorRGBX = +proc blendNormal(backdrop, source: ColorRGBX): ColorRGBX = if backdrop.a == 0: return source if source.a == 255: @@ -179,7 +179,7 @@ proc blendNormal(backdrop, source: ColorRGBX): ColorRGBX = result.b = source.b + ((backdrop.b.uint32 * k) div 255).uint8 result.a = blendAlpha(backdrop.a, source.a) -proc blendDarken(backdrop, source: ColorRGBX): ColorRGBX = +proc blendDarken(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -193,7 +193,7 @@ proc blendDarken(backdrop, source: ColorRGBX): ColorRGBX = result.b = blend(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendMultiply(backdrop, source: ColorRGBX): ColorRGBX = +proc blendMultiply(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -218,7 +218,7 @@ proc blendMultiply(backdrop, source: ColorRGBX): ColorRGBX = # result = alphaFix(backdrop, source, result) # result = result.toPremultipliedAlpha() -proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX = +proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba() source = source.rgba() @@ -235,7 +235,7 @@ proc blendColorBurn(backdrop, source: ColorRGBX): ColorRGBX = blended.b = blend(backdrop.b, source.b) result = alphaFix(backdrop, source, blended).rgbx() -proc blendLighten(backdrop, source: ColorRGBX): ColorRGBX = +proc blendLighten(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -249,7 +249,7 @@ proc blendLighten(backdrop, source: ColorRGBX): ColorRGBX = result.b = blend(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendScreen(backdrop, source: ColorRGBX): ColorRGBX = +proc blendScreen(backdrop, source: ColorRGBX): ColorRGBX = result.r = screen(backdrop.r, source.r) result.g = screen(backdrop.g, source.g) result.b = screen(backdrop.b, source.b) @@ -265,7 +265,7 @@ proc blendScreen(backdrop, source: ColorRGBX): ColorRGBX = # result = alphaFix(backdrop, source, result) # result = result.toPremultipliedAlpha() -proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX = +proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba() source = source.rgba() @@ -282,13 +282,13 @@ proc blendColorDodge(backdrop, source: ColorRGBX): ColorRGBX = blended.b = blend(backdrop.b, source.b) result = alphaFix(backdrop, source, blended).rgbx() -proc blendOverlay(backdrop, source: ColorRGBX): ColorRGBX = +proc blendOverlay(backdrop, source: ColorRGBX): ColorRGBX = result.r = hardLight(source.r, source.a, backdrop.r, backdrop.a) result.g = hardLight(source.g, source.a, backdrop.g, backdrop.a) result.b = hardLight(source.b, source.a, backdrop.b, backdrop.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX = +proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX = # proc softLight(backdrop, source: int32): uint8 {.inline.} = # ## Pegtop # ( @@ -362,13 +362,13 @@ proc blendSoftLight(backdrop, source: ColorRGBX): ColorRGBX = result = rgba.rgbx() -proc blendHardLight(backdrop, source: ColorRGBX): ColorRGBX = +proc blendHardLight(backdrop, source: ColorRGBX): ColorRGBX = result.r = hardLight(backdrop.r, backdrop.a, source.r, source.a) result.g = hardLight(backdrop.g, backdrop.a, source.g, source.a) result.b = hardLight(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendDifference(backdrop, source: ColorRGBX): ColorRGBX = +proc blendDifference(backdrop, source: ColorRGBX): ColorRGBX = proc blend( backdropColor, backdropAlpha, sourceColor, sourceAlpha: uint8 ): uint8 {.inline.} = @@ -384,7 +384,7 @@ proc blendDifference(backdrop, source: ColorRGBX): ColorRGBX = result.b = blend(backdrop.b, backdrop.a, source.b, source.a) result.a = blendAlpha(backdrop.a, source.a) -proc blendExclusion(backdrop, source: ColorRGBX): ColorRGBX = +proc blendExclusion(backdrop, source: ColorRGBX): ColorRGBX = proc blend(backdrop, source: uint32): uint8 {.inline.} = let v = (backdrop + source).int32 - ((2 * backdrop * source) div 255).int32 max(0, v).uint8 @@ -393,56 +393,56 @@ proc blendExclusion(backdrop, source: ColorRGBX): ColorRGBX = result.b = blend(backdrop.b.uint32, source.b.uint32) result.a = blendAlpha(backdrop.a, source.a) -proc blendColor(backdrop, source: ColorRGBX): ColorRGBX = +proc blendColor(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(source, Lum(backdrop)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendLuminosity(backdrop, source: ColorRGBX): ColorRGBX = +proc blendLuminosity(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(backdrop, Lum(source)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendHue(backdrop, source: ColorRGBX): ColorRGBX = +proc blendHue(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(SetSat(source, Sat(backdrop)), Lum(backdrop)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendSaturation(backdrop, source: ColorRGBX): ColorRGBX = +proc blendSaturation(backdrop, source: ColorRGBX): ColorRGBX = let backdrop = backdrop.rgba().color source = source.rgba().color blended = SetLum(SetSat(backdrop, Sat(source)), Lum(backdrop)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendMask(backdrop, source: ColorRGBX): ColorRGBX = +proc blendMask(backdrop, source: ColorRGBX): ColorRGBX = let k = source.a.uint32 result.r = ((backdrop.r * k) div 255).uint8 result.g = ((backdrop.g * k) div 255).uint8 result.b = ((backdrop.b * k) div 255).uint8 result.a = ((backdrop.a * k) div 255).uint8 -proc blendSubtractMask(backdrop, source: ColorRGBX): ColorRGBX = +proc blendSubtractMask(backdrop, source: ColorRGBX): ColorRGBX = let a = (backdrop.a.uint32 * (255 - source.a)) div 255 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.a = a.uint8 -proc blendExcludeMask(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 = ((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 = +proc blendOverwrite(backdrop, source: ColorRGBX): ColorRGBX = source # proc blendWhite(backdrop, source: ColorRGBX): ColorRGBX = @@ -475,21 +475,21 @@ proc blender*(blendMode: BlendMode): Blender {.raises: [].} = of bmSubtractMask: blendSubtractMask of bmExcludeMask: blendExcludeMask -proc maskNormal(backdrop, source: uint8): uint8 = +proc maskNormal(backdrop, source: uint8): uint8 = ## Blending masks blendAlpha(backdrop, source) -proc maskMask(backdrop, source: uint8): uint8 = +proc maskMask(backdrop, source: uint8): uint8 = ## Masking masks ((backdrop.uint32 * source) div 255).uint8 -proc maskSubtract(backdrop, source: uint8): uint8 = +proc maskSubtract(backdrop, source: uint8): uint8 = ((backdrop.uint32 * (255 - source)) div 255).uint8 -proc maskExclude(backdrop, source: uint8): uint8 = +proc maskExclude(backdrop, source: uint8): uint8 = max(backdrop, source) - min(backdrop, source) -proc maskOverwrite(backdrop, source: uint8): uint8 = +proc maskOverwrite(backdrop, source: uint8): uint8 = source proc masker*(blendMode: BlendMode): Masker {.raises: [PixieError].} = @@ -512,7 +512,7 @@ when defined(amd64) and not defined(pixieNoSimd): MaskerSimd* = proc(blackdrop, source: M128i): M128i {.raises: [].} ## Function signature returned by maskerSimd. - proc blendNormalSimd(backdrop, source: M128i): M128i = + proc blendNormalSimd(backdrop, source: M128i): M128i = let alphaMask = mm_set1_epi32(cast[int32](0xff000000)) oddMask = mm_set1_epi16(cast[int16](0xff00)) @@ -541,7 +541,7 @@ when defined(amd64) and not defined(pixieNoSimd): mm_or_si128(backdropEven, mm_slli_epi16(backdropOdd, 8)) ) - proc blendMaskSimd(backdrop, source: M128i): M128i = + proc blendMaskSimd(backdrop, source: M128i): M128i = let alphaMask = mm_set1_epi32(cast[int32](0xff000000)) oddMask = mm_set1_epi16(cast[int16](0xff00)) @@ -562,7 +562,7 @@ when defined(amd64) and not defined(pixieNoSimd): mm_or_si128(backdropEven, mm_slli_epi16(backdropOdd, 8)) - proc blendOverwriteSimd(backdrop, source: M128i): M128i = + proc blendOverwriteSimd(backdrop, source: M128i): M128i = source proc blenderSimd*(blendMode: BlendMode): BlenderSimd {.raises: [PixieError].} = @@ -578,7 +578,7 @@ when defined(amd64) and not defined(pixieNoSimd): ## Is there a blend function for a given blend mode with SIMD support? blendMode in {bmNormal, bmMask, bmOverwrite} - proc maskNormalSimd(backdrop, source: M128i): M128i = + proc maskNormalSimd(backdrop, source: M128i): M128i = ## Blending masks let oddMask = mm_set1_epi16(cast[int16](0xff00)) @@ -615,7 +615,7 @@ when defined(amd64) and not defined(pixieNoSimd): mm_or_si128(blendedEven, mm_slli_epi16(blendedOdd, 8)) - proc maskMaskSimd(backdrop, source: M128i): M128i = + proc maskMaskSimd(backdrop, source: M128i): M128i = let oddMask = mm_set1_epi16(cast[int16](0xff00)) div255 = mm_set1_epi16(cast[int16](0x8081)) diff --git a/src/pixie/contexts.nim b/src/pixie/contexts.nim index 4d8fc55..e16ed6e 100644 --- a/src/pixie/contexts.nim +++ b/src/pixie/contexts.nim @@ -495,7 +495,7 @@ proc getLineDash*(ctx: Context): seq[float32] {.inline, raises: [].} = proc setLineDash*(ctx: Context, lineDash: seq[float32]) {.inline, raises: [].} = ctx.lineDash = lineDash -proc getTransform*(ctx: Context): Mat3 {.inline, raises: []} = +proc getTransform*(ctx: Context): Mat3 {.inline, raises: [].} = ## Retrieves the current transform matrix being applied to the context. ctx.mat diff --git a/src/pixie/images.nim b/src/pixie/images.nim index e71b67e..d5a777a 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -884,10 +884,10 @@ proc draw*( proc drawTiled*( dst, src: Image, mat: Mat3, blendMode = bmNormal -) {.raises: [PixieError]} = +) {.raises: [PixieError].} = dst.drawCorrect(src, mat, true, blendMode) -proc resize*(srcImage: Image, width, height: int): Image {.raises: [PixieError]} = +proc resize*(srcImage: Image, width, height: int): Image {.raises: [PixieError].} = ## Resize an image to a given height and width. if width == srcImage.width and height == srcImage.height: result = srcImage.copy() @@ -904,7 +904,7 @@ proc resize*(srcImage: Image, width, height: int): Image {.raises: [PixieError]} proc shadow*( image: Image, offset: Vec2, spread, blur: float32, color: SomeColor -): Image {.raises: [PixieError]} = +): Image {.raises: [PixieError].} = ## Create a shadow of the image with the offset, spread and blur. let mask = image.newMask() @@ -916,7 +916,7 @@ proc shadow*( result.fill(color) result.draw(shifted, blendMode = bmMask) -proc superImage*(image: Image, x, y, w, h: int): Image {.raises: [PixieError]} = +proc superImage*(image: Image, x, y, w, h: int): Image {.raises: [PixieError].} = ## Either cuts a sub image or returns a super image with padded transparency. if x >= 0 and x + w <= image.width and y >= 0 and y + h <= image.height: result = image.subImage(x, y, w, h) diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index d10be81..058556f 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -1252,9 +1252,7 @@ proc computeCoverages( for j in i ..< fillStart + fillLen: coverages[j - startX] += sampleCoverage -proc clearUnsafe( - target: Image | Mask, startX, startY, toX, toY: int -) = +proc clearUnsafe(target: Image | Mask, startX, startY, toX, toY: int) = ## Clears data from [start, to). if startX == target.width or startY == target.height: return