Add support and demo for pixmaps (in memory drawing)

This commit is contained in:
inmarket 2015-01-13 13:50:46 +10:00
parent a22a32e8db
commit ef00cac45d
12 changed files with 584 additions and 13 deletions

View File

@ -0,0 +1,3 @@
DEMODIR = $(GFXLIB)/demos/modules/gdisp/pixmaps
GFXINC += $(DEMODIR)
GFXSRC += $(DEMODIR)/main.c

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* The operating system to use. One of these must be defined - preferably in your Makefile */
//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_PIXMAP TRUE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gfx.h"
#define PIXMAP_WIDTH 40
#define PIXMAP_HEIGHT 10
static GDisplay *pix;
static pixel_t *surface;
int main(void) {
coord_t width, height;
coord_t i, j;
// Initialize and clear the display
gfxInit();
// Get the screen size
width = gdispGetWidth();
height = gdispGetHeight();
// Create a pixmap and get a pointer to the bits
pix = gdispCreatePixmap(PIXMAP_WIDTH, PIXMAP_HEIGHT);
surface = gdispGetPixmapBits(pix);
// A pixmap can be treated either as a virtual display or as a memory framebuffer surface.
// We demonstrate writing to it using both methods.
// First demo drawing onto the surface directly
for(j = 0; j < PIXMAP_HEIGHT; j++)
for(i = 0; i < PIXMAP_WIDTH; i++)
surface[j*PIXMAP_WIDTH + i] = RGB2COLOR(0, 255-i*(256/PIXMAP_WIDTH), j*(256/PIXMAP_HEIGHT));
// Secondly, show drawing a line on it like a virtual display
gdispGDrawLine(pix, 0, 0, gdispGGetWidth(pix)-1, gdispGGetHeight(pix)-1, White);
i = j = 0;
while(TRUE) {
// Clear the old position
gdispFillArea(i, j, PIXMAP_WIDTH, PIXMAP_HEIGHT, Black);
// Change the position
i += PIXMAP_WIDTH/2;
if (i >= width - PIXMAP_WIDTH/2) {
i %= width - PIXMAP_WIDTH/2;
j = (j + PIXMAP_HEIGHT/2) % (height - PIXMAP_HEIGHT/2);
}
// Blit the pixmap to the real display at the new position
gdispBlitArea(i, j, PIXMAP_WIDTH, PIXMAP_HEIGHT, surface);
// Wait
gfxSleepMilliseconds(100);
}
}

View File

@ -104,6 +104,9 @@
// #define GDISP_NEED_IMAGE_PNG FALSE
// #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
//#define GDISP_NEED_PIXMAP FALSE
// #define GDISP_NEED_PIXMAP_IMAGE FALSE
//#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE // If not defined the native hardware orientation is used.
//#define GDISP_LINEBUF_SIZE 128
//#define GDISP_STARTUP_COLOR Black

View File

@ -21,17 +21,47 @@
// Include the GDRIVER infrastructure
#include "src/gdriver/sys_defs.h"
// Are we currently compiling the driver itself?
#if defined(GDISP_DRIVER_VMT)
#define IN_DRIVER TRUE
#else
#define IN_DRIVER FALSE
#endif
// Is this a multiple driver situation?
#if defined(GDISP_DRIVER_LIST)
#define IS_MULTIPLE TRUE
#else
#define IS_MULTIPLE FALSE
#endif
// Do we need to use VMT calling rather than direct calls to the driver?
#if IS_MULTIPLE || GDISP_NEED_PIXMAP
#define USE_VMT TRUE
#else
#define USE_VMT FALSE
#endif
// Are we in the pixmap virtual driver
#ifndef IN_PIXMAP_DRIVER
#define IN_PIXMAP_DRIVER FALSE
#endif
//------------------------------------------------------------------------------------------------------------
// Our special auto-detect hardware code which uses the VMT.
#define HARDWARE_AUTODETECT 2
#if defined(GDISP_DRIVER_LIST) && !defined(GDISP_DRIVER_VMT)
#if USE_VMT && !IN_DRIVER
// Multiple controllers the default is to hardware detect
#define HARDWARE_DEFAULT HARDWARE_AUTODETECT
#else
// The default is to call the routines directly
// The default is not to include code functions that aren't needed
#define HARDWARE_DEFAULT FALSE
#endif
//------------------------------------------------------------------------------------------------------------
/**
* @name GDISP hardware accelerated support
* @{
@ -191,9 +221,66 @@
#endif
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
//------------------------------------------------------------------------------------------------------------
// For pixmaps certain routines MUST not be FALSE as they are needed for pixmap drawing
// Similarly some routines MUST not be TRUE as pixmap's don't provide them.
#if GDISP_NEED_PIXMAP && !IN_DRIVER
#if !GDISP_HARDWARE_DEINIT
#undef GDISP_HARDWARE_DEINIT
#define GDISP_HARDWARE_DEINIT HARDWARE_AUTODETECT
#endif
#if !GDISP_HARDWARE_DRAWPIXEL
#undef GDISP_HARDWARE_DRAWPIXEL
#define GDISP_HARDWARE_DRAWPIXEL HARDWARE_AUTODETECT
#endif
#if !GDISP_HARDWARE_PIXELREAD
#undef GDISP_HARDWARE_PIXELREAD
#define GDISP_HARDWARE_PIXELREAD HARDWARE_AUTODETECT
#endif
#if !GDISP_HARDWARE_CONTROL
#undef GDISP_HARDWARE_CONTROL
#define GDISP_HARDWARE_CONTROL HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_FLUSH == TRUE
#undef GDISP_HARDWARE_FLUSH
#define GDISP_HARDWARE_FLUSH HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_STREAM_WRITE == TRUE
#undef GDISP_HARDWARE_STREAM_WRITE
#define GDISP_HARDWARE_STREAM_WRITE HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_STREAM_READ == TRUE
#undef GDISP_HARDWARE_STREAM_READ
#define GDISP_HARDWARE_STREAM_READ HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_CLEARS == TRUE
#undef GDISP_HARDWARE_CLEARS
#define GDISP_HARDWARE_CLEARS HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_FILLS == TRUE
#undef GDISP_HARDWARE_FILLS
#define GDISP_HARDWARE_FILLS HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_BITFILLS == TRUE
#undef GDISP_HARDWARE_BITFILLS
#define GDISP_HARDWARE_BITFILLS HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_SCROLL == TRUE
#undef GDISP_HARDWARE_SCROLL
#define GDISP_HARDWARE_SCROLL HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_QUERY == TRUE
#undef GDISP_HARDWARE_QUERY
#define GDISP_HARDWARE_QUERY HARDWARE_AUTODETECT
#endif
#if GDISP_HARDWARE_CLIP == TRUE
#undef GDISP_HARDWARE_CLIP
#define GDISP_HARDWARE_CLIP HARDWARE_AUTODETECT
#endif
#endif
//------------------------------------------------------------------------------------------------------------
/* Verify information for packed pixels and define a non-packed pixel macro */
#if !GDISP_PACKED_PIXELS
@ -224,6 +311,8 @@
void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color);
#endif
//------------------------------------------------------------------------------------------------------------
struct GDisplay {
struct GDriver d; // This must be the first element
#define gvmt(g) ((const GDISPVMT const *)((g)->d.vmt)) // For ease of access to the vmt member
@ -309,14 +398,16 @@ typedef struct GDISPVMT {
void (*flush)(GDisplay *g); // Uses no parameters
} GDISPVMT;
//------------------------------------------------------------------------------------------------------------
// Do we need function definitions or macro's (via the VMT)
#if !defined(GDISP_DRIVER_LIST) || defined(GDISP_DRIVER_VMT) || defined(__DOXYGEN__)
#if IN_DRIVER || !USE_VMT || defined(__DOXYGEN__)
#ifdef __cplusplus
extern "C" {
#endif
// Should the driver routines should be static or not
#if defined(GDISP_DRIVER_LIST)
#if USE_VMT
#define LLDSPEC static
#else
#define LLDSPEC
@ -325,8 +416,8 @@ typedef struct GDISPVMT {
/**
* @brief Initialize the driver.
* @return TRUE if successful.
* @param[in] g The driver structure
* @param[out] g->g The driver must fill in the GDISPControl structure
* @param[in] g The driver structure
* @param[out] g->g The driver must fill in the GDISPControl structure
*/
LLDSPEC bool_t gdisp_lld_init(GDisplay *g);
@ -602,16 +693,18 @@ typedef struct GDISPVMT {
#define gdisp_lld_set_clip(g) gvmt(g)->setclip(g)
#endif
//------------------------------------------------------------------------------------------------------------
// If compiling the driver then build the VMT and set the low level driver color macros.
#ifdef GDISP_DRIVER_VMT
#if IN_DRIVER
// Make sure the driver has a valid model
#if !GDISP_HARDWARE_STREAM_WRITE && !GDISP_HARDWARE_DRAWPIXEL
#error "GDISP Driver: Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be TRUE"
#endif
// If we are not using multiple displays then hard-code the VMT name
#if !defined(GDISP_DRIVER_LIST)
// If we are not using multiple displays then hard-code the VMT name (except for the pixmap driver)
#if !IS_MULTIPLE && !IN_PIXMAP_DRIVER
#undef GDISP_DRIVER_VMT
#define GDISP_DRIVER_VMT GDISPVMT_OnlyOne
#endif
@ -707,6 +800,8 @@ typedef struct GDISPVMT {
#endif
}};
//--------------------------------------------------------------------------------------------------------
/* Low level driver pixel format information */
//-------------------------
// True-Color color system
@ -956,6 +1051,12 @@ typedef struct GDISPVMT {
#endif
//------------------------------------------------------------------------------------------------------------
#undef IN_PIXMAP_DRIVER
#undef IS_MULTIPLE
#undef IN_DRIVER
#undef USE_VMT
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_H */

View File

@ -23,6 +23,8 @@
#if GFX_USE_GDISP || defined(__DOXYGEN__)
typedef uint16_t colorformat;
/**
* @name Color system masks
*

View File

@ -625,12 +625,12 @@ void _gdispDeinit(void)
bool_t _gdispInitDriver(GDriver *g, void *param, unsigned driverinstance, unsigned systeminstance) {
#define gd ((GDisplay *)g)
bool_t ret;
(void) param;
// Intialise fields
gd->systemdisplay = systeminstance;
gd->controllerdisplay = driverinstance;
gd->flags = 0;
gd->priv = param;
MUTEX_INIT(gd);
// Call the driver init

223
src/gdisp/gdisp_pixmap.c Normal file
View File

@ -0,0 +1,223 @@
/*
* This file is subject to the terms of the GFX License. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://ugfx.org/license.html
*/
#include "gfx.h"
#if GFX_USE_GDISP && GDISP_NEED_PIXMAP
// We undef everything because the system may think we are in a single controller situation
// but the pixmap supports adds another virtual display
#undef GDISP_HARDWARE_DEINIT
#undef GDISP_HARDWARE_FLUSH
#undef GDISP_HARDWARE_STREAM_WRITE
#undef GDISP_HARDWARE_STREAM_READ
#undef GDISP_HARDWARE_STREAM_POS
#undef GDISP_HARDWARE_DRAWPIXEL
#undef GDISP_HARDWARE_CLEARS
#undef GDISP_HARDWARE_FILLS
#undef GDISP_HARDWARE_BITFILLS
#undef GDISP_HARDWARE_SCROLL
#undef GDISP_HARDWARE_PIXELREAD
#undef GDISP_HARDWARE_CONTROL
#undef GDISP_HARDWARE_QUERY
#undef GDISP_HARDWARE_CLIP
#define GDISP_HARDWARE_DEINIT TRUE
#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define IN_PIXMAP_DRIVER TRUE
#define GDISP_DRIVER_VMT GDISPVMT_pixmap
// This pseudo driver currently only supports unpacked formats with more than 8 bits per pixel
// that is, we only support GRAY_SCALE and PALETTE with 8 bits per pixel or any unpacked TRUE_COLOR format.
#if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_GRAYSCALE) && (GDISP_LLD_PIXELFORMAT & 0xFF) != 8
#error "GDISP Pixmap: Pixmap's do not currently support the specified GDISP_LLD_PIXELFORMAT"
#endif
#include "src/gdisp/driver.h"
#include "src/gdriver/sys_defs.h"
typedef struct pixmap {
#if GDISP_NEED_PIXMAP_IMAGE
uint8_t imghdr[8]; // This field must come just before the data member.
#endif
color_t pixels[1]; // We really want pixels[0] but some compilers don't allow that even though it is C standard.
} pixmap;
GDisplay *gdispCreatePixmap(coord_t width, coord_t height) {
GDisplay *g;
pixmap *p;
unsigned i;
// Calculate the size of the display surface in bytes
i = width*height*sizeof(color_t);
if (i < 2*sizeof(coord_t))
i = 2*sizeof(coord_t);
// Allocate the pixmap
if (!(p = gfxAlloc(i+sizeof(pixmap)-sizeof(p->pixels))))
return 0;
// Fill in the image header (if required)
#if GDISP_NEED_PIXMAP_IMAGE
p->imghdr[0] = 'N';
p->imghdr[1] = 'I';
p->imghdr[2] = (uint8_t)(width >> 8);
p->imghdr[3] = (uint8_t)width;
p->imghdr[4] = (uint8_t)(height >> 8);
p->imghdr[5] = (uint8_t)height;
p->imghdr[6] = (uint8_t)(GDISP_PIXELFORMAT >> 8);
p->imghdr[7] = (uint8_t)(GDISP_PIXELFORMAT);
#endif
// Save the width and height so the driver can retrieve it.
((coord_t *)p->pixels)[0] = width;
((coord_t *)p->pixels)[1] = height;
// Register the driver
g = (GDisplay *)gdriverRegister(&GDISPVMT_pixmap->d, p);
if (!g)
gfxFree(p);
return g;
}
void gdispDeletePixmap(GDisplay *g) {
if (gvmt(g) != GDISPVMT_pixmap)
return;
gdriverUnRegister(&g->d);
}
pixel_t *gdispGetPixmapBits(GDisplay *g) {
if (gvmt(g) != GDISPVMT_pixmap)
return 0;
return ((pixmap *)g->priv)->pixels;
}
#if GDISP_NEED_PIXMAP_IMAGE
void *gdispGetPixmapMemoryImage(GDisplay *g) {
if (gvmt(g) != GDISPVMT_pixmap)
return 0;
return ((pixmap *)g->priv)->imghdr;
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
// The user api function should have already allocated and initialised the pixmap
// structure and put it into the priv member during driver initialisation.
if (!g->priv)
return FALSE;
// Initialize the GDISP structure
// Width and height were saved into the start of the framebuffer.
g->g.Width = ((coord_t *)((pixmap *)g->priv)->pixels)[0];
g->g.Height = ((coord_t *)((pixmap *)g->priv)->pixels)[1];
g->g.Backlight = 100;
g->g.Contrast = 50;
g->g.Orientation = GDISP_ROTATE_0;
g->g.Powermode = powerOn;
g->board = 0;
return TRUE;
}
LLDSPEC void gdisp_lld_deinit(GDisplay *g) {
gfxFree(g->priv);
}
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
unsigned pos;
#if GDISP_NEED_CONTROL
switch(g->g.Orientation) {
case GDISP_ROTATE_0:
default:
pos = g->p.y * g->g.Width + g->p.x;
break;
case GDISP_ROTATE_90:
pos = (g->g.Width-g->p.x-1) * g->g.Height + g->p.y;
break;
case GDISP_ROTATE_180:
pos = (g->g.Height-g->p.y-1) * g->g.Width + g->g.Width-g->p.x-1;
break;
case GDISP_ROTATE_270:
pos = g->p.x * g->g.Height + g->g.Height-g->p.y-1;
break;
}
#else
pos = g->p.y * g->g.Width + g->p.x;
#endif
((pixmap *)(g)->priv)->pixels[pos] = g->p.color;
}
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
unsigned pos;
#if GDISP_NEED_CONTROL
switch(g->g.Orientation) {
case GDISP_ROTATE_0:
default:
pos = g->p.y * g->g.Width + g->p.x;
break;
case GDISP_ROTATE_90:
pos = (g->g.Width-g->p.x-1) * g->g.Height + g->p.y;
break;
case GDISP_ROTATE_180:
pos = (g->g.Height-g->p.y-1) * g->g.Width + g->g.Width-g->p.x-1;
break;
case GDISP_ROTATE_270:
pos = g->p.x * g->g.Height + g->g.Height-g->p.y-1;
break;
}
#else
pos = g->p.y * g->g.Width + g->p.x;
#endif
return ((pixmap *)(g)->priv)->pixels[pos];
}
#if GDISP_NEED_CONTROL
LLDSPEC void gdisp_lld_control(GDisplay *g) {
switch(g->p.x) {
case GDISP_CONTROL_ORIENTATION:
if (g->g.Orientation == (orientation_t)g->p.ptr)
return;
switch((orientation_t)g->p.ptr) {
case GDISP_ROTATE_0:
case GDISP_ROTATE_180:
if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
coord_t tmp;
tmp = g->g.Width;
g->g.Width = g->g.Height;
g->g.Height = tmp;
}
break;
case GDISP_ROTATE_90:
case GDISP_ROTATE_270:
if (g->g.Orientation == GDISP_ROTATE_0 || g->g.Orientation == GDISP_ROTATE_180) {
coord_t tmp;
tmp = g->g.Width;
g->g.Width = g->g.Height;
g->g.Height = tmp;
}
break;
default:
return;
}
g->g.Orientation = (orientation_t)g->p.ptr;
return;
}
}
#endif
#endif /* GFX_USE_GDISP */

87
src/gdisp/gdisp_pixmap.h Normal file
View File

@ -0,0 +1,87 @@
/*
* This file is subject to the terms of the GFX License. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://ugfx.org/license.html
*/
/**
* @file src/gdisp/gdisp_pixmap.h
* @brief GDISP image header file.
*
* @defgroup Pixmap Pixmap
* @ingroup GDISP
*
* @note A Pixmap is an off-screen virtual display that can be drawn to just like any other
* display. It can then be copied to a real display using the standard gdispGBlitArea() call.
* @pre GDISP_NEED_PIXMAP must be TRUE in your gfxconf.h
* @{
*/
#ifndef _GDISP_PIXMAP_H
#define _GDISP_PIXMAP_H
#if (GFX_USE_GDISP && GDISP_NEED_PIXMAP) || defined(__DOXYGEN__)
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Create an off-screen pixmap that can be drawn to just like a normal display
*
* @param[in] width The width of the pixmap to be created
* @param[in] height The height of the pixmap to be created
*
* @note Once created, an off-screen pixmap can be drawn on using the standard gdispGxxxx calls.
* @note It must be destroyed using @p gdispDeleteOffscreenPixmap
* @note Because the RAM for the display area is allocated, on small micros only very small pixmaps should be considered.
* For example a 100x100 at 16 bits per pixel would be 20K of RAM (plus some overheads).
*/
GDisplay *gdispCreatePixmap(coord_t width, coord_t height);
/**
* @brief Destroy an off-screen pixmap
*
* @param[in] g The pixmap virtual display to delete
*
* @note If a normal display is passed to this routine, it will be ignored.
*/
void gdispDeletePixmap(GDisplay *g);
/**
* @brief Get a pointer to the pixels of the display surface.
* @return The pointer to the pixmap display surface or NULL if this display is not a pixmap.
*
* @param[in] g The pixmap virtual display
*
* @note The pointer returned can be used for calls to @p gdispGBlitArea() or can be read or written to directly
* by the application code. For any one particular pixmap the pointer will not change over the life of the pixmap
* (although different pixmaps will have different pixel pointers). Once a pixmap is deleted, the pixel pointer
* should not be used by the application.
*/
pixel_t *gdispGetPixmapBits(GDisplay *g);
#if GDISP_NEED_PIXMAP_IMAGE || defined(__DOXYGEN__)
/**
* @brief Get a pointer to a native format gdispImage.
* @return A pointer to a NATIVE format gdispImage in memory or NULL if this display is not a pixmap.
* @pre GDISP_NEED_PIXAMP_IMAGE must be TRUE in your gfxconf.h
*
* @param[in] g The pixmap virtual display
*
* @note The pointer returned can be passed to @p gdispImageOpenMemory() or to @gfileOpenMemory().
* @note If you are just wanting to copy to a real display it is more efficient to use @p gdispGetPixmapBits() and @p gdispGBlitArea().
* @note Like @p gdispGetPixmapBits(), the pointer returned is valid for the life of the pixmap.
*/
void *gdispGetPixmapMemoryImage(GDisplay *g);
#endif
#ifdef __cplusplus
}
#endif
#endif /* GFX_USE_GDISP && GDISP_NEED_PIXMAP */
#endif /* _GDISP_PIXMAP_H */
/** @} */

View File

@ -1113,6 +1113,10 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_IMAGE || defined(__DOXYGEN__)
#include "gdisp_image.h"
#endif
#if GDISP_NEED_PIXMAP || defined(__DOXYGEN__)
#include "gdisp_pixmap.h"
#endif
#endif /* GFX_USE_GDISP */

View File

@ -1,5 +1,6 @@
GFXSRC += $(GFXLIB)/src/gdisp/gdisp_gdisp.c \
$(GFXLIB)/src/gdisp/gdisp_fonts.c \
$(GFXLIB)/src/gdisp/gdisp_pixmap.c \
$(GFXLIB)/src/gdisp/gdisp_image.c \
$(GFXLIB)/src/gdisp/gdisp_image_native.c \
$(GFXLIB)/src/gdisp/gdisp_image_gif.c \

View File

@ -177,6 +177,13 @@
#ifndef GDISP_NEED_IMAGE
#define GDISP_NEED_IMAGE FALSE
#endif
/**
* @brief Is the image interface required.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_PIXMAP
#define GDISP_NEED_PIXMAP FALSE
#endif
/**
* @}
*
@ -337,6 +344,15 @@
#ifndef GDISP_NEED_ANTIALIAS
#define GDISP_NEED_ANTIALIAS FALSE
#endif
/**
* @}
*
* @name GDISP Pixmap Options
* @{
*/
#ifndef GDISP_NEED_PIXMAP_IMAGE
#define GDISP_NEED_PIXMAP_IMAGE FALSE
#endif
/**
* @}
*