📄 abl_swim.c
字号:
/***********************************************************************
* $Workfile: abl_swim.c $
* $Revision: 1.3 $
* $Author: WellsK $
* $Date: Jan 05 2004 10:55:56 $
*
* Project: Simple Windowing Interface Manager (SWIM)
*
* Description:
* See the swim.h header file for a description of this package.
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/abl/source/abl_swim.c-arc $
*
* Rev 1.3 Jan 05 2004 10:55:56 WellsK
* Corrected an virtual line draw issue that would cause a divide
* by zero when the line start and end points were the same.
*
* Rev 1.2 Sep 30 2003 16:56:24 WellsK
* Added swim_put_diamond function.
*
* Rev 1.1 Jun 25 2003 14:11:42 WellsK
* Changed default font type to point directly to helvr10 font data
* structure. Added functions to return virtual window sizes.
*
* Rev 1.0 Jun 09 2003 12:06:28 WellsK
* Initial revision.
*
*
***********************************************************************
* SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
* OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
* AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES,
* SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
*
* SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY
* FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A
* SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
* FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
*
* COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
**********************************************************************/
#include "abl_swim.h"
#include "abl_fonts.h"
#include "abl_helvr10.h"
/***********************************************************************
* Private functions
**********************************************************************/
/***********************************************************************
*
* Function: swim_put_line_raw
*
* Purpose: Draw a line on the physical display
*
* Processing:
* See function.
*
* Parameters:
* win : Window identifier
* x1 : Physical X position of X line start
* y1 : Physical Y position of Y line start
* x2 : Physical X position of X line end
* y2 : Physical Y position of Y line end
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void swim_put_line_raw(SWIM_WINDOW_T *win,
INT_32 x1,
INT_32 y1,
INT_32 x2,
INT_32 y2)
{
INT_32 xinc, yinc;
INT_32 pixel_start, pixel_end;
INT_32 line;
INT_32 offs;
INT_32 xv, yv;
/* Drawing is performed at a much 'higher' resolution that the
actual display. Before writing to the frame buffer, the 'lower'
resolution is restored. */
/* Swap x1 and x2 if x1 is larger than x2 */
if (x1 > x2)
{
line = x1;
x1 = x2;
x2 = line;
}
/* Swap y1 and y2 if y1 is larger than y2 */
if (y1 > y2)
{
line = y1;
y1 = y2;
y2 = line;
}
/* Determine difference X and Y values */
xinc = x2 - x1;
yinc = y2 - y1;
if (xinc > yinc)
{
/* Use X axis for drawing */
pixel_start = x1;
pixel_end = x2;
/* Determine incremental values for X and Y */
yinc = win->ypsize * yinc / xinc;
xinc = win->xpsize;
}
else
{
/* Use Y axis for drawing */
pixel_start = y1;
pixel_end = y2;
/* Determine scaling factors */
xinc = win->xpsize * xinc / yinc;
yinc = win->ypsize;
}
x1 = x1 * win->xpsize;
y1 = y1 * win->ypsize;
/* Draw line */
for (line = pixel_start; line <= pixel_end;)
{
/* Convert pixel address into real offset in display
Only plot if in physical display */
xv = x1 / win->xpsize;
yv = y1 / win->ypsize;
if ((xv >= 0) && (yv >= 0) &&
(xv <= (win->xpsize - 1)) &&
(yv <= (win->ypsize - 1)))
{
offs = xv + yv * win->xpsize;
* (win->fb + offs) = win->pen;
}
else
{
/* Out of display, force exit */
line = pixel_end + 1;
}
/* Increment X and Y pixel locations */
x1 = x1 + xinc;
y1 = y1 + yinc;
/* Increment to next pixel */
line++;
}
}
/***********************************************************************
* Public functions
**********************************************************************/
/***********************************************************************
*
* Function: swim_put_pixel
*
* Purpose: Puts a pixel at the virtual X, Y coordinate in the window
*
* Processing:
* Convert the virtual pixel position to a physical position.
* If the pixel is inside the window draw area, update the pixel
* on the display.
*
* Parameters:
* win : Window identifier
* x1 : Virtual X position of pixel
* y1 : Virtual Y position of pixel
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
* The pixel will not be displayed if the pixel exceeds the window
* virtual size. Pixel positions below 0 should not be used with
* this function.
*
**********************************************************************/
void swim_put_pixel(SWIM_WINDOW_T *win,
INT_32 x1,
INT_32 y1)
{
INT_16 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))
{
*(win->fb + realx + (realy * win->xpsize)) = win->pen;
}
}
/***********************************************************************
*
* Function: swim_put_line
*
* Purpose: Draw a line in the virtual window with clipping.
*
* Processing:
* See function.
*
* Parameters:
* win : Window identifier
* x1 : Virtual X position of X line start
* y1 : Virtual Y position of Y line start
* x2 : Virtual X position of X line end
* y2 : Virtual Y position of Y line end
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
* This function supports clipping.
*
**********************************************************************/
void swim_put_line(SWIM_WINDOW_T *win,
INT_32 x1,
INT_32 y1,
INT_32 x2,
INT_32 y2)
{
INT_32 xinc, yinc;
INT_32 pixel_start, pixel_end;
INT_32 line;
INT_32 offs;
INT_32 xv, yv;
/* Drawing is performed at a much 'higher' resolution that the
actual display. Before writing to the frame buffer, the 'lower'
resolution is restored. */
/* Swap x1 and x2 if x1 is larger than x2 */
if (x1 > x2)
{
line = x1;
x1 = x2;
x2 = line;
}
/* Swap y1 and y2 if y1 is larger than y2 */
if (y1 > y2)
{
line = y1;
y1 = y2;
y2 = line;
}
/* Convert virtual coordinates to physical coordinates */
x1 = x1 + win->xpvmin;
x2 = x2 + win->xpvmin;
y1 = y1 + win->ypvmin;
y2 = y2 + win->ypvmin;
/* Determine difference X and Y values */
xinc = x2 - x1;
yinc = y2 - y1;
if ((xinc == 0) && (yinc == 0))
{
/* Line origins are the same! Plot a pixel instead */
*(win->fb + x1 + (y1 * win->xpsize)) = win->pen;
}
else
{
if (xinc > yinc)
{
/* Use X axis for drawing */
pixel_start = x1;
pixel_end = x2;
/* Determine incremental values for X and Y */
yinc = win->ypsize * yinc / xinc;
xinc = win->xpsize;
}
else
{
/* Use Y axis for drawing */
pixel_start = y1;
pixel_end = y2;
/* Determine scaling factors */
xinc = win->xpsize * xinc / yinc;
yinc = win->ypsize;
}
x1 = x1 * win->xpsize;
y1 = y1 * win->ypsize;
/* Draw line */
for (line = pixel_start; line <= pixel_end;)
{
/* Convert pixel address into real offset in display
Only plot if in physical display */
xv = x1 / win->xpsize;
yv = y1 / win->ypsize;
if ((xv >= win->xpvmin) &&
(yv >= win->ypvmin) &&
(xv <= win->xpvmax) &&
(yv <= win->ypvmax))
{
offs = xv + yv * win->xpsize;
* (win->fb + offs) = win->pen;
}
else
{
/* Out of window, force exit */
line = pixel_end + 1;
}
/* Increment X and Y pixel locations */
x1 = x1 + xinc;
y1 = y1 + yinc;
/* Increment to next pixel */
line++;
}
}
}
/***********************************************************************
*
* Function: swim_put_diamond
*
* Purpose:
* Purpose: Draw a diamond in the virtual window
*
* Processing:
* See function.
*
* Parameters:
* win : Window identifier
* x : Virtual X position of the diamond
* y : Virtual Y position of the diamond
* rx : Radius for horizontal
* ry : Radius for vertical
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
* This function supports clipping.
*
**********************************************************************/
void swim_put_diamond(SWIM_WINDOW_T *win,
INT_32 x,
INT_32 y,
INT_32 rx,
INT_32 ry)
{
INT_32 xinc, idy, xleft, xright, pixel, ydsp;
/* For center line, limit to size of the window */
xleft = x - rx;
if (xleft < win->xpvmin)
{
xleft = win->xpvmin;
}
xright = x + rx;
if (xright > win->xpvmax)
{
xright = win->xpvmax;
}
/* Draw the left and right pixels of the center line in the pen
color */
* (win->fb + xleft + (y * win->xpsize)) = win->pen;
* (win->fb + xright + (y * win->xpsize)) = win->pen;
/* Draw the center line first in the fill color */
if ((y >= win->ypvmin) && (y <= win->ypvmax))
{
for (pixel = (xleft + 1); pixel < (xright - 1); pixel++)
{
* (win->fb + pixel + (y * win->xpsize)) = win->fill;
}
}
/* Draw the top and bottom halves of the diamond */
for (idy = 1; idy <= ry; idy++)
{
/* Compute left and right endpoints for the horizontal line */
xinc = ((ry - idy) * rx);
xleft = x - xinc / ry;
xright = x + xinc / ry;
/* Clip left and right edges if needed */
if (xleft < win->xpvmin)
{
xleft = win->xpvmin;
}
if (xright > win->xpvmax)
{
xright = win->xpvmax;
}
/* Convert virtual coordinates to physical coordinates */
xleft = xleft + win->xpmin;
xright = xright + win->xpmin;
/* Only render top line if it is visible */
if ((y - idy) >= win->ypvmin)
{
/* Convert to physical coordinate */
ydsp = ((y - idy) + win->ypmin) * win->xpsize;
/* Draw the left pixel of the line in the pen color */
* (win->fb + xleft + ydsp) = win->pen;
/* Draw top line in fill color */
for (pixel = (ydsp + xleft + 1);
pixel <= (ydsp + xright - 1); pixel++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -