diff options
Diffstat (limited to '')
-rw-r--r-- | src/image.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/image.cpp b/src/image.cpp new file mode 100644 index 0000000..384de9a --- /dev/null +++ b/src/image.cpp | |||
@@ -0,0 +1,143 @@ | |||
1 | #include "image.h" | ||
2 | #include "palette.h" | ||
3 | #include "font.h" | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | #include <string.h> | ||
7 | #include <png.h> | ||
8 | |||
9 | Image::Image() : | ||
10 | iWidth( 0 ), | ||
11 | iHeight( 0 ), | ||
12 | pPix( NULL ) | ||
13 | { | ||
14 | } | ||
15 | |||
16 | Image::Image( int32_t iWidth, int32_t iHeight ) : | ||
17 | iWidth( iWidth ), | ||
18 | iHeight( iHeight ), | ||
19 | pPix( NULL ) | ||
20 | { | ||
21 | pPix = new uint8_t[iWidth*iHeight]; | ||
22 | clear(); | ||
23 | } | ||
24 | |||
25 | Image::~Image() | ||
26 | { | ||
27 | delete[] pPix; | ||
28 | } | ||
29 | |||
30 | void Image::clear( uint8_t uColor ) | ||
31 | { | ||
32 | memset( pPix, uColor, iWidth*iHeight ); | ||
33 | } | ||
34 | |||
35 | void Image::set( int32_t x, int32_t y, uint8_t iCol ) | ||
36 | { | ||
37 | if( x < 0 || y < 0 || x >= iWidth || y >= iHeight ) | ||
38 | return; | ||
39 | |||
40 | pPix[x+y*iWidth] = iCol; | ||
41 | } | ||
42 | |||
43 | void Image::save( const char *sPath, class Palette &rPal ) | ||
44 | { | ||
45 | uint8_t **pRows = new uint8_t*[iHeight]; | ||
46 | for( int r = 0; r < iHeight; r++ ) | ||
47 | { | ||
48 | pRows[r] = pPix+(iWidth*r); | ||
49 | } | ||
50 | |||
51 | png_structp png_ptr = png_create_write_struct( | ||
52 | PNG_LIBPNG_VER_STRING, NULL, NULL, NULL | ||
53 | ); | ||
54 | png_infop info_ptr = png_create_info_struct(png_ptr); | ||
55 | png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, | ||
56 | 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, | ||
57 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT | ||
58 | ); | ||
59 | png_color *pCol = new png_color[rPal.getCount()]; | ||
60 | for( int j = 0; j < rPal.getCount(); j++ ) | ||
61 | { | ||
62 | uint8_t r, g, b; | ||
63 | rPal.getColor( j, r, g, b ); | ||
64 | pCol[j].red = r; | ||
65 | pCol[j].green = g; | ||
66 | pCol[j].blue = b; | ||
67 | } | ||
68 | png_set_PLTE( png_ptr, info_ptr, pCol, rPal.getCount()); | ||
69 | |||
70 | png_set_rows( png_ptr, info_ptr, pRows ); | ||
71 | |||
72 | FILE *fp = fopen(sPath, "wb"); | ||
73 | if( fp == NULL ) | ||
74 | { | ||
75 | printf("Error opening file!\n"); | ||
76 | exit( 1 ); | ||
77 | } | ||
78 | |||
79 | png_init_io( png_ptr, fp ); | ||
80 | png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); | ||
81 | png_destroy_write_struct( &png_ptr, &info_ptr ); | ||
82 | fclose( fp ); | ||
83 | |||
84 | delete[] pCol; | ||
85 | delete[] pRows; | ||
86 | } | ||
87 | |||
88 | void Image::drawText( class Font &rFnt, int32_t x, int32_t y, uint8_t uColor, | ||
89 | const char *sText ) | ||
90 | { | ||
91 | for( const char *s = sText; *s; s++ ) | ||
92 | { | ||
93 | Font::Glyph *pGlyph = rFnt.get( *s ); | ||
94 | if( pGlyph == NULL ) | ||
95 | continue; | ||
96 | |||
97 | for( int cy = 0; cy < pGlyph->pBox.y; cy++ ) | ||
98 | { | ||
99 | for( int cx = 0; cx < pGlyph->pBox.x; cx++ ) | ||
100 | { | ||
101 | int bit = 1<<(7-(cx%8)); | ||
102 | int byte = cx/8; | ||
103 | if( pGlyph->pData[byte+cy*pGlyph->iRowBytes]&bit ) | ||
104 | set( x+cx, y+cy-pGlyph->pBox.y-pGlyph->pOff.y, uColor ); | ||
105 | } | ||
106 | } | ||
107 | x += pGlyph->pDevOff.x; | ||
108 | y += pGlyph->pDevOff.y; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | void Image::drawLine( int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t uColor ) | ||
113 | { | ||
114 | if( x1 == x2 ) | ||
115 | { | ||
116 | // Vertical line, easy | ||
117 | if( y2 < y1 ) | ||
118 | { | ||
119 | int32_t r = y2; | ||
120 | y2 = y1; | ||
121 | y1 = r; | ||
122 | } | ||
123 | for( int j = y1; j <= y2; j++ ) | ||
124 | { | ||
125 | set( x1, j, uColor ); | ||
126 | } | ||
127 | } | ||
128 | else if( y1 == y2 ) | ||
129 | { | ||
130 | // Horizontal line, easy | ||
131 | if( x2 < x1 ) | ||
132 | { | ||
133 | int32_t r = x2; | ||
134 | x2 = x1; | ||
135 | x1 = r; | ||
136 | } | ||
137 | for( int j = x1; j <= x2; j++ ) | ||
138 | { | ||
139 | set( j, y1, uColor ); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||