summaryrefslogtreecommitdiff
path: root/src/image.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.cpp')
-rw-r--r--src/image.cpp143
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
9Image::Image() :
10 iWidth( 0 ),
11 iHeight( 0 ),
12 pPix( NULL )
13{
14}
15
16Image::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
25Image::~Image()
26{
27 delete[] pPix;
28}
29
30void Image::clear( uint8_t uColor )
31{
32 memset( pPix, uColor, iWidth*iHeight );
33}
34
35void 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
43void 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
88void 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
112void 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