summaryrefslogtreecommitdiffstats
path: root/src/target/ui-experiment/image.h
blob: 13c11f5b26c656ace4828d34d60de15ba3110064 (plain)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifndef _UI_IMAGE_H
#define _UI_IMAGE_H

/* for exit() */
#include <stdlib.h>

#include <ui/pixel.h>
#include <ui/font.h>

struct image {
	pxtype_t type;
	pxdims_t size;
	unsigned char *data;
};


struct image font_img_v = {
	.type = PXTYPE_MONO_V8,
	.size = {8, 2048},
	.data = &fontdata_r8x8,
};

struct image font_img_h = {
	.type = PXTYPE_MONO_H8,
	.size = {8, 2048},
	.data = &fontdata_r8x8_horiz,
};

px_t
image_get_pixel(struct image *img, pxoff_t x, pxoff_t y) {
	unsigned stride, base, offset;
	const uint8_t *p8;
	const uint16_t *p16;

	switch(img->type) {
	case PXTYPE_MONO_V8:
		stride = img->size.w;
		base = y / 8;
		offset = y % 8;
		p8 = (uint8_t*)(img->data + x + base * stride);
		return px_from_mono(((*p8) >> offset) & 1);
	case PXTYPE_MONO_H8:
		stride = img->size.w / 8;
		base = x / 8;
		offset = x % 8;
		p8 = (uint8_t*)(img->data + base + y * stride);
		return px_from_mono(((*p8) >> offset) & 1);
	case PXTYPE_RGB444:
		stride = img->size.w * 2;
		p16 = (uint16_t*)(img->data + x * 2 + y * stride);
		return px_from_rgb444(*p16);
	}

	return 0;
}

void
image_set_pixel(struct image *img, pxoff_t x, pxoff_t y, px_t v) {
	unsigned stride, base, offset;
	uint8_t *p8;
	uint16_t *p16;

	switch(img->type) {
	case PXTYPE_MONO_V8:
		stride = img->size.w;
		base = y / 8;
		offset = y % 8;
		p8 = (uint8_t*)(img->data + x + base * stride);
		*p8 |= (px_to_mono(v) << offset);
		break;
	case PXTYPE_MONO_H8:
		stride = img->size.w / 8;
		base = x / 8;
		offset = x % 8;
		p8 = (uint8_t*)(img->data + base + y * stride);
		*p8 |= (px_to_mono(v) << offset);
		break;
	case PXTYPE_RGB444:
		stride = img->size.w * 2;
		p16 = (uint16_t*)(img->data + x * 2 + y * stride);
		*p16 = px_to_rgb444(v);
		break;
	}
}

void
image_blit(struct image *dst, pxposn_t dstp,
		   struct image *src, pxposn_t srcp,
		   pxdims_t d)
{
	unsigned x, y, s;

	printf("blit %dx%d from %dx%d to %dx%d\n", d.w, d.h, srcp.x, srcp.y, dstp.x, dstp.y);

	// *cough* slow.
	for(y = 0; y < d.h; y++) {
		for(x = 0; x < d.w; x++) {
			px_t p = image_get_pixel(src, srcp.x + x, srcp.y + y);
			image_set_pixel(dst, dstp.x + x, dstp.y + y, p);
		}
	}
}

void
image_draw_char(struct image *dst, pxposn_t p, char chr) {
	unsigned char c = (unsigned char)chr;
	pxposn_t pf = {0,c*8};
	pxdims_t d = {8,8};
	image_blit(dst, p, &font_img_h, pf, d);
}

void
image_draw_string(struct image *dst, pxposn_t p, char *str) {
	while(*str) {
		image_draw_char(dst, p, *str);
		p.x += 8;
		str++;
	}
}

static void
image_fill_rect_rgb444(struct image *dst, pxrect_t rect, uint16_t color) {
	unsigned x, y, s;
	uint16_t *p;

	unsigned stride = dst->size.w * 2;

	for(y = rect.p.y; y < rect.p.y + rect.d.h; y++) {
		for(x = rect.p.x; x < rect.p.x + rect.d.w; x++) {
			p = (uint16_t*)&dst->data[x * 2 + y * stride];
			*p = color;
		}
	}
}

void
image_fill_rect(struct image *dst, pxrect_t rect, px_t color)
{
	switch(dst->type) {
	case PXTYPE_MONO_V8:
		break;
	case PXTYPE_MONO_H8:
		break;
	case PXTYPE_RGB444:
		image_fill_rect_rgb444(dst, rect, px_to_rgb444(color));
		break;
	}
}

void
image_draw_hline(struct image *dst, pxposn_t posn, pxoff_t len, px_t color)
{
}

void
image_draw_vline(struct image *dst, pxposn_t posn, pxoff_t len, px_t color)
{
}

void
image_draw_rect(struct image *dst, pxrect_t rect, px_t color)
{
}

#endif