libg15render
pixel.c
Go to the documentation of this file.
1 /*
2  This file is part of g15tools.
3 
4  g15tools is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  g15tools is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with g15lcd; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <fcntl.h>
20 #include "libg15render.h"
21 
22 void
23 swap (int *x, int *y)
24 {
25  int tmp;
26 
27  tmp = *x;
28  *x = *y;
29  *y = tmp;
30 }
31 
44 void
45 g15r_pixelReverseFill (g15canvas * canvas, int x1, int y1, int x2, int y2,
46  int fill, int color)
47 {
48  int x = 0;
49  int y = 0;
50 
51  for (x = x1; x <= x2; ++x)
52  {
53  for (y = y1; y <= y2; ++y)
54  {
55  if (!fill)
56  color = !g15r_getPixel (canvas, x, y);
57  g15r_setPixel (canvas, x, y, color);
58  }
59  }
60 }
61 
73 void
74 g15r_pixelOverlay (g15canvas * canvas, int x1, int y1, int width, int height,
75  short colormap[])
76 {
77  int i = 0;
78 
79  for (i = 0; i < (width * height); ++i)
80  {
81  int color = (colormap[i] ? G15_COLOR_BLACK : G15_COLOR_WHITE);
82  int x = x1 + i % width;
83  int y = y1 + i / width;
84  g15r_setPixel (canvas, x, y, color);
85  }
86 }
87 
98 void
99 g15r_drawLine (g15canvas * canvas, int px1, int py1, int px2, int py2,
100  const int color)
101 {
102  /*
103  * Bresenham's Line Algorithm
104  * http://en.wikipedia.org/wiki/Bresenham's_algorithm
105  */
106 
107  int steep = 0;
108 
109  if (abs (py2 - py1) > abs (px2 - px1))
110  steep = 1;
111 
112  if (steep)
113  {
114  swap (&px1, &py1);
115  swap (&px2, &py2);
116  }
117 
118  if (px1 > px2)
119  {
120  swap (&px1, &px2);
121  swap (&py1, &py2);
122  }
123 
124  int dx = px2 - px1;
125  int dy = abs (py2 - py1);
126 
127  int error = 0;
128  int y = py1;
129  int ystep = (py1 < py2) ? 1 : -1;
130  int x = 0;
131 
132  for (x = px1; x <= px2; ++x)
133  {
134  if (steep)
135  g15r_setPixel (canvas, y, x, color);
136  else
137  g15r_setPixel (canvas, x, y, color);
138 
139  error += dy;
140  if (2 * error >= dx)
141  {
142  y += ystep;
143  error -= dx;
144  }
145  }
146 }
147 
162 void
163 g15r_pixelBox (g15canvas * canvas, int x1, int y1, int x2, int y2, int color,
164  int thick, int fill)
165 {
166  int i = 0;
167  for (i = 0; i < thick; ++i)
168  {
169  g15r_drawLine (canvas, x1, y1, x2, y1, color); /* Top */
170  g15r_drawLine (canvas, x1, y1, x1, y2, color); /* Left */
171  g15r_drawLine (canvas, x2, y1, x2, y2, color); /* Right */
172  g15r_drawLine (canvas, x1, y2, x2, y2, color); /* Bottom */
173  x1++;
174  y1++;
175  x2--;
176  y2--;
177  }
178 
179  int x = 0, y = 0;
180 
181  if (fill)
182  {
183  for (x = x1; x <= x2; ++x)
184  for (y = y1; y <= y2; ++y)
185  g15r_setPixel (canvas, x, y, color);
186  }
187 
188 }
189 
202 void
203 g15r_drawCircle (g15canvas * canvas, int x, int y, int r, int fill, int color)
204 {
205  int xx, yy, dd;
206 
207  xx = 0;
208  yy = r;
209  dd = 2 * (1 - r);
210 
211  while (yy >= 0)
212  {
213  if (!fill)
214  {
215  g15r_setPixel (canvas, x + xx, y - yy, color);
216  g15r_setPixel (canvas, x + xx, y + yy, color);
217  g15r_setPixel (canvas, x - xx, y - yy, color);
218  g15r_setPixel (canvas, x - xx, y + yy, color);
219  }
220  else
221  {
222  g15r_drawLine (canvas, x - xx, y - yy, x + xx, y - yy, color);
223  g15r_drawLine (canvas, x - xx, y + yy, x + xx, y + yy, color);
224  }
225  if (dd + yy > 0)
226  {
227  yy--;
228  dd = dd - (2 * yy + 1);
229  }
230  if (xx > dd)
231  {
232  xx++;
233  dd = dd + (2 * xx + 1);
234  }
235  }
236 }
237 
251 void
252 g15r_drawRoundBox (g15canvas * canvas, int x1, int y1, int x2, int y2,
253  int fill, int color)
254 {
255  int y, shave = 3;
256 
257  if (shave > (x2 - x1) / 2)
258  shave = (x2 - x1) / 2;
259  if (shave > (y2 - y1) / 2)
260  shave = (y2 - y1) / 2;
261 
262  if ((x1 != x2) && (y1 != y2))
263  {
264  if (fill)
265  {
266  g15r_drawLine (canvas, x1 + shave, y1, x2 - shave, y1, color);
267  for (y = y1 + 1; y < y1 + shave; y++)
268  g15r_drawLine (canvas, x1 + 1, y, x2 - 1, y, color);
269  for (y = y1 + shave; y <= y2 - shave; y++)
270  g15r_drawLine (canvas, x1, y, x2, y, color);
271  for (y = y2 - shave + 1; y < y2; y++)
272  g15r_drawLine (canvas, x1 + 1, y, x2 - 1, y, color);
273  g15r_drawLine (canvas, x1 + shave, y2, x2 - shave, y2, color);
274  if (shave == 4)
275  {
276  g15r_setPixel (canvas, x1 + 1, y1 + 1,
277  color ==
280  g15r_setPixel (canvas, x1 + 1, y2 - 1,
281  color ==
282  G15_COLOR_WHITE ? G15_COLOR_BLACK :
283  G15_COLOR_WHITE);
284  g15r_setPixel (canvas, x2 - 1, y1 + 1,
285  color ==
286  G15_COLOR_WHITE ? G15_COLOR_BLACK :
287  G15_COLOR_WHITE);
288  g15r_setPixel (canvas, x2 - 1, y2 - 1,
289  color ==
290  G15_COLOR_WHITE ? G15_COLOR_BLACK :
291  G15_COLOR_WHITE);
292  }
293  }
294  else
295  {
296  g15r_drawLine (canvas, x1 + shave, y1, x2 - shave, y1, color);
297  g15r_drawLine (canvas, x1, y1 + shave, x1, y2 - shave, color);
298  g15r_drawLine (canvas, x2, y1 + shave, x2, y2 - shave, color);
299  g15r_drawLine (canvas, x1 + shave, y2, x2 - shave, y2, color);
300  if (shave > 1)
301  {
302  g15r_drawLine (canvas, x1 + 1, y1 + 1, x1 + shave - 1, y1 + 1,
303  color);
304  g15r_drawLine (canvas, x2 - shave + 1, y1 + 1, x2 - 1, y1 + 1,
305  color);
306  g15r_drawLine (canvas, x1 + 1, y2 - 1, x1 + shave - 1, y2 - 1,
307  color);
308  g15r_drawLine (canvas, x2 - shave + 1, y2 - 1, x2 - 1, y2 - 1,
309  color);
310  g15r_drawLine (canvas, x1 + 1, y1 + 1, x1 + 1, y1 + shave - 1,
311  color);
312  g15r_drawLine (canvas, x1 + 1, y2 - 1, x1 + 1, y2 - shave + 1,
313  color);
314  g15r_drawLine (canvas, x2 - 1, y1 + 1, x2 - 1, y1 + shave - 1,
315  color);
316  g15r_drawLine (canvas, x2 - 1, y2 - 1, x2 - 1, y2 - shave + 1,
317  color);
318  }
319  }
320  }
321 }
322 
336 void
337 g15r_drawBar (g15canvas * canvas, int x1, int y1, int x2, int y2, int color,
338  int num, int max, int type)
339 {
340  float len, length;
341  int x;
342  if (max == 0)
343  return;
344  if (num > max)
345  num = max;
346 
347  if (type == 2)
348  {
349  y1 += 2;
350  y2 -= 2;
351  x1 += 2;
352  x2 -= 2;
353  }
354 
355  len = ((float) max / (float) num);
356  length = (x2 - x1) / len;
357 
358  if (type == 1)
359  {
360  g15r_pixelBox (canvas, x1, y1 - type, x2, y2 + type, color ^ 1, 1, 1);
361  g15r_pixelBox (canvas, x1, y1 - type, x2, y2 + type, color, 1, 0);
362  }
363  else if (type == 2)
364  {
365  g15r_pixelBox (canvas, x1 - 2, y1 - type, x2 + 2, y2 + type, color ^ 1,
366  1, 1);
367  g15r_pixelBox (canvas, x1 - 2, y1 - type, x2 + 2, y2 + type, color, 1,
368  0);
369  }
370  else if (type == 3)
371  {
372  g15r_drawLine (canvas, x1, y1 - type, x1, y2 + type, color);
373  g15r_drawLine (canvas, x2, y1 - type, x2, y2 + type, color);
374  g15r_drawLine (canvas, x1, y1 + ((y2 - y1) / 2), x2,
375  y1 + ((y2 - y1) / 2), color);
376  }
377  g15r_pixelBox (canvas, x1, y1, (int) ceil (x1 + length), y2, color, 1, 1);
378 }
379 
386 int
387 g15r_loadWbmpSplash(g15canvas *canvas, char *filename)
388 {
389  int width=0, height=0;
390  char *buf;
391 
392  buf = g15r_loadWbmpToBuf(filename,
393  &width,
394  &height);
395 
396  memcpy (canvas->buffer, buf, G15_BUFFER_LEN);
397  return 0;
398 }
399 
410 void
411 g15r_drawIcon(g15canvas *canvas, char *buf, int my_x, int my_y, int width, int height)
412 {
413  int y,x,val;
414  unsigned int pixel_offset = 0;
415  unsigned int byte_offset, bit_offset;
416 
417  for (y=0; y < height - 1; y++)
418  for (x=0; x < width - 1; x++)
419  {
420  pixel_offset = y * width + x;
421  byte_offset = pixel_offset / BYTE_SIZE;
422  bit_offset = 7 - (pixel_offset % BYTE_SIZE);
423 
424  val = (buf[byte_offset] & (1 << bit_offset)) >> bit_offset;
425  g15r_setPixel (canvas, x + my_x, y + my_y, val);
426  }
427 }
428 
442 void
443 g15r_drawSprite(g15canvas *canvas, char *buf, int my_x, int my_y, int width, int height, int start_x, int start_y, int total_width)
444 {
445  int y,x,val;
446  unsigned int pixel_offset = 0;
447  unsigned int byte_offset, bit_offset;
448 
449  for (y=0; y < height - 1; y++)
450  for (x=0; x < width - 1; x++)
451  {
452  pixel_offset = (y + start_y) * total_width + (x + start_x);
453  byte_offset = pixel_offset / BYTE_SIZE;
454  bit_offset = 7 - (pixel_offset % BYTE_SIZE);
455 
456  val = (buf[byte_offset] & (1 << bit_offset)) >> bit_offset;
457  g15r_setPixel (canvas, x + my_x, y + my_y, val);
458  }
459 }
460 
468 char *
469 g15r_loadWbmpToBuf(char *filename, int *img_width, int *img_height)
470 {
471  int wbmp_fd;
472  int retval;
473  int x,y,val;
474  char *buf;
475  unsigned int buflen,header=4;
476  unsigned char headerbytes[5];
477  unsigned int pixel_offset = 0;
478  unsigned int byte_offset, bit_offset;
479 
480  wbmp_fd=open(filename,O_RDONLY);
481  if(!wbmp_fd){
482  return NULL;
483  }
484 
485  retval=read(wbmp_fd,headerbytes,5);
486 
487  if(retval){
488  if (headerbytes[2] & 1) {
489  *img_width = ((unsigned char)headerbytes[2] ^ 1) | (unsigned char)headerbytes[3];
490  *img_height = headerbytes[4];
491  header = 5;
492  } else {
493  *img_width = headerbytes[2];
494  *img_height = headerbytes[3];
495  }
496 
497  int byte_width = *img_width / 8;
498  if (*img_width %8)
499  byte_width++;
500 
501  buflen = byte_width * (*img_height);
502 
503  buf = (char *)malloc (buflen);
504  if (buf == NULL)
505  return NULL;
506 
507  if (header == 4)
508  buf[0]=headerbytes[4];
509 
510  retval=read(wbmp_fd,buf+(5-header),buflen);
511 
512  close(wbmp_fd);
513  }
514 
515  /* now invert the image */
516  for (y = 0; y < *img_height; y++)
517  for (x = 0; x < *img_width; x++)
518  {
519  pixel_offset = y * (*img_width) + x;
520  byte_offset = pixel_offset / BYTE_SIZE;
521  bit_offset = 7 - (pixel_offset % BYTE_SIZE);
522 
523  val = (buf[byte_offset] & (1 << bit_offset)) >> bit_offset;
524 
525  if (!val)
526  buf[byte_offset] = buf[byte_offset] | 1 << bit_offset;
527  else
528  buf[byte_offset] = buf[byte_offset] & ~(1 << bit_offset);
529  }
530 
531  return buf;
532 }
533 
544 void
545 g15r_drawBigNum (g15canvas * canvas, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, int color, int num)
546 {
547  x1 += 2;
548  x2 -= 2;
549 
550  switch(num){
551  case 0:
552  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
553  g15r_pixelBox (canvas, x1 +5, y1 +5, x2 -5, y2 - 6, 1 - color, 1, 1);
554  break;
555  case 1:
556  g15r_pixelBox (canvas, x2-5, y1, x2, y2 , color, 1, 1);
557  g15r_pixelBox (canvas, x1, y1, x2 -5, y2, 1 - color, 1, 1);
558  break;
559  case 2:
560  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
561  g15r_pixelBox (canvas, x1, y1+5, x2 -5, y1+((y2/2)-3), 1 - color, 1, 1);
562  g15r_pixelBox (canvas, x1+5, y1+((y2/2)+3), x2 , y2-6, 1 - color, 1, 1);
563  break;
564  case 3:
565  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
566  g15r_pixelBox (canvas, x1, y1+5, x2 -5, y1+((y2/2)-3), 1 - color, 1, 1);
567  g15r_pixelBox (canvas, x1, y1+((y2/2)+3), x2-5 , y2-6, 1 - color, 1, 1);
568  break;
569  case 4:
570  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
571  g15r_pixelBox (canvas, x1, y1+((y2/2)+3), x2 -5, y2, 1 - color, 1, 1);
572  g15r_pixelBox (canvas, x1+5, y1, x2-5 , y1+((y2/2)-3), 1 - color, 1, 1);
573  break;
574  case 5:
575  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
576  g15r_pixelBox (canvas, x1+5, y1+5, x2 , y1+((y2/2)-3), 1 - color, 1, 1);
577  g15r_pixelBox (canvas, x1, y1+((y2/2)+3), x2-5 , y2-6, 1 - color, 1, 1);
578  break;
579  case 6:
580  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
581  g15r_pixelBox (canvas, x1+5, y1+5, x2 , y1+((y2/2)-3), 1 - color, 1, 1);
582  g15r_pixelBox (canvas, x1+5, y1+((y2/2)+3), x2-5 , y2-6, 1 - color, 1, 1);
583  break;
584  case 7:
585  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
586  g15r_pixelBox (canvas, x1, y1+5, x2 -5, y2, 1 - color, 1, 1);
587  break;
588  case 8:
589  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
590  g15r_pixelBox (canvas, x1+5, y1+5, x2-5 , y1+((y2/2)-3), 1 - color, 1, 1);
591  g15r_pixelBox (canvas, x1+5, y1+((y2/2)+3), x2-5 , y2-6, 1 - color, 1, 1);
592  break;
593  case 9:
594  g15r_pixelBox (canvas, x1, y1, x2, y2 , color, 1, 1);
595  g15r_pixelBox (canvas, x1+5, y1+5, x2-5 , y1+((y2/2)-3), 1 - color, 1, 1);
596  g15r_pixelBox (canvas, x1, y1+((y2/2)+3), x2-5 , y2, 1 - color, 1, 1);
597  break;
598  case 10:
599  g15r_pixelBox (canvas, x2-5, y1+5, x2, y1+10 , color, 1, 1);
600  g15r_pixelBox (canvas, x2-5, y2-10, x2, y2-5 , color, 1, 1);
601  break;
602  case 11:
603  g15r_pixelBox (canvas, x1, y1+((y2/2)-2), x2, y1+((y2/2)+2), color, 1, 1);
604  break;
605  case 12:
606  g15r_pixelBox (canvas, x2-5, y2-5, x2, y2 , color, 1, 1);
607  break;
608  }
609 }
610