1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use texture::{
    Pixel,
    Texture,
};

#[derive(Copy, Clone)]
pub struct RGBA8 {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl Pixel for RGBA8 {
    fn is_transparent(&self) -> bool {
        self.a == 0
    }

    fn transparency() -> Option<Self> {
        Some(RGBA8 { r: 0, g: 0, b: 0, a: 0 })
    }

    fn outline() -> RGBA8 {
        RGBA8 { r: 255, g: 0, b: 0, a: 255 }
    }
}

pub struct MemoryRGBA8Texture {
    pixels: Vec<RGBA8>,
    width: u32,
    height: u32,
}

impl MemoryRGBA8Texture {
    pub fn from_memory(buf: &[u8], w: u32, h: u32) -> MemoryRGBA8Texture {
        let mut pixels = Vec::new();

        for pixel in buf.chunks(4) {
            pixels.push(RGBA8 {
                r: pixel[0],
                g: pixel[1],
                b: pixel[2],
                a: pixel[3],
            });
        }

        MemoryRGBA8Texture {
            pixels: pixels,
            width: w,
            height: h,
        }
    }

    #[inline(always)]
    fn index_for(&self, x: u32, y: u32) -> usize {
        (y * self.width + x) as usize
    }
}

impl Texture for MemoryRGBA8Texture {
    type Pixel = RGBA8;

    fn width(&self) -> u32 {
        self.width
    }

    fn height(&self) -> u32 {
        self.height
    }

    fn get(&self, x: u32, y: u32) -> Option<RGBA8> {
        if let Some(p) = self.pixels.get(self.index_for(x, y)) {
            Some(*p)
        } else {
            None
        }
    }

    fn set(&mut self, x: u32, y: u32, val: RGBA8) {
        let index = self.index_for(x, y);
        self.pixels[index] = val;
    }
}