A basic graphics package for the LPC4088 Display Module.

Dependents:   lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI lpc4088_displaymodule_fs_aid ... more

Fork of DMBasicGUI by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lpc_swim.c Source File

lpc_swim.c

00001 /*
00002  * @brief Simple Windowing Interface Manager (SWIM)
00003  *
00004  * @note
00005  * Copyright(C) NXP Semiconductors, 2012
00006  * All rights reserved.
00007  *
00008  * @par
00009  * Software that is described herein is for illustrative purposes only
00010  * which provides customers with programming information regarding the
00011  * LPC products.  This software is supplied "AS IS" without any warranties of
00012  * any kind, and NXP Semiconductors and its licensor disclaim any and
00013  * all warranties, express or implied, including all implied warranties of
00014  * merchantability, fitness for a particular purpose and non-infringement of
00015  * intellectual property rights.  NXP Semiconductors assumes no responsibility
00016  * or liability for the use of the software, conveys no license or rights under any
00017  * patent, copyright, mask work right, or any other intellectual property rights in
00018  * or to any products. NXP Semiconductors reserves the right to make changes
00019  * in the software without notification. NXP Semiconductors also makes no
00020  * representation or warranty that such application will be suitable for the
00021  * specified use without further testing or modification.
00022  *
00023  * @par
00024  * Permission to use, copy, modify, and distribute this software and its
00025  * documentation is hereby granted, under NXP Semiconductors' and its
00026  * licensor's relevant copyrights in the software, without fee, provided that it
00027  * is used in conjunction with NXP Semiconductors microcontrollers.  This
00028  * copyright, permission, and disclaimer notice must appear in all copies of
00029  * this code.
00030  */
00031 
00032 #include "lpc_swim.h"
00033 #include "lpc_fonts.h"
00034 #include "lpc_helvr10.h"
00035 
00036 /*****************************************************************************
00037  * Private types/enumerations/variables
00038  ****************************************************************************/
00039 
00040 static const FONT_T* defaultFont = (FONT_T*)&font_helvr10;
00041 
00042 /*****************************************************************************
00043  * Public types/enumerations/variables
00044  ****************************************************************************/
00045 
00046 /*****************************************************************************
00047  * Private functions
00048  ****************************************************************************/
00049 
00050 /* Absolute value function */
00051 static int32_t swim_abs(int32_t v1)
00052 {
00053     if (v1 > 0) {
00054         return v1;
00055     }
00056 
00057     return -v1;
00058 }
00059 
00060 /* Draw a line on the physical display */
00061 static void swim_put_line_raw(SWIM_WINDOW_T *win,
00062                               int32_t x1,
00063                               int32_t y1,
00064                               int32_t x2,
00065                               int32_t y2)
00066 {
00067     int32_t e2, sx, sy, dx, dy, err;
00068 
00069     /* calculate delta_x and delta_y */
00070     dx = swim_abs(x2 - x1);
00071     dy = swim_abs(y2 - y1);
00072 
00073     /* set the direction for the step for both x and y, and
00074        initialize the error */
00075     if (x1 < x2) {
00076         sx = 1;
00077     }
00078     else {
00079         sx = -1;
00080     }
00081 
00082     if (y1 < y2) {
00083         sy = 1;
00084     }
00085     else {
00086         sy = -1;
00087     }
00088 
00089     err = dx - dy;
00090 
00091     while (1) {
00092         if ((x1 >= 0) && (x1 <= win->xpsize) &&
00093             (y1 >= 0) && (y1 <= win->ypsize)) {
00094             swim_put_pixel_physical(win, x1, y1, win->pen);
00095         }
00096 
00097         if ((x1 == x2) && (y1 == y2)) {
00098             return;
00099         }
00100 
00101         e2 = 2 * err;
00102         if (e2 > -dy) {
00103             err -= dy;
00104             x1 += sx;
00105         }
00106         if (e2 < dx) {
00107             err += dx;
00108             y1 += sy;
00109         }
00110     }
00111 }
00112 
00113 /* Initializes a window and the default values for the window */
00114 static BOOL_32 swim_window_open_p(SWIM_WINDOW_T *win,
00115                                   int32_t xsize,
00116                                   int32_t ysize,
00117                                   COLOR_T *fbaddr,
00118                                   int32_t xwin_min,
00119                                   int32_t ywin_min,
00120                                   int32_t xwin_max,
00121                                   int32_t ywin_max,
00122                                   int32_t border_width,
00123                                   COLOR_T pcolor,
00124                                   COLOR_T bkcolor,
00125                                   COLOR_T fcolor,
00126                                   BOOL_32 clear)
00127 {
00128     int32_t i;
00129     BOOL_32 init = false;
00130 
00131     /* Before continuing, check to see that the window size is
00132        in the physical dimensions of the display */
00133     if ((xwin_min >= 0) && (ywin_min >= 0) &&
00134         (xwin_max < xsize) && (ywin_max < ysize)) {
00135         init = true;
00136     }
00137     else {
00138         /* Window size is out of the physical display size, so it
00139            should be invalidated */
00140         win->winused = 0x0;
00141     }
00142 
00143     if (init == true) {
00144         /* Save physical display dimensions */
00145         win->xpsize = xsize;
00146         win->ypsize = ysize;
00147 
00148         /* Save frame buffer address */
00149         win->fb = fbaddr;
00150 
00151         /* Save physical window dimensions and default colors */
00152         win->xpmin = xwin_min;
00153         win->ypmin = ywin_min;
00154         win->xpmax = xwin_max;
00155         win->ypmax = ywin_max;
00156         win->pen = pcolor;
00157         win->bkg = bkcolor;
00158         win->fill = fcolor;
00159 
00160         /* Compute physical window dimensions of draw area only */
00161         win->xpvmin = xwin_min + border_width;
00162         win->ypvmin = ywin_min + border_width;
00163         win->xpvmax = xwin_max - border_width;
00164         win->ypvmax = ywin_max - border_width;
00165 
00166         /* Compute virtual window size of draw area */
00167         win->xvsize = xwin_max - xwin_min - 2 * border_width;
00168         win->yvsize = ywin_max - ywin_min - 2 * border_width;
00169 
00170         /* Fill in any unused border padding between draw area and border
00171            will fill color */
00172         for (i = 0; i < border_width; i++) {
00173             swim_put_line_raw(win, (xwin_min + i),
00174                               (ywin_min + i), (xwin_max - i), (ywin_min + i));
00175             swim_put_line_raw(win, (xwin_max - i),
00176                               (ywin_min + i), (xwin_max - i), (ywin_max - i));
00177             swim_put_line_raw(win, (xwin_max - i),
00178                               (ywin_max - i), (xwin_min + i), (ywin_max - i));
00179             swim_put_line_raw(win, (xwin_min + i),
00180                               (ywin_max - i), (xwin_min + i), (ywin_min + i));
00181         }
00182 
00183         /* Clear draw area with background color */
00184         if (clear == true) {
00185             swim_clear_screen(win, bkcolor);
00186         }
00187 
00188         /* Use the default font and make background transparent */
00189         win->font = (FONT_T*)defaultFont;
00190 
00191         /* Set starting text position in upper left of window */
00192         win->xvpos = win->xpvmin;
00193         win->yvpos = win->ypvmin;
00194     }
00195 
00196     return init;
00197 }
00198 
00199 /* Circle support function */
00200 static void swim_plot4points(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t x, int32_t y, int32_t Filled)
00201 {
00202     int16_t x0, x1, y0, y1;
00203 
00204     y0 = cy + y;
00205     y1 = cy - y;
00206     if ( Filled ) {
00207         for ( x0 = cx - x; x0 <= cx + x; x0++ ) {
00208             swim_put_pixel_physical(win, x0, y0, win->pen);
00209             swim_put_pixel_physical(win, x0, y1, win->pen);
00210         }
00211     }
00212     else {
00213         x0 = cx + x;
00214         x1 = cx - x;
00215         swim_put_pixel_physical(win, x0, y0, win->pen);
00216         if (x != 0) {
00217             swim_put_pixel_physical(win, x1, y0, win->pen);
00218         }
00219         if (y != 0) {
00220             swim_put_pixel_physical(win, x0, y1, win->pen);
00221         }
00222         if (( x != 0) && ( y != 0) ) {
00223             swim_put_pixel_physical(win, x1, y1, win->pen);
00224         }
00225     }
00226 }
00227 
00228 /* Circle support function */
00229 static void swim_plot8points(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t x, int32_t y, int32_t Filled)
00230 {
00231     swim_plot4points(win, cx, cy, x, y, Filled);
00232     if (x != y) {
00233         swim_plot4points(win, cx, cy, y, x, Filled);
00234     }
00235 }
00236 
00237 /***********************************************************************
00238  * Public functions
00239  **********************************************************************/
00240 
00241 /* Puts a pixel at the virtual X, Y coordinate in the window */
00242 void swim_put_pixel(SWIM_WINDOW_T *win,
00243                     int32_t x1,
00244                     int32_t y1)
00245 {
00246     int16_t realx, realy;
00247 
00248     /* Convert virtual coordinate to physical coordinate taking into
00249        consideration the border size of the window */
00250     realx = win->xpvmin + x1;
00251     realy = win->ypvmin + y1;
00252 
00253     /* Only put the pixel in the window if it fits in the window */
00254     if ((realx <= win->xpvmax) &&
00255         (realy <= win->ypvmax)) {
00256         swim_put_pixel_physical(win, realx, realy, win->pen);
00257     }
00258 }
00259 
00260 /* Draw a line in the virtual window with clipping */
00261 void swim_put_line(SWIM_WINDOW_T *win,
00262                    int32_t x1,
00263                    int32_t y1,
00264                    int32_t x2,
00265                    int32_t y2)
00266 {
00267     int32_t e2, sx, sy, dx, dy, err;
00268 
00269     /* Convert virtual coordinates to physical coordinates */
00270     x1 = x1 + win->xpvmin;
00271     x2 = x2 + win->xpvmin;
00272     y1 = y1 + win->ypvmin;
00273     y2 = y2 + win->ypvmin;
00274 
00275     /* calculate delta_x and delta_y */
00276     dx = swim_abs(x2 - x1);
00277     dy = swim_abs(y2 - y1);
00278 
00279     /* set the direction for the step for both x and y, and
00280        initialize the error */
00281     if (x1 < x2) {
00282         sx = 1;
00283     }
00284     else {
00285         sx = -1;
00286     }
00287 
00288     if (y1 < y2) {
00289         sy = 1;
00290     }
00291     else {
00292         sy = -1;
00293     }
00294 
00295     err = dx - dy;
00296 
00297     while (1) {
00298         if ((x1 >= win->xpvmin) && (x1 <= win->xpvmax) &&
00299             (y1 >= win->ypvmin) && (y1 <= win->ypvmax)) {
00300             swim_put_pixel_physical(win, x1, y1, win->pen);
00301         }
00302 
00303         if ((x1 == x2) && (y1 == y2)) {
00304             return;
00305         }
00306 
00307         e2 = 2 * err;
00308         if (e2 > -dy) {
00309             err -= dy;
00310             x1 += sx;
00311         }
00312         if (e2 < dx) {
00313             err += dx;
00314             y1 += sy;
00315         }
00316     }
00317 }
00318 
00319 /* Draw a diamond in the virtual window */
00320 void swim_put_diamond(SWIM_WINDOW_T *win,
00321                       int32_t x,
00322                       int32_t y,
00323                       int32_t rx,
00324                       int32_t ry)
00325 {
00326     int32_t xleft, xright, xleft1, xleft2, xright1, idy, ypmid;
00327     int32_t ypmin, ypmax, dlta, err, e2;
00328 
00329     /* Use line draw functions to draw border in pen color in virtual
00330        coordinates */
00331     swim_put_line(win, x - rx, y, x, y - ry);
00332     swim_put_line(win, x + rx, y, x, y - ry);
00333     swim_put_line(win, x - rx, y, x, y + ry);
00334     swim_put_line(win, x + rx, y, x, y + ry);
00335 
00336     /* Adjust rx and rx for interior fill region minus border */
00337     rx--;
00338     ry--;
00339     if ((rx <= 0) || (ry <= 0)) {
00340         return;
00341     }
00342 
00343     /* Y limits in physical coordinates minus border line */
00344     ypmin = y - ry + win->ypvmin;
00345     ypmid = y + win->ypvmin;
00346     ypmax = y + ry + win->ypvmin;
00347 
00348     /* X starts draw from center line */
00349     xleft = xright = x + win->xpvmin;
00350 
00351     err = rx - ry;
00352     dlta = 1 + rx / ry;
00353 
00354     for (idy = ypmin; idy <= ypmid; idy++) {
00355         xleft1 = xleft2 = xleft;
00356         xright1 = xright;
00357 
00358         /* Clip left and right to virtual window size */
00359         if (xleft1 < win->xpvmin) {
00360             xleft2 = xleft1 = win->xpvmin;
00361         }
00362         if (xright1 > win->xpvmax) {
00363             xright1 = win->xpvmax;
00364         }
00365 
00366         /* Is top half visible? */
00367         if ((idy >= win->ypvmin) && (idy <= win->ypvmax)) {
00368             while (xleft1 <= xright1) {
00369                 swim_put_pixel_physical(win, xleft1, idy, win->fill);
00370                 xleft1++;
00371             }
00372         }
00373 
00374         /* Draw bottom half if visible */
00375         if ((ypmax >= ypmid) && (ypmax <= win->ypvmax)) {
00376             /* Mirror bottom */
00377             while (xleft2 <= xright1) {
00378                 swim_put_pixel_physical(win, xleft2, ypmax, win->fill);
00379                 xleft2++;
00380             }
00381         }
00382         ypmax--;
00383 
00384         e2 = 2 * err;
00385         if (e2 > -ry) {
00386             err -= ry;
00387             xleft -= dlta;
00388             xright += dlta;
00389         }
00390         if (e2 < rx) {
00391             err += rx;
00392         }
00393     }
00394 }
00395 
00396 /* Draws a circle in the virtual window */
00397 void swim_put_circle(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t radius, int32_t Filled)
00398 {
00399     int32_t Error = -radius;
00400     int16_t x = radius;
00401     int16_t y = 0;
00402 
00403     /* Convert virtual coordinates to physical coordinates */
00404     cx += win->xpvmin;
00405     cy += win->ypvmin;
00406 
00407     while ( x >= y ) {
00408         swim_plot8points(win, cx, cy, x, y, Filled);
00409 
00410         Error += y;
00411         ++y;
00412         Error += y;
00413 
00414         if ( Error >= 0 ) {
00415             --x;
00416             Error -= x;
00417             Error -= x;
00418         }
00419     }
00420 }
00421 
00422 /* Fills the draw area of the display with the selected color */
00423 void swim_clear_screen(SWIM_WINDOW_T *win,
00424                        COLOR_T colr)
00425 {
00426     int32_t x, y;
00427 
00428     for (y = win->ypvmin; y <= win->ypvmax; y++) {
00429         for (x = win->xpvmin; x <= win->xpvmax; x++) {
00430             swim_put_pixel_physical(win, x, y, colr);
00431         }
00432     }
00433 }
00434 
00435 /* Place a box with corners (X1, Y1) and (X2, Y2) */
00436 void swim_put_box(SWIM_WINDOW_T *win,
00437                   int32_t x1,
00438                   int32_t y1,
00439                   int32_t x2,
00440                   int32_t y2)
00441 {
00442     int32_t xinc, yinc;
00443     int32_t ysave;
00444 
00445     if (x1 > x2) {
00446         xinc = x1;
00447         x1 = x2;
00448         x2 = xinc;
00449     }
00450 
00451     /* Swap y1 and y2 if y1 is larger than y2 */
00452     if (y1 > y2) {
00453         yinc = y1;
00454         y1 = y2;
00455         y2 = yinc;
00456     }
00457 
00458     /* Convert virtual coordinates to physical coordinates */
00459     x1 = x1 + win->xpvmin;
00460     x2 = x2 + win->xpvmin;
00461     y1 = y1 + win->ypvmin;
00462     y2 = y2 + win->ypvmin;
00463 
00464     /* Clip boxes to window sizes */
00465     if (x1 < win->xpvmin) {
00466         x1 = win->xpvmin;
00467     }
00468     if (y1 < win->ypvmin) {
00469         y1 = win->ypvmin;
00470     }
00471     if (x2 > win->xpvmax) {
00472         x2 = win->xpvmax;
00473     }
00474     if (y2 > win->ypvmax) {
00475         y2 = win->ypvmax;
00476     }
00477 
00478     /* Get X and Y differences */
00479     xinc = x2 - x1;
00480     yinc = y2 - y1;
00481 
00482     /* Make outer edge of box in pen color */
00483     swim_put_line_raw(win, x1, y1, x2, y1);
00484     swim_put_line_raw(win, x2, y1, x2, y2);
00485     swim_put_line_raw(win, x2, y2, x1, y2);
00486     swim_put_line_raw(win, x1, y2, x1, y1);
00487 
00488     /* Increment X, Y values so they won't overwrite the edge */
00489     x1++;
00490     y1++;
00491 
00492     /* Draw the box inside with the fill color */
00493     ysave = y1;
00494     while (x1 < x2) {
00495         y1 = ysave;
00496         while (y1 < y2) {
00497             swim_put_pixel_physical(win, x1, y1, win->fill);
00498             y1++;
00499         }
00500 
00501         x1++;
00502     }
00503 }
00504 
00505 /* Initializes a window and the default values for the window */
00506 BOOL_32 swim_window_open(SWIM_WINDOW_T *win,
00507                          int32_t xsize,
00508                          int32_t ysize,
00509                          COLOR_T *fbaddr,
00510                          int32_t xwin_min,
00511                          int32_t ywin_min,
00512                          int32_t xwin_max,
00513                          int32_t ywin_max,
00514                          int32_t border_width,
00515                          COLOR_T pcolor,
00516                          COLOR_T bkcolor,
00517                          COLOR_T fcolor)
00518 {
00519     BOOL_32 init;
00520 
00521     init = swim_window_open_p(win, xsize, ysize, fbaddr, xwin_min,
00522                               ywin_min, xwin_max, ywin_max, border_width, pcolor, bkcolor,
00523                               fcolor, true);
00524 
00525     /* Default font background is not transparent */
00526     win->tfont = 1;
00527 
00528     return init;
00529 }
00530 
00531 /* Initializes a window without clearing it */
00532 BOOL_32 swim_window_open_noclear(SWIM_WINDOW_T *win,
00533                                  int32_t xsize,
00534                                  int32_t ysize,
00535                                  COLOR_T *fbaddr,
00536                                  int32_t xwin_min,
00537                                  int32_t ywin_min,
00538                                  int32_t xwin_max,
00539                                  int32_t ywin_max,
00540                                  int32_t border_width,
00541                                  COLOR_T pcolor,
00542                                  COLOR_T bkcolor,
00543                                  COLOR_T fcolor)
00544 {
00545     BOOL_32 init;
00546 
00547     init = swim_window_open_p(win, xsize, ysize, fbaddr, xwin_min,
00548                               ywin_min, xwin_max, ywin_max, border_width, pcolor, bkcolor,
00549                               fcolor, false);
00550 
00551     /* Default font background is transparent */
00552     win->tfont = 0;
00553 
00554     return init;
00555 }
00556 
00557 /* Deallocates a window */
00558 void swim_window_close(SWIM_WINDOW_T *win)
00559 {
00560     win->winused = 0x0;
00561 }
00562 
00563 /* Sets the pen color */
00564 void swim_set_pen_color(SWIM_WINDOW_T *win,
00565                         COLOR_T pen_color)
00566 {
00567     win->pen = pen_color;
00568 }
00569 
00570 /* Sets the fill color */
00571 void swim_set_fill_color(SWIM_WINDOW_T *win,
00572                          COLOR_T fill_color)
00573 {
00574     win->fill = fill_color;
00575 }
00576 
00577 /* Sets the color used for backgrounds */
00578 void swim_set_bkg_color(SWIM_WINDOW_T *win,
00579                         COLOR_T bkg_color)
00580 {
00581     win->bkg = bkg_color;
00582 }
00583 
00584 /* Sets the font to be used for all new windows */
00585 void swim_set_default_font(const FONT_T* def_font)
00586 {
00587     defaultFont = def_font;
00588 }
00589 
00590 /* Get the virtual window horizontal size */
00591 int32_t swim_get_horizontal_size(SWIM_WINDOW_T *win)
00592 {
00593     return win->xvsize;
00594 }
00595 
00596 /* Get the virtual window vertical size */
00597 int32_t swim_get_vertical_size(SWIM_WINDOW_T *win)
00598 {
00599     return win->yvsize;
00600 }
00601