Merge pull request #43 from inmarket/master

GDISP, GWIN updates
This commit is contained in:
Tectu 2013-03-18 01:57:18 -07:00
commit ffea4aa12e
7 changed files with 1247 additions and 1182 deletions

View file

@ -658,30 +658,35 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/** /**
* @brief Draw an enclosed polygon (convex, non-convex or complex). * @brief Draw an enclosed polygon (convex, non-convex or complex).
* *
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points * @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array * @param[in] cnt The number of points in the array
* @param[in] color The color to use * @param[in] color The color to use
* *
* @api * @api
*/ */
void gdispDrawPoly(const point *pntarray, unsigned cnt, color_t color); void gdispDrawPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
/** /**
* @brief Fill a convex polygon * @brief Fill a convex polygon
* @details Doesn't handle non-convex or complex polygons. * @details Doesn't handle non-convex or complex polygons.
* *
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points * @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array * @param[in] cnt The number of points in the array
* @param[in] color The color to use * @param[in] color The color to use
* *
* @note Convex polygons are those that have no internal angles. That is; * @note Convex polygons are those that have no internal angles. That is;
* you can draw a line from any point on the polygon to any other point * you can draw a line from any point on the polygon to any other point
* on the polygon without it going outside the polygon. * on the polygon without it going outside the polygon. In our case we generalise
* this a little by saying that an infinite horizontal line (at any y value) will cross
* no more than two edges on the polygon. Some non-convex polygons do fit this criteria
* and can therefore be drawn.
* @note This routine is designed to be very efficient with even simple display hardware. * @note This routine is designed to be very efficient with even simple display hardware.
* *
* @api * @api
*/ */
void gdispFillConvexPoly(const point *pntarray, unsigned cnt, color_t color); void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
#endif #endif
/* Extra Text Functions */ /* Extra Text Functions */

View file

@ -1,208 +1,207 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012, 2013 ChibiOS/GFX - Copyright (C) 2012, 2013
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* @file include/gwin/graph.h * @file include/gwin/graph.h
* @brief GWIN GRAPH module header file. * @brief GWIN GRAPH module header file.
* *
* @defgroup Graph Graph * @defgroup Graph Graph
* @ingroup GWIN * @ingroup GWIN
* *
* @details GWIN allows it to easily draw graphs. * @details GWIN allows it to easily draw graphs.
* @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
* @pre GWIN_NEED_GRAPH must be set to TRUE in your gfxconf.h * @pre GWIN_NEED_GRAPH must be set to TRUE in your gfxconf.h
* *
* @{ * @{
*/ */
#ifndef _GWIN_GRAPH_H #ifndef _GWIN_GRAPH_H
#define _GWIN_GRAPH_H #define _GWIN_GRAPH_H
#if GWIN_NEED_GRAPH || defined(__DOXYGEN__) #if GWIN_NEED_GRAPH || defined(__DOXYGEN__)
/*===========================================================================*/ /*===========================================================================*/
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
#define GW_GRAPH 0x0003 #define GW_GRAPH 0x0003
/*===========================================================================*/ /*===========================================================================*/
/* Type definitions */ /* Type definitions */
/*===========================================================================*/ /*===========================================================================*/
typedef struct GGraphPoint_t { // GDISP now has its own point structure
coord_t x, y; #define GGraphPoint point
} GGraphPoint;
typedef enum GGraphPointType_e {
typedef enum GGraphPointType_e { GGRAPH_POINT_NONE, GGRAPH_POINT_DOT, GGRAPH_POINT_SQUARE, GGRAPH_POINT_CIRCLE
GGRAPH_POINT_NONE, GGRAPH_POINT_DOT, GGRAPH_POINT_SQUARE, GGRAPH_POINT_CIRCLE } GGraphPointType;
} GGraphPointType;
typedef struct GGraphPointStyle_t {
typedef struct GGraphPointStyle_t { GGraphPointType type;
GGraphPointType type; coord_t size;
coord_t size; color_t color;
color_t color; } GGraphPointStyle;
} GGraphPointStyle;
typedef enum GGraphLineType_e {
typedef enum GGraphLineType_e { GGRAPH_LINE_NONE, GGRAPH_LINE_SOLID, GGRAPH_LINE_DOT, GGRAPH_LINE_DASH
GGRAPH_LINE_NONE, GGRAPH_LINE_SOLID, GGRAPH_LINE_DOT, GGRAPH_LINE_DASH } GGraphLineType;
} GGraphLineType;
typedef struct GGraphLineStyle_t {
typedef struct GGraphLineStyle_t { GGraphLineType type;
GGraphLineType type; coord_t size;
coord_t size; color_t color;
color_t color; } GGraphLineStyle;
} GGraphLineStyle;
typedef struct GGraphGridStyle_t {
typedef struct GGraphGridStyle_t { GGraphLineType type;
GGraphLineType type; coord_t size;
coord_t size; color_t color;
color_t color; coord_t spacing;
coord_t spacing; } GGraphGridStyle;
} GGraphGridStyle;
typedef struct GGraphStyle_t {
typedef struct GGraphStyle_t { GGraphPointStyle point;
GGraphPointStyle point; GGraphLineStyle line;
GGraphLineStyle line; GGraphLineStyle xaxis;
GGraphLineStyle xaxis; GGraphLineStyle yaxis;
GGraphLineStyle yaxis; GGraphGridStyle xgrid;
GGraphGridStyle xgrid; GGraphGridStyle ygrid;
GGraphGridStyle ygrid; uint16_t flags;
uint16_t flags; #define GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS 0x0001
#define GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS 0x0001 #define GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS 0x0002
#define GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS 0x0002 #define GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS 0x0004
#define GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS 0x0004 #define GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS 0x0008
#define GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS 0x0008 #define GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS)
#define GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS) #define GWIN_GRAPH_STYLE_NEGATIVE_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS)
#define GWIN_GRAPH_STYLE_NEGATIVE_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS) #define GWIN_GRAPH_STYLE_XAXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS)
#define GWIN_GRAPH_STYLE_XAXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS) #define GWIN_GRAPH_STYLE_YAXIS_ARROWS (GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS)
#define GWIN_GRAPH_STYLE_YAXIS_ARROWS (GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS) #define GWIN_GRAPH_STYLE_ALL_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_ARROWS|GWIN_GRAPH_STYLE_YAXIS_ARROWS)
#define GWIN_GRAPH_STYLE_ALL_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_ARROWS|GWIN_GRAPH_STYLE_YAXIS_ARROWS) } GGraphStyle;
} GGraphStyle;
// A graph window
// A graph window typedef struct GGraphObject_t {
typedef struct GGraphObject_t { GWindowObject gwin;
GWindowObject gwin; GGraphStyle style;
GGraphStyle style; coord_t xorigin, yorigin;
coord_t xorigin, yorigin; coord_t lastx, lasty;
coord_t lastx, lasty; } GGraphObject;
} GGraphObject;
/*===========================================================================*/
/*===========================================================================*/ /* External declarations. */
/* External declarations. */ /*===========================================================================*/
/*===========================================================================*/
#ifdef __cplusplus
#ifdef __cplusplus extern "C" {
extern "C" { #endif
#endif
/**
/** * @brief Create a graph window.
* @brief Create a graph window. * @return NULL if there is no resultant drawing area, otherwise a window handle.
* @return NULL if there is no resultant drawing area, otherwise a window handle. *
* * @param[in] gg The GGraphObject structure to initialise. If this is NULL the structure is dynamically allocated.
* @param[in] gg The GGraphObject structure to initialise. If this is NULL the structure is dynamically allocated. * @param[in] x,y The screen co-ordinates for the bottom left corner of the window
* @param[in] x,y The screen co-ordinates for the bottom left corner of the window * @param[in] width The width of the window
* @param[in] width The width of the window * @param[in] height The height of the window
* @param[in] height The height of the window * @note The console is not automatically cleared on creation. You must do that by calling gwinClear() (possibly after changing your background color)
* @note The console is not automatically cleared on creation. You must do that by calling gwinClear() (possibly after changing your background color) * @note The coordinate system within the window for graphing operations (but not for any other drawing
* @note The coordinate system within the window for graphing operations (but not for any other drawing * operation) is relative to the bottom left corner and then shifted right and up by the specified
* operation) is relative to the bottom left corner and then shifted right and up by the specified * graphing x and y origin. Note that this system is inverted in the y direction relative to the display.
* graphing x and y origin. Note that this system is inverted in the y direction relative to the display. * This gives the best graphing arrangement ie. increasing y values are closer to the top of the display.
* This gives the best graphing arrangement ie. increasing y values are closer to the top of the display. *
* * @api
* @api */
*/ GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height);
GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height);
/**
/** * @brief Set the style of the graphing operations.
* @brief Set the style of the graphing operations. *
* * @param[in] gh The window handle (must be a graph window)
* @param[in] gh The window handle (must be a graph window) * @param[in] pstyle The graph style to set.
* @param[in] pstyle The graph style to set. * @note The graph is not automatically redrawn. The new style will apply to any new drawing operations.
* @note The graph is not automatically redrawn. The new style will apply to any new drawing operations. *
* * @api
* @api */
*/ void gwinGraphSetStyle(GHandle gh, const GGraphStyle *pstyle);
void gwinGraphSetStyle(GHandle gh, const GGraphStyle *pstyle);
/**
/** * @brief Set the origin for graphing operations.
* @brief Set the origin for graphing operations. *
* * @param[in] gh The window handle (must be a graph window)
* @param[in] gh The window handle (must be a graph window) * @param[in] x, y The new origin for the graph (in graph coordinates relative to the bottom left corner).
* @param[in] x, y The new origin for the graph (in graph coordinates relative to the bottom left corner). * @note The graph is not automatically redrawn. The new origin will apply to any new drawing operations.
* @note The graph is not automatically redrawn. The new origin will apply to any new drawing operations. *
* * @api
* @api */
*/ void gwinGraphSetOrigin(GHandle gh, coord_t x, coord_t y);
void gwinGraphSetOrigin(GHandle gh, coord_t x, coord_t y);
/**
/** * @brief Draw the axis and the background grid.
* @brief Draw the axis and the background grid. *
* * @param[in] gh The window handle (must be a graph window)
* @param[in] gh The window handle (must be a graph window) * @note The graph is not automatically cleared. You must do that first by calling gwinClear().
* @note The graph is not automatically cleared. You must do that first by calling gwinClear(). *
* * @api
* @api */
*/ void gwinGraphDrawAxis(GHandle gh);
void gwinGraphDrawAxis(GHandle gh);
/**
/** * @brief Start a new set of graphing data.
* @brief Start a new set of graphing data. * @details This prevents a line being drawn from the last data point to the next point to be drawn.
* @details This prevents a line being drawn from the last data point to the next point to be drawn. *
* * @param[in] gh The window handle (must be a graph window)
* @param[in] gh The window handle (must be a graph window) *
* * @api
* @api */
*/ void gwinGraphStartSet(GHandle gh);
void gwinGraphStartSet(GHandle gh);
/**
/** * @brief Draw a graph point.
* @brief Draw a graph point. * @details A graph point and a line connecting to the previous point will be drawn.
* @details A graph point and a line connecting to the previous point will be drawn. *
* * @param[in] gh The window handle (must be a graph window)
* @param[in] gh The window handle (must be a graph window) * @param[in] x, y The new point for the graph.
* @param[in] x, y The new point for the graph. *
* * @api
* @api */
*/ void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y);
void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y);
/**
/** * @brief Draw multiple graph points.
* @brief Draw multiple graph points. * @details A graph point and a line connecting to each previous point will be drawn.
* @details A graph point and a line connecting to each previous point will be drawn. *
* * @param[in] gh The window handle (must be a graph window)
* @param[in] gh The window handle (must be a graph window) * @param[in] points The array of points for the graph.
* @param[in] points The array of points for the graph. * @param[in] count The number of points in the array.
* @param[in] count The number of points in the array. * @note This is slightly more efficient than calling gwinGraphDrawPoint() repeatedly.
* @note This is slightly more efficient than calling gwinGraphDrawPoint() repeatedly. *
* * @api
* @api */
*/ void gwinGraphDrawPoints(GHandle gh, const point *points, unsigned count);
void gwinGraphDrawPoints(GHandle gh, const GGraphPoint *points, unsigned count);
#ifdef __cplusplus
#ifdef __cplusplus }
} #endif
#endif
#endif /* GWIN_NEED_GRAPH */
#endif /* GWIN_NEED_GRAPH */
#endif /* _GWIN_GRAPH_H */
#endif /* _GWIN_GRAPH_H */ /** @} */
/** @} */

View file

@ -1,186 +1,503 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012, 2013 ChibiOS/GFX - Copyright (C) 2012, 2013
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* @file include/gwin/gwin.h * @file include/gwin/gwin.h
* @brief GWIN Graphic window subsystem header file. * @brief GWIN Graphic window subsystem header file.
* *
* @defgroup Window Window * @defgroup Window Window
* @ingroup GWIN * @ingroup GWIN
* *
* @details GWIN provides a basic window manager which allows it to easily * @details GWIN provides a basic window manager which allows it to easily
* create and destroy different windows on runtime. Each window * create and destroy different windows on runtime. Each window
* will have it's own properties such as colors, brushes as well as * will have it's own properties such as colors, brushes as well as
* it's own drawing origin. * it's own drawing origin.
* Moving the windows around is not supported yet. * Moving the windows around is not supported yet.
* *
* @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
* *
* @{ * @{
*/ */
#ifndef _GWIN_H #ifndef _GWIN_H
#define _GWIN_H #define _GWIN_H
#include "gfx.h" #include "gfx.h"
#if GFX_USE_GWIN || defined(__DOXYGEN__) #if GFX_USE_GWIN || defined(__DOXYGEN__)
/*===========================================================================*/ /*===========================================================================*/
/* Type definitions */ /* Type definitions */
/*===========================================================================*/ /*===========================================================================*/
typedef uint16_t GWindowType; typedef uint16_t GWindowType;
#define GW_WINDOW 0x0000 #define GW_WINDOW 0x0000
#define GW_FIRST_USER_WINDOW 0x8000 #define GW_FIRST_USER_WINDOW 0x8000
// A basic window // A basic window
typedef struct GWindowObject_t { typedef struct GWindowObject_t {
GWindowType type; // What type of window is this GWindowType type; // What type of window is this
uint16_t flags; // Internal flags uint16_t flags; // Internal flags
coord_t x, y; // Screen relative position coord_t x, y; // Screen relative position
coord_t width, height; // Dimensions of this window coord_t width, height; // Dimensions of this window
color_t color, bgcolor; // Current drawing colors color_t color, bgcolor; // Current drawing colors
#if GDISP_NEED_TEXT #if GDISP_NEED_TEXT
font_t font; // Current font font_t font; // Current font
#endif #endif
} GWindowObject, * GHandle; } GWindowObject, * GHandle;
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Base Functions */ /* Base Functions */
GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height);
void gwinDestroyWindow(GHandle gh); /**
* @brief Create a basic window.
/** * @return NULL if there is no resultant drawing area, otherwise a window handle.
* @brief Get the X coordinate of the window *
* @details Returns the X coordinate of the origin of the window. * @param[in] gw The window structure to initialize. If this is NULL the structure is dynamically allocated.
* The coordinate is relative to the physical screen zero point. * @param[in] x,y The screen coordinates for the bottom left corner of the window
* * @param[in] width The width of the window
* @param[in] gh The window * @param[in] height The height of the window
*/ * @note The default drawing color gets set to White and the background drawing color to Black.
#define gwinGetScreenX(gh) ((gh)->x) * @note No default font is set so make sure to set one before drawing any text.
* @note The dimensions and position may be changed to fit on the real screen.
/** * @note The window is not automatically cleared on creation. You must do that by calling gwinClear() (possibly after changing your background color)
* @brief Get the Y coordinate of the window *
* @details Returns the Y coordinate of the origin of the window. * @api
* The coordinate is relative to the physical screen zero point. */
* GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height);
* @param[in] gh The window
*/ /**
#define gwinGetScreenY(gh) ((gh)->y) * @brief Destroy a window (of any type). Releases any dynamically allocated memory.
*
/** * @param[in] gh The window handle
* @brief Get the width of the window *
* * @api
* @param[in] gh The window */
*/ void gwinDestroyWindow(GHandle gh);
#define gwinGetWidth(gh) ((gh)->width)
/**
/** * @brief Get the X coordinate of the window
* @brief Get the height of the window * @details Returns the X coordinate of the origin of the window.
* * The coordinate is relative to the physical screen zero point.
* @param[in] gh The window *
*/ * @param[in] gh The window
#define gwinGetHeight(gh) ((gh)->height) */
#define gwinGetScreenX(gh) ((gh)->x)
/**
* @brief Set foreground color /**
* @details Set the color which will be used to draw * @brief Get the Y coordinate of the window
* * @details Returns the Y coordinate of the origin of the window.
* @param[in] gh The window * The coordinate is relative to the physical screen zero point.
* @param[in] clr The color to be set *
*/ * @param[in] gh The window
#define gwinSetColor(gh, clr) (gh)->color = (clr) */
#define gwinGetScreenY(gh) ((gh)->y)
/**
* @brief Set background color /**
* @details Set the color which will be used as background * @brief Get the width of the window
* @note gwinClear() must be called to set the background color *
* * @param[in] gh The window
* @param[in] gh The window */
* @param[in] bgclr The background color #define gwinGetWidth(gh) ((gh)->width)
*/
#define gwinSetBgColor(gh, bgclr) (gh)->bgcolor = (bgclr) /**
* @brief Get the height of the window
/* Set up for text */ *
#if GDISP_NEED_TEXT * @param[in] gh The window
void gwinSetFont(GHandle gh, font_t font); */
#endif #define gwinGetHeight(gh) ((gh)->height)
/* Drawing Functions */ /**
void gwinClear(GHandle gh); * @brief Set foreground color
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y); * @details Set the color which will be used to draw
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1); *
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy); * @param[in] gh The window
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy); * @param[in] clr The color to be set
void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer); */
#define gwinSetColor(gh, clr) (gh)->color = (clr)
/* Circle Functions */
#if GDISP_NEED_CIRCLE /**
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius); * @brief Set background color
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius); * @details Set the color which will be used as background
#endif * @note gwinClear() must be called to set the background color
*
/* Ellipse Functions */ * @param[in] gh The window
#if GDISP_NEED_ELLIPSE * @param[in] bgclr The background color
void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b); */
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b); #define gwinSetBgColor(gh, bgclr) (gh)->bgcolor = (bgclr)
#endif
/* Set up for text */
/* Arc Functions */
#if GDISP_NEED_ARC #if GDISP_NEED_TEXT || defined(__DOXYGEN__)
void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle); /**
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle); * @brief Set the current font for this window.
#endif *
* @param[in] gh The window handle
/* Read a pixel Function */ * @param[in] font The font to use for text functions
#if GDISP_NEED_PIXELREAD *
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y); * @api
#endif */
void gwinSetFont(GHandle gh, font_t font);
/* Extra Text Functions */ #endif
#if GDISP_NEED_TEXT
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c); /* Drawing Functions */
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c);
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str); /**
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str); * @brief Clear the window
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify); * @note Uses the current background color to clear the window
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify); *
#endif * @param[in] gh The window handle
*
#ifdef __cplusplus * @api
} */
#endif void gwinClear(GHandle gh);
/* Include extra window types */ /**
#include "gwin/console.h" * @brief Set a pixel in the window
#include "gwin/button.h" * @note Uses the current foreground color to set the pixel
#include "gwin/graph.h" * @note May leave GDISP clipping to this window's dimensions
*
#endif /* GFX_USE_GWIN */ * @param[in] gh The window handle
* @param[in] x,y The coordinates of the pixel
#endif /* _GWIN_H */ *
/** @} */ * @api
*/
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y);
/**
* @brief Draw a line in the window
* @note Uses the current foreground color to draw the line
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x0,y0 The start position
* @param[in] x1,y1 The end position
*
* @api
*/
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1);
/**
* @brief Draw a box in the window
* @note Uses the current foreground color to draw the box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
*
* @api
*/
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy);
/**
* @brief Fill an rectangular area in the window
* @note Uses the current foreground color to fill the box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
*
* @api
*/
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy);
/**
* @brief Fill an area in the window using the supplied bitmap.
* @details The bitmap is in the pixel format specified by the low level driver
* @note If GDISP_NEED_ASYNC is defined then the buffer must be static
* or at least retained until this call has finished the blit. You can
* tell when all graphics drawing is finished by @p gdispIsBusy() going FALSE.
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @api
*/
void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer);
/* Circle Functions */
#if GDISP_NEED_CIRCLE || defined(__DOXYGEN__)
/**
* @brief Draw a circle in the window.
* @note Uses the current foreground color to draw the circle
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x, y The center of the circle
* @param[in] radius The radius of the circle
*
* @api
*/
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius);
/**
* @brief Draw a filled circle in the window.
* @note Uses the current foreground color to draw the filled circle
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x, y The center of the circle
* @param[in] radius The radius of the circle
*
* @api
*/
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius);
#endif
/* Ellipse Functions */
#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
/**
* @brief Draw an ellipse.
* @note Uses the current foreground color to draw the ellipse
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The center of the ellipse
* @param[in] a,b The dimensions of the ellipse
*
* @api
*/
void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b);
/**
* @brief Draw an filled ellipse.
* @note Uses the current foreground color to draw the filled ellipse
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The center of the ellipse
* @param[in] a,b The dimensions of the ellipse
*
* @api
*/
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b);
#endif
/* Arc Functions */
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
/*
* @brief Draw an arc in the window.
* @note Uses the current foreground color to draw the arc
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The center point
* @param[in] radius The radius of the arc
* @param[in] start The start angle (0 to 360)
* @param[in] end The end angle (0 to 360)
*
* @api
*/
void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle);
/*
* @brief Draw a filled arc in the window.
* @note Uses the current foreground color to draw the filled arc
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The center point
* @param[in] radius The radius of the arc
* @param[in] start The start angle (0 to 360)
* @param[in] end The end angle (0 to 360)
*
* @api
*/
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle);
#endif
/* Read a pixel Function */
#if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__)
/**
* @brief Get the color of a pixel in the window.
* @return The color of the pixel.
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position in the window
*
* @api
*/
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y);
#endif
/* Extra Text Functions */
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text character at the specified position in the window.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] c The character to draw
*
* @api
*/
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c);
/**
* @brief Draw a text character with a filled background at the specified position in the window.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] c The character to draw
*
* @api
*/
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c);
/**
* @brief Draw a text string in the window
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] str The string to draw
*
* @api
*/
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str);
/**
* @brief Draw a text string with a filled background in the window
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] str The string to draw
*
* @api
*/
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str);
/**
* @brief Draw a text string verticly centered within the specified box.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character.
* @note The specified box does not need to align with the window box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
* @param[in] justify Justify the text left, center or right within the box
*
* @api
*/
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
/**
* @brief Draw a text string verticly centered within the specified filled box.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
* @note The entire box is filled. Note this box does not need to align with the window box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
* @param[in] justify Justify the text left, center or right within the box
*
* @api
*/
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
#endif
#if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__)
/**
* @brief Draw an enclosed polygon (convex, non-convex or complex).
*
* @note Uses the current foreground color.
*
* @param[in] gh The window handle
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array
*
* @api
*/
void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt);
/**
* @brief Fill a convex polygon
* @details Doesn't handle non-convex or complex polygons.
*
* @note Uses the current foreground color.
*
* @param[in] gh The window handle
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array
*
* @note Convex polygons are those that have no internal angles. That is;
* you can draw a line from any point on the polygon to any other point
* on the polygon without it going outside the polygon. In our case we generalise
* this a little by saying that an infinite horizontal line (at any y value) will cross
* no more than two edges on the polygon. Some non-convex polygons do fit this criteria
* and can therefore be drawn.
* @note This routine is designed to be very efficient with even simple display hardware.
*
* @api
*/
void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt);
#endif
#ifdef __cplusplus
}
#endif
/* Include extra window types */
#include "gwin/console.h"
#include "gwin/button.h"
#include "gwin/graph.h"
#endif /* GFX_USE_GWIN */
#endif /* _GWIN_H */
/** @} */

View file

@ -566,16 +566,16 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
} }
#if GDISP_NEED_CONVEX_POLYGON #if GDISP_NEED_CONVEX_POLYGON
void gdispDrawPoly(const point *pntarray, unsigned cnt, color_t color) { void gdispDrawPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
const point *epnt, *p; const point *epnt, *p;
epnt = &pntarray[cnt-1]; epnt = &pntarray[cnt-1];
for(p = pntarray; p < epnt; p++) for(p = pntarray; p < epnt; p++)
gdispDrawLine(p->x, p->y, p[1].x, p[1].y, color); gdispDrawLine(tx+p->x, ty+p->y, tx+p[1].x, ty+p[1].y, color);
gdispDrawLine(p->x, p->y, pntarray->x, pntarray->y, color); gdispDrawLine(tx+p->x, ty+p->y, tx+pntarray->x, ty+pntarray->y, color);
} }
void gdispFillConvexPoly(const point *pntarray, unsigned cnt, color_t color) { void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
const point *lpnt, *rpnt, *epnts; const point *lpnt, *rpnt, *epnts;
fpcoord_t lx, rx, lk, rk; fpcoord_t lx, rx, lk, rk;
coord_t y, ymax, lxc, rxc; coord_t y, ymax, lxc, rxc;
@ -622,14 +622,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
*/ */
if (lxc < rxc) { if (lxc < rxc) {
if (rxc - lxc == 1) if (rxc - lxc == 1)
gdispDrawPixel(lxc, y, color); gdispDrawPixel(tx+lxc, ty+y, color);
else else
gdispDrawLine(lxc, y, rxc-1, y, color); gdispDrawLine(tx+lxc, ty+y, tx+rxc-1, ty+y, color);
} else if (lxc > rxc) { } else if (lxc > rxc) {
if (lxc - rxc == 1) if (lxc - rxc == 1)
gdispDrawPixel(rxc, y, color); gdispDrawPixel(tx+rxc, ty+y, color);
else else
gdispDrawLine(rxc, y, lxc-1, y, color); gdispDrawLine(tx+rxc, ty+y, tx+lxc-1, ty+y, color);
} }
lx += lk; lx += lk;

View file

@ -306,16 +306,16 @@ void gwinButtonDraw_Square(GHandle gh, bool_t isdown, const char *txt, const GBu
(void) param; (void) param;
point arw[7]; point arw[7];
arw[0].x = gh->x+gh->width/2; arw[0].y = gh->y; arw[0].x = gh->width/2; arw[0].y = 0;
arw[1].x = gh->x+gh->width-1; arw[1].y = gh->y+gh->height/ARROWHEAD_DIVIDER; arw[1].x = gh->width-1; arw[1].y = gh->height/ARROWHEAD_DIVIDER;
arw[2].x = gh->x+(gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[2].y = gh->y+gh->height/ARROWHEAD_DIVIDER; arw[2].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[2].y = gh->height/ARROWHEAD_DIVIDER;
arw[3].x = gh->x+(gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[3].y = gh->y+gh->height-1; arw[3].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[3].y = gh->height-1;
arw[4].x = gh->x+(gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[4].y = gh->y+gh->height-1; arw[4].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[4].y = gh->height-1;
arw[5].x = gh->x+(gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[5].y = gh->y+gh->height/ARROWHEAD_DIVIDER; arw[5].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[5].y = gh->height/ARROWHEAD_DIVIDER;
arw[6].x = gh->x; arw[6].y = gh->y+gh->height/ARROWHEAD_DIVIDER; arw[6].x = 0; arw[6].y = gh->height/ARROWHEAD_DIVIDER;
gdispFillConvexPoly(arw, 7, pstyle->color_fill); gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill);
gdispDrawPoly(arw, 7, pstyle->color_edge); gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge);
gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter);
} }
@ -324,16 +324,16 @@ void gwinButtonDraw_Square(GHandle gh, bool_t isdown, const char *txt, const GBu
(void) param; (void) param;
point arw[7]; point arw[7];
arw[0].x = gh->x+gh->width/2; arw[0].y = gh->y+gh->height-1; arw[0].x = gh->width/2; arw[0].y = gh->height-1;
arw[1].x = gh->x+gh->width-1; arw[1].y = gh->y+gh->height-1-gh->height/ARROWHEAD_DIVIDER; arw[1].x = gh->width-1; arw[1].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER;
arw[2].x = gh->x+(gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[2].y = gh->y+gh->height-1-gh->height/ARROWHEAD_DIVIDER; arw[2].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[2].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER;
arw[3].x = gh->x+(gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[3].y = gh->y; arw[3].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[3].y = 0;
arw[4].x = gh->x+(gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[4].y = gh->y; arw[4].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[4].y = 0;
arw[5].x = gh->x+(gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[5].y = gh->y+gh->height-1-gh->height/ARROWHEAD_DIVIDER; arw[5].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[5].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER;
arw[6].x = gh->x; arw[6].y = gh->y+gh->height-1-gh->height/ARROWHEAD_DIVIDER; arw[6].x = 0; arw[6].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER;
gdispFillConvexPoly(arw, 7, pstyle->color_fill); gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill);
gdispDrawPoly(arw, 7, pstyle->color_edge); gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge);
gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter);
} }
@ -342,16 +342,16 @@ void gwinButtonDraw_Square(GHandle gh, bool_t isdown, const char *txt, const GBu
(void) param; (void) param;
point arw[7]; point arw[7];
arw[0].x = gh->x; arw[0].y = gh->y+gh->height/2; arw[0].x = 0; arw[0].y = gh->height/2;
arw[1].x = gh->x+gh->width/ARROWHEAD_DIVIDER; arw[1].y = gh->y; arw[1].x = gh->width/ARROWHEAD_DIVIDER; arw[1].y = 0;
arw[2].x = gh->x+gh->width/ARROWHEAD_DIVIDER; arw[2].y = gh->y+(gh->height - gh->height/ARROWBODY_DIVIDER)/2; arw[2].x = gh->width/ARROWHEAD_DIVIDER; arw[2].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2;
arw[3].x = gh->x+gh->width-1; arw[3].y = gh->y+(gh->height - gh->height/ARROWBODY_DIVIDER)/2; arw[3].x = gh->width-1; arw[3].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2;
arw[4].x = gh->x+gh->width-1; arw[4].y = gh->y+(gh->height + gh->height/ARROWBODY_DIVIDER)/2; arw[4].x = gh->width-1; arw[4].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2;
arw[5].x = gh->x+gh->width/ARROWHEAD_DIVIDER; arw[5].y = gh->y+(gh->height + gh->height/ARROWBODY_DIVIDER)/2; arw[5].x = gh->width/ARROWHEAD_DIVIDER; arw[5].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2;
arw[6].x = gh->x+gh->width/ARROWHEAD_DIVIDER; arw[6].y = gh->y+gh->height-1; arw[6].x = gh->width/ARROWHEAD_DIVIDER; arw[6].y = gh->height-1;
gdispFillConvexPoly(arw, 7, pstyle->color_fill); gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill);
gdispDrawPoly(arw, 7, pstyle->color_edge); gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge);
gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter);
} }
@ -360,16 +360,16 @@ void gwinButtonDraw_Square(GHandle gh, bool_t isdown, const char *txt, const GBu
(void) param; (void) param;
point arw[7]; point arw[7];
arw[0].x = gh->x+gh->width-1; arw[0].y = gh->y+gh->height/2; arw[0].x = gh->width-1; arw[0].y = gh->height/2;
arw[1].x = gh->x+gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[1].y = gh->y; arw[1].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[1].y = 0;
arw[2].x = gh->x+gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[2].y = gh->y+(gh->height - gh->height/ARROWBODY_DIVIDER)/2; arw[2].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[2].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2;
arw[3].x = gh->x; arw[3].y = gh->y+(gh->height - gh->height/ARROWBODY_DIVIDER)/2; arw[3].x = 0; arw[3].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2;
arw[4].x = gh->x; arw[4].y = gh->y+(gh->height + gh->height/ARROWBODY_DIVIDER)/2; arw[4].x = 0; arw[4].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2;
arw[5].x = gh->x+gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[5].y = gh->y+(gh->height + gh->height/ARROWBODY_DIVIDER)/2; arw[5].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[5].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2;
arw[6].x = gh->x+gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[6].y = gh->y+gh->height-1; arw[6].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[6].y = gh->height-1;
gdispFillConvexPoly(arw, 7, pstyle->color_fill); gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill);
gdispDrawPoly(arw, 7, pstyle->color_edge); gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge);
gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter);
} }
#endif #endif

View file

@ -1,362 +1,362 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012, 2013 ChibiOS/GFX - Copyright (C) 2012, 2013
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* @file src/gwin/graph.c * @file src/gwin/graph.c
* @brief GWIN sub-system button code. * @brief GWIN sub-system button code.
* *
* @defgroup Graph Graph * @defgroup Graph Graph
* @ingroup GWIN * @ingroup GWIN
* *
* @{ * @{
*/ */
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "gfx.h" #include "gfx.h"
#if (GFX_USE_GWIN && GWIN_NEED_GRAPH) || defined(__DOXYGEN__) #if (GFX_USE_GWIN && GWIN_NEED_GRAPH) || defined(__DOXYGEN__)
#include "gwin/internal.h" #include "gwin/internal.h"
#define GGRAPH_FLG_CONNECTPOINTS (GWIN_FIRST_CONTROL_FLAG<<0) #define GGRAPH_FLG_CONNECTPOINTS (GWIN_FIRST_CONTROL_FLAG<<0)
#define GGRAPH_ARROW_SIZE 5 #define GGRAPH_ARROW_SIZE 5
static const GGraphStyle GGraphDefaultStyle = { static const GGraphStyle GGraphDefaultStyle = {
{ GGRAPH_POINT_DOT, 0, White }, // point { GGRAPH_POINT_DOT, 0, White }, // point
{ GGRAPH_LINE_DOT, 2, Gray }, // line { GGRAPH_LINE_DOT, 2, Gray }, // line
{ GGRAPH_LINE_SOLID, 0, White }, // x axis { GGRAPH_LINE_SOLID, 0, White }, // x axis
{ GGRAPH_LINE_SOLID, 0, White }, // y axis { GGRAPH_LINE_SOLID, 0, White }, // y axis
{ GGRAPH_LINE_NONE, 0, White, 0 }, // x grid { GGRAPH_LINE_NONE, 0, White, 0 }, // x grid
{ GGRAPH_LINE_NONE, 0, White, 0 }, // y grid { GGRAPH_LINE_NONE, 0, White, 0 }, // y grid
GWIN_GRAPH_STYLE_XAXIS_ARROWS|GWIN_GRAPH_STYLE_YAXIS_ARROWS // flags GWIN_GRAPH_STYLE_XAXIS_ARROWS|GWIN_GRAPH_STYLE_YAXIS_ARROWS // flags
}; };
static void pointto(GGraphObject *gg, coord_t x, coord_t y, const GGraphPointStyle *style) { static void pointto(GGraphObject *gg, coord_t x, coord_t y, const GGraphPointStyle *style) {
if (style->type == GGRAPH_POINT_NONE) if (style->type == GGRAPH_POINT_NONE)
return; return;
// Convert to device space. Note the y-axis is inverted. // Convert to device space. Note the y-axis is inverted.
x += gg->gwin.x + gg->xorigin; x += gg->gwin.x + gg->xorigin;
y = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y; y = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y;
if (style->size <= 1) { if (style->size <= 1) {
gdispDrawPixel(x, y, style->color); gdispDrawPixel(x, y, style->color);
return; return;
} }
switch(style->type) { switch(style->type) {
case GGRAPH_POINT_SQUARE: case GGRAPH_POINT_SQUARE:
gdispDrawBox(x-style->size, y-style->size, 2*style->size, 2*style->size, style->color); gdispDrawBox(x-style->size, y-style->size, 2*style->size, 2*style->size, style->color);
break; break;
#if GDISP_NEED_CIRCLE #if GDISP_NEED_CIRCLE
case GGRAPH_POINT_CIRCLE: case GGRAPH_POINT_CIRCLE:
gdispDrawCircle(x, y, style->size, style->color); gdispDrawCircle(x, y, style->size, style->color);
break; break;
#endif #endif
case GGRAPH_POINT_DOT: case GGRAPH_POINT_DOT:
default: default:
gdispDrawPixel(x, y, style->color); gdispDrawPixel(x, y, style->color);
break; break;
} }
} }
static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t y1, const GGraphLineStyle *style) { static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t y1, const GGraphLineStyle *style) {
coord_t dy, dx; coord_t dy, dx;
coord_t addx, addy; coord_t addx, addy;
coord_t P, diff, i; coord_t P, diff, i;
coord_t run_on, run_off, run; coord_t run_on, run_off, run;
if (style->type == GGRAPH_LINE_NONE) if (style->type == GGRAPH_LINE_NONE)
return; return;
// Convert to device space. Note the y-axis is inverted. // Convert to device space. Note the y-axis is inverted.
x0 += gg->gwin.x + gg->xorigin; x0 += gg->gwin.x + gg->xorigin;
y0 = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y0; y0 = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y0;
x1 += gg->gwin.x + gg->xorigin; x1 += gg->gwin.x + gg->xorigin;
y1 = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y1; y1 = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y1;
if (style->size <= 0) { if (style->size <= 0) {
// Use the driver to draw a solid line // Use the driver to draw a solid line
gdispDrawLine(x0, y0, x1, y1, style->color); gdispDrawLine(x0, y0, x1, y1, style->color);
return; return;
} }
switch (style->type) { switch (style->type) {
case GGRAPH_LINE_DOT: case GGRAPH_LINE_DOT:
run_on = 1; run_on = 1;
run_off = -style->size; run_off = -style->size;
break; break;
case GGRAPH_LINE_DASH: case GGRAPH_LINE_DASH:
run_on = style->size; run_on = style->size;
run_off = -style->size; run_off = -style->size;
break; break;
case GGRAPH_LINE_SOLID: case GGRAPH_LINE_SOLID:
default: default:
// Use the driver to draw a solid line // Use the driver to draw a solid line
gdispDrawLine(x0, y0, x1, y1, style->color); gdispDrawLine(x0, y0, x1, y1, style->color);
return; return;
} }
// Use Bresenham's algorithm modified to draw a stylized line // Use Bresenham's algorithm modified to draw a stylized line
run = 0; run = 0;
if (x1 >= x0) { if (x1 >= x0) {
dx = x1 - x0; dx = x1 - x0;
addx = 1; addx = 1;
} else { } else {
dx = x0 - x1; dx = x0 - x1;
addx = -1; addx = -1;
} }
if (y1 >= y0) { if (y1 >= y0) {
dy = y1 - y0; dy = y1 - y0;
addy = 1; addy = 1;
} else { } else {
dy = y0 - y1; dy = y0 - y1;
addy = -1; addy = -1;
} }
if (dx >= dy) { if (dx >= dy) {
dy *= 2; dy *= 2;
P = dy - dx; P = dy - dx;
diff = P - dx; diff = P - dx;
for(i=0; i<=dx; ++i) { for(i=0; i<=dx; ++i) {
if (run++ >= 0) { if (run++ >= 0) {
if (run >= run_on) if (run >= run_on)
run = run_off; run = run_off;
gdispDrawPixel(x0, y0, style->color); gdispDrawPixel(x0, y0, style->color);
} }
if (P < 0) { if (P < 0) {
P += dy; P += dy;
x0 += addx; x0 += addx;
} else { } else {
P += diff; P += diff;
x0 += addx; x0 += addx;
y0 += addy; y0 += addy;
} }
} }
} else { } else {
dx *= 2; dx *= 2;
P = dx - dy; P = dx - dy;
diff = P - dy; diff = P - dy;
for(i=0; i<=dy; ++i) { for(i=0; i<=dy; ++i) {
if (run++ >= 0) { if (run++ >= 0) {
if (run >= run_on) if (run >= run_on)
run = run_off; run = run_off;
gdispDrawPixel(x0, y0, style->color); gdispDrawPixel(x0, y0, style->color);
} }
if (P < 0) { if (P < 0) {
P += dx; P += dx;
y0 += addy; y0 += addy;
} else { } else {
P += diff; P += diff;
x0 += addx; x0 += addx;
y0 += addy; y0 += addy;
} }
} }
} }
} }
GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gg = (GGraphObject *)_gwinInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject)))) if (!(gg = (GGraphObject *)_gwinInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject))))
return 0; return 0;
gg->gwin.type = GW_GRAPH; gg->gwin.type = GW_GRAPH;
gg->xorigin = gg->yorigin = 0; gg->xorigin = gg->yorigin = 0;
gg->lastx = gg->lasty = 0; gg->lastx = gg->lasty = 0;
gwinGraphSetStyle(&gg->gwin, &GGraphDefaultStyle); gwinGraphSetStyle(&gg->gwin, &GGraphDefaultStyle);
return (GHandle)gg; return (GHandle)gg;
} }
void gwinGraphSetStyle(GHandle gh, const GGraphStyle *pstyle) { void gwinGraphSetStyle(GHandle gh, const GGraphStyle *pstyle) {
#define gg ((GGraphObject *)gh) #define gg ((GGraphObject *)gh)
if (gh->type != GW_GRAPH) if (gh->type != GW_GRAPH)
return; return;
gg->style.point.type = pstyle->point.type; gg->style.point.type = pstyle->point.type;
gg->style.point.size = pstyle->point.size; gg->style.point.size = pstyle->point.size;
gg->style.point.color = pstyle->point.color; gg->style.point.color = pstyle->point.color;
gg->style.line.type = pstyle->line.type; gg->style.line.type = pstyle->line.type;
gg->style.line.size = pstyle->line.size; gg->style.line.size = pstyle->line.size;
gg->style.line.color = pstyle->line.color; gg->style.line.color = pstyle->line.color;
gg->style.xaxis.type = pstyle->xaxis.type; gg->style.xaxis.type = pstyle->xaxis.type;
gg->style.xaxis.size = pstyle->xaxis.size; gg->style.xaxis.size = pstyle->xaxis.size;
gg->style.xaxis.color = pstyle->xaxis.color; gg->style.xaxis.color = pstyle->xaxis.color;
gg->style.yaxis.type = pstyle->yaxis.type; gg->style.yaxis.type = pstyle->yaxis.type;
gg->style.yaxis.size = pstyle->yaxis.size; gg->style.yaxis.size = pstyle->yaxis.size;
gg->style.yaxis.color = pstyle->yaxis.color; gg->style.yaxis.color = pstyle->yaxis.color;
gg->style.xgrid.type = pstyle->xgrid.type; gg->style.xgrid.type = pstyle->xgrid.type;
gg->style.xgrid.size = pstyle->xgrid.size; gg->style.xgrid.size = pstyle->xgrid.size;
gg->style.xgrid.color = pstyle->xgrid.color; gg->style.xgrid.color = pstyle->xgrid.color;
gg->style.xgrid.spacing = pstyle->xgrid.spacing; gg->style.xgrid.spacing = pstyle->xgrid.spacing;
gg->style.ygrid.type = pstyle->ygrid.type; gg->style.ygrid.type = pstyle->ygrid.type;
gg->style.ygrid.size = pstyle->ygrid.size; gg->style.ygrid.size = pstyle->ygrid.size;
gg->style.ygrid.color = pstyle->ygrid.color; gg->style.ygrid.color = pstyle->ygrid.color;
gg->style.ygrid.spacing = pstyle->ygrid.spacing; gg->style.ygrid.spacing = pstyle->ygrid.spacing;
gg->style.flags = pstyle->flags; gg->style.flags = pstyle->flags;
#undef gg #undef gg
} }
void gwinGraphSetOrigin(GHandle gh, coord_t x, coord_t y) { void gwinGraphSetOrigin(GHandle gh, coord_t x, coord_t y) {
#define gg ((GGraphObject *)gh) #define gg ((GGraphObject *)gh)
if (gh->type != GW_GRAPH) if (gh->type != GW_GRAPH)
return; return;
gg->xorigin = x; gg->xorigin = x;
gg->yorigin = y; gg->yorigin = y;
#undef gg #undef gg
} }
void gwinGraphDrawAxis(GHandle gh) { void gwinGraphDrawAxis(GHandle gh) {
#define gg ((GGraphObject *)gh) #define gg ((GGraphObject *)gh)
coord_t i, xmin, ymin, xmax, ymax; coord_t i, xmin, ymin, xmax, ymax;
if (gh->type != GW_GRAPH) if (gh->type != GW_GRAPH)
return; return;
xmin = -gg->xorigin; xmin = -gg->xorigin;
xmax = gh->width-gg->xorigin-1; xmax = gh->width-gg->xorigin-1;
ymin = -gg->yorigin; ymin = -gg->yorigin;
ymax = gh->height-gg->yorigin-1; ymax = gh->height-gg->yorigin-1;
// x grid - this code assumes that the GGraphGridStyle is a superset of GGraphListStyle // x grid - this code assumes that the GGraphGridStyle is a superset of GGraphListStyle
if (gg->style.xgrid.type != GGRAPH_LINE_NONE && gg->style.xgrid.spacing >= 2) { if (gg->style.xgrid.type != GGRAPH_LINE_NONE && gg->style.xgrid.spacing >= 2) {
for(i = gg->style.xgrid.spacing; i <= xmax; i += gg->style.xgrid.spacing) for(i = gg->style.xgrid.spacing; i <= xmax; i += gg->style.xgrid.spacing)
lineto(gg, i, ymin, i, ymax, (GGraphLineStyle *)&gg->style.xgrid); lineto(gg, i, ymin, i, ymax, (GGraphLineStyle *)&gg->style.xgrid);
for(i = -gg->style.xgrid.spacing; i >= xmin; i -= gg->style.xgrid.spacing) for(i = -gg->style.xgrid.spacing; i >= xmin; i -= gg->style.xgrid.spacing)
lineto(gg, i, ymin, i, ymax, (GGraphLineStyle *)&gg->style.xgrid); lineto(gg, i, ymin, i, ymax, (GGraphLineStyle *)&gg->style.xgrid);
} }
// y grid - this code assumes that the GGraphGridStyle is a superset of GGraphListStyle // y grid - this code assumes that the GGraphGridStyle is a superset of GGraphListStyle
if (gg->style.ygrid.type != GGRAPH_LINE_NONE && gg->style.ygrid.spacing >= 2) { if (gg->style.ygrid.type != GGRAPH_LINE_NONE && gg->style.ygrid.spacing >= 2) {
for(i = gg->style.ygrid.spacing; i <= ymax; i += gg->style.ygrid.spacing) for(i = gg->style.ygrid.spacing; i <= ymax; i += gg->style.ygrid.spacing)
lineto(gg, xmin, i, xmax, i, (GGraphLineStyle *)&gg->style.ygrid); lineto(gg, xmin, i, xmax, i, (GGraphLineStyle *)&gg->style.ygrid);
for(i = -gg->style.ygrid.spacing; i >= ymin; i -= gg->style.ygrid.spacing) for(i = -gg->style.ygrid.spacing; i >= ymin; i -= gg->style.ygrid.spacing)
lineto(gg, xmin, i, xmax, i, (GGraphLineStyle *)&gg->style.ygrid); lineto(gg, xmin, i, xmax, i, (GGraphLineStyle *)&gg->style.ygrid);
} }
// x axis // x axis
lineto(gg, xmin, 0, xmax, 0, &gg->style.xaxis); lineto(gg, xmin, 0, xmax, 0, &gg->style.xaxis);
if ((gg->style.flags & GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS)) { if ((gg->style.flags & GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS)) {
if (xmin > 0 || xmin < -(GGRAPH_ARROW_SIZE+1)) { if (xmin > 0 || xmin < -(GGRAPH_ARROW_SIZE+1)) {
lineto(gg, xmin, 0, xmin+GGRAPH_ARROW_SIZE, GGRAPH_ARROW_SIZE, &gg->style.xaxis); lineto(gg, xmin, 0, xmin+GGRAPH_ARROW_SIZE, GGRAPH_ARROW_SIZE, &gg->style.xaxis);
lineto(gg, xmin, 0, xmin+GGRAPH_ARROW_SIZE, -GGRAPH_ARROW_SIZE, &gg->style.xaxis); lineto(gg, xmin, 0, xmin+GGRAPH_ARROW_SIZE, -GGRAPH_ARROW_SIZE, &gg->style.xaxis);
} }
} }
if ((gg->style.flags & GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS)) { if ((gg->style.flags & GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS)) {
if (xmax < 0 || xmax > (GGRAPH_ARROW_SIZE+1)) { if (xmax < 0 || xmax > (GGRAPH_ARROW_SIZE+1)) {
lineto(gg, xmax, 0, xmax-GGRAPH_ARROW_SIZE, GGRAPH_ARROW_SIZE, &gg->style.xaxis); lineto(gg, xmax, 0, xmax-GGRAPH_ARROW_SIZE, GGRAPH_ARROW_SIZE, &gg->style.xaxis);
lineto(gg, xmax, 0, xmax-GGRAPH_ARROW_SIZE, -GGRAPH_ARROW_SIZE, &gg->style.xaxis); lineto(gg, xmax, 0, xmax-GGRAPH_ARROW_SIZE, -GGRAPH_ARROW_SIZE, &gg->style.xaxis);
} }
} }
// y axis // y axis
lineto(gg, 0, ymin, 0, ymax, &gg->style.yaxis); lineto(gg, 0, ymin, 0, ymax, &gg->style.yaxis);
if ((gg->style.flags & GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS)) { if ((gg->style.flags & GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS)) {
if (ymin > 0 || ymin < -(GGRAPH_ARROW_SIZE+1)) { if (ymin > 0 || ymin < -(GGRAPH_ARROW_SIZE+1)) {
lineto(gg, 0, ymin, GGRAPH_ARROW_SIZE, ymin+GGRAPH_ARROW_SIZE, &gg->style.yaxis); lineto(gg, 0, ymin, GGRAPH_ARROW_SIZE, ymin+GGRAPH_ARROW_SIZE, &gg->style.yaxis);
lineto(gg, 0, ymin, -GGRAPH_ARROW_SIZE, ymin+GGRAPH_ARROW_SIZE, &gg->style.yaxis); lineto(gg, 0, ymin, -GGRAPH_ARROW_SIZE, ymin+GGRAPH_ARROW_SIZE, &gg->style.yaxis);
} }
} }
if ((gg->style.flags & GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS)) { if ((gg->style.flags & GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS)) {
if (ymax < 0 || ymax > (GGRAPH_ARROW_SIZE+1)) { if (ymax < 0 || ymax > (GGRAPH_ARROW_SIZE+1)) {
lineto(gg, 0, ymax, GGRAPH_ARROW_SIZE, ymax-GGRAPH_ARROW_SIZE, &gg->style.yaxis); lineto(gg, 0, ymax, GGRAPH_ARROW_SIZE, ymax-GGRAPH_ARROW_SIZE, &gg->style.yaxis);
lineto(gg, 0, ymax, -GGRAPH_ARROW_SIZE, ymax-GGRAPH_ARROW_SIZE, &gg->style.yaxis); lineto(gg, 0, ymax, -GGRAPH_ARROW_SIZE, ymax-GGRAPH_ARROW_SIZE, &gg->style.yaxis);
} }
} }
#undef gg #undef gg
} }
void gwinGraphStartSet(GHandle gh) { void gwinGraphStartSet(GHandle gh) {
if (gh->type != GW_GRAPH) if (gh->type != GW_GRAPH)
return; return;
gh->flags &= ~GGRAPH_FLG_CONNECTPOINTS; gh->flags &= ~GGRAPH_FLG_CONNECTPOINTS;
} }
void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y) { void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y) {
#define gg ((GGraphObject *)gh) #define gg ((GGraphObject *)gh)
if (gh->type != GW_GRAPH) if (gh->type != GW_GRAPH)
return; return;
if ((gh->flags & GGRAPH_FLG_CONNECTPOINTS)) { if ((gh->flags & GGRAPH_FLG_CONNECTPOINTS)) {
// Draw the line // Draw the line
lineto(gg, gg->lastx, gg->lasty, x, y, &gg->style.line); lineto(gg, gg->lastx, gg->lasty, x, y, &gg->style.line);
// Redraw the previous point because the line may have overwritten it // Redraw the previous point because the line may have overwritten it
pointto(gg, gg->lastx, gg->lasty, &gg->style.point); pointto(gg, gg->lastx, gg->lasty, &gg->style.point);
} else } else
gh->flags |= GGRAPH_FLG_CONNECTPOINTS; gh->flags |= GGRAPH_FLG_CONNECTPOINTS;
// Save this point for next time. // Save this point for next time.
gg->lastx = x; gg->lastx = x;
gg->lasty = y; gg->lasty = y;
// Draw this point. // Draw this point.
pointto(gg, x, y, &gg->style.point); pointto(gg, x, y, &gg->style.point);
#undef gg #undef gg
} }
void gwinGraphDrawPoints(GHandle gh, const GGraphPoint *points, unsigned count) { void gwinGraphDrawPoints(GHandle gh, const point *points, unsigned count) {
#define gg ((GGraphObject *)gh) #define gg ((GGraphObject *)gh)
unsigned i; unsigned i;
const GGraphPoint *p; const point *p;
if (gh->type != GW_GRAPH) if (gh->type != GW_GRAPH)
return; return;
// Draw the connecting lines // Draw the connecting lines
for(p = points, i = 0; i < count; p++, i++) { for(p = points, i = 0; i < count; p++, i++) {
if ((gh->flags & GGRAPH_FLG_CONNECTPOINTS)) { if ((gh->flags & GGRAPH_FLG_CONNECTPOINTS)) {
// Draw the line // Draw the line
lineto(gg, gg->lastx, gg->lasty, p->x, p->y, &gg->style.line); lineto(gg, gg->lastx, gg->lasty, p->x, p->y, &gg->style.line);
// Redraw the previous point because the line may have overwritten it // Redraw the previous point because the line may have overwritten it
if (i == 0) if (i == 0)
pointto(gg, gg->lastx, gg->lasty, &gg->style.point); pointto(gg, gg->lastx, gg->lasty, &gg->style.point);
} else } else
gh->flags |= GGRAPH_FLG_CONNECTPOINTS; gh->flags |= GGRAPH_FLG_CONNECTPOINTS;
// Save this point for next time. // Save this point for next time.
gg->lastx = p->x; gg->lastx = p->x;
gg->lasty = p->y; gg->lasty = p->y;
} }
// Draw the points. // Draw the points.
for(p = points, i = 0; i < count; p++, i++) for(p = points, i = 0; i < count; p++, i++)
pointto(gg, p->x, p->y, &gg->style.point); pointto(gg, p->x, p->y, &gg->style.point);
#undef gg #undef gg
} }
#endif /* GFX_USE_GWIN && GWIN_NEED_GRAPH */ #endif /* GFX_USE_GWIN && GWIN_NEED_GRAPH */
/** @} */ /** @} */

View file

@ -31,7 +31,7 @@
#include "hal.h" #include "hal.h"
#include "gfx.h" #include "gfx.h"
#if GFX_USE_GWIN || defined(__DOXYGEN__) #if GFX_USE_GWIN
#include "gwin/internal.h" #include "gwin/internal.h"
@ -64,27 +64,12 @@ GHandle _gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_
gw->height = height; gw->height = height;
gw->color = White; gw->color = White;
gw->bgcolor = Black; gw->bgcolor = Black;
#if GDISP_NEED_TEXT #if GDISP_NEED_TEXT
gw->font = 0; gw->font = 0;
#endif #endif
return (GHandle)gw; return (GHandle)gw;
} }
/**
* @brief Create a basic window.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
* @param[in] gw The window structure to initialise. If this is NULL the structure is dynamically allocated.
* @param[in] x,y The screen co-ordinates for the bottom left corner of the window
* @param[in] width The width of the window
* @param[in] height The height of the window
* @note The default drawing color gets set to White and the background drawing color to Black.
* @note No default font is set so make sure to set one before drawing any text.
* @note The dimensions and position may be changed to fit on the real screen.
* @note The window is not automatically cleared on creation. You must do that by calling gwinClear() (possibly after changing your background color)
*
* @api
*/
GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gw = (GWindowObject *)_gwinInit((GWindowObject *)gw, x, y, width, height, sizeof(GWindowObject)))) if (!(gw = (GWindowObject *)_gwinInit((GWindowObject *)gw, x, y, width, height, sizeof(GWindowObject))))
return 0; return 0;
@ -92,13 +77,6 @@ GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width,
return (GHandle)gw; return (GHandle)gw;
} }
/**
* @brief Destroy a window (of any type). Releases any dynamicly allocated memory.
*
* @param[in] gh The window handle
*
* @api
*/
void gwinDestroyWindow(GHandle gh) { void gwinDestroyWindow(GHandle gh) {
// Clean up any type specific dynamic memory allocations // Clean up any type specific dynamic memory allocations
switch(gh->type) { switch(gh->type) {
@ -123,34 +101,18 @@ void gwinDestroyWindow(GHandle gh) {
} }
} }
#if GDISP_NEED_TEXT || defined(__DOXYGEN__) #if GDISP_NEED_TEXT
/** void gwinSetFont(GHandle gh, font_t font) {
* @brief Set the current font for this window. gh->font = font;
* #if GWIN_NEED_CONSOLE
* @param[in] gh The window handle if (font && gh->type == GW_CONSOLE) {
* @param[in] font The font to use for text functions ((GConsoleObject *)gh)->fy = gdispGetFontMetric(font, fontHeight);
* ((GConsoleObject *)gh)->fp = gdispGetFontMetric(font, fontCharPadding);
* @api }
*/ #endif
void gwinSetFont(GHandle gh, font_t font) {
gh->font = font;
#if GWIN_NEED_CONSOLE
if (font && gh->type == GW_CONSOLE) {
((GConsoleObject *)gh)->fy = gdispGetFontMetric(font, fontHeight);
((GConsoleObject *)gh)->fp = gdispGetFontMetric(font, fontCharPadding);
} }
#endif #endif
}
#endif
/**
* @brief Clear the window
* @note Uses the current background color to clear the window
*
* @param[in] gh The window handle
*
* @api
*/
void gwinClear(GHandle gh) { void gwinClear(GHandle gh) {
#if GDISP_NEED_CLIP #if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height); gdispSetClip(gh->x, gh->y, gh->width, gh->height);
@ -165,16 +127,6 @@ void gwinClear(GHandle gh) {
#endif #endif
} }
/**
* @brief Set a pixel in the window
* @note Uses the current foreground color to set the pixel
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The coordinates of the pixel
*
* @api
*/
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) { void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
#if GDISP_NEED_CLIP #if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height); gdispSetClip(gh->x, gh->y, gh->width, gh->height);
@ -182,17 +134,6 @@ void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
gdispDrawPixel(gh->x+x, gh->y+y, gh->color); gdispDrawPixel(gh->x+x, gh->y+y, gh->color);
} }
/**
* @brief Draw a line in the window
* @note Uses the current foreground color to draw the line
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x0,y0 The start position
* @param[in] x1,y1 The end position
*
* @api
*/
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) { void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
#if GDISP_NEED_CLIP #if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height); gdispSetClip(gh->x, gh->y, gh->width, gh->height);
@ -200,17 +141,6 @@ void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
gdispDrawLine(gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color); gdispDrawLine(gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
} }
/**
* @brief Draw a box in the window
* @note Uses the current foreground color to draw the box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
*
* @api
*/
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
#if GDISP_NEED_CLIP #if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height); gdispSetClip(gh->x, gh->y, gh->width, gh->height);
@ -218,17 +148,6 @@ void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
gdispDrawBox(gh->x+x, gh->y+y, cx, cy, gh->color); gdispDrawBox(gh->x+x, gh->y+y, cx, cy, gh->color);
} }
/**
* @brief Fill an rectangular area in the window
* @note Uses the current foreground color to fill the box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
*
* @api
*/
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
#if GDISP_NEED_CLIP #if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height); gdispSetClip(gh->x, gh->y, gh->width, gh->height);
@ -236,23 +155,6 @@ void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
gdispFillArea(gh->x+x, gh->y+y, cx, cy, gh->color); gdispFillArea(gh->x+x, gh->y+y, cx, cy, gh->color);
} }
/**
* @brief Fill an area in the window using the supplied bitmap.
* @details The bitmap is in the pixel format specified by the low level driver
* @note If GDISP_NEED_ASYNC is defined then the buffer must be static
* or at least retained until this call has finished the blit. You can
* tell when all graphics drawing is finished by @p gdispIsBusy() going FALSE.
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @api
*/
void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
#if GDISP_NEED_CLIP #if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height); gdispSetClip(gh->x, gh->y, gh->width, gh->height);
@ -260,285 +162,127 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
gdispBlitAreaEx(gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer); gdispBlitAreaEx(gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
} }
#if GDISP_NEED_CIRCLE || defined(__DOXYGEN__) #if GDISP_NEED_CIRCLE
/** void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
* @brief Draw a circle in the window. #if GDISP_NEED_CLIP
* @note Uses the current foreground color to draw the circle gdispSetClip(gh->x, gh->y, gh->width, gh->height);
* @note May leave GDISP clipping to this window's dimensions #endif
* gdispDrawCircle(gh->x+x, gh->y+y, radius, gh->color);
* @param[in] gh The window handle }
* @param[in] x, y The center of the circle
* @param[in] radius The radius of the circle void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
* #if GDISP_NEED_CLIP
* @api gdispSetClip(gh->x, gh->y, gh->width, gh->height);
*/ #endif
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) { gdispFillCircle(gh->x+x, gh->y+y, radius, gh->color);
#if GDISP_NEED_CLIP }
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawCircle(gh->x+x, gh->y+y, radius, gh->color);
}
#endif #endif
#if GDISP_NEED_CIRCLE || defined(__DOXYGEN__) #if GDISP_NEED_ELLIPSE
/** void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
* @brief Draw a filled circle in the window. #if GDISP_NEED_CLIP
* @note Uses the current foreground color to draw the filled circle gdispSetClip(gh->x, gh->y, gh->width, gh->height);
* @note May leave GDISP clipping to this window's dimensions #endif
* gdispDrawEllipse(gh->x+x, gh->y+y, a, b, gh->color);
* @param[in] gh The window handle }
* @param[in] x, y The center of the circle
* @param[in] radius The radius of the circle void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
* #if GDISP_NEED_CLIP
* @api gdispSetClip(gh->x, gh->y, gh->width, gh->height);
*/ #endif
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) { gdispFillEllipse(gh->x+x, gh->y+y, a, b, gh->color);
#if GDISP_NEED_CLIP }
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillCircle(gh->x+x, gh->y+y, radius, gh->color);
}
#endif #endif
#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__) #if GDISP_NEED_ARC
/** void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
* @brief Draw an ellipse. #if GDISP_NEED_CLIP
* @note Uses the current foreground color to draw the ellipse gdispSetClip(gh->x, gh->y, gh->width, gh->height);
* @note May leave GDISP clipping to this window's dimensions #endif
* gdispDrawArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
* @param[in] gh The window handle }
* @param[in] x,y The center of the ellipse
* @param[in] a,b The dimensions of the ellipse void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
* #if GDISP_NEED_CLIP
* @api gdispSetClip(gh->x, gh->y, gh->width, gh->height);
*/ #endif
void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) { gdispFillArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
#if GDISP_NEED_CLIP }
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawEllipse(gh->x+x, gh->y+y, a, b, gh->color);
}
#endif #endif
#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__) #if GDISP_NEED_PIXELREAD
/** color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
* @brief Draw an filled ellipse. #if GDISP_NEED_CLIP
* @note Uses the current foreground color to draw the filled ellipse gdispSetClip(gh->x, gh->y, gh->width, gh->height);
* @note May leave GDISP clipping to this window's dimensions #endif
* return gdispGetPixelColor(gh->x+x, gh->y+y);
* @param[in] gh The window handle }
* @param[in] x,y The center of the ellipse
* @param[in] a,b The dimensions of the ellipse
*
* @api
*/
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillEllipse(gh->x+x, gh->y+y, a, b, gh->color);
}
#endif #endif
#if GDISP_NEED_ARC || defined(__DOXYGEN__) #if GDISP_NEED_TEXT
/* void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
* @brief Draw an arc in the window. if (!gh->font) return;
* @note Uses the current foreground color to draw the arc #if GDISP_NEED_CLIP
* @note May leave GDISP clipping to this window's dimensions gdispSetClip(gh->x, gh->y, gh->width, gh->height);
* #endif
* @param[in] gh The window handle gdispDrawChar(gh->x+x, gh->y+y, c, gh->font, gh->color);
* @param[in] x,y The center point }
* @param[in] radius The radius of the arc
* @param[in] start The start angle (0 to 360) void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
* @param[in] end The end angle (0 to 360) if (!gh->font) return;
* #if GDISP_NEED_CLIP
* @api gdispSetClip(gh->x, gh->y, gh->width, gh->height);
*/ #endif
void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) { gdispFillChar(gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
#if GDISP_NEED_CLIP }
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
gdispDrawArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color); if (!gh->font) return;
} #if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawString(gh->x+x, gh->y+y, str, gh->font, gh->color);
}
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillString(gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
}
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
}
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
}
#endif #endif
#if GDISP_NEED_ARC || defined(__DOXYGEN__) #if GDISP_NEED_CONVEX_POLYGON
/* void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
* @brief Draw a filled arc in the window. #if GDISP_NEED_CLIP
* @note Uses the current foreground color to draw the filled arc gdispSetClip(gh->x, gh->y, gh->width, gh->height);
* @note May leave GDISP clipping to this window's dimensions #endif
* gdispDrawPoly(tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
* @param[in] gh The window handle }
* @param[in] x,y The center point
* @param[in] radius The radius of the arc
* @param[in] start The start angle (0 to 360)
* @param[in] end The end angle (0 to 360)
*
* @api
*/
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
}
#endif
#if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__) void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
/** #if GDISP_NEED_CLIP
* @brief Get the color of a pixel in the window. gdispSetClip(gh->x, gh->y, gh->width, gh->height);
* @return The color of the pixel. #endif
* @note May leave GDISP clipping to this window's dimensions gdispFillConvexPoly(tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
* }
* @param[in] gh The window handle
* @param[in] x,y The position in the window
*
* @api
*/
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
return gdispGetPixelColor(gh->x+x, gh->y+y);
}
#endif
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text character at the specified position in the window.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] c The character to draw
*
* @api
*/
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawChar(gh->x+x, gh->y+y, c, gh->font, gh->color);
}
#endif
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text character with a filled background at the specified position in the window.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] c The character to draw
*
* @api
*/
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillChar(gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
}
#endif
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text string in the window
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] str The string to draw
*
* @api
*/
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawString(gh->x+x, gh->y+y, str, gh->font, gh->color);
}
#endif
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text string with a filled background in the window
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text
* @param[in] str The string to draw
*
* @api
*/
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillString(gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
}
#endif
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text string verticly centered within the specified box.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character.
* @note The specified box does not need to align with the window box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
* @param[in] justify Justify the text left, center or right within the box
*
* @api
*/
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
}
#endif
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text string verticly centered within the specified filled box.
* @pre The font must have been set.
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
* @note The entire box is filled. Note this box does not need to align with the window box
* @note May leave GDISP clipping to this window's dimensions
*
* @param[in] gh The window handle
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
* @param[in] justify Justify the text left, center or right within the box
*
* @api
*/
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
if (!gh->font) return;
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
}
#endif #endif
#endif /* GFX_USE_GWIN */ #endif /* GFX_USE_GWIN */