LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpc_swim.c
Go to the documentation of this file.
1 /*
2  * @brief Simple Windowing Interface Manager (SWIM)
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "lpc_swim.h"
33 #include "lpc_fonts.h"
34 #include "lpc_helvr10.h"
35 
36 /*****************************************************************************
37  * Private types/enumerations/variables
38  ****************************************************************************/
39 
40 /*****************************************************************************
41  * Public types/enumerations/variables
42  ****************************************************************************/
43 
44 /*****************************************************************************
45  * Private functions
46  ****************************************************************************/
47 
48 /* Absolute value function */
49 static int32_t swim_abs(int32_t v1)
50 {
51  if (v1 > 0) {
52  return v1;
53  }
54 
55  return -v1;
56 }
57 
58 /* Draw a line on the physical display */
60  int32_t x1,
61  int32_t y1,
62  int32_t x2,
63  int32_t y2)
64 {
65  int32_t e2, sx, sy, dx, dy, err;
66 
67  /* calculate delta_x and delta_y */
68  dx = swim_abs(x2 - x1);
69  dy = swim_abs(y2 - y1);
70 
71  /* set the direction for the step for both x and y, and
72  initialize the error */
73  if (x1 < x2) {
74  sx = 1;
75  }
76  else {
77  sx = -1;
78  }
79 
80  if (y1 < y2) {
81  sy = 1;
82  }
83  else {
84  sy = -1;
85  }
86 
87  err = dx - dy;
88 
89  while (1) {
90  if ((x1 >= 0) && (x1 <= win->xpsize) &&
91  (y1 >= 0) && (y1 <= win->ypsize)) {
92  *(win->fb + x1 + (y1 * win->xpsize)) = win->pen;
93  }
94 
95  if ((x1 == x2) && (y1 == y2)) {
96  return;
97  }
98 
99  e2 = 2 * err;
100  if (e2 > -dy) {
101  err -= dy;
102  x1 += sx;
103  }
104  if (e2 < dx) {
105  err += dx;
106  y1 += sy;
107  }
108  }
109 }
110 
111 /* Initializes a window and the default values for the window */
113  int32_t xsize,
114  int32_t ysize,
115  COLOR_T *fbaddr,
116  int32_t xwin_min,
117  int32_t ywin_min,
118  int32_t xwin_max,
119  int32_t ywin_max,
120  int32_t border_width,
121  COLOR_T pcolor,
122  COLOR_T bkcolor,
123  COLOR_T fcolor,
124  BOOL_32 clear)
125 {
126  int32_t i;
127  BOOL_32 init = false;
128 
129  /* Before continuing, check to see that the window size is
130  in the physical dimensions of the display */
131  if ((xwin_min >= 0) && (ywin_min >= 0) &&
132  (xwin_max < xsize) && (ywin_max < ysize)) {
133  init = true;
134  }
135  else {
136  /* Window size is out of the physical display size, so it
137  should be invalidated */
138  win->winused = 0x0;
139  }
140 
141  if (init == true) {
142  /* Save physical display dimensions */
143  win->xpsize = xsize;
144  win->ypsize = ysize;
145 
146  /* Save frame buffer address */
147  win->fb = fbaddr;
148 
149  /* Save physical window dimensions and default colors */
150  win->xpmin = xwin_min;
151  win->ypmin = ywin_min;
152  win->xpmax = xwin_max;
153  win->ypmax = ywin_max;
154  win->pen = pcolor;
155  win->bkg = bkcolor;
156  win->fill = fcolor;
157 
158  /* Compute physical window dimensions of draw area only */
159  win->xpvmin = xwin_min + border_width;
160  win->ypvmin = ywin_min + border_width;
161  win->xpvmax = xwin_max - border_width;
162  win->ypvmax = ywin_max - border_width;
163 
164  /* Compute virtual window size of draw area */
165  win->xvsize = xwin_max - xwin_min - 2 * border_width;
166  win->yvsize = ywin_max - ywin_min - 2 * border_width;
167 
168  /* Fill in any unused border padding between draw area and border
169  will fill color */
170  for (i = 0; i < border_width; i++) {
171  swim_put_line_raw(win, (xwin_min + i),
172  (ywin_min + i), (xwin_max - i), (ywin_min + i));
173  swim_put_line_raw(win, (xwin_max - i),
174  (ywin_min + i), (xwin_max - i), (ywin_max - i));
175  swim_put_line_raw(win, (xwin_max - i),
176  (ywin_max - i), (xwin_min + i), (ywin_max - i));
177  swim_put_line_raw(win, (xwin_min + i),
178  (ywin_max - i), (xwin_min + i), (ywin_min + i));
179  }
180 
181  /* Clear draw area with background color */
182  if (clear == true) {
183  swim_clear_screen(win, bkcolor);
184  }
185 
186  /* Use the default font and make background transparent */
187  win->font = (FONT_T *) &font_helvr10;
188 
189  /* Set starting text position in upper left of window */
190  win->xvpos = win->xpvmin;
191  win->yvpos = win->ypvmin;
192  }
193 
194  return init;
195 }
196 
197 /* Circle support function */
198 static void swim_plot4points(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t x, int32_t y, int32_t Filled)
199 {
200  int16_t x0, x1, y0, y1;
201 
202  y0 = cy + y;
203  y1 = cy - y;
204  if ( Filled ) {
205  for ( x0 = cx - x; x0 <= cx + x; x0++ ) {
206  *(win->fb + x0 + (y0 * win->xpsize)) = win->pen;
207  *(win->fb + x0 + (y1 * win->xpsize)) = win->pen;
208  }
209  }
210  else {
211  x0 = cx + x;
212  x1 = cx - x;
213  *(win->fb + x0 + (y0 * win->xpsize)) = win->pen;
214  if (x != 0) {
215  *(win->fb + x1 + (y0 * win->xpsize)) = win->pen;
216  }
217  if (y != 0) {
218  *(win->fb + x0 + (y1 * win->xpsize)) = win->pen;
219  }
220  if (( x != 0) && ( y != 0) ) {
221  *(win->fb + x1 + (y1 * win->xpsize)) = win->pen;
222  }
223  }
224 }
225 
226 /* Circle support function */
227 static void swim_plot8points(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t x, int32_t y, int32_t Filled)
228 {
229  swim_plot4points(win, cx, cy, x, y, Filled);
230  if (x != y) {
231  swim_plot4points(win, cx, cy, y, x, Filled);
232  }
233 }
234 
235 /***********************************************************************
236  * Public functions
237  **********************************************************************/
238 
239 /* Puts a pixel at the virtual X, Y coordinate in the window */
241  int32_t x1,
242  int32_t y1)
243 {
244  int16_t realx, realy;
245 
246  /* Convert virtual coordinate to physical coordinate taking into
247  consideration the border size of the window */
248  realx = win->xpvmin + x1;
249  realy = win->ypvmin + y1;
250 
251  /* Only put the pixel in the window if it fits in the window */
252  if ((realx <= win->xpvmax) &&
253  (realy <= win->ypvmax)) {
254  *(win->fb + realx + (realy * win->xpsize)) = win->pen;
255  }
256 }
257 
258 /* Draw a line in the virtual window with clipping */
260  int32_t x1,
261  int32_t y1,
262  int32_t x2,
263  int32_t y2)
264 {
265  int32_t e2, sx, sy, dx, dy, err;
266 
267  /* Convert virtual coordinates to physical coordinates */
268  x1 = x1 + win->xpvmin;
269  x2 = x2 + win->xpvmin;
270  y1 = y1 + win->ypvmin;
271  y2 = y2 + win->ypvmin;
272 
273  /* calculate delta_x and delta_y */
274  dx = swim_abs(x2 - x1);
275  dy = swim_abs(y2 - y1);
276 
277  /* set the direction for the step for both x and y, and
278  initialize the error */
279  if (x1 < x2) {
280  sx = 1;
281  }
282  else {
283  sx = -1;
284  }
285 
286  if (y1 < y2) {
287  sy = 1;
288  }
289  else {
290  sy = -1;
291  }
292 
293  err = dx - dy;
294 
295  while (1) {
296  if ((x1 >= win->xpvmin) && (x1 <= win->xpvmax) &&
297  (y1 >= win->ypvmin) && (y1 <= win->ypvmax)) {
298  *(win->fb + x1 + (y1 * win->xpsize)) = win->pen;
299  }
300 
301  if ((x1 == x2) && (y1 == y2)) {
302  return;
303  }
304 
305  e2 = 2 * err;
306  if (e2 > -dy) {
307  err -= dy;
308  x1 += sx;
309  }
310  if (e2 < dx) {
311  err += dx;
312  y1 += sy;
313  }
314  }
315 }
316 
317 /* Draw a diamond in the virtual window */
319  int32_t x,
320  int32_t y,
321  int32_t rx,
322  int32_t ry)
323 {
324  int32_t xleft, xright, xleft1, xleft2, xright1, idy, ypmid;
325  int32_t ypmin, ypmax, dlta, err, e2;
326 
327  /* Use line draw functions to draw border in pen color in virtual
328  coordinates */
329  swim_put_line(win, x - rx, y, x, y - ry);
330  swim_put_line(win, x + rx, y, x, y - ry);
331  swim_put_line(win, x - rx, y, x, y + ry);
332  swim_put_line(win, x + rx, y, x, y + ry);
333 
334  /* Adjust rx and rx for interior fill region minus border */
335  rx--;
336  ry--;
337  if ((rx <= 0) || (ry <= 0)) {
338  return;
339  }
340 
341  /* Y limits in physical coordinates minus border line */
342  ypmin = y - ry + win->ypvmin;
343  ypmid = y + win->ypvmin;
344  ypmax = y + ry + win->ypvmin;
345 
346  /* X starts draw from center line */
347  xleft = xright = x + win->xpvmin;
348 
349  err = rx - ry;
350  dlta = 1 + rx / ry;
351 
352  for (idy = ypmin; idy <= ypmid; idy++) {
353  xleft1 = xleft2 = xleft;
354  xright1 = xright;
355 
356  /* Clip left and right to virtual window size */
357  if (xleft1 < win->xpvmin) {
358  xleft2 = xleft1 = win->xpvmin;
359  }
360  if (xright1 > win->xpvmax) {
361  xright1 = win->xpvmax;
362  }
363 
364  /* Is top half visible? */
365  if ((idy >= win->ypvmin) && (idy <= win->ypvmax)) {
366  while (xleft1 <= xright1) {
367  *(win->fb + xleft1 + (idy * win->xpsize)) = win->fill;
368  xleft1++;
369  }
370  }
371 
372  /* Draw bottom half if visible */
373  if ((ypmax >= ypmid) && (ypmax <= win->ypvmax)) {
374  /* Mirror bottom */
375  while (xleft2 <= xright1) {
376  *(win->fb + xleft2 + (ypmax * win->xpsize)) = win->fill;
377  xleft2++;
378  }
379  }
380  ypmax--;
381 
382  e2 = 2 * err;
383  if (e2 > -ry) {
384  err -= ry;
385  xleft -= dlta;
386  xright += dlta;
387  }
388  if (e2 < rx) {
389  err += rx;
390  }
391  }
392 }
393 
394 /* Draws a circle in the virtual window */
395 void swim_put_circle(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t radius, int32_t Filled)
396 {
397  int32_t Error = -radius;
398  int16_t x = radius;
399  int16_t y = 0;
400 
401  while ( x >= y ) {
402  swim_plot8points(win, cx, cy, x, y, Filled);
403 
404  Error += y;
405  ++y;
406  Error += y;
407 
408  if ( Error >= 0 ) {
409  --x;
410  Error -= x;
411  Error -= x;
412  }
413  }
414 }
415 
416 /* Fills the draw area of the display with the selected color */
418  COLOR_T colr)
419 {
420  int32_t x, y;
421 
422  for (y = win->ypvmin; y <= win->ypvmax; y++) {
423  for (x = win->xpvmin; x <= win->xpvmax; x++) {
424  *(win->fb + x + (y * win->xpsize)) = colr;
425  }
426  }
427 }
428 
429 /* Place a box with corners (X1, Y1) and (X2, Y2) */
431  int32_t x1,
432  int32_t y1,
433  int32_t x2,
434  int32_t y2)
435 {
436  int32_t xinc, yinc;
437  int32_t ysave;
438 
439  if (x1 > x2) {
440  xinc = x1;
441  x1 = x2;
442  x2 = xinc;
443  }
444 
445  /* Swap y1 and y2 if y1 is larger than y2 */
446  if (y1 > y2) {
447  yinc = y1;
448  y1 = y2;
449  y2 = yinc;
450  }
451 
452  /* Convert virtual coordinates to physical coordinates */
453  x1 = x1 + win->xpvmin;
454  x2 = x2 + win->xpvmin;
455  y1 = y1 + win->ypvmin;
456  y2 = y2 + win->ypvmin;
457 
458  /* Clip boxes to window sizes */
459  if (x1 < win->xpvmin) {
460  x1 = win->xpvmin;
461  }
462  if (y1 < win->ypvmin) {
463  y1 = win->ypvmin;
464  }
465  if (x2 > win->xpvmax) {
466  x2 = win->xpvmax;
467  }
468  if (y2 > win->ypvmax) {
469  y2 = win->ypvmax;
470  }
471 
472  /* Get X and Y differences */
473  xinc = x2 - x1;
474  yinc = y2 - y1;
475 
476  /* Make outer edge of box in pen color */
477  swim_put_line_raw(win, x1, y1, x2, y1);
478  swim_put_line_raw(win, x2, y1, x2, y2);
479  swim_put_line_raw(win, x2, y2, x1, y2);
480  swim_put_line_raw(win, x1, y2, x1, y1);
481 
482  /* Increment X, Y values so they won't overwrite the edge */
483  x1++;
484  y1++;
485 
486  /* Draw the box inside with the fill color */
487  ysave = y1;
488  while (x1 < x2) {
489  y1 = ysave;
490  while (y1 < y2) {
491  *(win->fb + x1 + (y1 * win->xpsize)) = win->fill;
492  y1++;
493  }
494 
495  x1++;
496  }
497 }
498 
499 /* Initializes a window and the default values for the window */
501  int32_t xsize,
502  int32_t ysize,
503  COLOR_T *fbaddr,
504  int32_t xwin_min,
505  int32_t ywin_min,
506  int32_t xwin_max,
507  int32_t ywin_max,
508  int32_t border_width,
509  COLOR_T pcolor,
510  COLOR_T bkcolor,
511  COLOR_T fcolor)
512 {
513  BOOL_32 init;
514 
515  init = swim_window_open_p(win, xsize, ysize, fbaddr, xwin_min,
516  ywin_min, xwin_max, ywin_max, border_width, pcolor, bkcolor,
517  fcolor, true);
518 
519  /* Default font background is not transparent */
520  win->tfont = 1;
521 
522  return init;
523 }
524 
525 /* Initializes a window without clearing it */
527  int32_t xsize,
528  int32_t ysize,
529  COLOR_T *fbaddr,
530  int32_t xwin_min,
531  int32_t ywin_min,
532  int32_t xwin_max,
533  int32_t ywin_max,
534  int32_t border_width,
535  COLOR_T pcolor,
536  COLOR_T bkcolor,
537  COLOR_T fcolor)
538 {
539  BOOL_32 init;
540 
541  init = swim_window_open_p(win, xsize, ysize, fbaddr, xwin_min,
542  ywin_min, xwin_max, ywin_max, border_width, pcolor, bkcolor,
543  fcolor, false);
544 
545  /* Default font background is transparent */
546  win->tfont = 0;
547 
548  return init;
549 }
550 
551 /* Deallocates a window */
553 {
554  win->winused = 0x0;
555 }
556 
557 /* Sets the pen color */
559  COLOR_T pen_color)
560 {
561  win->pen = pen_color;
562 }
563 
564 /* Sets the fill color */
566  COLOR_T fill_color)
567 {
568  win->fill = fill_color;
569 }
570 
571 /* Sets the color used for backgrounds */
573  COLOR_T bkg_color)
574 {
575  win->bkg = bkg_color;
576 }
577 
578 /* Get the virtual window horizontal size */
580 {
581  return win->xvsize;
582 }
583 
584 /* Get the virtual window vertical size */
586 {
587  return win->yvsize;
588 }