GDISP fixes and new routines. Many GWIN changes.
GDISP: Fix gdisp???Arc to use (possibly) hardware accelerated routines. Fix Arc orientation so 0 degrees is on x axis and 90 degrees points to the top of screen (instead of the bottom). Add rounded box routines (if ARC support is turned on). Add a gdispDrawStringBox to match the gdispFillStringBox routine. Repair prototypes in wrong place in gdisp.h GWIN: Extract the concept of a Window Handle to allow many new features. Allow dynamic creation of window objects as well as static initialisation. Seperate the console code into a console specific window type. Add buttons as a specific window type. The drawing code is complete, the input (touch or mouse) is still to be implemented.
This commit is contained in:
parent
a55da05d2e
commit
d3b4c499ab
7 changed files with 1268 additions and 780 deletions
|
@ -166,6 +166,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#if GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC
|
||||
/* These routines can be hardware accelerated
|
||||
* - Do not add a routine here unless it has also been added to the hardware acceleration layer
|
||||
*/
|
||||
|
||||
/* Base Functions */
|
||||
bool_t gdispInit(void);
|
||||
|
@ -253,8 +256,9 @@ extern "C" {
|
|||
|
||||
#endif
|
||||
|
||||
/* Now obsolete functions */
|
||||
#define gdispBlitArea(x, y, cx, cy, buffer) gdispBlitAreaEx(x, y, cx, cy, 0, 0, cx, buffer)
|
||||
/* These routines are not hardware accelerated
|
||||
* - Do not add a hardware accelerated routines here.
|
||||
*/
|
||||
|
||||
/* Extra drawing functions */
|
||||
void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
|
||||
|
@ -263,17 +267,31 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
|
|||
#if GDISP_NEED_TEXT
|
||||
void gdispDrawString(coord_t x, coord_t y, const char *str, font_t font, color_t color);
|
||||
void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor);
|
||||
void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify);
|
||||
void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgColor, justify_t justify);
|
||||
coord_t gdispGetFontMetric(font_t font, fontmetric_t metric);
|
||||
coord_t gdispGetCharWidth(char c, font_t font);
|
||||
coord_t gdispGetStringWidth(const char* str, font_t font);
|
||||
#endif
|
||||
|
||||
/* Extra Arc Functions */
|
||||
#if GDISP_NEED_ARC
|
||||
void gdispDrawRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
|
||||
void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
|
||||
#endif
|
||||
|
||||
/* Support routine for packed pixel formats */
|
||||
#ifndef gdispPackPixels
|
||||
void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color);
|
||||
#endif
|
||||
|
||||
/* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/* Now obsolete functions */
|
||||
#define gdispBlitArea(x, y, cx, cy, buffer) gdispBlitAreaEx(x, y, cx, cy, 0, 0, cx, buffer)
|
||||
|
||||
/* Macro definitions for common gets and sets */
|
||||
#define gdispSetPowerMode(powerMode) gdispControl(GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
|
||||
#define gdispSetOrientation(newOrientation) gdispControl(GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
|
||||
|
|
|
@ -291,7 +291,7 @@
|
|||
|
||||
#if GDISP_NEED_ARC && !GDISP_HARDWARE_ARCS
|
||||
|
||||
#include <maths.h>
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
* @brief Internal helper function for gdispDrawArc()
|
||||
|
@ -307,7 +307,7 @@
|
|||
* @notapi
|
||||
*/
|
||||
static void _draw_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
|
||||
if (start >= 0 && start <= 180) {
|
||||
if (/*start >= 0 && */start <= 180) {
|
||||
float x_maxI = x + radius*cos(start*M_PI/180);
|
||||
float x_minI;
|
||||
|
||||
|
@ -322,13 +322,13 @@
|
|||
|
||||
do {
|
||||
if(x-a <= x_maxI && x-a >= x_minI)
|
||||
GDISP_LLD(drawpixel)(x-a, y+b, color);
|
||||
GDISP_LLD(drawpixel)(x-a, y-b, color);
|
||||
if(x+a <= x_maxI && x+a >= x_minI)
|
||||
GDISP_LLD(drawpixel)(x+a, y+b, color);
|
||||
GDISP_LLD(drawpixel)(x+a, y-b, color);
|
||||
if(x-b <= x_maxI && x-b >= x_minI)
|
||||
GDISP_LLD(drawpixel)(x-b, y+a, color);
|
||||
GDISP_LLD(drawpixel)(x-b, y-a, color);
|
||||
if(x+b <= x_maxI && x+b >= x_minI)
|
||||
GDISP_LLD(drawpixel)(x+b, y+a, color);
|
||||
GDISP_LLD(drawpixel)(x+b, y-a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
|
@ -356,13 +356,13 @@
|
|||
|
||||
do {
|
||||
if(x-a <= x_maxII && x-a >= x_minII)
|
||||
GDISP_LLD(drawpixel)(x-a, y-b, color);
|
||||
GDISP_LLD(drawpixel)(x-a, y+b, color);
|
||||
if(x+a <= x_maxII && x+a >= x_minII)
|
||||
GDISP_LLD(drawpixel)(x+a, y-b, color);
|
||||
GDISP_LLD(drawpixel)(x+a, y+b, color);
|
||||
if(x-b <= x_maxII && x-b >= x_minII)
|
||||
GDISP_LLD(drawpixel)(x-b, y-a, color);
|
||||
GDISP_LLD(drawpixel)(x-b, y+a, color);
|
||||
if(x+b <= x_maxII && x+b >= x_minII)
|
||||
GDISP_LLD(drawpixel)(x+b, y-a, color);
|
||||
GDISP_LLD(drawpixel)(x+b, y+a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
|
@ -387,14 +387,96 @@
|
|||
#endif
|
||||
|
||||
#if GDISP_NEED_ARC && !GDISP_HARDWARE_ARCFILLS
|
||||
/*
|
||||
* @brief Internal helper function for gdispDrawArc()
|
||||
*
|
||||
* @note DO NOT USE DIRECTLY!
|
||||
*
|
||||
* @param[in] x, y The middle point of the arc
|
||||
* @param[in] start The start angle of the arc
|
||||
* @param[in] end The end angle of the arc
|
||||
* @param[in] radius The radius of the arc
|
||||
* @param[in] color The color in which the arc will be drawn
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void _fill_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
|
||||
if (/*start >= 0 && */start <= 180) {
|
||||
float x_maxI = x + radius*cos(start*M_PI/180);
|
||||
float x_minI;
|
||||
|
||||
if (end > 180)
|
||||
x_minI = x - radius;
|
||||
else
|
||||
x_minI = x + radius*cos(end*M_PI/180);
|
||||
|
||||
int a = 0;
|
||||
int b = radius;
|
||||
int P = 1 - radius;
|
||||
|
||||
do {
|
||||
if(x-a <= x_maxI && x-a >= x_minI)
|
||||
GDISP_LLD(drawline)(x, y, x-a, y-b, color);
|
||||
if(x+a <= x_maxI && x+a >= x_minI)
|
||||
GDISP_LLD(drawline)(x, y, x+a, y-b, color);
|
||||
if(x-b <= x_maxI && x-b >= x_minI)
|
||||
GDISP_LLD(drawline)(x, y, x-b, y-a, color);
|
||||
if(x+b <= x_maxI && x+b >= x_minI)
|
||||
GDISP_LLD(drawline)(x, y, x+b, y-a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
a = a + 1;
|
||||
} else {
|
||||
P = P + 5 + 2*(a - b);
|
||||
a = a + 1;
|
||||
b = b - 1;
|
||||
}
|
||||
} while(a <= b);
|
||||
}
|
||||
|
||||
if (end > 180 && end <= 360) {
|
||||
float x_maxII = x+radius*cos(end*M_PI/180);
|
||||
float x_minII;
|
||||
|
||||
if(start <= 180)
|
||||
x_minII = x - radius;
|
||||
else
|
||||
x_minII = x+radius*cos(start*M_PI/180);
|
||||
|
||||
int a = 0;
|
||||
int b = radius;
|
||||
int P = 1 - radius;
|
||||
|
||||
do {
|
||||
if(x-a <= x_maxII && x-a >= x_minII)
|
||||
GDISP_LLD(drawline)(x, y, x-a, y+b, color);
|
||||
if(x+a <= x_maxII && x+a >= x_minII)
|
||||
GDISP_LLD(drawline)(x, y, x+a, y+b, color);
|
||||
if(x-b <= x_maxII && x-b >= x_minII)
|
||||
GDISP_LLD(drawline)(x, y, x-b, y+a, color);
|
||||
if(x+b <= x_maxII && x+b >= x_minII)
|
||||
GDISP_LLD(drawline)(x, y, x+b, y+a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
a = a + 1;
|
||||
} else {
|
||||
P = P + 5 + 2*(a - b);
|
||||
a = a + 1;
|
||||
b = b - 1;
|
||||
}
|
||||
} while (a <= b);
|
||||
}
|
||||
}
|
||||
|
||||
void GDISP_LLD(fillarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color) {
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)radius;
|
||||
(void)startangle;
|
||||
(void)endangle;
|
||||
(void)color;
|
||||
#warning "GDISP: FillArc Emulation Not Implemented Yet"
|
||||
if(endangle < startangle) {
|
||||
_fill_arc(x, y, startangle, 360, radius, color);
|
||||
_fill_arc(x, y, 0, endangle, radius, color);
|
||||
} else {
|
||||
_fill_arc(x, y, startangle, endangle, radius, color);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -88,4 +88,3 @@ struct font {
|
|||
|
||||
#endif /* _GDISP_FONTS_H */
|
||||
/** @} */
|
||||
|
||||
|
|
197
include/gwin.h
197
include/gwin.h
|
@ -45,52 +45,119 @@
|
|||
* @name GWIN more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should console functions be included.
|
||||
* @details Defaults to TRUE
|
||||
*/
|
||||
#ifndef GWIN_NEED_CONSOLE
|
||||
#define GWIN_NEED_CONSOLE TRUE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should button functions be included.
|
||||
* @details Defaults to FALSE for now as implementation is not complete
|
||||
*/
|
||||
#ifndef GWIN_NEED_BUTTON
|
||||
#define GWIN_NEED_BUTTON FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver details and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !GFX_USE_GDISP
|
||||
#if !defined(GFX_USE_GDISP)
|
||||
#error "GWIN: GFX_USE_GDISP must also be defined"
|
||||
#endif
|
||||
|
||||
#include "gdisp.h"
|
||||
|
||||
#if !GDISP_NEED_CLIP
|
||||
#warning "GWIN: Drawing can occur outside the defined window as GDISP_NEED_CLIP is FALSE"
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_CONSOLE && !GDISP_NEED_TEXT
|
||||
#error "GWIN: Text support (GDISP_NEED_TEXT) is required if GWIN_NEED_CONSOLE is defined."
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON && !GDISP_NEED_TEXT
|
||||
#error "GWIN: Text support (GDISP_NEED_TEXT) is required if GWIN_NEED_BUTTON is defined."
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON
|
||||
#warning "GWIN: Button support is not complete yet"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannelVMT
|
||||
*
|
||||
* @brief @p GWindow virtual methods table.
|
||||
*/
|
||||
struct GWindowVMT {
|
||||
_base_asynchronous_channel_methods
|
||||
};
|
||||
typedef enum GWindowType_e {
|
||||
GW_WINDOW, GW_CONSOLE, GW_BUTTON
|
||||
} GWindowType;
|
||||
|
||||
struct GWindowText {
|
||||
const struct GWindowVMT *vmt;
|
||||
_base_asynchronous_channel_data
|
||||
font_t font; // Current font
|
||||
uint8_t fy; // Current font height
|
||||
uint8_t fp; // Current font inter-character spacing
|
||||
coord_t cx,cy; // Cursor position
|
||||
};
|
||||
|
||||
typedef struct GWindow_t {
|
||||
#if GDISP_NEED_TEXT
|
||||
struct GWindowText txt;
|
||||
#endif
|
||||
// A basic window
|
||||
typedef struct GWindowObject_t {
|
||||
GWindowType type; // What type of window is this
|
||||
uint16_t flags; // Internal flags
|
||||
coord_t x, y; // Screen relative position
|
||||
coord_t width, height; // Dimensions of this window
|
||||
color_t color, bgcolor; // Current drawing colors
|
||||
} GWindow;
|
||||
#if GDISP_NEED_TEXT
|
||||
font_t font; // Current font
|
||||
#endif
|
||||
} GWindowObject, * GHandle;
|
||||
|
||||
#if GWIN_NEED_CONSOLE
|
||||
// A console window. Supports wrapped text writing and a cursor.
|
||||
typedef struct GConsoleObject_t {
|
||||
GWindowObject gwin;
|
||||
|
||||
struct GConsoleWindowStream_t {
|
||||
const struct GConsoleWindowVMT_t *vmt;
|
||||
_base_asynchronous_channel_data
|
||||
} stream;
|
||||
|
||||
coord_t cx,cy; // Cursor position
|
||||
uint8_t fy; // Current font height
|
||||
uint8_t fp; // Current font inter-character spacing
|
||||
} GConsoleObject;
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON
|
||||
typedef enum GButtonShape_e {
|
||||
GBTN_3D, GBTN_SQUARE, GBTN_ROUNDED, GBTN_ELLIPSE
|
||||
} GButtonShape;
|
||||
|
||||
typedef struct GButtonStyle_t {
|
||||
GButtonShape shape;
|
||||
color_t color_up_edge;
|
||||
color_t color_up_fill;
|
||||
color_t color_up_txt;
|
||||
color_t color_dn_edge;
|
||||
color_t color_dn_fill;
|
||||
color_t color_dn_txt;
|
||||
} GButtonStyle;
|
||||
|
||||
typedef enum GButtonType_e {
|
||||
GBTN_NORMAL, GBTN_TOGGLE
|
||||
} GButtonType;
|
||||
|
||||
typedef enum GButtonState_e {
|
||||
GBTN_UP, GBTN_DOWN
|
||||
} GButtonState;
|
||||
|
||||
// A button window
|
||||
typedef struct GButtonObject_t {
|
||||
GWindowObject gwin;
|
||||
|
||||
GButtonStyle style;
|
||||
GButtonState state;
|
||||
GButtonType type;
|
||||
const char * txt;
|
||||
void * callback; // To be fixed
|
||||
void * inputsrc; // To be fixed
|
||||
} GButtonObject;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
@ -101,70 +168,81 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/* Base Functions */
|
||||
bool_t gwinInit(GWindow *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);
|
||||
void gwinDestroyWindow(GHandle gh);
|
||||
|
||||
/* Status Functions */
|
||||
#define gwinGetScreenX(gw) ((gw)->x)
|
||||
#define gwinGetScreenY(gw) ((gw)->y)
|
||||
#define gwinGetWidth(gw) ((gw)->width)
|
||||
#define gwinGetHeight(gw) ((gw)->height)
|
||||
#define gwinGetScreenX(gh) ((gh)->x)
|
||||
#define gwinGetScreenY(gh) ((gh)->y)
|
||||
#define gwinGetWidth(gh) ((gh)->width)
|
||||
#define gwinGetHeight(gh) ((gh)->height)
|
||||
|
||||
/* Set up for drawing */
|
||||
#define gwinSetColor(gw, clr) (gw)->color = (clr)
|
||||
#define gwinSetBgColor(gw, bgclr) (gw)->bgcolor = (bgclr)
|
||||
#define gwinSetColor(gh, clr) (gh)->color = (clr)
|
||||
#define gwinSetBgColor(gh, bgclr) (gh)->bgcolor = (bgclr)
|
||||
|
||||
/* Set up for text */
|
||||
#if GDISP_NEED_TEXT
|
||||
void gwinSetFont(GWindow *gw, font_t font);
|
||||
#define gwinGetStream(gw) ((BaseSequentialStream *)gw)
|
||||
void gwinSetFont(GHandle gh, font_t font);
|
||||
#endif
|
||||
|
||||
/* Drawing Functions */
|
||||
void gwinClear(GWindow *gw);
|
||||
void gwinDrawPixel(GWindow *gw, coord_t x, coord_t y);
|
||||
void gwinDrawLine(GWindow *gw, coord_t x0, coord_t y0, coord_t x1, coord_t y1);
|
||||
void gwinDrawBox(GWindow *gw, coord_t x, coord_t y, coord_t cx, coord_t cy);
|
||||
void gwinFillArea(GWindow *gw, coord_t x, coord_t y, coord_t cx, coord_t cy);
|
||||
void gwinBlitArea(GWindow *gw, 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 gwinClear(GHandle gh);
|
||||
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y);
|
||||
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);
|
||||
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy);
|
||||
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
|
||||
void gwinDrawCircle(GWindow *gw, coord_t x, coord_t y, coord_t radius);
|
||||
void gwinFillCircle(GWindow *gw, coord_t x, coord_t y, coord_t radius);
|
||||
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius);
|
||||
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius);
|
||||
#endif
|
||||
|
||||
/* Ellipse Functions */
|
||||
#if GDISP_NEED_ELLIPSE
|
||||
void gwinDrawEllipse(GWindow *gw, coord_t x, coord_t y, coord_t a, coord_t b);
|
||||
void gwinFillEllipse(GWindow *gw, coord_t x, coord_t y, coord_t a, coord_t b);
|
||||
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);
|
||||
#endif
|
||||
|
||||
/* Arc Functions */
|
||||
#if GDISP_NEED_ARC
|
||||
void gwinDrawArc(GWindow *gw, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle);
|
||||
void gwinFillArc(GWindow *gw, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle);
|
||||
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);
|
||||
#endif
|
||||
|
||||
/* Read a pixel Function */
|
||||
#if GDISP_NEED_PIXELREAD
|
||||
color_t gwinGetPixelColor(GWindow *gw, coord_t x, coord_t y);
|
||||
#endif
|
||||
|
||||
/* Scrolling Function - clears the area scrolled out */
|
||||
#if GDISP_NEED_SCROLL
|
||||
void gwinVerticalScroll(GWindow *gw, int lines);
|
||||
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y);
|
||||
#endif
|
||||
|
||||
/* Extra Text Functions */
|
||||
#if GDISP_NEED_TEXT
|
||||
void gwinDrawChar(GWindow *gw, coord_t x, coord_t y, char c);
|
||||
void gwinFillChar(GWindow *gw, coord_t x, coord_t y, char c);
|
||||
void gwinDrawString(GWindow *gw, coord_t x, coord_t y, const char *str);
|
||||
void gwinFillString(GWindow *gw, coord_t x, coord_t y, const char *str);
|
||||
void gwinBoxString(GWindow *gw, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
|
||||
void gwinPutChar(GWindow *gw, char c);
|
||||
void gwinPutString(GWindow *gw, const char *str);
|
||||
void gwinPutCharArray(GWindow *gw, const char *str, size_t n);
|
||||
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c);
|
||||
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);
|
||||
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
|
||||
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_CONSOLE
|
||||
GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height, font_t font);
|
||||
BaseSequentialStream *gwinGetConsoleStream(GHandle gh);
|
||||
void gwinPutChar(GHandle gh, char c);
|
||||
void gwinPutString(GHandle gh, const char *str);
|
||||
void gwinPutCharArray(GHandle gh, const char *str, size_t n);
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON
|
||||
GHandle gwinCreateButton(GButtonObject *gb, coord_t x, coord_t y, coord_t width, coord_t height, font_t font, GButtonType type);
|
||||
void gwinSetButtonStyle(GHandle gh, const GButtonStyle *style);
|
||||
void gwinSetButtonText(GHandle gh, const char *txt, bool_t useAlloc);
|
||||
void gwinButtonDraw(GHandle gh);
|
||||
#define gwinGetButtonState(gh) (((GButtonObject *)(gh))->state)
|
||||
//void gwinSetButtonCallback(GHandle gh, ????);
|
||||
//void gwinSetButtonInput(GHandle gh, ????);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -175,4 +253,3 @@ void gwinPutCharArray(GWindow *gw, const char *str, size_t n);
|
|||
|
||||
#endif /* _GWIN_H */
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@ current stable: 1.3
|
|||
FIX: Nokia 6610 fix
|
||||
FEATURE: New driver: Win32
|
||||
FEATURE: implementation of gdispFillArc()
|
||||
FIX: Hardware accelerate Arc routines
|
||||
FIX: Fix axis orientation for Arc routines
|
||||
FEATURE: new gdisp rounded box routines
|
||||
FEATURE: new gdispDrawStringBox()
|
||||
FEATURE: GWIN infrastructure
|
||||
|
||||
|
||||
*** changes after 1.2 ***
|
||||
|
@ -41,4 +46,3 @@ FEATURE: added SSD1963 DMA support
|
|||
FEATURE: added touchpad interface for storing calibration values (#define TOUCHPAD_STORE_CALIBRATION)
|
||||
CHANGE: replaced every GDISP_XXX macro with GDISP_XXX
|
||||
CHANGE: removed last digit of version number
|
||||
|
||||
|
|
408
src/gdisp.c
408
src/gdisp.c
|
@ -494,93 +494,7 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
|
||||
|
||||
#include "math.h"
|
||||
|
||||
/*
|
||||
* @brief Internal helper function for gdispDrawArc()
|
||||
*
|
||||
* @note DO NOT USE DIRECTLY!
|
||||
*
|
||||
* @param[in] x, y The middle point of the arc
|
||||
* @param[in] start The start angle of the arc
|
||||
* @param[in] end The end angle of the arc
|
||||
* @param[in] radius The radius of the arc
|
||||
* @param[in] color The color in which the arc will be drawn
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _draw_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
|
||||
if(start > 0 && start <= 180) {
|
||||
float x_maxI = x + radius*cos(start*M_PI/180);
|
||||
float x_minI;
|
||||
|
||||
if (end > 180)
|
||||
x_minI = x - radius;
|
||||
else
|
||||
x_minI = x + radius*cos(end*M_PI/180);
|
||||
|
||||
int a = 0;
|
||||
int b = radius;
|
||||
int P = 1 - radius;
|
||||
|
||||
do {
|
||||
if(x-a <= x_maxI && x-a >= x_minI)
|
||||
gdispDrawPixel(x-a, y+b, color);
|
||||
if(x+a <= x_maxI && x+a >= x_minI)
|
||||
gdispDrawPixel(x+a, y+b, color);
|
||||
if(x-b <= x_maxI && x-b >= x_minI)
|
||||
gdispDrawPixel(x-b, y+a, color);
|
||||
if(x+b <= x_maxI && x+b >= x_minI)
|
||||
gdispDrawPixel(x+b, y+a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
a = a + 1;
|
||||
} else {
|
||||
P = P + 5 + 2*(a - b);
|
||||
a = a + 1;
|
||||
b = b - 1;
|
||||
}
|
||||
} while(a <= b);
|
||||
}
|
||||
|
||||
if (end > 180 && end <= 360) {
|
||||
float x_maxII = x+radius*cos(end*M_PI/180);
|
||||
float x_minII;
|
||||
|
||||
if(start <= 180)
|
||||
x_minII = x - radius;
|
||||
else
|
||||
x_minII = x+radius*cos(start*M_PI/180);
|
||||
|
||||
int a = 0;
|
||||
int b = radius;
|
||||
int P = 1 - radius;
|
||||
|
||||
do {
|
||||
if(x-a <= x_maxII && x-a >= x_minII)
|
||||
gdispDrawPixel(x-a, y-b, color);
|
||||
if(x+a <= x_maxII && x+a >= x_minII)
|
||||
gdispDrawPixel(x+a, y-b, color);
|
||||
if(x-b <= x_maxII && x-b >= x_minII)
|
||||
gdispDrawPixel(x-b, y-a, color);
|
||||
if(x+b <= x_maxII && x+b >= x_minII)
|
||||
gdispDrawPixel(x+b, y-a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
a = a + 1;
|
||||
} else {
|
||||
P = P + 5 + 2*(a - b);
|
||||
a = a + 1;
|
||||
b = b - 1;
|
||||
}
|
||||
} while (a <= b);
|
||||
}
|
||||
}
|
||||
|
||||
#if (GDISP_NEED_ARC && GDISP_NEED_MULTITHREAD) || defined(__DOXYGEN__)
|
||||
/*
|
||||
* @brief Draw an arc.
|
||||
* @pre The GDISP must be in powerOn or powerSleep mode.
|
||||
|
@ -594,100 +508,24 @@ void _draw_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radi
|
|||
* @api
|
||||
*/
|
||||
void gdispDrawArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
if(end < start) {
|
||||
_draw_arc(x, y, start, 360, radius, color);
|
||||
_draw_arc(x, y, 0, end, radius, color);
|
||||
} else {
|
||||
_draw_arc(x, y, start, end, radius, color);
|
||||
chMtxLock(&gdispMutex);
|
||||
GDISP_LLD(drawarc)(x, y, radius, start, end, color);
|
||||
chMtxUnlock();
|
||||
}
|
||||
#elif GDISP_NEED_ARC && GDISP_NEED_ASYNC
|
||||
void gdispDrawArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWARC);
|
||||
p->drawarc.x = x;
|
||||
p->drawarc.y = y;
|
||||
p->drawarc.radius = radius;
|
||||
p->drawarc.start = start;
|
||||
p->drawarc.end = end;
|
||||
p->drawarc.color = color;
|
||||
chMBPost(&gdispMailbox, (msg_t)p, TIME_INFINITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
|
||||
/*
|
||||
* @brief Internal helper function for gdispFillArc()
|
||||
*
|
||||
* @note DO NOT USE DIRECTLY!
|
||||
* @note Not very efficient currently - does lots of overdrawing
|
||||
*
|
||||
* @param[in] x, y The middle point of the arc
|
||||
* @param[in] start The start angle of the arc
|
||||
* @param[in] end The end angle of the arc
|
||||
* @param[in] radius The radius of the arc
|
||||
* @param[in] color The color in which the arc will be drawn
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _fill_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
|
||||
if(start > 0 && start <= 180) {
|
||||
float x_maxI = x + radius*cos(start*M_PI/180);
|
||||
float x_minI;
|
||||
|
||||
if (end > 180)
|
||||
x_minI = x - radius;
|
||||
else
|
||||
x_minI = x + radius*cos(end*M_PI/180);
|
||||
|
||||
int a = 0;
|
||||
int b = radius;
|
||||
int P = 1 - radius;
|
||||
|
||||
do {
|
||||
if(x-a <= x_maxI && x-a >= x_minI)
|
||||
gdispDrawLine(x, y, x-a, y+b, color);
|
||||
if(x+a <= x_maxI && x+a >= x_minI)
|
||||
gdispDrawLine(x, y, x+a, y+b, color);
|
||||
if(x-b <= x_maxI && x-b >= x_minI)
|
||||
gdispDrawLine(x, y, x-b, y+a, color);
|
||||
if(x+b <= x_maxI && x+b >= x_minI)
|
||||
gdispDrawLine(x, y, x+b, y+a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
a = a + 1;
|
||||
} else {
|
||||
P = P + 5 + 2*(a - b);
|
||||
a = a + 1;
|
||||
b = b - 1;
|
||||
}
|
||||
} while(a <= b);
|
||||
}
|
||||
|
||||
if (end > 180 && end <= 360) {
|
||||
float x_maxII = x+radius*cos(end*M_PI/180);
|
||||
float x_minII;
|
||||
|
||||
if(start <= 180)
|
||||
x_minII = x - radius;
|
||||
else
|
||||
x_minII = x+radius*cos(start*M_PI/180);
|
||||
|
||||
int a = 0;
|
||||
int b = radius;
|
||||
int P = 1 - radius;
|
||||
|
||||
do {
|
||||
if(x-a <= x_maxII && x-a >= x_minII)
|
||||
gdispDrawLine(x, y, x-a, y-b, color);
|
||||
if(x+a <= x_maxII && x+a >= x_minII)
|
||||
gdispDrawLine(x, y, x+a, y-b, color);
|
||||
if(x-b <= x_maxII && x-b >= x_minII)
|
||||
gdispDrawLine(x, y, x-b, y-a, color);
|
||||
if(x+b <= x_maxII && x+b >= x_minII)
|
||||
gdispDrawLine(x, y, x+b, y-a, color);
|
||||
|
||||
if (P < 0) {
|
||||
P = P + 3 + 2*a;
|
||||
a = a + 1;
|
||||
} else {
|
||||
P = P + 5 + 2*(a - b);
|
||||
a = a + 1;
|
||||
b = b - 1;
|
||||
}
|
||||
} while (a <= b);
|
||||
}
|
||||
}
|
||||
|
||||
#if (GDISP_NEED_ARC && GDISP_NEED_MULTITHREAD) || defined(__DOXYGEN__)
|
||||
/*
|
||||
* @brief Draw a filled arc.
|
||||
* @pre The GDISP must be in powerOn or powerSleep mode.
|
||||
|
@ -702,12 +540,78 @@ void _fill_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radi
|
|||
* @api
|
||||
*/
|
||||
void gdispFillArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
if(end < start) {
|
||||
_fill_arc(x, y, start, 360, radius, color);
|
||||
_fill_arc(x, y, 0, end, radius, color);
|
||||
} else {
|
||||
_fill_arc(x, y, start, end, radius, color);
|
||||
chMtxLock(&gdispMutex);
|
||||
GDISP_LLD(fillarc)(x, y, radius, start, end, color);
|
||||
chMtxUnlock();
|
||||
}
|
||||
#elif GDISP_NEED_ARC && GDISP_NEED_ASYNC
|
||||
void gdispFillArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_FILLARC);
|
||||
p->fillarc.x = x;
|
||||
p->fillarc.y = y;
|
||||
p->fillarc.radius = radius;
|
||||
p->fillarc.start = start;
|
||||
p->fillarc.end = end;
|
||||
p->fillarc.color = color;
|
||||
chMBPost(&gdispMailbox, (msg_t)p, TIME_INFINITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Draw a rectangular box with rounded corners
|
||||
* @pre The GDISP unit must be in powerOn or powerSleep mode.
|
||||
*
|
||||
* @param[in] x,y The start position
|
||||
* @param[in] cx,cy The size of the box (outside dimensions)
|
||||
* @param[in] radius The radius of the rounded corners
|
||||
* @param[in] color The color to use
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gdispDrawRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
|
||||
if (2*radius > cx || 2*radius > cy) {
|
||||
gdispDrawBox(x, y, cx, cy, color);
|
||||
return;
|
||||
}
|
||||
gdispDrawArc(x+radius, y+radius, radius, 90, 180, color);
|
||||
gdispDrawLine(x+radius+1, y, x+cx-2-radius, y, color);
|
||||
gdispDrawArc(x+cx-1-radius, y+radius, radius, 0, 90, color);
|
||||
gdispDrawLine(x+cx-1, y+radius+1, x+cx-1, y+cy-2-radius, color);
|
||||
gdispDrawArc(x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
|
||||
gdispDrawLine(x+radius+1, y+cy-1, x+cx-2-radius, y+cy-1, color);
|
||||
gdispDrawArc(x+radius, y+cy-1-radius, radius, 180, 270, color);
|
||||
gdispDrawLine(x, y+radius+1, x, y+cy-2-radius, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Draw a filled rectangular box with rounded corners
|
||||
* @pre The GDISP unit must be in powerOn or powerSleep mode.
|
||||
*
|
||||
* @param[in] x,y The start position
|
||||
* @param[in] cx,cy The size of the box (outside dimensions)
|
||||
* @param[in] radius The radius of the rounded corners
|
||||
* @param[in] color The color to use
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
|
||||
coord_t radius2;
|
||||
|
||||
radius2 = radius*2;
|
||||
if (radius2 > cx || radius2 > cy) {
|
||||
gdispFillArea(x, y, cx, cy, color);
|
||||
return;
|
||||
}
|
||||
gdispFillArc(x+radius, y+radius, radius, 90, 180, color);
|
||||
gdispFillArea(x+radius+1, y, cx-radius2, radius, color);
|
||||
gdispFillArc(x+cx-1-radius, y+radius, radius, 0, 90, color);
|
||||
gdispFillArc(x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
|
||||
gdispFillArea(x+radius+1, y+cy-radius, cx-radius2, radius, color);
|
||||
gdispFillArc(x+radius, y+cy-1-radius, radius, 180, 270, color);
|
||||
gdispFillArea(x, y+radius, cx, cy-radius2, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -877,10 +781,9 @@ void gdispFillArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t
|
|||
* @brief Draw a rectangular box.
|
||||
* @pre The GDISP unit must be in powerOn or powerSleep mode.
|
||||
*
|
||||
* @param[in] x0,y0 The start position
|
||||
* @param[in] x,y The start position
|
||||
* @param[in] cx,cy The size of the box (outside dimensions)
|
||||
* @param[in] color The color to use
|
||||
* @param[in] filled Should the box should be filled
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
@ -928,6 +831,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
|
|||
char c;
|
||||
int first;
|
||||
|
||||
if (!str) return;
|
||||
|
||||
first = 1;
|
||||
p = font->charPadding * font->xscale;
|
||||
while(*str) {
|
||||
|
@ -969,6 +874,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
|
|||
char c;
|
||||
int first;
|
||||
|
||||
if (!str) return;
|
||||
|
||||
first = 1;
|
||||
h = font->height * font->yscale;
|
||||
p = font->charPadding * font->xscale;
|
||||
|
@ -998,6 +905,137 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
|
|||
/**
|
||||
* @brief Draw a text string verticly centered within the specified box.
|
||||
* @pre The GDISP unit must be in powerOn or powerSleep mode.
|
||||
*
|
||||
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
|
||||
* @param[in] str The string to draw
|
||||
* @param[in] color The color to use
|
||||
* @param[in] justify Justify the text left, center or right within the box
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify) {
|
||||
/* No mutex required as we only call high level functions which have their own mutex */
|
||||
coord_t w, h, p, ypos, xpos;
|
||||
char c;
|
||||
int first;
|
||||
const char *rstr;
|
||||
|
||||
if (!str) str = "";
|
||||
|
||||
h = font->height * font->yscale;
|
||||
p = font->charPadding * font->xscale;
|
||||
|
||||
/* Oops - font too large for the area */
|
||||
if (h > cy) return;
|
||||
|
||||
/* See if we need to fill above the font */
|
||||
ypos = (cy - h + 1)/2;
|
||||
if (ypos > 0) {
|
||||
y += ypos;
|
||||
cy -= ypos;
|
||||
}
|
||||
|
||||
/* See if we need to fill below the font */
|
||||
ypos = cy - h;
|
||||
if (ypos > 0)
|
||||
cy -= ypos;
|
||||
|
||||
/* get the start of the printable string and the xpos */
|
||||
switch(justify) {
|
||||
case justifyCenter:
|
||||
/* Get the length of the entire string */
|
||||
w = gdispGetStringWidth(str, font);
|
||||
if (w <= cx)
|
||||
xpos = x + (cx - w)/2;
|
||||
else {
|
||||
/* Calculate how much of the string we need to get rid of */
|
||||
ypos = (w - cx)/2;
|
||||
xpos = 0;
|
||||
first = 1;
|
||||
while(*str) {
|
||||
/* Get the next printable character */
|
||||
c = *str++;
|
||||
w = _getCharWidth(font, c) * font->xscale;
|
||||
if (!w) continue;
|
||||
|
||||
/* Handle inter-character padding */
|
||||
if (p) {
|
||||
if (!first) {
|
||||
xpos += p;
|
||||
if (xpos > ypos) break;
|
||||
} else
|
||||
first = 0;
|
||||
}
|
||||
|
||||
/* Print the character */
|
||||
xpos += w;
|
||||
if (xpos > ypos) break;
|
||||
}
|
||||
xpos = ypos - xpos + x;
|
||||
}
|
||||
break;
|
||||
case justifyRight:
|
||||
/* Find the end of the string */
|
||||
for(rstr = str; *str; str++);
|
||||
xpos = x+cx - 2;
|
||||
first = 1;
|
||||
for(str--; str >= rstr; str--) {
|
||||
/* Get the next printable character */
|
||||
c = *str;
|
||||
w = _getCharWidth(font, c) * font->xscale;
|
||||
if (!w) continue;
|
||||
|
||||
/* Handle inter-character padding */
|
||||
if (p) {
|
||||
if (!first) {
|
||||
if (xpos - p < x) break;
|
||||
xpos -= p;
|
||||
} else
|
||||
first = 0;
|
||||
}
|
||||
|
||||
/* Print the character */
|
||||
if (xpos - w < x) break;
|
||||
xpos -= w;
|
||||
}
|
||||
str++;
|
||||
break;
|
||||
case justifyLeft:
|
||||
/* Fall through */
|
||||
default:
|
||||
xpos = x+1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print characters until we run out of room */
|
||||
first = 1;
|
||||
while(*str) {
|
||||
/* Get the next printable character */
|
||||
c = *str++;
|
||||
w = _getCharWidth(font, c) * font->xscale;
|
||||
if (!w) continue;
|
||||
|
||||
/* Handle inter-character padding */
|
||||
if (p) {
|
||||
if (!first) {
|
||||
if (xpos + p > x+cx) break;
|
||||
xpos += p;
|
||||
} else
|
||||
first = 0;
|
||||
}
|
||||
|
||||
/* Print the character */
|
||||
if (xpos + w > x+cx) break;
|
||||
gdispDrawChar(xpos, y, c, font, color);
|
||||
xpos += w;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Draw a text string verticly centered within the specified box. The box background is filled with the specified background color.
|
||||
* @pre The GDISP unit must be in powerOn or powerSleep mode.
|
||||
* @note The entire box is filled
|
||||
*
|
||||
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
|
||||
|
@ -1015,6 +1053,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
|
|||
int first;
|
||||
const char *rstr;
|
||||
|
||||
if (!str) str = "";
|
||||
|
||||
h = font->height * font->yscale;
|
||||
p = font->charPadding * font->xscale;
|
||||
|
||||
|
|
1236
src/gwin.c
1236
src/gwin.c
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue