1 | void glcdPrint(const prog_char* string, uint8_t flashstored) {
|
2 |
|
3 | if ((glcd.FontData == 0) | (string == 0)) return;
|
4 |
|
5 | uint8_t flags = (flashstored == 0 ? 0x30 : 0x70) | (glcd.FontBitsPixel & 0x80) | (glcd.Flags.All & 0x0F);
|
6 | uint8_t c, i, FontHeight = glcd.FontHeight;
|
7 | while (1) {
|
8 | if (flags & 0x40) c = pgm_read_byte(string);
|
9 | else c = *string;
|
10 | if (!(c)) break;
|
11 | string++;
|
12 | if (c == '\n') {
|
13 | glcd.Cursor.x = glcd.Window.x1;
|
14 | glcd.Cursor.y += FontHeight;
|
15 | if (glcd.Cursor.y + FontHeight > glcd.Window.y2) glcd.Cursor.y = glcd.Window.y1;
|
16 | flags |= 0x10; // invalidate LCD address pointer
|
17 | continue;
|
18 | }
|
19 | if ((c < glcd.FontFirstChar) | (c > glcd.FontLastChar)) continue;
|
20 | uint8_t charwidth = GLCD_READFUNC(glcd.FontData + GLCD_FONT_HEADER_SIZE + (c - glcd.FontFirstChar));
|
21 | if (!(charwidth)) continue;
|
22 | uint8_t width = charwidth;
|
23 | if (c < 128) width++;
|
24 | if ((flags & 0x01) & (width < glcd.FontWidth)) width = glcd.FontWidth; // FixedFont ??
|
25 | if ((flags & 0x02) & (glcd.Cursor.x + width >= glcd.Window.x2)) { // LineFeed ??
|
26 | glcd.Cursor.x = glcd.Window.x1;
|
27 | glcd.Cursor.y += FontHeight;
|
28 | if (glcd.Cursor.y + FontHeight > glcd.Window.y2) glcd.Cursor.y = glcd.Window.y1;
|
29 | flags |= 0x10; // invalidate LCD address pointer
|
30 | }
|
31 | uint16_t bits;
|
32 | glcdFontData_t data; // Achtung! wenn der Font zb. auf Devices mit mehr als 64Kb FLASH oberhalb von 64Kb gespeichert ist muß das hier auf uint32_t und GLCD_READFUNC() angepasst werden
|
33 | uint8_t bitspixel = glcd.FontBitsPixel & 0x7F, bitsmask = 0xFF >> (8 - bitspixel), bitscount, RLE[4], charofs = glcd.FontLastChar - glcd.FontFirstChar;
|
34 | if (flags & 0x80) { // compressed Font ??
|
35 | data = glcd.FontData + (GLCD_FONT_HEADER_SIZE +1) + charofs;
|
36 | uint8_t padding = GLCD_READFUNC(data++);
|
37 | RLE[0] = 1;
|
38 | RLE[1] = GLCD_READFUNC(data++);
|
39 | RLE[2] = GLCD_READFUNC(data++);
|
40 | RLE[3] = GLCD_READFUNC(data++);
|
41 | uint32_t index = 0;
|
42 | for (i = glcd.FontFirstChar; i < c; i++) index += GLCD_READFUNC(data++);
|
43 | index *= padding;
|
44 | data = glcd.FontData + (GLCD_FONT_HEADER_SIZE +6) + (charofs *2) + index;
|
45 | bits = GLCD_READFUNC(data++);
|
46 | bitscount = 8;
|
47 | } else {
|
48 | data = glcd.FontData + GLCD_FONT_HEADER_SIZE;
|
49 | uint32_t index = 0;
|
50 | for (i = glcd.FontFirstChar; i < c; i++) index += GLCD_READFUNC(data++);
|
51 | index *= FontHeight * bitspixel;
|
52 | bitscount = index % 8;
|
53 | index /= 8;
|
54 | data = glcd.FontData + (GLCD_FONT_HEADER_SIZE +1) + charofs + index;
|
55 | bits = GLCD_READFUNC(data++) >> bitscount;
|
56 | bitscount = 8 - bitscount;
|
57 | }
|
58 | if (flags & 0x20) { // inialize LCD ??
|
59 | flags ^= 0x20;
|
60 | GLCD_CS_ON();
|
61 | #ifdef GLCD_ROTATE
|
62 | GLCD_SETMODE(0x37);
|
63 | #else
|
64 | GLCD_SETMODE(0x3F);
|
65 | #endif
|
66 | GLCD_SETCOMPARE(NONE);
|
67 | }
|
68 | if (flags & 0x10) { // LCD address pointer invalid ??
|
69 | flags ^= 0x10;
|
70 | GLCD_CS_PULSE();
|
71 | #ifdef GLCD_ROTATE
|
72 | GLCD_WINDOW(glcd.Cursor.y, glcd.Cursor.x, glcd.Cursor.y + FontHeight -1, GLCD_RIGHT);
|
73 | GLCD_SETADDR(glcd.Cursor.y, glcd.Cursor.x);
|
74 | #else
|
75 | GLCD_WINDOW(glcd.Cursor.x, glcd.Cursor.y, GLCD_RIGHT, glcd.Cursor.y + FontHeight -1);
|
76 | GLCD_SETADDR(glcd.Cursor.x, glcd.Cursor.y);
|
77 | #endif
|
78 | GLCD_STARTDATA();
|
79 | }
|
80 | glcd.Cursor.x += width;
|
81 | uint8_t leftwidth = 0;
|
82 | uint8_t rightwidth = width - charwidth;
|
83 | if (flags & 0x01) { // FixedFont ??
|
84 | leftwidth = rightwidth / 2;
|
85 | rightwidth -= leftwidth;
|
86 | }
|
87 | uint8_t ch,cl;
|
88 | ch = glcd.Colors[0] >> 8;
|
89 | cl = glcd.Colors[0] & 0xFF;
|
90 | for (; leftwidth > 0; leftwidth--) {
|
91 | for (i = FontHeight; i > 0; i--) {
|
92 | GLCD_WAIT();
|
93 | GLCD_OUT(ch);
|
94 | GLCD_WAIT();
|
95 | GLCD_OUT(cl);
|
96 | }
|
97 | }
|
98 | uint8_t pixelcount = 0;
|
99 | for (; charwidth > 0; charwidth--) {
|
100 | for (i = FontHeight; i > 0; i--) {
|
101 | if (!(pixelcount)) {
|
102 | pixelcount++;
|
103 | while (bitscount <= 8) {
|
104 | bits |= GLCD_READFUNC(data++) << bitscount;
|
105 | bitscount += 8;
|
106 | }
|
107 | if (flags & 0x80) { // compresed Font ??
|
108 | pixelcount = RLE[bits & 0x03];
|
109 | bits >>= 2;
|
110 | bitscount -= 2;
|
111 | }
|
112 | bitscount -= bitspixel;
|
113 | uint8_t j = bits & bitsmask;
|
114 | ch = glcd.Colors[j] >> 8;
|
115 | cl = glcd.Colors[j] & 0xFF;
|
116 | bits >>= bitspixel;
|
117 | }
|
118 | pixelcount--;
|
119 | GLCD_WAIT();
|
120 | GLCD_OUT(ch);
|
121 | GLCD_WAIT();
|
122 | GLCD_OUT(cl);
|
123 | }
|
124 | }
|
125 | ch = glcd.Colors[0] >> 8;
|
126 | cl = glcd.Colors[0] & 0xFF;
|
127 | for (; rightwidth > 0; rightwidth--) {
|
128 | for (i = FontHeight; i > 0; i--) {
|
129 | GLCD_WAIT();
|
130 | GLCD_OUT(ch);
|
131 | GLCD_WAIT();
|
132 | GLCD_OUT(cl);
|
133 | }
|
134 | }
|
135 | GLCD_WAIT();
|
136 | }
|
137 | if (!(flags & 0x20)) { // have LCD initialized, anything done ??
|
138 | GLCD_CS_PULSE();
|
139 | GLCD_RESETWINDOW();
|
140 | GLCD_SETMODE(0x30);
|
141 | GLCD_CS_OFF();
|
142 | }
|
143 | }
|