-
Notifications
You must be signed in to change notification settings - Fork 1
/
itty.c
executable file
·129 lines (108 loc) · 3.33 KB
/
itty.c
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Copyright 2013, 2014 Chris Rhodin <chris@notav8.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "project.h"
#include <avr/pgmspace.h>
#include <stdint.h>
#include "itty.h"
#include "ilitek_fastio.h"
void itty_draw_canvas(idim_t x, idim_t y, itty_canvas_s const * ic, itty_canvas_data_s * icd)
{
/* fill the background */
ilitek_draw_rect(x, pgm_read_byte(&ic->x_size),
y, pgm_read_byte(&ic->y_size),
icd->bg_color);
}
/*
* Draw a border around the outside of the specified canvas.
*/
void itty_draw_border(idim_t x, idim_t y, itty_canvas_s const * ic, itty_canvas_data_s * icd)
{
icolor_t * border_color;
irect_s border_rect;
idim_t border_size;
border_size = pgm_read_byte(&ic->border_size);
border_rect.x = x;
border_rect.x_size = pgm_read_byte(&ic->x_size);
border_rect.y = y;
border_rect.y_size = pgm_read_byte(&ic->y_size);
border_color = icd->border_color;
while (border_size--) {
border_rect.x--;
border_rect.y--;
border_rect.x_size += 2;
border_rect.y_size += 2;
ilitek_draw_box(border_rect, *border_color++);
}
}
void itty_draw_window(itty_window_s * iw)
{
itty_draw_context_s draw_context;
/* only draw if required */
if (iw->dirty) {
itty_draw_border(iw->x, iw->y, iw->ic, iw->icd);
itty_draw_canvas(iw->x, iw->y, iw->ic, iw->icd);
iw->dirty = 0;
}
draw_context.x = iw->x;
draw_context.y = iw->y;
draw_context.flash = &iw->ic->flash[0];
draw_context.sram = &iw->icd->sram[0];
for (;;) {
itty_draw_f draw_f;
draw_f = (itty_draw_f) pgm_read_word(draw_context.flash++);
if (draw_f) draw_f(&draw_context);
else break;
}
}
/*
* Draw a one pixel wide line.
*/
void itty_draw_line(ipoint_s p0, ipoint_s p1, icolor_t color)
{
uint8_t x_len;
uint8_t y_len;
uint8_t pixels;
uint16_t x_acc;
uint16_t y_acc;
int16_t x_inc;
int16_t y_inc;
if (p0.x <= p1.x) x_len = p1.x - p0.x;
else x_len = p0.x - p1.x;
if (p0.y <= p1.y) y_len = p1.y - p0.y;
else y_len = p0.y - p1.y;
x_acc = p0.x << 8;
y_acc = p0.y << 8;
if (x_len >= y_len) {
pixels = x_len;
y_inc = ((uint16_t) y_len << 8) / (uint16_t) x_len;
y_acc += y_inc >> 1;
x_inc = 0x0100;
}
else {
pixels = y_len;
x_inc = ((uint16_t) x_len << 8) / (uint16_t) y_len;
x_acc += x_inc >> 1;
y_inc = 0x0100;
}
if (p0.x > p1.x) x_inc = -x_inc;
if (p0.y > p1.y) y_inc = -y_inc;
do {
ilitek_draw_pixel(x_acc >> 8, y_acc >> 8, color);
x_acc += x_inc;
y_acc += y_inc;
} while (pixels--);
}