| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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 */
59 static void swim_put_line_raw(SWIM_WINDOW_T *win,
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 */
112 static BOOL_32 swim_window_open_p(SWIM_WINDOW_T *win,
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 */
240 void swim_put_pixel(SWIM_WINDOW_T *win,
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 */
259 void swim_put_line(SWIM_WINDOW_T *win,
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 */
318 void swim_put_diamond(SWIM_WINDOW_T *win,
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 */
417 void swim_clear_screen(SWIM_WINDOW_T *win,
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) */
430 void swim_put_box(SWIM_WINDOW_T *win,
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 */
500 BOOL_32 swim_window_open(SWIM_WINDOW_T *win,
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 */
526 BOOL_32 swim_window_open_noclear(SWIM_WINDOW_T *win,
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 */
552 void swim_window_close(SWIM_WINDOW_T *win)
553 {
554 win->winused = 0x0;
555 }
556
557 /* Sets the pen color */
558 void swim_set_pen_color(SWIM_WINDOW_T *win,
559 COLOR_T pen_color)
560 {
561 win->pen = pen_color;
562 }
563
564 /* Sets the fill color */
565 void swim_set_fill_color(SWIM_WINDOW_T *win,
566 COLOR_T fill_color)
567 {
568 win->fill = fill_color;
569 }
570
571 /* Sets the color used for backgrounds */
572 void swim_set_bkg_color(SWIM_WINDOW_T *win,
573 COLOR_T bkg_color)
574 {
575 win->bkg = bkg_color;
576 }
577
578 /* Get the virtual window horizontal size */
579 int32_t swim_get_horizontal_size(SWIM_WINDOW_T *win)
580 {
581 return win->xvsize;
582 }
583
584 /* Get the virtual window vertical size */
585 int32_t swim_get_vertical_size(SWIM_WINDOW_T *win)
586 {
587 return win->yvsize;
588 }