From ff1e6bd12d1c71c85637f073067576573ec35056 Mon Sep 17 00:00:00 2001
From: Ryan Oldenburg <ryan@guzba.com>
Date: Sat, 11 Dec 2021 17:57:02 -0600
Subject: [PATCH 1/3] image.unsafe[x, y]

---
 src/pixie/images.nim | 85 ++++++++++++++++++++++----------------------
 src/pixie/paints.nim | 10 +++---
 src/pixie/paths.nim  | 12 +++----
 3 files changed, 54 insertions(+), 53 deletions(-)

diff --git a/src/pixie/images.nim b/src/pixie/images.nim
index 6945fb4..8dba1b7 100644
--- a/src/pixie/images.nim
+++ b/src/pixie/images.nim
@@ -11,6 +11,9 @@ type
     width*, height*: int
     data*: seq[ColorRGBX]
 
+  UnsafeImage = object
+    image: Image
+
 when defined(release):
   {.push checks: off.}
 
@@ -58,31 +61,32 @@ proc inside*(image: Image, x, y: int): bool {.inline, raises: [].} =
 proc dataIndex*(image: Image, x, y: int): int {.inline, raises: [].} =
   image.width * y + x
 
-proc getRgbaUnsafe*(image: Image, x, y: int): ColorRGBX {.inline, raises: [].} =
+template unsafe*(src: Image): UnsafeImage =
+  UnsafeImage(image: src)
+
+template `[]`*(view: UnsafeImage, x, y: int): ColorRGBX =
   ## Gets a color from (x, y) coordinates.
   ## * No bounds checking *
   ## Make sure that x, y are in bounds.
   ## Failure in the assumptions will cause unsafe memory reads.
-  image.data[image.dataIndex(x, y)]
+  view.image.data[view.image.dataIndex(x, y)]
 
-proc setRgbaUnsafe*(
-  image: Image, x, y: int, color: ColorRGBX
-) {.inline, raises: [].} =
+template `[]=`*(view: UnsafeImage, x, y: int, color: ColorRGBX) =
   ## Sets a color from (x, y) coordinates.
   ## * No bounds checking *
   ## Make sure that x, y are in bounds.
   ## Failure in the assumptions will cause unsafe memory writes.
-  image.data[image.dataIndex(x, y)] = color
+  view.image.data[view.image.dataIndex(x, y)] = color
 
 proc `[]`*(image: Image, x, y: int): ColorRGBX {.inline, raises: [].} =
   ## Gets a pixel at (x, y) or returns transparent black if outside of bounds.
   if image.inside(x, y):
-    return image.getRgbaUnsafe(x, y)
+    return image.unsafe[x, y]
 
 proc `[]=`*(image: Image, x, y: int, color: SomeColor) {.inline, raises: [].} =
   ## Sets a pixel at (x, y) or does nothing if outside of bounds.
   if image.inside(x, y):
-    image.setRgbaUnsafe(x, y, color.asRgbx())
+    image.unsafe[x, y] = color.asRgbx()
 
 proc getColor*(image: Image, x, y: int): Color {.inline, raises: [].} =
   ## Gets a color at (x, y) or returns transparent black if outside of bounds.
@@ -239,7 +243,7 @@ proc diff*(master, image: Image): (float32, Image) {.raises: [PixieError].} =
       c.g = diff.clamp(0, 255).uint8
       c.b = (-diff).clamp(0, 255).uint8
       c.a = 255
-      diffImage.setRgbaUnsafe(x, y, c)
+      diffImage.unsafe[x, y] = c
       diffScore += abs(m.r.int - u.r.int) +
         abs(m.g.int - u.g.int) +
         abs(m.b.int - u.b.int) +
@@ -316,10 +320,10 @@ proc minifyBy2*(image: Image, power = 1): Image {.raises: [PixieError].} =
 
       for x in x ..< resultEvenWidth:
         let
-          a = src.getRgbaUnsafe(x * 2 + 0, y * 2 + 0)
-          b = src.getRgbaUnsafe(x * 2 + 1, y * 2 + 0)
-          c = src.getRgbaUnsafe(x * 2 + 1, y * 2 + 1)
-          d = src.getRgbaUnsafe(x * 2 + 0, y * 2 + 1)
+          a = src.unsafe[x * 2 + 0, y * 2 + 0]
+          b = src.unsafe[x * 2 + 1, y * 2 + 0]
+          c = src.unsafe[x * 2 + 1, y * 2 + 1]
+          d = src.unsafe[x * 2 + 0, y * 2 + 1]
           rgba = rgbx(
             ((a.r.uint32 + b.r + c.r + d.r) div 4).uint8,
             ((a.g.uint32 + b.g + c.g + d.g) div 4).uint8,
@@ -327,31 +331,28 @@ proc minifyBy2*(image: Image, power = 1): Image {.raises: [PixieError].} =
             ((a.a.uint32 + b.a + c.a + d.a) div 4).uint8
           )
 
-        result.setRgbaUnsafe(x, y, rgba)
+        result.unsafe[x, y] = rgba
 
       if srcWidthIsOdd:
         let rgbx = mix(
-          src.getRgbaUnsafe(src.width - 1, y * 2 + 0),
-          src.getRgbaUnsafe(src.width - 1, y * 2 + 1),
+          src.unsafe[src.width - 1, y * 2 + 0],
+          src.unsafe[src.width - 1, y * 2 + 1],
           0.5
         ) * 0.5
-        result.setRgbaUnsafe(result.width - 1, y, rgbx)
+        result.unsafe[result.width - 1, y] = rgbx
 
     if srcHeightIsOdd:
       for x in 0 ..< resultEvenWidth:
         let rgbx = mix(
-          src.getRgbaUnsafe(x * 2 + 0, src.height - 1),
-          src.getRgbaUnsafe(x * 2 + 1, src.height - 1),
+          src.unsafe[x * 2 + 0, src.height - 1],
+          src.unsafe[x * 2 + 1, src.height - 1],
           0.5
         ) * 0.5
-        result.setRgbaUnsafe(x, result.height - 1, rgbx)
+        result.unsafe[x, result.height - 1] = rgbx
 
       if srcWidthIsOdd:
-        result.setRgbaUnsafe(
-          result.width - 1,
-          result.height - 1,
-          src.getRgbaUnsafe(src.width - 1, src.height - 1) * 0.25
-        )
+        result.unsafe[result.width - 1, result.height - 1] =
+          src.unsafe[src.width - 1, src.height - 1] * 0.25
 
     # Set src as this result for if we do another power
     src = result
@@ -384,7 +385,7 @@ proc magnifyBy2*(image: Image, power = 1): Image {.raises: [PixieError].} =
           x += 2
     for _ in x ..< image.width:
       let
-        rgbx = image.getRgbaUnsafe(x, y)
+        rgbx = image.unsafe[x, y]
         resultIdx = result.dataIndex(x * scale, y * scale)
       for i in 0 ..< scale:
         result.data[resultIdx + i] = rgbx
@@ -547,10 +548,10 @@ proc blur*(
       for xx in x - radius ..< min(x + radius, 0):
         values += outOfBounds * kernel[xx - x + radius]
       for xx in max(x - radius, 0) .. min(x + radius, image.width - 1):
-        values += image.getRgbaUnsafe(xx, y) * kernel[xx - x + radius]
+        values += image.unsafe[xx, y] * kernel[xx - x + radius]
       for xx in max(x - radius, image.width) .. x + radius:
         values += outOfBounds * kernel[xx - x + radius]
-      blurX.setRgbaUnsafe(y, x, rgbx(values))
+      blurX.unsafe[y, x] = rgbx(values)
 
   # Blur in the Y direction.
   for y in 0 ..< image.height:
@@ -559,10 +560,10 @@ proc blur*(
       for yy in y - radius ..< min(y + radius, 0):
         values += outOfBounds * kernel[yy - y + radius]
       for yy in max(y - radius, 0) .. min(y + radius, image.height - 1):
-        values += blurX.getRgbaUnsafe(yy, x) * kernel[yy - y + radius]
+        values += blurX.unsafe[yy, x] * kernel[yy - y + radius]
       for yy in max(y - radius, image.height) .. y + radius:
         values += outOfBounds * kernel[yy - y + radius]
-      image.setRgbaUnsafe(x, y, rgbx(values))
+      image.unsafe[x, y] = rgbx(values)
 
 proc newMask*(image: Image): Mask {.raises: [PixieError].} =
   ## Returns a new mask using the alpha values of the image.
@@ -611,10 +612,10 @@ proc getRgbaSmooth*(
 
   var x0y0, x1y0, x0y1, x1y1: ColorRGBX
   if wrapped:
-    x0y0 = image.getRgbaUnsafe(x0 mod image.width, y0 mod image.height)
-    x1y0 = image.getRgbaUnsafe(x1 mod image.width, y0 mod image.height)
-    x0y1 = image.getRgbaUnsafe(x0 mod image.width, y1 mod image.height)
-    x1y1 = image.getRgbaUnsafe(x1 mod image.width, y1 mod image.height)
+    x0y0 = image.unsafe[x0 mod image.width, y0 mod image.height]
+    x1y0 = image.unsafe[x1 mod image.width, y0 mod image.height]
+    x0y1 = image.unsafe[x0 mod image.width, y1 mod image.height]
+    x1y1 = image.unsafe[x1 mod image.width, y1 mod image.height]
   else:
     x0y0 = image[x0, y0]
     x1y0 = image[x1, y0]
@@ -677,7 +678,7 @@ proc drawCorrect(
         yFloat = samplePos.y - h
 
       when type(a) is Image:
-        let backdrop = a.getRgbaUnsafe(x, y)
+        let backdrop = a.unsafe[x, y]
         when type(b) is Image:
           let
             sample = b.getRgbaSmooth(xFloat, yFloat, tiled)
@@ -686,7 +687,7 @@ proc drawCorrect(
           let
             sample = b.getValueSmooth(xFloat, yFloat)
             blended = blender(backdrop, rgbx(0, 0, 0, sample))
-        a.setRgbaUnsafe(x, y, blended)
+        a.unsafe[x, y] = blended
       else: # a is a Mask
         let backdrop = a.getValueUnsafe(x, y)
         when type(b) is Image:
@@ -791,7 +792,7 @@ proc drawUber(
 
       for x in xMin ..< xMax:
         when type(a) is Image:
-          let backdrop = a.getRgbaUnsafe(x, y)
+          let backdrop = a.unsafe[x, y]
           when type(b) is Image:
             let
               sample = b.getRgbaSmooth(srcPos.x, srcPos.y)
@@ -800,7 +801,7 @@ proc drawUber(
             let
               sample = b.getValueSmooth(srcPos.x, srcPos.y)
               blended = blender(backdrop, rgbx(0, 0, 0, sample))
-          a.setRgbaUnsafe(x, y, blended)
+          a.unsafe[x, y] = blended
         else: # a is a Mask
           let backdrop = a.getValueUnsafe(x, y)
           when type(b) is Image:
@@ -892,20 +893,20 @@ proc drawUber(
         let samplePos = ivec2((srcPos.x - h).int32, (srcPos.y - h).int32)
 
         when type(a) is Image:
-          let backdrop = a.getRgbaUnsafe(x, y)
+          let backdrop = a.unsafe[x, y]
           when type(b) is Image:
             let
-              sample = b.getRgbaUnsafe(samplePos.x, samplePos.y)
+              sample = b.unsafe[samplePos.x, samplePos.y]
               blended = blender(backdrop, sample)
           else: # b is a Mask
             let
               sample = b.getValueUnsafe(samplePos.x, samplePos.y)
               blended = blender(backdrop, rgbx(0, 0, 0, sample))
-          a.setRgbaUnsafe(x, y, blended)
+          a.unsafe[x, y] = blended
         else: # a is a Mask
           let backdrop = a.getValueUnsafe(x, y)
           when type(b) is Image:
-            let sample = b.getRgbaUnsafe(samplePos.x, samplePos.y).a
+            let sample = b.unsafe[samplePos.x, samplePos.y].a
           else: # b is a Mask
             let sample = b.getValueUnsafe(samplePos.x, samplePos.y)
           a.setValueUnsafe(x, y, masker(backdrop, sample))
diff --git a/src/pixie/paints.nim b/src/pixie/paints.nim
index 9b9bbaa..ba81df6 100644
--- a/src/pixie/paints.nim
+++ b/src/pixie/paints.nim
@@ -142,7 +142,7 @@ proc fillGradientLinear(image: Image, paint: Paint) =
         t = toLineSpace(at, to, xy)
         rgbx = paint.gradientColor(t)
       for y in 0 ..< image.height:
-        image.setRgbaUnsafe(x, y, rgbx)
+        image.unsafe[x, y] = rgbx
       inc x
 
   elif at.x == to.x: # Vertical gradient
@@ -158,7 +158,7 @@ proc fillGradientLinear(image: Image, paint: Paint) =
           mm_storeu_si128(image.data[image.dataIndex(x, y)].addr, colorVec)
           x += 4
       for x in x ..< image.width:
-        image.setRgbaUnsafe(x, y, rgbx)
+        image.unsafe[x, y] = rgbx
 
   else:
     for y in 0 ..< image.height:
@@ -166,7 +166,7 @@ proc fillGradientLinear(image: Image, paint: Paint) =
         let
           xy = vec2(x.float32, y.float32)
           t = toLineSpace(at, to, xy)
-        image.setRgbaUnsafe(x, y, paint.gradientColor(t))
+        image.unsafe[x, y] = paint.gradientColor(t)
 
 proc fillGradientRadial(image: Image, paint: Paint) =
   ## Fills a radial gradient.
@@ -197,7 +197,7 @@ proc fillGradientRadial(image: Image, paint: Paint) =
       let
         xy = vec2(x.float32, y.float32)
         t = (mat * xy).length()
-      image.setRgbaUnsafe(x, y, paint.gradientColor(t))
+      image.unsafe[x, y] = paint.gradientColor(t)
 
 proc fillGradientAngular(image: Image, paint: Paint) =
   ## Fills an angular gradient.
@@ -223,7 +223,7 @@ proc fillGradientAngular(image: Image, paint: Paint) =
         xy = vec2(x.float32, y.float32)
         angle = normalize(xy - center).angle()
         t = (angle + gradientAngle + f32PI / 2).fixAngle() / 2 / f32PI + 0.5.float32
-      image.setRgbaUnsafe(x, y, paint.gradientColor(t))
+      image.unsafe[x, y] = paint.gradientColor(t)
 
 proc fillGradient*(image: Image, paint: Paint) {.raises: [PixieError].} =
   ## Fills with the Paint gradient.
diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim
index acca6bb..67d9a2f 100644
--- a/src/pixie/paths.nim
+++ b/src/pixie/paths.nim
@@ -1400,7 +1400,7 @@ proc fillCoverage(
     if coverage != 0 or blendMode == bmExcludeMask:
       if blendMode == bmNormal and coverage == 255 and rgbx.a == 255:
         # Skip blending
-        image.setRgbaUnsafe(x, y, rgbx)
+        image.unsafe[x, y] = rgbx
       else:
         var source = rgbx
         if coverage != 255:
@@ -1408,10 +1408,10 @@ proc fillCoverage(
           source.g = ((source.g.uint32 * coverage) div 255).uint8
           source.b = ((source.b.uint32 * coverage) div 255).uint8
           source.a = ((source.a.uint32 * coverage) div 255).uint8
-        let backdrop = image.getRgbaUnsafe(x, y)
-        image.setRgbaUnsafe(x, y, blender(backdrop, source))
+        let backdrop = image.unsafe[x, y]
+        image.unsafe[x, y] = blender(backdrop, source)
     elif blendMode == bmMask:
-      image.setRgbaUnsafe(x, y, rgbx(0, 0, 0, 0))
+      image.unsafe[x, y] = rgbx(0, 0, 0, 0)
     inc x
 
   if blendMode == bmMask:
@@ -1515,8 +1515,8 @@ proc fillHits(
             x += 4
 
     for x in x ..< fillStart + fillLen:
-      let backdrop = image.getRgbaUnsafe(x, y)
-      image.setRgbaUnsafe(x, y, blender(backdrop, rgbx))
+      let backdrop = image.unsafe[x, y]
+      image.unsafe[x, y] = blender(backdrop, rgbx)
 
   if blendMode == bmMask:
     image.clearUnsafe(0, y, startX, y)

From 18a81b3d0e55068c9e3e13e7df9a1d4ee332890f Mon Sep 17 00:00:00 2001
From: Ryan Oldenburg <ryan@guzba.com>
Date: Sat, 11 Dec 2021 18:04:01 -0600
Subject: [PATCH 2/3] mask.unsafe[x, y]

---
 src/pixie/images.nim | 14 ++++++------
 src/pixie/masks.nim  | 54 +++++++++++++++++++++-----------------------
 src/pixie/paths.nim  | 10 ++++----
 3 files changed, 38 insertions(+), 40 deletions(-)

diff --git a/src/pixie/images.nim b/src/pixie/images.nim
index 8dba1b7..a863331 100644
--- a/src/pixie/images.nim
+++ b/src/pixie/images.nim
@@ -689,7 +689,7 @@ proc drawCorrect(
             blended = blender(backdrop, rgbx(0, 0, 0, sample))
         a.unsafe[x, y] = blended
       else: # a is a Mask
-        let backdrop = a.getValueUnsafe(x, y)
+        let backdrop = a.unsafe[x, y]
         when type(b) is Image:
           let sample = b.getRgbaSmooth(xFloat, yFloat, tiled).a
         else: # b is a Mask
@@ -803,12 +803,12 @@ proc drawUber(
               blended = blender(backdrop, rgbx(0, 0, 0, sample))
           a.unsafe[x, y] = blended
         else: # a is a Mask
-          let backdrop = a.getValueUnsafe(x, y)
+          let backdrop = a.unsafe[x, y]
           when type(b) is Image:
             let sample = b.getRgbaSmooth(srcPos.x, srcPos.y).a
           else: # b is a Mask
             let sample = b.getValueSmooth(srcPos.x, srcPos.y)
-          a.setValueUnsafe(x, y, masker(backdrop, sample))
+          a.unsafe[x, y] = masker(backdrop, sample)
 
         srcPos += dx
 
@@ -900,16 +900,16 @@ proc drawUber(
               blended = blender(backdrop, sample)
           else: # b is a Mask
             let
-              sample = b.getValueUnsafe(samplePos.x, samplePos.y)
+              sample = b.unsafe[samplePos.x, samplePos.y]
               blended = blender(backdrop, rgbx(0, 0, 0, sample))
           a.unsafe[x, y] = blended
         else: # a is a Mask
-          let backdrop = a.getValueUnsafe(x, y)
+          let backdrop = a.unsafe[x, y]
           when type(b) is Image:
             let sample = b.unsafe[samplePos.x, samplePos.y].a
           else: # b is a Mask
-            let sample = b.getValueUnsafe(samplePos.x, samplePos.y)
-          a.setValueUnsafe(x, y, masker(backdrop, sample))
+            let sample = b.unsafe[samplePos.x, samplePos.y]
+          a.unsafe[x, y] = masker(backdrop, sample)
 
         srcPos += dx
 
diff --git a/src/pixie/masks.nim b/src/pixie/masks.nim
index 525ee15..0076a9a 100644
--- a/src/pixie/masks.nim
+++ b/src/pixie/masks.nim
@@ -9,6 +9,9 @@ type
     width*, height*: int
     data*: seq[uint8]
 
+  UnsafeMask = object
+    mask: Mask
+
 when defined(release):
   {.push checks: off.}
 
@@ -38,29 +41,24 @@ proc inside*(mask: Mask, x, y: int): bool {.inline, raises: [].} =
 proc dataIndex*(mask: Mask, x, y: int): int {.inline, raises: [].} =
   mask.width * y + x
 
-proc getValueUnsafe*(mask: Mask, x, y: int): uint8 {.inline, raises: [].} =
-  ## Gets a value from (x, y) coordinates.
-  ## * No bounds checking *
-  ## Make sure that x, y are in bounds.
-  ## Failure in the assumptions will case unsafe memory reads.
-  result = mask.data[mask.dataIndex(x, y)]
+template unsafe*(src: Mask): UnsafeMask =
+  UnsafeMask(mask: src)
 
-proc setValueUnsafe*(mask: Mask, x, y: int, value: uint8) {.inline, raises: [].} =
-  ## Sets a value from (x, y) coordinates.
-  ## * No bounds checking *
-  ## Make sure that x, y are in bounds.
-  ## Failure in the assumptions will case unsafe memory writes.
-  mask.data[mask.dataIndex(x, y)] = value
+template `[]`*(view: UnsafeMask, x, y: int): uint8 =
+  view.mask.data[view.mask.dataIndex(x, y)]
+
+template `[]=`*(view: UnsafeMask, x, y: int, color: uint8) =
+  view.mask.data[view.mask.dataIndex(x, y)] = color
 
 proc `[]`*(mask: Mask, x, y: int): uint8 {.inline, raises: [].} =
   ## Gets a value at (x, y) or returns transparent black if outside of bounds.
   if mask.inside(x, y):
-    return mask.getValueUnsafe(x, y)
+    return mask.unsafe[x, y]
 
 proc `[]=`*(mask: Mask, x, y: int, value: uint8) {.inline, raises: [].} =
   ## Sets a value at (x, y) or does nothing if outside of bounds.
   if mask.inside(x, y):
-    mask.setValueUnsafe(x, y, value)
+    mask.unsafe[x, y] = value
 
 proc getValue*(mask: Mask, x, y: int): uint8 {.inline, raises: [].} =
   ## Gets a value at (x, y) or returns transparent black if outside of bounds.
@@ -144,11 +142,11 @@ proc minifyBy2*(mask: Mask, power = 1): Mask {.raises: [PixieError].} =
 
       for x in x ..< result.width:
         let value =
-          src.getValueUnsafe(x * 2 + 0, y * 2 + 0).uint32 +
-          src.getValueUnsafe(x * 2 + 1, y * 2 + 0) +
-          src.getValueUnsafe(x * 2 + 1, y * 2 + 1) +
-          src.getValueUnsafe(x * 2 + 0, y * 2 + 1)
-        result.setValueUnsafe(x, y, (value div 4).uint8)
+          src.unsafe[x * 2 + 0, y * 2 + 0].uint32 +
+          src.unsafe[x * 2 + 1, y * 2 + 0] +
+          src.unsafe[x * 2 + 1, y * 2 + 1] +
+          src.unsafe[x * 2 + 0, y * 2 + 1]
+        result.unsafe[x, y] = (value div 4).uint8
 
     # Set src as this result for if we do another power
     src = result
@@ -163,7 +161,7 @@ proc magnifyBy2*(mask: Mask, power = 1): Mask {.raises: [PixieError].} =
   for y in 0 ..< result.height:
     for x in 0 ..< mask.width:
       let
-        value = mask.getValueUnsafe(x, y div scale)
+        value = mask.unsafe[x, y div scale]
         scaledX = x * scale
         idx = result.dataIndex(scaledX, y)
       for i in 0 ..< scale:
@@ -222,24 +220,24 @@ proc spread*(mask: Mask, spread: float32) {.raises: [PixieError].} =
     for x in 0 ..< mask.width:
       var maxValue: uint8
       for xx in max(x - spread, 0) .. min(x + spread, mask.width - 1):
-        let value = mask.getValueUnsafe(xx, y)
+        let value = mask.unsafe[xx, y]
         if value > maxValue:
           maxValue = value
         if maxValue == 255:
           break
-      spreadX.setValueUnsafe(y, x, maxValue)
+      spreadX.unsafe[y, x] = maxValue
 
   # Spread in the Y direction and modify mask.
   for y in 0 ..< mask.height:
     for x in 0 ..< mask.width:
       var maxValue: uint8
       for yy in max(y - spread, 0) .. min(y + spread, mask.height - 1):
-        let value = spreadX.getValueUnsafe(yy, x)
+        let value = spreadX.unsafe[yy, x]
         if value > maxValue:
           maxValue = value
         if maxValue == 255:
           break
-      mask.setValueUnsafe(x, y, maxValue)
+      mask.unsafe[x, y] = maxValue
 
 proc ceil*(mask: Mask) {.raises: [].} =
   ## A value of 0 stays 0. Anything else turns into 255.
@@ -277,10 +275,10 @@ proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) {.raises: [Pixie
       for xx in x - radius ..< min(x + radius, 0):
         value += outOfBounds * kernel[xx - x + radius].uint32
       for xx in max(x - radius, 0) .. min(x + radius, mask.width - 1):
-        value += mask.getValueUnsafe(xx, y) * kernel[xx - x + radius].uint32
+        value += mask.unsafe[xx, y] * kernel[xx - x + radius].uint32
       for xx in max(x - radius, mask.width) .. x + radius:
         value += outOfBounds * kernel[xx - x + radius].uint32
-      blurX.setValueUnsafe(y, x, (value div 256 div 255).uint8)
+      blurX.unsafe[y, x] = (value div 256 div 255).uint8
 
   # Blur in the Y direction and modify image.
   for y in 0 ..< mask.height:
@@ -289,10 +287,10 @@ proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) {.raises: [Pixie
       for yy in y - radius ..< min(y + radius, 0):
         value += outOfBounds * kernel[yy - y + radius].uint32
       for yy in max(y - radius, 0) .. min(y + radius, mask.height - 1):
-        value += blurX.getValueUnsafe(yy, x) * kernel[yy - y + radius].uint32
+        value += blurX.unsafe[yy, x] * kernel[yy - y + radius].uint32
       for yy in max(y - radius, mask.height) .. y + radius:
         value += outOfBounds * kernel[yy - y + radius].uint32
-      mask.setValueUnsafe(x, y, (value div 256 div 255).uint8)
+      mask.unsafe[x, y] = (value div 256 div 255).uint8
 
 when defined(release):
   {.pop.}
diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim
index 67d9a2f..5af66e1 100644
--- a/src/pixie/paths.nim
+++ b/src/pixie/paths.nim
@@ -1449,10 +1449,10 @@ proc fillCoverage(
   while x < startX + coverages.len:
     let coverage = coverages[x - startX]
     if coverage != 0 or blendMode == bmExcludeMask:
-      let backdrop = mask.getValueUnsafe(x, y)
-      mask.setValueUnsafe(x, y, masker(backdrop, coverage))
+      let backdrop = mask.unsafe[x, y]
+      mask.unsafe[x, y] = masker(backdrop, coverage)
     elif blendMode == bmMask:
-      mask.setValueUnsafe(x, y, 0)
+      mask.unsafe[x, y] = 0
     inc x
 
   if blendMode == bmMask:
@@ -1564,8 +1564,8 @@ proc fillHits(
           x += 16
 
     for x in x ..< fillStart + fillLen:
-      let backdrop = mask.getValueUnsafe(x, y)
-      mask.setValueUnsafe(x, y, masker(backdrop, 255))
+      let backdrop = mask.unsafe[x, y]
+      mask.unsafe[x, y] = masker(backdrop, 255)
 
   if blendMode == bmMask:
     mask.clearUnsafe(0, y, startX, y)

From 2c2e35bff5b3e94702e07d35898dcd8be24fb193 Mon Sep 17 00:00:00 2001
From: Ryan Oldenburg <ryan@guzba.com>
Date: Sat, 11 Dec 2021 18:06:11 -0600
Subject: [PATCH 3/3] comments back

---
 src/pixie/masks.nim | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/pixie/masks.nim b/src/pixie/masks.nim
index 0076a9a..affa6e3 100644
--- a/src/pixie/masks.nim
+++ b/src/pixie/masks.nim
@@ -45,9 +45,17 @@ template unsafe*(src: Mask): UnsafeMask =
   UnsafeMask(mask: src)
 
 template `[]`*(view: UnsafeMask, x, y: int): uint8 =
+  ## Gets a value from (x, y) coordinates.
+  ## * No bounds checking *
+  ## Make sure that x, y are in bounds.
+  ## Failure in the assumptions will case unsafe memory reads.
   view.mask.data[view.mask.dataIndex(x, y)]
 
 template `[]=`*(view: UnsafeMask, x, y: int, color: uint8) =
+  ## Sets a value from (x, y) coordinates.
+  ## * No bounds checking *
+  ## Make sure that x, y are in bounds.
+  ## Failure in the assumptions will case unsafe memory writes.
   view.mask.data[view.mask.dataIndex(x, y)] = color
 
 proc `[]`*(mask: Mask, x, y: int): uint8 {.inline, raises: [].} =