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
Diff: lpc_swim/lpc_swim.c
- Revision:
- 0:4977187e90c7
- Child:
- 17:6e2abf107800
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc_swim/lpc_swim.c Thu Dec 11 11:03:57 2014 +0000 @@ -0,0 +1,593 @@ +/* + * @brief Simple Windowing Interface Manager (SWIM) + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "lpc_swim.h" +#include "lpc_fonts.h" +#include "lpc_helvr10.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Absolute value function */ +static int32_t swim_abs(int32_t v1) +{ + if (v1 > 0) { + return v1; + } + + return -v1; +} + +/* Draw a line on the physical display */ +static void swim_put_line_raw(SWIM_WINDOW_T *win, + int32_t x1, + int32_t y1, + int32_t x2, + int32_t y2) +{ + int32_t e2, sx, sy, dx, dy, err; + + /* calculate delta_x and delta_y */ + dx = swim_abs(x2 - x1); + dy = swim_abs(y2 - y1); + + /* set the direction for the step for both x and y, and + initialize the error */ + if (x1 < x2) { + sx = 1; + } + else { + sx = -1; + } + + if (y1 < y2) { + sy = 1; + } + else { + sy = -1; + } + + err = dx - dy; + + while (1) { + if ((x1 >= 0) && (x1 <= win->xpsize) && + (y1 >= 0) && (y1 <= win->ypsize)) { + swim_put_pixel_physical(win, x1, y1, win->pen); + } + + if ((x1 == x2) && (y1 == y2)) { + return; + } + + e2 = 2 * err; + if (e2 > -dy) { + err -= dy; + x1 += sx; + } + if (e2 < dx) { + err += dx; + y1 += sy; + } + } +} + +/* Initializes a window and the default values for the window */ +static BOOL_32 swim_window_open_p(SWIM_WINDOW_T *win, + int32_t xsize, + int32_t ysize, + COLOR_T *fbaddr, + int32_t xwin_min, + int32_t ywin_min, + int32_t xwin_max, + int32_t ywin_max, + int32_t border_width, + COLOR_T pcolor, + COLOR_T bkcolor, + COLOR_T fcolor, + BOOL_32 clear) +{ + int32_t i; + BOOL_32 init = false; + + /* Before continuing, check to see that the window size is + in the physical dimensions of the display */ + if ((xwin_min >= 0) && (ywin_min >= 0) && + (xwin_max < xsize) && (ywin_max < ysize)) { + init = true; + } + else { + /* Window size is out of the physical display size, so it + should be invalidated */ + win->winused = 0x0; + } + + if (init == true) { + /* Save physical display dimensions */ + win->xpsize = xsize; + win->ypsize = ysize; + + /* Save frame buffer address */ + win->fb = fbaddr; + + /* Save physical window dimensions and default colors */ + win->xpmin = xwin_min; + win->ypmin = ywin_min; + win->xpmax = xwin_max; + win->ypmax = ywin_max; + win->pen = pcolor; + win->bkg = bkcolor; + win->fill = fcolor; + + /* Compute physical window dimensions of draw area only */ + win->xpvmin = xwin_min + border_width; + win->ypvmin = ywin_min + border_width; + win->xpvmax = xwin_max - border_width; + win->ypvmax = ywin_max - border_width; + + /* Compute virtual window size of draw area */ + win->xvsize = xwin_max - xwin_min - 2 * border_width; + win->yvsize = ywin_max - ywin_min - 2 * border_width; + + /* Fill in any unused border padding between draw area and border + will fill color */ + for (i = 0; i < border_width; i++) { + swim_put_line_raw(win, (xwin_min + i), + (ywin_min + i), (xwin_max - i), (ywin_min + i)); + swim_put_line_raw(win, (xwin_max - i), + (ywin_min + i), (xwin_max - i), (ywin_max - i)); + swim_put_line_raw(win, (xwin_max - i), + (ywin_max - i), (xwin_min + i), (ywin_max - i)); + swim_put_line_raw(win, (xwin_min + i), + (ywin_max - i), (xwin_min + i), (ywin_min + i)); + } + + /* Clear draw area with background color */ + if (clear == true) { + swim_clear_screen(win, bkcolor); + } + + /* Use the default font and make background transparent */ + win->font = (FONT_T *) &font_helvr10; + + /* Set starting text position in upper left of window */ + win->xvpos = win->xpvmin; + win->yvpos = win->ypvmin; + } + + return init; +} + +/* Circle support function */ +static void swim_plot4points(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t x, int32_t y, int32_t Filled) +{ + int16_t x0, x1, y0, y1; + + y0 = cy + y; + y1 = cy - y; + if ( Filled ) { + for ( x0 = cx - x; x0 <= cx + x; x0++ ) { + swim_put_pixel_physical(win, x0, y0, win->pen); + swim_put_pixel_physical(win, x0, y1, win->pen); + } + } + else { + x0 = cx + x; + x1 = cx - x; + swim_put_pixel_physical(win, x0, y0, win->pen); + if (x != 0) { + swim_put_pixel_physical(win, x1, y0, win->pen); + } + if (y != 0) { + swim_put_pixel_physical(win, x0, y1, win->pen); + } + if (( x != 0) && ( y != 0) ) { + swim_put_pixel_physical(win, x1, y1, win->pen); + } + } +} + +/* Circle support function */ +static void swim_plot8points(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t x, int32_t y, int32_t Filled) +{ + swim_plot4points(win, cx, cy, x, y, Filled); + if (x != y) { + swim_plot4points(win, cx, cy, y, x, Filled); + } +} + +/*********************************************************************** + * Public functions + **********************************************************************/ + +/* Puts a pixel at the virtual X, Y coordinate in the window */ +void swim_put_pixel(SWIM_WINDOW_T *win, + int32_t x1, + int32_t y1) +{ + int16_t realx, realy; + + /* Convert virtual coordinate to physical coordinate taking into + consideration the border size of the window */ + realx = win->xpvmin + x1; + realy = win->ypvmin + y1; + + /* Only put the pixel in the window if it fits in the window */ + if ((realx <= win->xpvmax) && + (realy <= win->ypvmax)) { + swim_put_pixel_physical(win, realx, realy, win->pen); + } +} + +/* Draw a line in the virtual window with clipping */ +void swim_put_line(SWIM_WINDOW_T *win, + int32_t x1, + int32_t y1, + int32_t x2, + int32_t y2) +{ + int32_t e2, sx, sy, dx, dy, err; + + /* Convert virtual coordinates to physical coordinates */ + x1 = x1 + win->xpvmin; + x2 = x2 + win->xpvmin; + y1 = y1 + win->ypvmin; + y2 = y2 + win->ypvmin; + + /* calculate delta_x and delta_y */ + dx = swim_abs(x2 - x1); + dy = swim_abs(y2 - y1); + + /* set the direction for the step for both x and y, and + initialize the error */ + if (x1 < x2) { + sx = 1; + } + else { + sx = -1; + } + + if (y1 < y2) { + sy = 1; + } + else { + sy = -1; + } + + err = dx - dy; + + while (1) { + if ((x1 >= win->xpvmin) && (x1 <= win->xpvmax) && + (y1 >= win->ypvmin) && (y1 <= win->ypvmax)) { + swim_put_pixel_physical(win, x1, y1, win->pen); + } + + if ((x1 == x2) && (y1 == y2)) { + return; + } + + e2 = 2 * err; + if (e2 > -dy) { + err -= dy; + x1 += sx; + } + if (e2 < dx) { + err += dx; + y1 += sy; + } + } +} + +/* Draw a diamond in the virtual window */ +void swim_put_diamond(SWIM_WINDOW_T *win, + int32_t x, + int32_t y, + int32_t rx, + int32_t ry) +{ + int32_t xleft, xright, xleft1, xleft2, xright1, idy, ypmid; + int32_t ypmin, ypmax, dlta, err, e2; + + /* Use line draw functions to draw border in pen color in virtual + coordinates */ + swim_put_line(win, x - rx, y, x, y - ry); + swim_put_line(win, x + rx, y, x, y - ry); + swim_put_line(win, x - rx, y, x, y + ry); + swim_put_line(win, x + rx, y, x, y + ry); + + /* Adjust rx and rx for interior fill region minus border */ + rx--; + ry--; + if ((rx <= 0) || (ry <= 0)) { + return; + } + + /* Y limits in physical coordinates minus border line */ + ypmin = y - ry + win->ypvmin; + ypmid = y + win->ypvmin; + ypmax = y + ry + win->ypvmin; + + /* X starts draw from center line */ + xleft = xright = x + win->xpvmin; + + err = rx - ry; + dlta = 1 + rx / ry; + + for (idy = ypmin; idy <= ypmid; idy++) { + xleft1 = xleft2 = xleft; + xright1 = xright; + + /* Clip left and right to virtual window size */ + if (xleft1 < win->xpvmin) { + xleft2 = xleft1 = win->xpvmin; + } + if (xright1 > win->xpvmax) { + xright1 = win->xpvmax; + } + + /* Is top half visible? */ + if ((idy >= win->ypvmin) && (idy <= win->ypvmax)) { + while (xleft1 <= xright1) { + swim_put_pixel_physical(win, xleft1, idy, win->fill); + xleft1++; + } + } + + /* Draw bottom half if visible */ + if ((ypmax >= ypmid) && (ypmax <= win->ypvmax)) { + /* Mirror bottom */ + while (xleft2 <= xright1) { + swim_put_pixel_physical(win, xleft2, ypmax, win->fill); + xleft2++; + } + } + ypmax--; + + e2 = 2 * err; + if (e2 > -ry) { + err -= ry; + xleft -= dlta; + xright += dlta; + } + if (e2 < rx) { + err += rx; + } + } +} + +/* Draws a circle in the virtual window */ +void swim_put_circle(SWIM_WINDOW_T *win, int32_t cx, int32_t cy, int32_t radius, int32_t Filled) +{ + int32_t Error = -radius; + int16_t x = radius; + int16_t y = 0; + + /* Convert virtual coordinates to physical coordinates */ + cx += win->xpvmin; + cy += win->ypvmin; + + while ( x >= y ) { + swim_plot8points(win, cx, cy, x, y, Filled); + + Error += y; + ++y; + Error += y; + + if ( Error >= 0 ) { + --x; + Error -= x; + Error -= x; + } + } +} + +/* Fills the draw area of the display with the selected color */ +void swim_clear_screen(SWIM_WINDOW_T *win, + COLOR_T colr) +{ + int32_t x, y; + + for (y = win->ypvmin; y <= win->ypvmax; y++) { + for (x = win->xpvmin; x <= win->xpvmax; x++) { + swim_put_pixel_physical(win, x, y, colr); + } + } +} + +/* Place a box with corners (X1, Y1) and (X2, Y2) */ +void swim_put_box(SWIM_WINDOW_T *win, + int32_t x1, + int32_t y1, + int32_t x2, + int32_t y2) +{ + int32_t xinc, yinc; + int32_t ysave; + + if (x1 > x2) { + xinc = x1; + x1 = x2; + x2 = xinc; + } + + /* Swap y1 and y2 if y1 is larger than y2 */ + if (y1 > y2) { + yinc = y1; + y1 = y2; + y2 = yinc; + } + + /* Convert virtual coordinates to physical coordinates */ + x1 = x1 + win->xpvmin; + x2 = x2 + win->xpvmin; + y1 = y1 + win->ypvmin; + y2 = y2 + win->ypvmin; + + /* Clip boxes to window sizes */ + if (x1 < win->xpvmin) { + x1 = win->xpvmin; + } + if (y1 < win->ypvmin) { + y1 = win->ypvmin; + } + if (x2 > win->xpvmax) { + x2 = win->xpvmax; + } + if (y2 > win->ypvmax) { + y2 = win->ypvmax; + } + + /* Get X and Y differences */ + xinc = x2 - x1; + yinc = y2 - y1; + + /* Make outer edge of box in pen color */ + swim_put_line_raw(win, x1, y1, x2, y1); + swim_put_line_raw(win, x2, y1, x2, y2); + swim_put_line_raw(win, x2, y2, x1, y2); + swim_put_line_raw(win, x1, y2, x1, y1); + + /* Increment X, Y values so they won't overwrite the edge */ + x1++; + y1++; + + /* Draw the box inside with the fill color */ + ysave = y1; + while (x1 < x2) { + y1 = ysave; + while (y1 < y2) { + swim_put_pixel_physical(win, x1, y1, win->fill); + y1++; + } + + x1++; + } +} + +/* Initializes a window and the default values for the window */ +BOOL_32 swim_window_open(SWIM_WINDOW_T *win, + int32_t xsize, + int32_t ysize, + COLOR_T *fbaddr, + int32_t xwin_min, + int32_t ywin_min, + int32_t xwin_max, + int32_t ywin_max, + int32_t border_width, + COLOR_T pcolor, + COLOR_T bkcolor, + COLOR_T fcolor) +{ + BOOL_32 init; + + init = swim_window_open_p(win, xsize, ysize, fbaddr, xwin_min, + ywin_min, xwin_max, ywin_max, border_width, pcolor, bkcolor, + fcolor, true); + + /* Default font background is not transparent */ + win->tfont = 1; + + return init; +} + +/* Initializes a window without clearing it */ +BOOL_32 swim_window_open_noclear(SWIM_WINDOW_T *win, + int32_t xsize, + int32_t ysize, + COLOR_T *fbaddr, + int32_t xwin_min, + int32_t ywin_min, + int32_t xwin_max, + int32_t ywin_max, + int32_t border_width, + COLOR_T pcolor, + COLOR_T bkcolor, + COLOR_T fcolor) +{ + BOOL_32 init; + + init = swim_window_open_p(win, xsize, ysize, fbaddr, xwin_min, + ywin_min, xwin_max, ywin_max, border_width, pcolor, bkcolor, + fcolor, false); + + /* Default font background is transparent */ + win->tfont = 0; + + return init; +} + +/* Deallocates a window */ +void swim_window_close(SWIM_WINDOW_T *win) +{ + win->winused = 0x0; +} + +/* Sets the pen color */ +void swim_set_pen_color(SWIM_WINDOW_T *win, + COLOR_T pen_color) +{ + win->pen = pen_color; +} + +/* Sets the fill color */ +void swim_set_fill_color(SWIM_WINDOW_T *win, + COLOR_T fill_color) +{ + win->fill = fill_color; +} + +/* Sets the color used for backgrounds */ +void swim_set_bkg_color(SWIM_WINDOW_T *win, + COLOR_T bkg_color) +{ + win->bkg = bkg_color; +} + +/* Get the virtual window horizontal size */ +int32_t swim_get_horizontal_size(SWIM_WINDOW_T *win) +{ + return win->xvsize; +} + +/* Get the virtual window vertical size */ +int32_t swim_get_vertical_size(SWIM_WINDOW_T *win) +{ + return win->yvsize; +} +