aboutsummaryrefslogtreecommitdiff
path: root/shell/menu/font_drawing.c
blob: 9b964effd0e45f7403ee0485e5c273a26c8e7d79 (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
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "video_blit.h"
#include "font_drawing.h"
#include "font_menudata.h"

extern int32_t screen_width;
//#define setPixel(buffer, x,y,c) 

static inline void setPixel(uint16_t* restrict buffer, uint32_t x, uint32_t y, uint16_t c)
{
	if (x < BACKBUFFER_WIDTH_RESOLUTION && y < BACKBUFFER_HEIGHT_RESOLUTION)
	{
		*((uint16_t* restrict)buffer + ((x) + (y) * BACKBUFFER_WIDTH_RESOLUTION)) = c;
	}
}

static int32_t isOutlinePixel(uint8_t* charfont, uint32_t x, uint32_t y)
{
	uint32_t xis0 = !x, xis7 = x == 7, yis0 = !y, yis7 = y == 7;
	
	if(xis0)
	{
		if (yis0)
		{
			return !(*charfont & 0x80) && ((*charfont & 0x40) || (charfont[1] & 0x80) || (charfont[1] & 0x40));
		}
		else if (yis7)
		{
			return !(charfont[7] & 0x80) && ((charfont[7] & 0x40) || (charfont[6] & 0x80) || (charfont[6] & 0x40));
		}
		else
		{
			return !(charfont[y] & 0x80) && (
				(charfont[y - 1] & 0x80) || (charfont[y - 1] & 0x40) ||
				(charfont[y] & 0x40) ||
				(charfont[y + 1] & 0x80) || (charfont[y + 1] & 0x40));
		}
	}
	else if (xis7)
	{
		if (yis0)
		{
			return !(*charfont & 0x01) && ((*charfont & 0x02) || (charfont[1] & 0x01) || (charfont[1] & 0x02));
		}
		else if (yis7)
		{
			return !(charfont[7] & 0x01) && ((charfont[7] & 0x02) || (charfont[6] & 0x01) || (charfont[6] & 0x02));
		}
		else
		{
			return !(charfont[y] & 0x01) && (
				(charfont[y - 1] & 0x01) || (charfont[y - 1] & 0x02) ||
				(charfont[y] & 0x02) ||
				(charfont[y + 1] & 0x01) || (charfont[y + 1] & 0x02));
		}
	}
	else
	{
		uint32_t b = 1 << (7 - x);
		if (yis0)
		{
			return !(*charfont & b) && (
				(*charfont & (b << 1)) || (*charfont & (b >> 1)) ||
				(charfont[1] & (b << 1)) || (charfont[1] & b) || (charfont[1] & (b >> 1)));
		}
		else if (yis7)
		{
			return !(charfont[7] & b) && (
				(charfont[7] & (b << 1)) || (charfont[7] & (b >> 1)) ||
				(charfont[6] & (b << 1)) || (charfont[6] & b) || (charfont[6] & (b >> 1)));
		}
		else
		{
			return !(charfont[y] & b) && (
				(charfont[y] & (b << 1)) || (charfont[y] & (b >> 1)) ||
				(charfont[y - 1] & (b << 1)) || (charfont[y - 1] & b) || (charfont[y - 1] & (b >> 1)) ||
				(charfont[y + 1] & (b << 1)) || (charfont[y + 1] & b) || (charfont[y + 1] & (b >> 1)));
		}
	}
}

static void drawChar(uint16_t* restrict buffer, uint32_t *x, uint32_t *y, uint32_t margin, char ch, uint16_t fc, uint16_t olc)
{
	uint32_t i, j;
	uint8_t *charSprite;
	if (ch == '\n')
	{
		*x = margin;
		*y += 8;
	}
	else if(*y < (BACKBUFFER_HEIGHT_RESOLUTION-1))
	{
		charSprite = ch * 8 + n2DLib_font;
		// Draw charSprite as monochrome 8*8 image using given color
		for(i = 0; i < 8; i++)
		{
			for(j = 7; j; j--)
			{
				if((charSprite[i] >> j) & 1)
				{
					setPixel(buffer, *x + (7 - j), *y + i, fc);
				}
				else if(isOutlinePixel(charSprite, 7 - j, i))
				{
					setPixel(buffer, *x + (7 - j), *y + i, olc);
				}
			}
		}
		*x += 8;
	}
}

static void drawString(uint16_t* restrict buffer, uint32_t *x, uint32_t *y, uint32_t _x, const char *str, uint16_t fc, uint16_t olc)
{
	uint32_t i;
	size_t size_font;

	size_font = strnlen(str, (BACKBUFFER_WIDTH_RESOLUTION/8)) + 1;
	for(i = 0; i <  size_font; i++)
		drawChar(buffer, x, y, _x, str[i], fc, olc);
}

void print_string(const char *s, const uint16_t fg_color, const uint16_t bg_color, uint32_t x, uint32_t y, uint16_t* restrict buffer) 
{
	if (!s) return;
	
	drawString(buffer, &x, &y, 0, s, fg_color, bg_color);
}