[render_text] Move all glyphs to the left...
[wikipediardware.git] / gui-lib / guilib.c
blob36d703ce2c51ae426ff9d76719c4033551363f0a
1 /*
2 * guilib - a minimal pixel framework
3 * Copyright (c) 2008, 2009 Daniel Mack <daniel@caiaq.de>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <file-io.h>
20 #include <msg.h>
21 #include <string.h>
22 #include "guilib.h"
23 #include "glyph.h"
24 #include "fontfile.h"
25 #include <regs.h>
26 #include <lcd.h>
27 #include <wikireader.h>
30 // just redfine, fix later
31 #define FRAMEBUFFER_WIDTH LCD_WIDTH_PIXELS
32 #define FRAMEBUFFER_HEIGHT LCD_HEIGHT_LINES
33 #define FRAMEBUFFER_SCANLINE LCD_VRAM_WIDTH_PIXELS
34 #define FRAMEBUFFER_SIZE LCD_VRAM_SIZE
37 #define EXTRACT_PIXEL(x, y) \
38 unsigned int byte = (x + FRAMEBUFFER_SCANLINE * y) / 8; \
39 unsigned int bit = (x + FRAMEBUFFER_SCANLINE * y) % 8; \
41 if (byte >= FRAMEBUFFER_SIZE) \
42 return;
45 unsigned int guilib_framebuffer_width(void)
47 return FRAMEBUFFER_WIDTH;
50 unsigned int guilib_framebuffer_height(void)
52 return FRAMEBUFFER_HEIGHT;
55 unsigned int guilib_framebuffer_size(void)
57 return FRAMEBUFFER_SIZE;
62 * Special version for really setting the pixel as it
63 * should be... This does not take DISPLAY_INVERTED into
64 * account.
66 static void guilib_set_pixel_plain(int x, int y, int v)
68 EXTRACT_PIXEL(x, y)
70 if (v)
71 framebuffer[byte] |= (1 << (7 - bit));
72 else
73 framebuffer[byte] &= ~(1 << (7 - bit));
76 void guilib_set_pixel(int x, int y, int v)
78 EXTRACT_PIXEL(x, y)
80 if (v)
81 #ifdef DISPLAY_INVERTED
82 framebuffer[byte] &= ~(1 << (7 - bit));
83 else
84 framebuffer[byte] |= (1 << (7 - bit));
85 #else
86 framebuffer[byte] |= (1 << (7 - bit));
87 else
88 framebuffer[byte] &= ~(1 << (7 - bit));
89 #endif
92 int guilib_get_pixel(int x, int y)
94 unsigned int byte = (x + FRAMEBUFFER_SCANLINE * y) / 8;
95 unsigned int bit = (x + FRAMEBUFFER_SCANLINE * y) % 8;
96 int bit_set = (framebuffer[byte] & 1<<(7-bit)) != 0;
97 #ifdef DISPLAY_INVERTED
98 bit_set = !bit_set;
99 #endif
100 return bit_set;
104 * Invert the pixels of lines starting at @param start_line
105 * and the following @param height lines.
107 void guilib_invert(int start_line, int height)
109 int x, y;
111 for (y = 0; y < height; ++y) {
112 for (x = 0; x < FRAMEBUFFER_SCANLINE; x += 8) {
113 unsigned int byte = (x + FRAMEBUFFER_SCANLINE * (start_line + y)) / 8;
114 framebuffer[byte] = ~framebuffer[byte];
120 * Clear the content of the screen.
122 void guilib_clear(void)
124 #ifdef DISPLAY_INVERTED
125 memset(framebuffer, ~0, FRAMEBUFFER_SIZE);
126 #else
127 memset(framebuffer, 0, FRAMEBUFFER_SIZE);
128 #endif
131 /* The idea is that every function which calls painting routines calls
132 * guilib_fb_lock() before any operation and guilib_fb_unlock() after
133 * it. This way, only the last of these functions in the calling stack
134 * will actually execute fb_refresh(). */
135 static int fb_ref = 0;
137 void guilib_fb_lock(void)
139 fb_ref++;
142 void guilib_fb_unlock(void)
144 if (fb_ref == 0)
145 return;
147 if (--fb_ref == 0)
148 fb_refresh();
151 #define IMG_GET_PIXEL(img,x,y) \
152 (img->data[(x + img->width * y) / 8] >> (7 - (x + img->width * y) % 8) & 1)
154 void guilib_blit_image(const struct guilib_image *img, int x, int y)
156 unsigned int xx, yy;
158 /* special case: the image has the same width than the
159 * height and is rendered at y=0. Then we can go for a
160 * simple memcpy() */
162 if (y == 0 && img->width == FRAMEBUFFER_SCANLINE) {
163 memcpy(framebuffer + (x + FRAMEBUFFER_SCANLINE * y) / 8,
164 img->data, (img->width * img->height) / 8);
165 return;
168 /* special case: the image will be blitted byte aligned.
169 * we can simply copy over all the bytes, without bit
170 * fiddling. We can copy it line by line*/
172 if ((x & 7) == 0 && img->width == FRAMEBUFFER_WIDTH) {
173 unsigned int i;
174 for (i = 0; i < img->height; ++i) {
175 unsigned char *d = framebuffer + (x + FRAMEBUFFER_SCANLINE * (y+i)) / 8;
176 memcpy(d, &img->data[(i*img->width) / 8], img->width / 8);
179 return;
182 /* hardest case - go for bit fiddling */
183 for (xx = 0; xx < img->width; xx++)
184 for (yy = 0; yy < img->height; yy++)
185 guilib_set_pixel_plain(x + xx, y + yy,
186 IMG_GET_PIXEL(img, xx, yy));
189 #define FONTFILE "/fontfile.gen"
191 void guilib_init(void)
193 msg(MSG_INFO, "guilib_init:: clear\n");
194 guilib_clear();
195 msg(MSG_INFO, "guilib_init:: font file %s\n", FONTFILE);
197 /* just some tests ... */
198 if (read_font_file(FONTFILE) != 0) {
199 msg(MSG_INFO, "unable to load font file %s\n", FONTFILE);
200 return;
203 msg(MSG_INFO, "loaded font file %s\n", FONTFILE);