Subversion Repositories group.electronics

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
126 pfowler 1
/*
2
 * gfx.c
3
 *
4
 *  Created on: 28/11/2013
5
 *      Author: pfowler
6
 */
7
 
8
#include <avr/io.h>
9
#include <stdlib.h>
10
#include <avr/pgmspace.h>
11
#include <string.h>
12
 
13
#include "avrutil.h"
14
#include "gfx.h"
15
 
16
 
17
void gfx_init(uint8_t* buffer, uint8_t width, uint8_t height) {
18
	gfx.width = width;
19
	gfx.height = height;
20
	gfx.buffer = buffer;
21
 
22
	gfx_font.cursor_x = 0;
23
	gfx_font.cursor_y = 0;
24
	gfx_font.textsize = 1;
25
	gfx_font.textcolor = 1;
26
	gfx_font.textbgcolor = 1;
27
	gfx_font.wrap = 1;
28
}
29
 
30
uint8_t gfx_getRotation(void) {
31
	return gfx.rotation;
32
}
33
 
34
void gfx_setRotation(uint8_t x) {
35
	gfx.rotation = (x & 3);
36
	uint8_t ow = gfx.width;
37
	uint8_t oh = gfx.height;
38
 
39
	switch(gfx.rotation) {
40
		case 0:
41
		case 2:
42
			gfx.width  = ow;
43
			gfx.height = oh;
44
			break;
45
		case 1:
46
		case 3:
47
			gfx.width  = oh;
48
			gfx.height = ow;
49
			break;
50
	}
51
}
52
 
53
void gfx_setDrawFunc(pixelptr ptr) {
54
	gfx.drawPixel = ptr;
55
}
56
 
57
void gfx_setFlipFunc(flipptr ptr) {
58
	gfx.flip = ptr;
59
}
60
 
61
void gfx_flip(void) {
62
	(*gfx.flip)();
63
}
64
 
65
void gfx_clear(void) {
66
	memset(gfx.buffer, 0x00, (gfx.width * gfx.height / 8));
67
}
68
 
69
void gfx_drawPixel(uint16_t x, uint16_t y, uint8_t color) {
70
	if (gfx.drawPixel) {
71
		(*gfx.drawPixel)(gfx.buffer, x, y, color);
72
		return;
73
	}
74
 
75
	if (color)
76
		gfx.buffer[x+ (y/8)*gfx.width] |= _BV((y%8));
77
	else
78
		gfx.buffer[x+ (y/8)*gfx.width] &= ~_BV((y%8));
79
}
80
 
81
void gfx_drawFastVLine(uint8_t x, uint8_t y, uint8_t h, uint8_t color) {
82
	gfx_drawLine(x, y, x, y+h-1, color);
83
}
84
 
85
void gfx_drawFastHLine(uint8_t x, uint8_t y, uint8_t w, uint8_t color) {
86
	gfx_drawLine(x, y, x+w-1, y, color);
87
}
88
 
89
void gfx_drawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) {
90
	gfx_drawFastHLine(x, y, w, color);
91
	gfx_drawFastHLine(x, y+h-1, w, color);
92
	gfx_drawFastVLine(x, y, h, color);
93
	gfx_drawFastVLine(x+w-1, y, h, color);
94
}
95
 
96
void gfx_fillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) {
97
	uint8_t i;
98
	for (i=x; i<x+w; i++) {
99
		gfx_drawFastVLine(i, y, h, color);
100
	}
101
}
102
 
103
void gfx_fillScreen(uint8_t color) {
104
	gfx_fillRect(0, 0, gfx.width, gfx.height, 1);
105
}
106
 
107
void gfx_drawLine(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color) {
108
	int8_t steep = abs(y1 - y0) > abs(x1 - x0);
109
	//uint8_t t = 0;
110
	if (steep) {
111
		swapu(&x0, &y0);
112
		swapu(&x1, &y1);
113
	}
114
 
115
	if (x0 > x1) {
116
		swapu(&x0, &x1);
117
		swapu(&y0, &y1);
118
	}
119
 
120
	int8_t dx, dy;
121
	dx = x1 - x0;
122
	dy = abs(y1-y0);
123
 
124
	int8_t err = dx /2;
125
	int8_t ystep;
126
 
127
	if (y0 < y1)
128
		ystep = 1;
129
	else
130
		ystep = -1;
131
 
132
	for (; x0<=x1; x0++) {
133
		if (steep)
134
			gfx_drawPixel(y0, x0, color);
135
		else
136
			gfx_drawPixel(x0, y0, color);
137
		err -= dy;
138
		if (err < 0) {
139
			y0 += ystep;
140
			err += dx;
141
		}
142
	}
143
}
144
 
145
void gfx_drawChar(uint8_t x, uint8_t y, unsigned char c, uint8_t color, uint8_t bg, uint8_t size) {
146
	if((x >= gfx.width)             || // Clip right
147
		(y >= gfx.height)           || // Clip bottom
148
		((x + 6 * size - 1) < 0) || // Clip left
149
		((y + 8 * size - 1) < 0))   // Clip top
150
		return;
151
 
152
	uint8_t i;
153
	for (i=0; i<6; i++) {
154
		uint8_t line;
155
		if (i == 5)
156
			line = 0x0;
157
		else
158
			line = pgm_read_byte(gfx_font_data + (c*5)+i);
159
 
160
		uint8_t j;
161
		for (j=0; j<8; j++) {
162
			if (line & 0x01) {
163
				if (size == 1)
164
					gfx_drawPixel(x+i, y+j, color);
165
				else
166
					gfx_fillRect(x+(i*size), y+(j*size), size, size, color);
167
			} else if (bg != color) {
168
				if (size==1)
169
					gfx_drawPixel(x+i, y+j, bg);
170
				else
171
					gfx_fillRect(x+i*size, y+j*size, size, size, bg);
172
			}
173
			line >>= 1;
174
		}
175
	}
176
}
177
 
178
void gfx_writec(uint8_t c) {
179
	if (c == '\n') {
180
		gfx_font.cursor_y += gfx_font.textsize*8;
181
		gfx_font.cursor_x = 0;
182
	} else if (c == '\r') {
183
 
184
	} else {
185
		gfx_drawChar(gfx_font.cursor_x, gfx_font.cursor_y, c,
186
				gfx_font.textcolor, gfx_font.textbgcolor, gfx_font.textsize);
187
		gfx_font.cursor_x += gfx_font.textsize * 6;
188
 
189
		if (gfx_font.wrap &&
190
				(gfx_font.cursor_x > (gfx.width - gfx_font.textsize*6))) {
191
			gfx_font.cursor_y += gfx_font.textsize = 8;
192
			gfx_font.cursor_x = 0;
193
		}
194
	}
195
}
196
 
197
void gfx_writeb(uint8_t *buffer, size_t size) {
198
	while (size--)
199
		gfx_writec(*buffer++);
200
}
201
 
202
void gfx_writes(char* s) {
203
	while (*s)
204
		gfx_writec(*s++);
205
}
206
 
207
void gfx_printNumber(unsigned long n, uint8_t base) {
208
	unsigned char buf[8 * sizeof(long)];
209
	unsigned long i = 0;
210
 
211
	if (n==0) {
212
		gfx_writec('0');
213
		return;
214
	}
215
 
216
	while (n > 0) {
217
		buf[i++] = n % base;
218
		n /= base;
219
	}
220
 
221
	for (; i>0; i--)
222
		gfx_writec((buf[i-1]<10) ?
223
				'0' + buf[i-1] :
224
				'A' + buf[i-1]-10);
225
}
226
 
227
void gfx_printFloat(double number, uint8_t digits) {
228
	if (number < 0.0) {
229
		gfx_writec('-');
230
		number = -number;
231
	}
232
 
233
	double rounding = 0.5;
234
	uint8_t i;
235
	for (i=0; i<digits; ++i)
236
		rounding /= 10.0;
237
 
238
	number += rounding;
239
 
240
	unsigned long int_part = (unsigned long)number;
241
	double remainder = number - (double)int_part;
242
	gfx_printNumber(int_part, 10);
243
 
244
	if (digits > 0)
245
		gfx_writec('.');
246
 
247
	while (digits-- > 0) {
248
		remainder *= 10.0;
249
		unsigned long toPrint = (unsigned long)remainder;
250
		gfx_printNumber(toPrint, 10);
251
		remainder -= toPrint;
252
 
253
	}
254
}
255
 
256
void gfx_setCursor(uint8_t x, uint8_t y) {
257
	gfx_font.cursor_x = x;
258
	gfx_font.cursor_y = y;
259
}
260
 
261
void gfx_setTextSize(uint8_t s) {
262
	gfx_font.textsize = (s>0)? s : 1;
263
}
264
 
265
void gfx_setTextColor(uint8_t c) {
266
	gfx_font.textcolor = c;
267
}
268
 
269
void gfx_setTextBgColor(uint8_t bg) {
270
	gfx_font.textbgcolor = bg;
271
}
272
 
273
void gfx_setTextWrap(uint8_t w) {
274
	gfx_font.wrap = w;
275
}
276
 
277