diff --git a/src/pixie/images.nim b/src/pixie/images.nim index c01e8a4..7ca2b4f 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -6,11 +6,6 @@ type width*, height*: int data*: seq[ColorRGBA] - Mask* = ref object - ## Main image object that holds the mask data. - width*, height*: int - data*: seq[uint8] - proc newImage*(width, height: int): Image = ## Creates a new image with appropriate dimensions. result = Image() diff --git a/src/pixie/masks.nim b/src/pixie/masks.nim new file mode 100644 index 0000000..d9119b5 --- /dev/null +++ b/src/pixie/masks.nim @@ -0,0 +1,55 @@ + +type + Mask* = ref object + ## Main mask object that holds the mask data. + width*, height*: int + data*: seq[uint8] + +proc newMask*(width, height: int): Mask = + ## Creates a new mask with appropriate dimensions. + result = Mask() + result.width = width + result.height = height + result.data = newSeq[uint8](width * height) + +proc inside*(mask: Mask, x, y: int): bool {.inline.} = + ## Returns true if (x, y) is inside the mask. + x >= 0 and x < mask.width and y >= 0 and y < mask.height + +proc copy*(mask: Mask): Mask = + ## Copies an mask creating a new mask. + result = newMask(mask.width, mask.height) + result.data = mask.data + +proc `$`*(mask: Mask): string = + ## Display the mask size and channels. + "" + +proc getRgbaUnsafe*(mask: Mask, x, y: int): uint8 {.inline.} = + ## Gets a alpha 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.width * y + x] + +proc `[]`*(mask: Mask, x, y: int): uint8 {.inline.} = + ## Gets a pixel at (x, y) or returns transparent black if outside of bounds. + if mask.inside(x, y): + return mask.getRgbaUnsafe(x, y) + +proc setRgbaUnsafe*(mask: Mask, x, y: int, alpha: uint8) {.inline.} = + ## Sets a color 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.width * y + x] = alpha + +proc `[]=`*(mask: Mask, x, y: int, alpha: uint8) {.inline.} = + ## Sets a pixel at (x, y) or does nothing if outside of bounds. + if mask.inside(x, y): + mask.setRgbaUnsafe(x, y, alpha) + +proc fill*(mask: Mask, alpha: uint8) = + ## Fills the mask with a solid color. + for i in 0 ..< mask.data.len: + mask.data[i] = alpha