1 module CPUblit.draw; 2 3 import CPUblit.colorspaces; 4 /** 5 * Draws a line using a fixed point method. Is capable of drawing lines diagonally. 6 */ 7 public @nogc void drawLine(T)(int x0, int y0, int x1, int y1, T color, T* dest, int destWidth){ 8 static if(!(T == "ubyte" || T == "ushort" || T == "Color32Bit")){ 9 static assert("Template parameter '" ~ T.stringof ~ "' is not supported!"); 10 } 11 if(x1 < x0){ 12 int k = x1; 13 x1 = x0; 14 x0 = k; 15 } 16 if(y1 < y0){ 17 int k = y1; 18 y1 = y0; 19 y0 = k; 20 } 21 int dx = x1 - x0; 22 int dy = y1 - y0; 23 if(!dx || !dy){ 24 if(!dy){ 25 sizediff_t offset = destWidth * y1; 26 for(int x = x0; x <= x1; x++){ 27 dest[offset + x] = color; 28 } 29 }else{ 30 sizediff_t offset = destWidth * y0 + x0; 31 for(int y = y0; y <= y1; y++){ 32 dest[offset] = color; 33 offset += destWidth; 34 } 35 } 36 }else if(dx>=dy){ 37 int D = 2*dy - dx; 38 int y = y0; 39 for(int x = x0; x <= x1; x++){ 40 dest[destWidth * y + x] = color; 41 if(D > 0){ 42 y += 1; 43 D -= 2*dx; 44 } 45 D += 2*dx; 46 } 47 }else{ 48 int D = 2*dx - dy; 49 int x = x0; 50 for(int y = y0; y <= y1; y++){ 51 dest[destWidth * y + x] = color; 52 if(D > 0){ 53 x += 1; 54 D -= 2*dy; 55 } 56 D += 2*dy; 57 } 58 } 59 } 60 /** 61 * Draws a rectangle. 62 */ 63 public @nogc void drawRectangle(T)(int x0, int y0, int x1, int y1, T color, T*dest, int destWidth){ 64 static if(!(T == "ubyte" || T == "ushort" || T == "Color32Bit")){ 65 static assert("Template parameter '" ~ T.stringof ~ "' is not supported!"); 66 } 67 drawLine(x0,y0,x0,y1,color,dest,destWidth); 68 drawLine(x0,y0,x1,y0,color,dest,destWidth); 69 drawLine(x1,y0,x1,y1,color,dest,destWidth); 70 drawLine(x0,y1,x1,y1,color,dest,destWidth); 71 } 72 /** 73 * Draws a filled rectangle. 74 * TODO: Upgrade algorhithm to use SSE2/MMX for faster filling. 75 */ 76 public @nogc void drawFilledRectangle(T)(int x0, int y0, int x1, int y1, T color, T* dest, int destWidth){ 77 if(x1 < x0){ 78 int k = x1; 79 x1 = x0; 80 x0 = k; 81 } 82 if(y1 < y0){ 83 int k = y1; 84 y1 = y0; 85 y0 = k; 86 } 87 int targetWidth = y1 - y0; 88 89 while(targetWidth){ 90 drawLine!T(x0, y0, x1, y0, color, dest, destWidth); 91 targetWidth--; 92 } 93 }