diff options
author | inmarket <andrewh@inmarket.com.au> | 2014-02-19 00:36:52 +1000 |
---|---|---|
committer | inmarket <andrewh@inmarket.com.au> | 2014-02-19 00:36:52 +1000 |
commit | 37966ff16d923bbca53c9464815cb49cbd7fc3be (patch) | |
tree | d92db57067ffadd50cadf3ccf70efba3ac16e114 /src/gdisp | |
parent | 1e131851d6732e22f055c893face6b473a26f111 (diff) | |
download | uGFX-37966ff16d923bbca53c9464815cb49cbd7fc3be.tar.gz uGFX-37966ff16d923bbca53c9464815cb49cbd7fc3be.tar.bz2 uGFX-37966ff16d923bbca53c9464815cb49cbd7fc3be.zip |
Integrate the include files with each module. Simplifies structure of code.
Diffstat (limited to 'src/gdisp')
-rw-r--r-- | src/gdisp/colors.h | 377 | ||||
-rw-r--r-- | src/gdisp/driver.h | 873 | ||||
-rw-r--r-- | src/gdisp/fonts/build_fonts.sh | 2 | ||||
-rw-r--r-- | src/gdisp/fonts/fonts.h | 34 | ||||
-rw-r--r-- | src/gdisp/gdisp.c | 2 | ||||
-rw-r--r-- | src/gdisp/image.h | 307 | ||||
-rw-r--r-- | src/gdisp/mcufont/mf_config.h | 4 | ||||
-rw-r--r-- | src/gdisp/sys_defs.h | 994 | ||||
-rw-r--r-- | src/gdisp/sys_make.mk (renamed from src/gdisp/gdisp.mk) | 0 | ||||
-rw-r--r-- | src/gdisp/sys_options.h | 381 | ||||
-rw-r--r-- | src/gdisp/sys_rules.h | 85 |
11 files changed, 3038 insertions, 21 deletions
diff --git a/src/gdisp/colors.h b/src/gdisp/colors.h new file mode 100644 index 00000000..efd7076c --- /dev/null +++ b/src/gdisp/colors.h @@ -0,0 +1,377 @@ +/* + * 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 include/gdisp/colors.h + * @brief GDISP color definitions header file. + * + * @defgroup Colors Colors + * @ingroup GDISP + * @{ + */ + +#ifndef _GDISP_COLORS_H +#define _GDISP_COLORS_H + +#include "gfx.h" + +#if GFX_USE_GDISP || defined(__DOXYGEN__) + +/** + * For pixel formats we do some assignment of codes to enable + * format auto-calculation. (Undocumented). + * 0x2RGB TRUECOLOR RGB format, R = red bits, G = green bits, B = blue bits + * 0x3RGB TRUECOLOR BGR format, R = red bits, G = green bits, B = blue bits + * 0x40XX GRAYSCALE XX = bits + * 0x60XX PALLETTE XX = bits + * 0x8XXX CUSTOM format. + */ +#define GDISP_COLORSYSTEM_MASK 0xF000 +#define GDISP_COLORSYSTEM_RGB 0x2000 +#define GDISP_COLORSYSTEM_BGR 0x3000 + +/** + * @brief Color Type Constants + * @{ + */ +#define GDISP_COLORSYSTEM_TRUECOLOR 0x2000 +#define GDISP_COLORSYSTEM_GRAYSCALE 0x4000 +#define GDISP_COLORSYSTEM_PALETTE 0x6000 +/** @} */ + +/** + * @brief Pixel Format Constants + * @{ + */ +#define GDISP_PIXELFORMAT_MONO (GDISP_COLORSYSTEM_GRAYSCALE|0x0001) +#define GDISP_PIXELFORMAT_GRAY4 (GDISP_COLORSYSTEM_GRAYSCALE|0x0002) +#define GDISP_PIXELFORMAT_GRAY16 (GDISP_COLORSYSTEM_GRAYSCALE|0x0004) +#define GDISP_PIXELFORMAT_GRAY256 (GDISP_COLORSYSTEM_GRAYSCALE|0x0008) +#define GDISP_PIXELFORMAT_RGB565 (GDISP_COLORSYSTEM_RGB|0x0565) +#define GDISP_PIXELFORMAT_BGR565 (GDISP_COLORSYSTEM_BGR|0x0565) +#define GDISP_PIXELFORMAT_RGB888 (GDISP_COLORSYSTEM_RGB|0x0888) +#define GDISP_PIXELFORMAT_BGR888 (GDISP_COLORSYSTEM_BGR|0x0888) +#define GDISP_PIXELFORMAT_RGB444 (GDISP_COLORSYSTEM_RGB|0x0444) +#define GDISP_PIXELFORMAT_BGR444 (GDISP_COLORSYSTEM_BGR|0x0444) +#define GDISP_PIXELFORMAT_RGB332 (GDISP_COLORSYSTEM_RGB|0x0332) +#define GDISP_PIXELFORMAT_BGR332 (GDISP_COLORSYSTEM_BGR|0x0332) +#define GDISP_PIXELFORMAT_RGB666 (GDISP_COLORSYSTEM_RGB|0x0666) +#define GDISP_PIXELFORMAT_BGR666 (GDISP_COLORSYSTEM_BGR|0x0666) +#define GDISP_PIXELFORMAT_ERROR 0x0000 +/** @} */ + +/** + * @name Some basic colors + * @{ + */ +#define White HTML2COLOR(0xFFFFFF) +#define Black HTML2COLOR(0x000000) +#define Gray HTML2COLOR(0x808080) +#define Grey Gray +#define Blue HTML2COLOR(0x0000FF) +#define Red HTML2COLOR(0xFF0000) +#define Fuchsia HTML2COLOR(0xFF00FF) +#define Magenta Fuchsia +#define Green HTML2COLOR(0x008000) +#define Yellow HTML2COLOR(0xFFFF00) +#define Aqua HTML2COLOR(0x00FFFF) +#define Cyan Aqua +#define Lime HTML2COLOR(0x00FF00) +#define Maroon HTML2COLOR(0x800000) +#define Navy HTML2COLOR(0x000080) +#define Olive HTML2COLOR(0x808000) +#define Purple HTML2COLOR(0x800080) +#define Silver HTML2COLOR(0xC0C0C0) +#define Teal HTML2COLOR(0x008080) +#define Orange HTML2COLOR(0xFFA500) +#define Pink HTML2COLOR(0xFFC0CB) +#define SkyBlue HTML2COLOR(0x87CEEB) +/** @} */ + +#if defined(__DOXYGEN__) + /** + * @brief The color system (grayscale, palette or truecolor) + */ + #define COLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR + /** + * @brief The number of bits in a color value + */ + #define COLOR_BITS 16 + /** + * @brief The number of bits for each of red, green and blue + * @{ + */ + #define COLOR_BITS_R 5 + #define COLOR_BITS_G 6 + #define COLOR_BITS_B 5 + /** @} */ + /** + * @brief The number of bits to shift each of red, green and blue to put it in the correct place in the color + * @{ + */ + #define COLOR_SHIFT_R 11 + #define COLOR_SHIFT_G 5 + #define COLOR_SHIFT_B 0 + /** @} */ + /** + * @brief Does the color need masking to remove invalid bits + */ + #define COLOR_NEEDS_MASK FALSE + /** + * @brief If the color needs masking to remove invalid bits, this is the mask + */ + #define COLOR_MASK 0xFFFF + /** + * @brief The color type + * @{ + */ + #define COLOR_TYPE uint16_t + /** @} */ + /** + * @brief The number of bits in the color type (not necessarily the same as COLOR_BITS). + */ + #define COLOR_TYPE_BITS 16 + /** + * @brief Convert a luminance (0 to 255) into a color value. + * @note The word "Luma" is used instead of grey or gray due to the spelling ambiguities of the word grey + * @note This is not a weighted luminance conversion in the color tv style. + * @note @p LUMA2COLOR() uses a linear conversion (0.33R + 0.33G + 0.33B). Note this is different to color + * tv luminance (0.26126R + 0.7152G + 0.0722B), digital tv luminance of (0.299R + 0.587G + 0.114B), or + * @p LUMA_OF() which uses (0.25R + 0.5G + 0.25B). + */ + #define LUMA2COLOR(l) ((color_t)((((l) & 0xF8)<<8) | (((l) & 0xFC)<<3) | (((l) & 0xF8)>>3))) + /** + * @brief Convert red, green, blue (each 0 to 255) into a color value. + */ + #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3))) + /** + * @brief Convert a 6 digit HTML code (hex) into a color value. + */ + #define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3))) + /** + * @brief Extract the luma/red/green/blue component (0 to 255) of a color value. + * @note This uses quick and dirty bit shifting. If you want more exact colors + * use @p EXACT_RED_OF() etc which uses multiplies and divides. For constant + * colors using @p EXACT_RED_OF() is no more expensive because the compiler + * evaluates the arithmetic. + * @note @p LUMA_OF() returns a roughly weighted luminance (0.25R + 0.5G + 0.25B). Note this is + * different to @p LUMA2COLOR() which uses a linear conversion (0.33R + 0.33G + 0.33B) and + * color tv luminance of (0.26126R + 0.7152G + 0.0722B) and digital tv luminance of (0.299R + 0.587G + 0.114B). + * @note A 5 bit color component maximum value (0x1F) converts to 0xF8 (slightly off-color) + * @{ + */ + #define LUMA_OF(c) ((RED_OF(c)+((uint16_t)GREEN_OF(c)<<1)+BLUE_OF(c))>>2) + #define RED_OF(c) (((c) & 0xF800)>>8) + #define GREEN_OF(c) (((c)&0x007E)>>3) + #define BLUE_OF(c) (((c)&0x001F)<<3) + /** @} */ + /** + * @brief Extract the exact luma/red/green/blue component (0 to 255) of a color value. + * @note This uses multiplies and divides rather than bit shifting. + * This gives exact equivalent colors at the expense of more cpu intensive + * operations. Note for constants this is no more expensive than @p REF_OF() + * because the compiler evaluates the arithmetic. + * @note @p EXACT_LUMA_OF() returns a roughly weighted luminance (0.25R + 0.5G + 0.25B). Note this is + * different to @p LUMA2COLOR() which uses a linear conversion (0.33R + 0.33G + 0.33B) and + * color tv luminance of (0.26126R + 0.7152G + 0.0722B) and digital tv luminance of (0.299R + 0.587G + 0.114B). + * @note A 5 bit color component maximum value (0x1F) converts to 0xFF (the true equivalent color) + * @{ + */ + #define EXACT_LUMA_OF(c) ((EXACT_RED_OF(c)+((uint16_t)EXACT_GREEN_OF(c)<<1)+EXACT_BLUE_OF(c))>>2) + #define EXACT_RED_OF(c) (((((c)>>11)&0x1F)*255)/31) + #define EXACT_GREEN_OF(c) (((((c)>>5)&0x3F)*255)/63) + #define EXACT_BLUE_OF(c) (((((c)>>0)&0x1F)*255)/31) + /** @} */ +#endif + +/* + * We use this big mess of macros to calculate all the components + * to prevent user errors in the color definitions. It greatly simplifies + * the above definitions and ensures a consistent implementation. + */ + +//------------------------- +// True-Color color system +//------------------------- +#if GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR + #define COLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR + + // Calculate the number of bits + #define COLOR_BITS_R ((GDISP_PIXELFORMAT>>8) & 0x0F) + #define COLOR_BITS_G ((GDISP_PIXELFORMAT>>4) & 0x0F) + #define COLOR_BITS_B ((GDISP_PIXELFORMAT>>0) & 0x0F) + #define COLOR_BITS (COLOR_BITS_R + COLOR_BITS_G + COLOR_BITS_B) + + // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking + #if COLOR_BITS <= 8 + #define COLOR_TYPE uint8_t + #define COLOR_TYPE_BITS 8 + #elif COLOR_BITS <= 16 + #define COLOR_TYPE uint16_t + #define COLOR_TYPE_BITS 16 + #elif COLOR_BITS <= 32 + #define COLOR_TYPE uint32_t + #define COLOR_TYPE_BITS 32 + #else + #error "GDISP: Cannot define color types with more than 32 bits" + #endif + #if COLOR_TYPE_BITS == COLOR_BITS + #define COLOR_NEEDS_MASK FALSE + #else + #define COLOR_NEEDS_MASK TRUE + #endif + #define COLOR_MASK() ((1 << COLOR_BITS)-1) + + // Calculate the component bit shifts + #if (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB + #define COLOR_SHIFT_R (COLOR_BITS_B+COLOR_BITS_G) + #define COLOR_SHIFT_G COLOR_BITS_B + #define COLOR_SHIFT_B 0 + #else + #define COLOR_SHIFT_B (COLOR_BITS_R+COLOR_BITS_G) + #define COLOR_SHIFT_G COLOR_BITS_R + #define COLOR_SHIFT_R 0 + #endif + + // Calculate RED_OF, GREEN_OF, BLUE_OF and RGB2COLOR + #if COLOR_BITS_R + COLOR_SHIFT_R == 8 + #define RED_OF(c) ((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R)) + #define RGB2COLOR_R(r) ((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1)))) + #elif COLOR_BITS_R + COLOR_SHIFT_R > 8 + #define RED_OF(c) (((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R)) >> (COLOR_BITS_R+COLOR_SHIFT_R-8)) + #define RGB2COLOR_R(r) (((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1)))) << (COLOR_BITS_R+COLOR_SHIFT_R-8)) + #else // COLOR_BITS_R + COLOR_SHIFT_R < 8 + #define RED_OF(c) (((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R)) << (8-(COLOR_BITS_R+COLOR_SHIFT_R))) + #define RGB2COLOR_R(r) (((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1)))) >> (8-(COLOR_BITS_R+COLOR_SHIFT_R))) + #endif + #if COLOR_BITS_G + COLOR_SHIFT_G == 8 + #define GREEN_OF(c) ((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G)) + #define RGB2COLOR_G(g) ((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1)))) + #elif COLOR_BITS_G + COLOR_SHIFT_G > 8 + #define GREEN_OF(c) (((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G)) >> (COLOR_BITS_G+COLOR_SHIFT_G-8)) + #define RGB2COLOR_G(g) (((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1)))) << (COLOR_BITS_G+COLOR_SHIFT_G-8)) + #else // COLOR_BITS_G + COLOR_SHIFT_G < 8 + #define GREEN_OF(c) (((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G)) << (8-(COLOR_BITS_G+COLOR_SHIFT_G))) + #define RGB2COLOR_G(g) (((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1)))) >> (8-(COLOR_BITS_G+COLOR_SHIFT_G))) + #endif + #if COLOR_BITS_B + COLOR_SHIFT_B == 8 + #define BLUE_OF(c) ((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B)) + #define RGB2COLOR_B(b) ((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))) + #elif COLOR_BITS_B + COLOR_SHIFT_B > 8 + #define BLUE_OF(c) (((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B)) >> (COLOR_BITS_B+COLOR_SHIFT_B-8)) + #define RGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))) << (COLOR_BITS_B+COLOR_SHIFT_B-8)) + #else // COLOR_BITS_B + COLOR_SHIFT_B < 8 + #define BLUE_OF(c) (((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B)) << (8-(COLOR_BITS_B+COLOR_SHIFT_B))) + #define RGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))) >> (8-(COLOR_BITS_B+COLOR_SHIFT_B))) + #endif + #define LUMA_OF(c) ((RED_OF(c)+((uint16_t)GREEN_OF(c)<<1)+BLUE_OF(c))>>2) + #define EXACT_RED_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_R)&((1<<COLOR_BITS_R)-1))*255)/((1<<COLOR_BITS_R)-1)) + #define EXACT_GREEN_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_G)&((1<<COLOR_BITS_G)-1))*255)/((1<<COLOR_BITS_G)-1)) + #define EXACT_BLUE_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_B)&((1<<COLOR_BITS_B)-1))*255)/((1<<COLOR_BITS_B)-1)) + #define EXACT_LUMA_OF(c) ((EXACT_RED_OF(c)+((uint16_t)EXACT_GREEN_OF(c)<<1)+EXACT_BLUE_OF(c))>>2) + #define LUMA2COLOR(l) (RGB2COLOR_R(l) | RGB2COLOR_G(l) | RGB2COLOR_B(l)) + #define RGB2COLOR(r,g,b) (RGB2COLOR_R(r) | RGB2COLOR_G(g) | RGB2COLOR_B(b)) + + // Calculate HTML2COLOR + #if COLOR_BITS_R + COLOR_SHIFT_R == 24 + #define HTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16)) + #elif COLOR_BITS_R + COLOR_SHIFT_R > 24 + #define HTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16)) << (COLOR_BITS_R+COLOR_SHIFT_R-24)) + #else // COLOR_BITS_R + COLOR_SHIFT_R < 24 + #define HTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16)) >> (24-(COLOR_BITS_R+COLOR_SHIFT_R))) + #endif + #if COLOR_BITS_G + COLOR_SHIFT_G == 16 + #define HTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8)) + #elif COLOR_BITS_G + COLOR_SHIFT_G > 16 + #define HTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8)) << (COLOR_BITS_G+COLOR_SHIFT_G-16)) + #else // COLOR_BITS_G + COLOR_SHIFT_G < 16 + #define HTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8)) >> (16-(COLOR_BITS_G+COLOR_SHIFT_G))) + #endif + #if COLOR_BITS_B + COLOR_SHIFT_B == 8 + #define HTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))) + #elif COLOR_BITS_B + COLOR_SHIFT_B > 8 + #define HTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))) << (COLOR_BITS_B+COLOR_SHIFT_B-8)) + #else // COLOR_BITS_B + COLOR_SHIFT_B < 8 + #define HTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))) >> (8-(COLOR_BITS_B+COLOR_SHIFT_B))) + #endif + #define HTML2COLOR(h) ((COLOR_TYPE)(HTML2COLOR_R(h) | HTML2COLOR_G(h) | HTML2COLOR_B(h))) + +//------------------------- +// Gray-scale color system +//------------------------- +#elif (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE + #define COLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE + + // Calculate the number of bits and shifts + #define COLOR_BITS (GDISP_PIXELFORMAT & 0xFF) + #define COLOR_BITS_R COLOR_BITS + #define COLOR_BITS_G COLOR_BITS + #define COLOR_BITS_B COLOR_BITS + #define COLOR_SHIFT_R 0 + #define COLOR_SHIFT_G 0 + #define COLOR_SHIFT_B 0 + + // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking + #if COLOR_BITS <= 8 + #define COLOR_TYPE uint8_t + #define COLOR_TYPE_BITS 8 + #else + #error "GDISP: Cannot define gray-scale color types with more than 8 bits" + #endif + #if COLOR_TYPE_BITS == COLOR_BITS + #define COLOR_NEEDS_MASK FALSE + #else + #define COLOR_NEEDS_MASK TRUE + #endif + #define COLOR_MASK() ((1 << COLOR_BITS)-1) + + #if COLOR_BITS == 1 + #define RGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0) + #define LUMA2COLOR(l) ((l) ? 1 : 0) + #define HTML2COLOR(h) ((h) ? 1 : 0) + #define LUMA_OF(c) ((c) ? 255 : 0) + #define EXACT_LUMA_OF(c) LUMA_OF(c) + #else + // They eye is more sensitive to green + #define RGB2COLOR(r,g,b) ((COLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-COLOR_BITS))) + #define LUMA2COLOR(l) ((COLOR_TYPE)((l)>>(8-COLOR_BITS))) + #define HTML2COLOR(h) ((COLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-COLOR_BITS))) + #define LUMA_OF(c) (((c) & ((1<<COLOR_BITS)-1)) << (8-COLOR_BITS)) + #define EXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<COLOR_BITS)-1))*255)/((1<<COLOR_BITS)-1)) + #endif + + #define RED_OF(c) LUMA_OF(c) + #define GREEN_OF(c) LUMA_OF(c) + #define BLUE_OF(c) LUMA_OF(c) + #define EXACT_RED_OF(c) EXACT_LUMA_OF(c) + #define EXACT_GREEN_OF(c) EXACT_LUMA_OF(c) + #define EXACT_BLUE_OF(c) EXACT_LUMA_OF(c) + +//------------------------- +// Palette color system +//------------------------- +#elif (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE + #define COLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE + + #error "GDISP: A palette color system is not currently supported" + +//------------------------- +// Some other color system +//------------------------- +#else + #error "GDISP: Unsupported color system" +#endif + +/** + * @brief The color type definition + */ +typedef COLOR_TYPE color_t; + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_COLORS_H */ +/** @} */ diff --git a/src/gdisp/driver.h b/src/gdisp/driver.h new file mode 100644 index 00000000..f45b3f87 --- /dev/null +++ b/src/gdisp/driver.h @@ -0,0 +1,873 @@ +/* + * 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/driver.h + * @brief GDISP Graphic Driver subsystem low level driver header. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_H +#define _GDISP_LLD_H + +#if GFX_USE_GDISP // || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Error checks. */ +/*===========================================================================*/ + +#if GDISP_TOTAL_CONTROLLERS > 1 && !defined(GDISP_DRIVER_VMT) + #define HARDWARE_AUTODETECT 2 + #define HARDWARE_DEFAULT HARDWARE_AUTODETECT +#else + #define HARDWARE_AUTODETECT 2 + #define HARDWARE_DEFAULT FALSE +#endif + +/** + * @name GDISP hardware accelerated support + * @{ + */ + /** + * @brief The display hardware can benefit from being flushed. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + * @note Some controllers ** require ** the application to flush + */ + #ifndef GDISP_HARDWARE_FLUSH + #define GDISP_HARDWARE_FLUSH HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware streaming writing is supported. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by each driver + */ + #ifndef GDISP_HARDWARE_STREAM_WRITE + #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware streaming reading of the display surface is supported. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + * + */ + #ifndef GDISP_HARDWARE_STREAM_READ + #define GDISP_HARDWARE_STREAM_READ HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware supports setting the cursor position within the stream window. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + * @note This is used to optimise setting of individual pixels within a stream window. + * It should therefore not be implemented unless it is cheaper than just setting + * a new window. + */ + #ifndef GDISP_HARDWARE_STREAM_POS + #define GDISP_HARDWARE_STREAM_POS HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware accelerated draw pixel. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver + */ + #ifndef GDISP_HARDWARE_DRAWPIXEL + #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware accelerated screen clears. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + * @note This clears the entire display surface regardless of the clipping area currently set + */ + #ifndef GDISP_HARDWARE_CLEARS + #define GDISP_HARDWARE_CLEARS HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware accelerated rectangular fills. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + */ + #ifndef GDISP_HARDWARE_FILLS + #define GDISP_HARDWARE_FILLS HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware accelerated fills from an image. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + */ + #ifndef GDISP_HARDWARE_BITFILLS + #define GDISP_HARDWARE_BITFILLS HARDWARE_DEFAULT + #endif + + /** + * @brief Hardware accelerated scrolling. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + */ + #ifndef GDISP_HARDWARE_SCROLL + #define GDISP_HARDWARE_SCROLL HARDWARE_DEFAULT + #endif + + /** + * @brief Reading back of pixel values. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + */ + #ifndef GDISP_HARDWARE_PIXELREAD + #define GDISP_HARDWARE_PIXELREAD HARDWARE_DEFAULT + #endif + + /** + * @brief The driver supports one or more control commands. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + */ + #ifndef GDISP_HARDWARE_CONTROL + #define GDISP_HARDWARE_CONTROL HARDWARE_DEFAULT + #endif + + /** + * @brief The driver supports a non-standard query. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + */ + #ifndef GDISP_HARDWARE_QUERY + #define GDISP_HARDWARE_QUERY HARDWARE_DEFAULT + #endif + + /** + * @brief The driver supports a clipping in hardware. + * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT + * + * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 + * @note If this is defined the driver must perform its own clipping on all calls to + * the driver and respond appropriately if a parameter is outside the display area. + * @note If this is not defined then the software ensures that all calls to the + * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION + * has been set). + */ + #ifndef GDISP_HARDWARE_CLIP + #define GDISP_HARDWARE_CLIP HARDWARE_DEFAULT + #endif +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +struct GDisplay { + // The public GDISP stuff - must be the first element + GDISPControl g; + + #if GDISP_TOTAL_CONTROLLERS > 1 + const struct GDISPVMT const * vmt; // The Virtual Method Table + #endif + + void * priv; // A private area just for the drivers use. + void * board; // A private area just for the board interfaces use. + + uint8_t systemdisplay; + uint8_t controllerdisplay; + uint16_t flags; + #define GDISP_FLG_INSTREAM 0x0001 // We are in a user based stream operation + #define GDISP_FLG_SCRSTREAM 0x0002 // The stream area currently covers the whole screen + #define GDISP_FLG_DRIVER 0x0004 // This flags and above are for use by the driver + + // Multithread Mutex + #if GDISP_NEED_MULTITHREAD + gfxMutex mutex; + #endif + + // Software clipping + #if GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) + coord_t clipx0, clipy0; + coord_t clipx1, clipy1; /* not inclusive */ + #endif + + // Driver call parameters + struct { + coord_t x, y; + coord_t cx, cy; + coord_t x1, y1; + coord_t x2, y2; + color_t color; + void *ptr; + } p; + + // In call working buffers + + #if GDISP_NEED_TEXT + // Text rendering parameters + struct { + font_t font; + color_t color; + color_t bgcolor; + coord_t clipx0, clipy0; + coord_t clipx1, clipy1; + } t; + #endif + #if GDISP_LINEBUF_SIZE != 0 && ((GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL) || (!GDISP_HARDWARE_STREAM_WRITE && GDISP_HARDWARE_BITFILLS)) + // A pixel line buffer + color_t linebuf[GDISP_LINEBUF_SIZE]; + #endif + +}; + +#if GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT) || defined(__DOXYGEN__) + #if GDISP_TOTAL_CONTROLLERS > 1 + #define LLDSPEC static + #else + #define LLDSPEC + #endif + + #ifdef __cplusplus + extern "C" { + #endif + + /** + * @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 + */ + LLDSPEC bool_t gdisp_lld_init(GDisplay *g); + + #if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__) + /** + * @brief Flush the current drawing operations to the display + * @pre GDISP_HARDWARE_FLUSH is TRUE + * + * @param[in] g The driver structure + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_flush(GDisplay *g); + #endif + + #if GDISP_HARDWARE_STREAM_WRITE || defined(__DOXYGEN__) + /** + * @brief Start a streamed write operation + * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE + * + * @param[in] g The driver structure + * + * @note g->p.x,g->p.y The window position + * @note g->p.cx,g->p.cy The window size + * + * @note The parameter variables must not be altered by the driver. + * @note Streaming operations that wrap the defined window have + * undefined results. + * @note This must be followed by a call to @p gdisp_lld_write_pos() if GDISP_HARDWARE_STREAM_POS is TRUE. + */ + LLDSPEC void gdisp_lld_write_start(GDisplay *g); + + /** + * @brief Send a pixel to the current streaming position and then increment that position + * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE + * + * @param[in] g The driver structure + * + * @note g->p.color The color to display at the curent position + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_write_color(GDisplay *g); + + /** + * @brief End the current streaming write operation + * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE + * + * @param[in] g The driver structure + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_write_stop(GDisplay *g); + + #if GDISP_HARDWARE_STREAM_POS || defined(__DOXYGEN__) + /** + * @brief Change the current position within the current streaming window + * @pre GDISP_HARDWARE_STREAM_POS is TRUE and GDISP_HARDWARE_STREAM_WRITE is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The new position (which will always be within the existing stream window) + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_write_pos(GDisplay *g); + #endif + #endif + + #if GDISP_HARDWARE_STREAM_READ || defined(__DOXYGEN__) + /** + * @brief Start a streamed read operation + * @pre GDISP_HARDWARE_STREAM_READ is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The window position + * @param[in] g->p.cx,g->p.cy The window size + * + * @note The parameter variables must not be altered by the driver. + * @note Streaming operations that wrap the defined window have + * undefined results. + */ + LLDSPEC void gdisp_lld_read_start(GDisplay *g); + + /** + * @brief Read a pixel from the current streaming position and then increment that position + * @return The color at the current position + * @pre GDISP_HARDWARE_STREAM_READ is TRUE + * + * @param[in] g The driver structure + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC color_t gdisp_lld_read_color(GDisplay *g); + + /** + * @brief End the current streaming operation + * @pre GDISP_HARDWARE_STREAM_READ is TRUE + * + * @param[in] g The driver structure + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_read_stop(GDisplay *g); + #endif + + #if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__) + /** + * @brief Draw a pixel + * @pre GDISP_HARDWARE_DRAWPIXEL is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The pixel position + * @param[in] g->p.color The color to set + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g); + #endif + + #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) + /** + * @brief Clear the screen using the defined color + * @pre GDISP_HARDWARE_CLEARS is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.color The color to set + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_clear(GDisplay *g); + #endif + + #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) + /** + * @brief Fill an area with a single color + * @pre GDISP_HARDWARE_FILLS is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * @param[in] g->p.color The color to set + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_fill_area(GDisplay *g); + #endif + + #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__) + /** + * @brief Fill an area using a bitmap + * @pre GDISP_HARDWARE_BITFILLS is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * @param[in] g->p.x1,g->p.y1 The starting position in the bitmap + * @param[in] g->p.x2 The width of a bitmap line + * @param[in] g->p.ptr The pointer to the bitmap + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_blit_area(GDisplay *g); + #endif + + #if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__) + /** + * @brief Read a pixel from the display + * @return The color at the defined position + * @pre GDISP_HARDWARE_PIXELREAD is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The pixel position + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g); + #endif + + #if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__) + /** + * @brief Scroll an area of the screen + * @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * @param[in] g->p.y1 The number of lines to scroll (positive or negative) + * + * @note The parameter variables must not be altered by the driver. + * @note This can be easily implemented if the hardware supports + * display area to display area copying. + * @note Clearing the exposed area on the scroll operation is not + * needed as the high level code handles this. + */ + LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g); + #endif + + #if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__) + /** + * @brief Control some feature of the hardware + * @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x The operation to perform + * @param[in] g->p.ptr The operation parameter + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_control(GDisplay *g); + #endif + + #if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__) + /** + * @brief Query some feature of the hardware + * @return The information requested (typecast as void *) + * @pre GDISP_HARDWARE_QUERY is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x What to query + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void *gdisp_lld_query(GDisplay *g); // Uses p.x (=what); + #endif + + #if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__) + /** + * @brief Set the hardware clipping area + * @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_set_clip(GDisplay *g); + #endif + + #ifdef __cplusplus + } + #endif +#endif // GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT) + + +#if GDISP_TOTAL_CONTROLLERS > 1 + + typedef struct GDISPVMT { + bool_t (*init)(GDisplay *g); + void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy + void (*writepos)(GDisplay *g); // Uses p.x,p.y + void (*writecolor)(GDisplay *g); // Uses p.color + void (*writestop)(GDisplay *g); // Uses no parameters + void (*readstart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy + color_t (*readcolor)(GDisplay *g); // Uses no parameters + void (*readstop)(GDisplay *g); // Uses no parameters + void (*pixel)(GDisplay *g); // Uses p.x,p.y p.color + void (*clear)(GDisplay *g); // Uses p.color + void (*fill)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.color + void (*blit)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer) + color_t (*get)(GDisplay *g); // Uses p.x,p.y + void (*vscroll)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color + void (*control)(GDisplay *g); // Uses p.x (=what) p.ptr (=value) + void *(*query)(GDisplay *g); // Uses p.x (=what); + void (*setclip)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy + void (*flush)(GDisplay *g); // Uses no parameters + } GDISPVMT; + + #if defined(GDISP_DRIVER_VMT) + #if !GDISP_HARDWARE_STREAM_WRITE && !GDISP_HARDWARE_DRAWPIXEL + #error "GDISP Driver: Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be TRUE" + #endif + const GDISPVMT const GDISP_DRIVER_VMT[1] = {{ + gdisp_lld_init, + #if GDISP_HARDWARE_FLUSH + gdisp_lld_flush, + #else + 0, + #endif + #if GDISP_HARDWARE_STREAM_WRITE + gdisp_lld_write_start, + #if GDISP_HARDWARE_STREAM_POS + gdisp_lld_write_pos, + #else + 0, + #endif + gdisp_lld_write_color, + gdisp_lld_write_stop, + #else + 0, 0, 0, 0, + #endif + #if GDISP_HARDWARE_STREAM_READ + gdisp_lld_read_start, + gdisp_lld_read_color, + gdisp_lld_read_stop, + #else + 0, 0, 0, + #endif + #if GDISP_HARDWARE_DRAWPIXEL + gdisp_lld_draw_pixel, + #else + 0, + #endif + #if GDISP_HARDWARE_CLEARS + gdisp_lld_clear, + #else + 0, + #endif + #if GDISP_HARDWARE_FILLS + gdisp_lld_fill_area, + #else + 0, + #endif + #if GDISP_HARDWARE_BITFILLS + gdisp_lld_blit_area, + #else + 0, + #endif + #if GDISP_HARDWARE_PIXELREAD + gdisp_lld_get_pixel_color, + #else + 0, + #endif + #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL + gdisp_lld_vertical_scroll, + #else + 0, + #endif + #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL + gdisp_lld_control, + #else + 0, + #endif + #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY + gdisp_lld_query, + #else + 0, + #endif + #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) + gdisp_lld_set_clip, + #else + 0, + #endif + }}; + + #else + #define gdisp_lld_init(g) g->vmt->init(g) + #define gdisp_lld_flush(g) g->vmt->flush(g) + #define gdisp_lld_write_start(g) g->vmt->writestart(g) + #define gdisp_lld_write_pos(g) g->vmt->writepos(g) + #define gdisp_lld_write_color(g) g->vmt->writecolor(g) + #define gdisp_lld_write_stop(g) g->vmt->writestop(g) + #define gdisp_lld_read_start(g) g->vmt->readstart(g) + #define gdisp_lld_read_color(g) g->vmt->readcolor(g) + #define gdisp_lld_read_stop(g) g->vmt->readstop(g) + #define gdisp_lld_draw_pixel(g) g->vmt->pixel(g) + #define gdisp_lld_clear(g) g->vmt->clear(g) + #define gdisp_lld_fill_area(g) g->vmt->fill(g) + #define gdisp_lld_blit_area(g) g->vmt->blit(g) + #define gdisp_lld_get_pixel_color(g) g->vmt->get(g) + #define gdisp_lld_vertical_scroll(g) g->vmt->vscroll(g) + #define gdisp_lld_control(g) g->vmt->control(g) + #define gdisp_lld_query(g) g->vmt->query(g) + #define gdisp_lld_set_clip(g) g->vmt->setclip(g) + #endif // GDISP_LLD_DECLARATIONS + +#endif // GDISP_TOTAL_CONTROLLERS > 1 + +/* Verify information for packed pixels and define a non-packed pixel macro */ +#if !GDISP_PACKED_PIXELS + #define gdispPackPixels(buf,cx,x,y,c) { ((color_t *)(buf))[(y)*(cx)+(x)] = (c); } +#elif !GDISP_HARDWARE_BITFILLS + #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers." +#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \ + && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \ + && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \ + && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM + #error "GDISP: A packed pixel format has been specified for an unsupported pixel format." +#endif + +/* Support routine for packed pixel formats */ +#if !defined(gdispPackPixels) || defined(__DOXYGEN__) + /** + * @brief Pack a pixel into a pixel buffer. + * @note This function performs no buffer boundary checking + * regardless of whether GDISP_NEED_CLIP has been specified. + * + * @param[in] buf The buffer to put the pixel in + * @param[in] cx The width of a pixel line + * @param[in] x, y The location of the pixel to place + * @param[in] color The color to put into the buffer + * + * @api + */ + void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color); +#endif + +/* Low level driver pixel format information */ +//------------------------- +// True-Color color system +//------------------------- +#if GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR + #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR + + // Calculate the number of bits + #define LLDCOLOR_BITS_R ((GDISP_LLD_PIXELFORMAT>>8) & 0x0F) + #define LLDCOLOR_BITS_G ((GDISP_LLD_PIXELFORMAT>>4) & 0x0F) + #define LLDCOLOR_BITS_B ((GDISP_LLD_PIXELFORMAT>>0) & 0x0F) + #define LLDCOLOR_BITS (LLDCOLOR_BITS_R + LLDCOLOR_BITS_G + LLDCOLOR_BITS_B) + + // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking + #if LLDCOLOR_BITS <= 8 + #define LLDCOLOR_TYPE uint8_t + #define LLDCOLOR_TYPE_BITS 8 + #elif LLDCOLOR_BITS <= 16 + #define LLDCOLOR_TYPE uint16_t + #define LLDCOLOR_TYPE_BITS 16 + #elif LLDCOLOR_BITS <= 32 + #define LLDCOLOR_TYPE uint32_t + #define LLDCOLOR_TYPE_BITS 32 + #else + #error "GDISP: Cannot define low level driver color types with more than 32 bits" + #endif + #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS + #define LLDCOLOR_NEEDS_MASK FALSE + #else + #define LLDCOLOR_NEEDS_MASK TRUE + #endif + #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1) + + // Calculate the component bit shifts + #if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB + #define LLDCOLOR_SHIFT_R (LLDCOLOR_BITS_B+LLDCOLOR_BITS_G) + #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_B + #define LLDCOLOR_SHIFT_B 0 + #else + #define LLDCOLOR_SHIFT_B (LLDCOLOR_BITS_R+LLDCOLOR_BITS_G) + #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_R + #define LLDCOLOR_SHIFT_R 0 + #endif + + // Calculate LLDRED_OF, LLDGREEN_OF, LLDBLUE_OF and LLDRGB2COLOR + #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 8 + #define LLDRED_OF(c) ((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) + #define LLDRGB2COLOR_R(r) ((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) + #elif LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R > 8 + #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) >> (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8)) + #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8)) + #else // LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R < 8 + #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) << (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R))) + #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) >> (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R))) + #endif + #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 8 + #define LLDGREEN_OF(c) ((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) + #define LLDRGB2COLOR_G(g) ((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) + #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 8 + #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) >> (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8)) + #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8)) + #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 8 + #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) << (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G))) + #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) >> (8-(LLDCOLOR_BITS_LLDG+COLOR_SHIFT_G))) + #endif + #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8 + #define LLDBLUE_OF(c) ((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) + #define LLDRGB2COLOR_B(b) ((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) + #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8 + #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) >> (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8)) + #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8)) + #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8 + #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) << (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B))) + #define LLDRGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B))) + #endif + #define LLDLUMA_OF(c) ((LLDRED_OF(c)+((uint16_t)LLDGREEN_OF(c)<<1)+LLDBLUE_OF(c))>>2) + #define LLDEXACT_RED_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_R)&((1<<LLDCOLOR_BITS_R)-1))*255)/((1<<LLDCOLOR_BITS_R)-1)) + #define LLDEXACT_GREEN_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_G)&((1<<LLDCOLOR_BITS_G)-1))*255)/((1<<LLDCOLOR_BITS_G)-1)) + #define LLDEXACT_BLUE_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_B)&((1<<LLDCOLOR_BITS_B)-1))*255)/((1<<LLDCOLOR_BITS_B)-1)) + #define LLDEXACT_LUMA_OF(c) ((LLDEXACT_RED_OF(c)+((uint16_t)LLDEXACT_GREEN_OF(c)<<1)+LLDEXACT_BLUE_OF(c))>>2) + #define LLDLUMA2COLOR(l) (LLDRGB2COLOR_R(l) | LLDRGB2COLOR_G(l) | LLDRGB2COLOR_B(l)) + #define LLDRGB2COLOR(r,g,b) (LLDRGB2COLOR_R(r) | LLDRGB2COLOR_G(g) | LLDRGB2COLOR_B(b)) + + // Calculate LLDHTML2COLOR + #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 24 + #define LLDHTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) + #elif COLOR_BITS_R + COLOR_SHIFT_R > 24 + #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-24)) + #else // COLOR_BITS_R + COLOR_SHIFT_R < 24 + #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) >> (24-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R))) + #endif + #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 16 + #define LLDHTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) + #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 16 + #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-16)) + #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 16 + #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) >> (16-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G))) + #endif + #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8 + #define LLDHTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) + #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8 + #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8)) + #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8 + #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B))) + #endif + #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(LLDHTML2COLOR_R(h) | LLDHTML2COLOR_G(h) | LLDHTML2COLOR_B(h))) + +//------------------------- +// Gray-scale color system +//------------------------- +#elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE + #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE + + // Calculate the number of bits and shifts + #define LLDCOLOR_BITS (GDISP_LLD_PIXELFORMAT & 0xFF) + #define LLDCOLOR_BITS_R LLDCOLOR_BITS + #define LLDCOLOR_BITS_G LLDCOLOR_BITS + #define LLDCOLOR_BITS_B LLDCOLOR_BITS + #define LLDCOLOR_SHIFT_R 0 + #define LLDCOLOR_SHIFT_G 0 + #define LLDCOLOR_SHIFT_B 0 + + // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking + #if LLDCOLOR_BITS <= 8 + #define LLDCOLOR_TYPE uint8_t + #define LLDCOLOR_TYPE_BITS 8 + #else + #error "GDISP: Cannot define gray-scale low level driver color types with more than 8 bits" + #endif + #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS + #define LLDCOLOR_NEEDS_MASK FALSE + #else + #define LLDCOLOR_NEEDS_MASK TRUE + #endif + #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1) + + #if COLOR_BITS == 1 + #define LLDRGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0) + #define LLDLUMA2COLOR(l) ((l) ? 1 : 0) + #define LLDHTML2COLOR(h) ((h) ? 1 : 0) + #define LLDLUMA_OF(c) ((c) ? 255 : 0) + #define LLDEXACT_LUMA_OF(c) LLDLUMA_OF(c) + #else + // They eye is more sensitive to green + #define LLDRGB2COLOR(r,g,b) ((LLDCOLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-LLDCOLOR_BITS))) + #define LLDLUMA2COLOR(l) ((LLDCOLOR_TYPE)((l)>>(8-LLDCOLOR_BITS))) + #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-LLDCOLOR_BITS))) + #define LLDLUMA_OF(c) (((c) & ((1<<LLDCOLOR_BITS)-1)) << (8-LLDCOLOR_BITS)) + #define LLDEXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<LLDCOLOR_BITS)-1))*255)/((1<<LLDCOLOR_BITS)-1)) + #endif + + #define LLDRED_OF(c) LLDLUMA_OF(c) + #define LLDGREEN_OF(c) LLDLUMA_OF(c) + #define LLDBLUE_OF(c) LLDLUMA_OF(c) + #define LLDEXACT_RED_OF(c) LLDEXACT_LUMA_OF(c) + #define LLDEXACT_GREEN_OF(c) LLDEXACT_LUMA_OF(c) + #define LLDEXACT_BLUE_OF(c) LLDEXACT_LUMA_OF(c) + +//------------------------- +// Palette color system +//------------------------- +#elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE + #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE + + #error "GDISP: A palette color system for low level drivers is not currently supported" + +//------------------------- +// Some other color system +//------------------------- +#else + #error "GDISP: Unsupported color system for low level drivers" +#endif + +/* Which is the larger color type */ +#if COLOR_BITS > LLDCOLOR_BITS + #define LARGER_COLOR_BITS COLOR_BITS + #define LARGER_COLOR_TYPE COLOR_TYPE +#else + #define LARGER_COLOR_BITS LLDCOLOR_BITS + #define LARGER_COLOR_TYPE LLDCOLOR_TYPE +#endif + +/** + * @brief Controls color conversion accuracy for a low level driver + * @details Should higher precision be used when converting colors. + * @note Color conversion is only necessary if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT + * @note It only makes sense to turn this on if you have a high bit depth display but + * are running the application in low bit depths. + * @note To achieve higher color accuracy bit shifting is replaced with multiplies and divides. + */ +#ifndef GDISP_HARDWARE_USE_EXACT_COLOR + #if LLDCOLOR_BITS_R - COLOR_BITS_R >= LLDCOLOR_BITS_R/2 || LLDCOLOR_BITS_G - COLOR_BITS_G >= LLDCOLOR_BITS_G/2 || LLDCOLOR_BITS_B - COLOR_BITS_B >= LLDCOLOR_BITS_B/2 + #define GDISP_HARDWARE_USE_EXACT_COLOR TRUE + #else + #define GDISP_HARDWARE_USE_EXACT_COLOR FALSE + #endif +#endif + +/* Low level driver pixel format conversion functions */ +#if GDISP_PIXELFORMAT == GDISP_LLD_PIXELFORMAT || defined(__DOXYGEN__) + /** + * @brief Convert from a standard color format to the low level driver pixel format + * @note For use only by low level drivers + */ + #define gdispColor2Native(c) (c) + /** + * @brief Convert from a low level driver pixel format to the standard color format + * @note For use only by low level drivers + */ + #define gdispNative2Color(c) (c) +#else + LLDCOLOR_TYPE gdispColor2Native(color_t c); + color_t gdispNative2Color(LLDCOLOR_TYPE c); +#endif + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_H */ +/** @} */ diff --git a/src/gdisp/fonts/build_fonts.sh b/src/gdisp/fonts/build_fonts.sh index b6c26602..4ce93a40 100644 --- a/src/gdisp/fonts/build_fonts.sh +++ b/src/gdisp/fonts/build_fonts.sh @@ -72,7 +72,7 @@ for file in *.c; do defname='GDISP_INCLUDE_FONT_'$upper echo '#if defined('$defname') && '$defname >> fonts.h echo '#define GDISP_FONT_FOUND' >> fonts.h - echo '#include "../src/gdisp/fonts/'$file'"' >> fonts.h + echo '#include "src/gdisp/fonts/'$file'"' >> fonts.h echo '#endif' >> fonts.h done diff --git a/src/gdisp/fonts/fonts.h b/src/gdisp/fonts/fonts.h index 7d696044..af851dbd 100644 --- a/src/gdisp/fonts/fonts.h +++ b/src/gdisp/fonts/fonts.h @@ -3,87 +3,87 @@ #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS10) && GDISP_INCLUDE_FONT_DEJAVUSANS10 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans10.c" +#include "src/gdisp/fonts/DejaVuSans10.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS12_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS12_AA #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans12_aa.c" +#include "src/gdisp/fonts/DejaVuSans12_aa.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS12) && GDISP_INCLUDE_FONT_DEJAVUSANS12 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans12.c" +#include "src/gdisp/fonts/DejaVuSans12.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS16_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS16_AA #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans16_aa.c" +#include "src/gdisp/fonts/DejaVuSans16_aa.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS16) && GDISP_INCLUDE_FONT_DEJAVUSANS16 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans16.c" +#include "src/gdisp/fonts/DejaVuSans16.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS24_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS24_AA #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans24_aa.c" +#include "src/gdisp/fonts/DejaVuSans24_aa.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS24) && GDISP_INCLUDE_FONT_DEJAVUSANS24 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans24.c" +#include "src/gdisp/fonts/DejaVuSans24.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS32_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS32_AA #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans32_aa.c" +#include "src/gdisp/fonts/DejaVuSans32_aa.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANS32) && GDISP_INCLUDE_FONT_DEJAVUSANS32 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSans32.c" +#include "src/gdisp/fonts/DejaVuSans32.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA) && GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSansBold12_aa.c" +#include "src/gdisp/fonts/DejaVuSansBold12_aa.c" #endif #if defined(GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12) && GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/DejaVuSansBold12.c" +#include "src/gdisp/fonts/DejaVuSansBold12.c" #endif #if defined(GDISP_INCLUDE_FONT_FIXED_10X20) && GDISP_INCLUDE_FONT_FIXED_10X20 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/fixed_10x20.c" +#include "src/gdisp/fonts/fixed_10x20.c" #endif #if defined(GDISP_INCLUDE_FONT_FIXED_5X8) && GDISP_INCLUDE_FONT_FIXED_5X8 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/fixed_5x8.c" +#include "src/gdisp/fonts/fixed_5x8.c" #endif #if defined(GDISP_INCLUDE_FONT_FIXED_7X14) && GDISP_INCLUDE_FONT_FIXED_7X14 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/fixed_7x14.c" +#include "src/gdisp/fonts/fixed_7x14.c" #endif #if defined(GDISP_INCLUDE_FONT_LARGENUMBERS) && GDISP_INCLUDE_FONT_LARGENUMBERS #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/LargeNumbers.c" +#include "src/gdisp/fonts/LargeNumbers.c" #endif #if defined(GDISP_INCLUDE_FONT_UI1) && GDISP_INCLUDE_FONT_UI1 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/UI1.c" +#include "src/gdisp/fonts/UI1.c" #endif #if defined(GDISP_INCLUDE_FONT_UI2) && GDISP_INCLUDE_FONT_UI2 #define GDISP_FONT_FOUND -#include "../src/gdisp/fonts/UI2.c" +#include "src/gdisp/fonts/UI2.c" #endif #if defined(GDISP_INCLUDE_USER_FONTS) && GDISP_INCLUDE_USER_FONTS diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c index 949bedaf..2ac55f1b 100644 --- a/src/gdisp/gdisp.c +++ b/src/gdisp/gdisp.c @@ -17,7 +17,7 @@ #if GFX_USE_GDISP /* Include the low level driver information */ -#include "gdisp/lld/gdisp_lld.h" +#include "src/gdisp/driver.h" #if 1 #undef INLINE diff --git a/src/gdisp/image.h b/src/gdisp/image.h new file mode 100644 index 00000000..607f1007 --- /dev/null +++ b/src/gdisp/image.h @@ -0,0 +1,307 @@ +/* + * 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 include/gdisp/image.h + * @brief GDISP image header file. + * + * @defgroup Image Image + * @ingroup GDISP + * @{ + */ + +#ifndef _GDISP_IMAGE_H +#define _GDISP_IMAGE_H +#if (GFX_USE_GDISP && GDISP_NEED_IMAGE) || defined(__DOXYGEN__) + +/** + * @brief The type of image + */ +typedef uint16_t gdispImageType; + #define GDISP_IMAGE_TYPE_UNKNOWN 0 + #define GDISP_IMAGE_TYPE_NATIVE 1 + #define GDISP_IMAGE_TYPE_GIF 2 + #define GDISP_IMAGE_TYPE_BMP 3 + #define GDISP_IMAGE_TYPE_JPG 4 + #define GDISP_IMAGE_TYPE_PNG 5 + +/** + * @brief An image error code + */ +typedef uint16_t gdispImageError; + #define GDISP_IMAGE_ERR_OK 0 + #define GDISP_IMAGE_ERR_UNRECOVERABLE 0x8000 + #define GDISP_IMAGE_ERR_BADFORMAT (GDISP_IMAGE_ERR_UNRECOVERABLE+1) + #define GDISP_IMAGE_ERR_BADDATA (GDISP_IMAGE_ERR_UNRECOVERABLE+2) + #define GDISP_IMAGE_ERR_UNSUPPORTED (GDISP_IMAGE_ERR_UNRECOVERABLE+3) + #define GDISP_IMAGE_ERR_UNSUPPORTED_OK 3 + #define GDISP_IMAGE_ERR_NOMEMORY (GDISP_IMAGE_ERR_UNRECOVERABLE+4) + #define GDISP_IMAGE_ERR_NOSUCHFILE (GDISP_IMAGE_ERR_UNRECOVERABLE+5) + +/** + * @brief Image flags + */ +typedef uint16_t gdispImageFlags; + #define GDISP_IMAGE_FLG_TRANSPARENT 0x0001 /* The image has transparency */ + #define GDISP_IMAGE_FLG_ANIMATED 0x0002 /* The image has animation */ + #define GDISP_IMAGE_FLG_MULTIPAGE 0x0004 /* The image has multiple pages */ + +struct gdispImageIO; + +/** + * @brief An image IO close function + * + * @param[in] pio Pointer to the io structure + * @param[in] desc The descriptor. A filename or an image structure pointer. + * + */ +typedef void (*gdispImageIOCloseFn)(struct gdispImageIO *pio); + +/** + * @brief An image IO read function + * @returns The number of bytes actually read or 0 on error + * + * @param[in] pio Pointer to the io structure + * @param[in] buf Where the results should be placed + * @param[in] len The number of bytes to read + * + */ +typedef size_t (*gdispImageIOReadFn)(struct gdispImageIO *pio, void *buf, size_t len); + +/** + * @brief An image IO seek function + * + * @param[in] pio Pointer to the io structure + * @param[in] pos Which byte to seek to relative to the start of the "file". + * + */ +typedef void (*gdispImageIOSeekFn)(struct gdispImageIO *pio, size_t pos); + +typedef struct gdispImageIOFunctions { + gdispImageIOReadFn read; /* @< The function to read input */ + gdispImageIOSeekFn seek; /* @< The function to seek input */ + gdispImageIOCloseFn close; /* @< The function to close input */ + } gdispImageIOFunctions; + +/** + * @brief The structure defining the IO routines for image handling + */ +typedef struct gdispImageIO { + const void * fd; /* @< The "file" descriptor */ + size_t pos; /* @< The current "file" position */ + const gdispImageIOFunctions *fns; /* @< The current "file" functions */ +} gdispImageIO; + +/** + * @brief The structure for an image + */ +typedef struct gdispImage { + gdispImageType type; /* @< The image type */ + gdispImageFlags flags; /* @< The image flags */ + color_t bgcolor; /* @< The default background color */ + coord_t width, height; /* @< The image dimensions */ + GFILE * f; /* @< The underlying GFILE */ + #if GDISP_NEED_IMAGE_ACCOUNTING + uint32_t memused; /* @< How much RAM is currently allocated */ + uint32_t maxmemused; /* @< How much RAM has been allocated (maximum) */ + #endif + const struct gdispImageHandlers * fns; /* @< Don't mess with this! */ + struct gdispImagePrivate * priv; /* @< Don't mess with this! */ +} gdispImage; + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Deprecated Functions. + */ + gdispImageError DEPRECATED("Use gdispImageOpenGFile() instead") gdispImageOpen(gdispImage *img); + bool_t DEPRECATED("Use gdispImageOpenMemory() instead") gdispImageSetMemoryReader(gdispImage *img, const void *memimage); + #if GFX_USE_OS_CHIBIOS + bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr); + #endif + #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX + bool_t DEPRECATED("Please use gdispImageOpenFile() instead") gdispImageSetFileReader(gdispImage *img, const char *filename); + #define gdispImageSetSimulFileReader(img, fname) gdispImageSetFileReader(img, fname) + #endif + + /** + * @brief Open an image using an open GFILE and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @param[in] img The image structure + * @param[in] f The open GFILE stream. + * + * @pre The GFILE must be open for reading. + * + * @note This determines which decoder to use and then initialises all other fields + * in the gdispImage structure. + * @note The image background color is set to White. + * @note There are three types of return - everything OK, partial success and unrecoverable + * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can + * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE + * bit in the error code. + * A partial success return code means an image can still be drawn but perhaps with + * reduced functionality eg only the first page of a multi-page image. + * @note @p gdispImageClose() should be called when finished with the image. This will close + * the image and its underlying GFILE file. Note that images opened with partial success + * (eg GDISP_IMAGE_ERR_UNSUPPORTED_OK) + * still need to be closed when you are finished with them. + */ + gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *f); + + /** + * @brief Open an image in a file and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre You must have included the file-system support into GFILE that you want to use. + * + * @param[in] img The image structure + * @param[in] filename The filename to open + * + * @note This function just opens the GFILE using the filename and passes it to @p gdispImageOpenGFile(). + */ + #define gdispImageOpenFile(img, filename) gdispImageOpenGFile((img), gfileOpen((filename), "rb")) + + /** + * @brief Open an image in a ChibiOS basefilestream and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre GFILE_NEED_CHIBIOSFS and GFX_USE_OS_CHIBIOS must be TRUE. This only makes sense on the ChibiOS + * operating system. + * + * @param[in] img The image structure + * @param[in] BaseFileStreamPtr A pointer to an open BaseFileStream + * + * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile(). + */ + #define gdispImageOpenBaseFileStream(img, BaseFileStreamPtr) gdispImageOpenGFile((img), gfileOpenBaseFileStream((BaseFileStreamPtr), "rb")) + + /** + * @brief Open an image in memory and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre GFILE_NEED_MEMFS must be TRUE + * + * @param[in] img The image structure + * @param[in] ptr A pointer to the image bytes in memory + * + * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile(). + */ + #define gdispImageOpenMemory(img, ptr) gdispImageOpenGFile((img), gfileOpenMemory((void *)(ptr), "rb")) + + /** + * @brief Close an image and release any dynamically allocated working storage. + * + * @param[in] img The image structure + * + * @pre gdispImageOpenFile() must have returned successfully. + * + * @note Also calls the IO close function (if it hasn't already been called). + */ + void gdispImageClose(gdispImage *img); + + /** + * @brief Is an image open. + * @return TRUE if the image is currently open. + * + * @param[in] img The image structure + * + * @note Be careful with calling this on an uninitialized image structure as the image + * will contain random data which may be interpreted as meaning the image + * is open. Clearing the Image structure to 0's will guarantee the image + * is seen as being closed. + */ + bool_t gdispImageIsOpen(gdispImage *img); + + /** + * @brief Set the background color of the image. + * + * @param[in] img The image structure + * @param[in] bgcolor The background color to use + * + * @pre gdispImageOpen() must have returned successfully. + * + * @note This color is only used when an image has to restore part of the background before + * continuing with drawing that includes transparency eg some GIF animations. + */ + void gdispImageSetBgColor(gdispImage *img, color_t bgcolor); + + /** + * @brief Cache the image + * @details Decodes and caches the current frame into RAM. + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @param[in] img The image structure + * + * @pre gdispImageOpen() must have returned successfully. + * + * @note This can use a LOT of RAM! + * @note The decoder may choose to ignore the request for caching. If it does so it will + * return GDISP_IMAGE_ERR_UNSUPPORTED_OK. + * @note A fatal error here does not necessarily mean that drawing the image will fail. For + * example, a GDISP_IMAGE_ERR_NOMEMORY error simply means there isn't enough RAM to + * cache the image. + */ + gdispImageError gdispImageCache(gdispImage *img); + + /** + * @brief Draw the image + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @param[in] g The display to draw on + * @param[in] img The image structure + * @param[in] x,y The screen location to draw the image + * @param[in] cx,cy The area on the screen to draw + * @param[in] sx,sy The image position to start drawing at + * + * @pre gdispImageOpen() must have returned successfully. + * + * @note If sx,sy + cx,cy is outside the image boundaries the area outside the image + * is simply not drawn. + * @note If @p gdispImageCache() has been called first for this frame, this routine will draw using a + * fast blit from the cached frame. If not, it reads the input and decodes it as it + * is drawing. This may be significantly slower than if the image has been cached (but + * uses a lot less RAM) + */ + gdispImageError gdispGImageDraw(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + #define gdispImageDraw(img,x,y,cx,cy,sx,sy) gdispGImageDraw(GDISP,img,x,y,cx,cy,sx,sy) + + /** + * @brief Prepare for the next frame/page in the image file. + * @return A time in milliseconds to keep displaying the current frame before trying to draw + * the next frame. Watch out for the special values TIME_IMMEDIATE and TIME_INFINITE. + * + * @param[in] img The image structure + * + * @pre gdispImageOpen() must have returned successfully. + * + * @note It will return TIME_IMMEDIATE if the first frame/page hasn't been drawn or if the next frame + * should be drawn immediately. + * @note It will return TIME_INFINITE if another image frame doesn't exist or an error has occurred. + * @note Images that support multiple pages (eg TIFF files) will return TIME_IMMEDIATE between pages + * and then TIME_INFINITE when there are no more pages. + * @note An image that displays a looped animation will never return TIME_INFINITE unless it + * gets an error. + * @note Calling gdispImageDraw() after getting a TIME_INFINITE will go back to drawing the first + * frame/page. + */ + delaytime_t gdispImageNext(gdispImage *img); + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */ +#endif /* _GDISP_IMAGE_H */ +/** @} */ + diff --git a/src/gdisp/mcufont/mf_config.h b/src/gdisp/mcufont/mf_config.h index 36268c6b..88838c1d 100644 --- a/src/gdisp/mcufont/mf_config.h +++ b/src/gdisp/mcufont/mf_config.h @@ -14,7 +14,7 @@ * Configuration settings related to GFX * *******************************************************/ -#include <gfx.h> +#include "gfx.h" #if !GFX_USE_GDISP || !GDISP_NEED_TEXT #define MF_NO_COMPILE // Don't compile any font code @@ -31,7 +31,7 @@ #endif #define MF_USE_KERNING GDISP_NEED_TEXT_KERNING -#define MF_FONT_FILE_NAME "../src/gdisp/fonts/fonts.h" +#define MF_FONT_FILE_NAME "src/gdisp/fonts/fonts.h" /* These are not used for now */ #define MF_USE_ADVANCED_WORDWRAP 0 diff --git a/src/gdisp/sys_defs.h b/src/gdisp/sys_defs.h new file mode 100644 index 00000000..a40d6e80 --- /dev/null +++ b/src/gdisp/sys_defs.h @@ -0,0 +1,994 @@ +/* + * 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/sys_defs.h + * @brief GDISP Graphic Driver subsystem header file. + * + * @addtogroup GDISP + * + * @brief Module to interface graphic / pixel oriented displays + * + * @details The GDISP module provides high level abstraction to interface pixel oriented graphic displays. + * + * @pre GFX_USE_GDISP must be set to TRUE in gfxconf.h + * + * @note Each drawing routine supports a gispXXXX and a gdispGXXXX function. The difference is that the + * gdispXXXX function does not require a display to be specified. Note there is a slight anomoly + * in the naming with gdispGBlitArea() vs gdispBlitAreaEx() and gdispBlitArea(), the later of + * which is now deprecated. + * @{ + */ + +#ifndef _GDISP_H +#define _GDISP_H + +#include "gfx.h" + +/* This type definition is defined here as it gets used in other gfx sub-systems even + * if GFX_USE_GDISP is FALSE. + */ + +/** + * @brief The type for a coordinate or length on the screen. + */ +typedef int16_t coord_t; + +#if GFX_USE_GDISP || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Type definitions */ +/*===========================================================================*/ + +/** + * @brief Type for a 2D point on the screen. + */ +typedef struct point { coord_t x, y; } point, point_t; +/** + * @brief Type for the text justification. + */ +typedef enum justify { justifyLeft=0, justifyCenter=1, justifyRight=2 } justify_t; +/** + * @brief Type for the font metric. + */ +typedef enum fontmetric { fontHeight, fontDescendersHeight, fontLineSpacing, fontCharPadding, fontMinWidth, fontMaxWidth } fontmetric_t; +/** + * @brief The type of a font. + */ +typedef const struct mf_font_s* font_t; +/** + * @brief Type for the screen orientation. + * @note GDISP_ROTATE_LANDSCAPE and GDISP_ROTATE_PORTRAIT are internally converted to the + * most appropriate other orientation. + */ +typedef enum orientation { GDISP_ROTATE_0=0, GDISP_ROTATE_90=90, GDISP_ROTATE_180=180, GDISP_ROTATE_270=270, GDISP_ROTATE_PORTRAIT=1000, GDISP_ROTATE_LANDSCAPE=1001 } orientation_t; +/** + * @brief Type for the available power modes for the screen. + */ +typedef enum powermode { powerOff, powerSleep, powerDeepSleep, powerOn } powermode_t; + +/* + * This is not documented in Doxygen as it is meant to be a black-box. + * Applications should always use the routines and macros defined + * below to access it in case the implementation ever changed. + */ +typedef struct GDISPControl { + coord_t Width; + coord_t Height; + orientation_t Orientation; + powermode_t Powermode; + uint8_t Backlight; + uint8_t Contrast; +} GDISPControl; + +/* + * Our black box display structure. We know only one thing about it... + * The first member is a GDISPControl structure. + */ +typedef struct GDisplay GDisplay; + +/** + * @brief The default screen to use for the gdispXXXX calls. + * @note This is set by default to the first display in the system. You can change + * it by calling @p gdispGSetDisplay(). + */ +extern GDisplay *GDISP; + +/*===========================================================================*/ +/* Constants. */ +/*===========================================================================*/ + +/** + * @brief Driver Control Constants + * @details Unsupported control codes are ignored. + * @note The value parameter should always be typecast to (void *). + * @note There are some predefined and some specific to the low level driver. + * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t + * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t + * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver + * that only supports off/on anything other + * than zero is on. + * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. + * GDISP_CONTROL_LLD - Low level driver control constants start at + * this value. + */ +#define GDISP_CONTROL_POWER 0 +#define GDISP_CONTROL_ORIENTATION 1 +#define GDISP_CONTROL_BACKLIGHT 2 +#define GDISP_CONTROL_CONTRAST 3 +#define GDISP_CONTROL_LLD 1000 + +/*===========================================================================*/ +/* Defines relating to the display hardware */ +/*===========================================================================*/ + +#if !defined(GDISP_TOTAL_CONTROLLERS) || GDISP_TOTAL_CONTROLLERS == 1 + // Pull in the default hardware configuration for a single controller. + // If we have multiple controllers the settings must be set in the + // users gfxconf.h file. + #include "gdisp_lld_config.h" + + // Unless the user has specified a specific pixel format, use + // the native format for the controller. + #if !defined(GDISP_PIXELFORMAT) && defined(GDISP_LLD_PIXELFORMAT) + #define GDISP_PIXELFORMAT GDISP_LLD_PIXELFORMAT + #endif +#endif + +/** + * @name GDISP pixel format choices + * @{ + */ + /** + * @brief The pixel format. + * @details It generally defaults to the hardware pixel format. + * @note This doesn't need to match the hardware pixel format. + * It is definitely more efficient when it does. + * @note When GDISP_TOTAL_CONTROLLERS > 1, this must + * be explicitly defined and should ensure the best match + * with your hardware across all devices. + */ + #ifndef GDISP_PIXELFORMAT + #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR + #endif + /** + * @brief Do pixels require packing for a blit + * @note Is only valid for a pixel format that doesn't fill it's datatype. eg formats: + * GDISP_PIXELFORMAT_RGB888 + * GDISP_PIXELFORMAT_RGB444 + * GDISP_PIXELFORMAT_RGB666 + * GDISP_PIXELFORMAT_CUSTOM + * @note Very few cases should actually require packed pixels as the low + * level driver can also pack on the fly as it is sending it + * to the graphics device. + * @note Packed pixels are not really supported at this point. + */ + #ifndef GDISP_PACKED_PIXELS + #define GDISP_PACKED_PIXELS FALSE + #endif + + /** + * @brief Do lines of pixels require packing for a blit + * @note Ignored if GDISP_PACKED_PIXELS is FALSE + */ + #ifndef GDISP_PACKED_LINES + #define GDISP_PACKED_LINES FALSE + #endif +/** @} */ + +/*===========================================================================*/ +/* Defines related to the pixel format */ +/*===========================================================================*/ + +/* Load our color definitions and pixel formats */ +#include "colors.h" + +/** + * @brief The type of a pixel. + */ +typedef color_t pixel_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Base Functions */ + +/** + * @brief Blend 2 colors according to the alpha + * @return The combined color + * + * @param[in] fg The foreground color + * @param[in] bg The background color + * @param[in] alpha The alpha value (0-255). 0 is all background, 255 is all foreground. + * + * @api + */ +color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha); + +/** + * @brief Get the specified display + * @return The pointer to the display or NULL if the display doesn't exist + * @note The GDISP variable contains the display used by the gdispXxxx routines + * as opposed to the gdispGXxxx routines which take an explicit display + * parameter. + * @note Displays are numbered from 0 to GDISP_TOTAL_DISPLAYS - 1 + * + * @param[in] display The display number (0..n) + * + * @api + */ +GDisplay *gdispGetDisplay(unsigned display); + +/** + * @brief Set the current default display to the specified display + * @note The default display is used for the gdispXxxx functions. + * @note The default display is contained in the variable GDISP. Using + * this function to set it protects against it being set to a NULL + * value. + * @note If a NULL is passed for the dispay this call is ignored. + * + * @param[in] g The display to use + * + * @api + */ +void gdispSetDisplay(GDisplay *g); + +/* Drawing Functions */ + +/** + * @brief Flush current drawing operations to the display + * @note Some low level drivers do not update the display until + * the display is flushed. For others it is optional but can + * help prevent tearing effects. For some it is ignored. + * Calling it at the end of a logic set of drawing operations + * in your application will ensure controller portability. If you + * know your controller does not need to be flushed there is no + * need to call it (which is in reality most controllers). + * @note Even for displays that require flushing, there is no need to + * call this function if GDISP_NEED_AUTOFLUSH is TRUE. + * Calling it again won't hurt though. + * + * + * @param[in] g The display to use + * + * @api + */ +void gdispGFlush(GDisplay *g); +#define gdispFlush() gdispGFlush(GDISP) + +/** + * @brief Clear the display to the specified color. + * + * @param[in] g The display to use + * @param[in] color The color to use when clearing the screen + * + * @api + */ +void gdispGClear(GDisplay *g, color_t color); +#define gdispClear(c) gdispGClear(GDISP, c) + +/** + * @brief Set a pixel in the specified color. + * + * @param[in] g The display to use + * @param[in] x,y The position to set the pixel. + * @param[in] color The color to use + * + * @api + */ +void gdispGDrawPixel(GDisplay *g, coord_t x, coord_t y, color_t color); +#define gdispDrawPixel(x,y,c) gdispGDrawPixel(GDISP,x,y,c) + +/** + * @brief Draw a line. + * + * @param[in] g The display to use + * @param[in] x0,y0 The start position + * @param[in] x1,y1 The end position + * @param[in] color The color to use + * + * @api + */ +void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color); +#define gdispDrawLine(x0,y0,x1,y1,c) gdispGDrawLine(GDISP,x0,y0,x1,y1,c) + +/** + * @brief Fill an area with a color. + * + * @param[in] g The display to use + * @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 + * + * @api + */ +void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); +#define gdispFillArea(x,y,cx,cy,c) gdispGFillArea(GDISP,x,y,cx,cy,c) + +/** + * @brief Fill an area using the supplied bitmap. + * @details The bitmap is in the pixel format specified by the low level driver + * @note If a packed pixel format is used and the width doesn't + * match a whole number of bytes, the next line will start on a + * non-byte boundary (no end-of-line padding). + * @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. + * + * @param[in] g The display to use + * @param[in] x,y The start position + * @param[in] cx,cy The size of the filled area + * @param[in] srcx,srcy The bitmap position to start the fill form + * @param[in] srccx The width of a line in the bitmap + * @param[in] buffer The bitmap in the driver's pixel format + * + * @api + */ +void gdispGBlitArea(GDisplay *g, 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 gdispBlitAreaEx(x,y,cx,cy,sx,sy,rx,b) gdispGBlitArea(GDISP,x,y,cx,cy,sx,sy,rx,b) + +/** + * @brief Draw a rectangular box. + * + * @param[in] g The display to use + * @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 + * + * @api + */ +void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); +#define gdispDrawBox(x,y,cx,cy,c) gdispGDrawBox(GDISP,x,y,cx,cy,c) + +/* Streaming Functions */ + +#if GDISP_NEED_STREAMING || defined(__DOXYGEN__) + /** + * @brief Start a streaming operation. + * @details Stream data to a window on the display sequentially and very fast. + * @note While streaming is in operation - no other calls to GDISP functions + * can be made (with the exception of @p gdispBlendColor() and streaming + * functions). If a call is made (eg in a multi-threaded application) the other + * call is blocked waiting for the streaming operation to finish. + * @note @p gdispStreamStop() must be called to finish the streaming operation. + * @note If more data is written than the defined area then the results are unspecified. + * Some drivers may wrap back to the beginning of the area, others may just + * ignore subsequent data. + * @note Unlike most operations that clip the defined area to the display to generate + * a smaller active area, this call will just silently fail if any of the stream + * region lies outside the current clipping area. + * @note A streaming operation may be terminated early (without writing to every location + * in the stream area) by calling @p gdispStreamStop(). + * + * @param[in] g The display to use + * @param[in] x,y The start position + * @param[in] cx,cy The size of the streamable area + * + * @api + */ + void gdispGStreamStart(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy); + #define gdispStreamStart(x,y,cx,cy) gdispGStreamStart(GDISP,x,y,cx,cy) + + /** + * @brief Send pixel data to the stream. + * @details Write a pixel to the next position in the streamed area and increment the position + * @pre @p gdispStreamStart() has been called. + * @note If the gdispStreamStart() has not been called (or failed due to clipping), the + * data provided here is simply thrown away. + * + * @param[in] g The display to use + * @param[in] color The color of the pixel to write + * + * @api + */ + void gdispGStreamColor(GDisplay *g, color_t color); + #define gdispStreamColor(c) gdispGStreamColor(GDISP,c) + + /** + * @brief Finish the current streaming operation. + * @details Completes the current streaming operation and allows other GDISP calls to operate again. + * @pre @p gdispStreamStart() has been called. + * @note If the gdispStreamStart() has not been called (or failed due to clipping), this + * call is simply ignored. + * + * @param[in] g The display to use + * + * @api + */ + void gdispGStreamStop(GDisplay *g); + #define gdispStreamStop() gdispGStreamStop(GDISP) +#endif + +/* Clipping Functions */ + +#if GDISP_NEED_CLIP || defined(__DOXYGEN__) + /** + * @brief Clip all drawing to the defined area. + * + * @param[in] g The display to use + * @param[in] x,y The start position + * @param[in] cx,cy The size of the clip area + * + * @api + */ + void gdispGSetClip(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy); + #define gdispSetClip(x,y,cx,cy) gdispGSetClip(GDISP,x,y,cx,cy) +#endif + +/* Circle Functions */ + +#if GDISP_NEED_CIRCLE || defined(__DOXYGEN__) + /** + * @brief Draw a circle. + * + * @param[in] g The display to use + * @param[in] x,y The center of the circle + * @param[in] radius The radius of the circle + * @param[in] color The color to use + * + * @api + */ + void gdispGDrawCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color); + #define gdispDrawCircle(x,y,r,c) gdispGDrawCircle(GDISP,x,y,r,c) + + /** + * @brief Draw a filled circle. + * + * @param[in] g The display to use + * @param[in] x,y The center of the circle + * @param[in] radius The radius of the circle + * @param[in] color The color to use + * + * @api + */ + void gdispGFillCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color); + #define gdispFillCircle(x,y,r,c) gdispGFillCircle(GDISP,x,y,r,c) +#endif + +/* Ellipse Functions */ + +#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__) + /** + * @brief Draw an ellipse. + * + * @param[in] g The display to use + * @param[in] x,y The center of the ellipse + * @param[in] a,b The dimensions of the ellipse + * @param[in] color The color to use + * + * @api + */ + void gdispGDrawEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color); + #define gdispDrawEllipse(x,y,a,b,c) gdispGDrawEllipse(GDISP,x,y,a,b,c) + + /** + * @brief Draw a filled ellipse. + * + * @param[in] g The display to use + * @param[in] x,y The center of the ellipse + * @param[in] a,b The dimensions of the ellipse + * @param[in] color The color to use + * + * @api + */ + void gdispGFillEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color); + #define gdispFillEllipse(x,y,a,b,c) gdispGFillEllipse(GDISP,x,y,a,b,c) +#endif + +/* Arc Functions */ + +#if GDISP_NEED_ARC || defined(__DOXYGEN__) + /* + * @brief Draw an arc. + * + * @param[in] g The display to use + * @param[in] x0,y0 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) + * @param[in] color The color of the arc + * + * @api + */ + void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color); + #define gdispDrawArc(x,y,r,s,e,c) gdispGDrawArc(GDISP,x,y,r,s,e,c) + + /* + * @brief Draw a filled arc. + * @note Not very efficient currently - does lots of overdrawing + * + * @param[in] g The display to use + * @param[in] x0,y0 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) + * @param[in] color The color of the arc + * + * @api + */ + void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color); + #define gdispFillArc(x,y,r,s,e,c) gdispGFillArc(GDISP,x,y,r,s,e,c) +#endif + +/* Read a pixel Function */ + +#if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__) + /** + * @brief Get the color of a pixel. + * @return The color of the pixel. + * + * @param[in] g The display to use + * @param[in] x,y The position of the pixel + * + * @api + */ + color_t gdispGGetPixelColor(GDisplay *g, coord_t x, coord_t y); + #define gdispGetPixelColor(x,y) gdispGGetPixelColor(GDISP,x,y) +#endif + +/* Scrolling Function - clears the area scrolled out */ + +#if GDISP_NEED_SCROLL || defined(__DOXYGEN__) + /** + * @brief Scroll vertically a section of the screen. + * @pre GDISP_NEED_SCROLL must be set to TRUE in gfxconf.h + * @note Optional. + * @note If lines is >= cy, it is equivelent to a area fill with bgcolor. + * + * @param[in] g The display to use + * @param[in] x, y The start of the area to be scrolled + * @param[in] cx, cy The size of the area to be scrolled + * @param[in] lines The number of lines to scroll (Can be positive or negative) + * @param[in] bgcolor The color to fill the newly exposed area. + * + * @api + */ + void gdispGVerticalScroll(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor); + #define gdispVerticalScroll(x,y,cx,cy,l,b) gdispGVerticalScroll(GDISP,x,y,cx,cy,l,b) +#endif + +/* Set driver specific control */ + +#if GDISP_NEED_CONTROL || defined(__DOXYGEN__) + /** + * @brief Control hardware specific parts of the display. eg powermodes, backlight etc + * @note Depending on the hardware implementation this function may not + * support some codes. They will be ignored. + * + * @param[in] g The display to use + * @param[in] what what you want to control + * @param[in] value The value to be assigned + * + * @api + */ + void gdispGControl(GDisplay *g, unsigned what, void *value); + #define gdispControl(w,v) gdispGControl(GDISP,w,v) +#endif + +/* Query driver specific data */ + +#if GDISP_NEED_QUERY || defined(__DOXYGEN__) + /** + * @brief Query a property of the display. + * @note The result must be typecast to the correct type. + * @note An unsupported query will return (void *)-1. + * + * @param[in] g The display to use + * @param[in] what What to query + * + * @api + */ + void *gdispGQuery(GDisplay *g, unsigned what); + #define gdispQuery(w) gdispGQuery(GDISP,w) +#endif + +#if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__) + /** + * @brief Draw an enclosed polygon (convex, non-convex or complex). + * + * @param[in] g The display to use + * @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 + * @param[in] color The color to use + * + * @api + */ + void gdispGDrawPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color); + #define gdispDrawPoly(x,y,p,i,c) gdispGDrawPoly(GDISP,x,y,p,i,c) + + /** + * @brief Fill a convex polygon + * @details Doesn't handle non-convex or complex polygons. + * + * @param[in] g The display to use + * @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 + * @param[in] color The color to use + * + * @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 gdispGFillConvexPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color); + #define gdispFillConvexPoly(x,y,p,i,c) gdispGFillConvexPoly(GDISP,x,y,p,i,c) + + /** + * @brief Draw a line with a specified thickness + * @details The line thickness is specified in pixels. The line ends can + * be selected to be either flat or round. + * @note Uses gdispGFillConvexPoly() internally to perform the drawing. + * + * @param[in] g The display to use + * @param[in] x0,y0 The start position + * @param[in] x1,y1 The end position + * @param[in] color The color to use + * @param[in] width The width of the line + * @param[in] round Use round ends for the line + * + * @api + */ + void gdispGDrawThickLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color, coord_t width, bool_t round); + #define gdispDrawThickLine(x0,y0,x1,y1,c,w,r) gdispGDrawThickLine(GDISP,x0,y0,x1,y1,c,w,r) +#endif + +/* Text Functions */ + +#if GDISP_NEED_TEXT || defined(__DOXYGEN__) + /** + * @brief Draw a text character. + * + * @param[in] g The display to use + * @param[in] x,y The position for the text + * @param[in] c The character to draw + * @param[in] font The font to use + * @param[in] color The color to use + * + * @api + */ + void gdispGDrawChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color); + #define gdispDrawChar(x,y,s,f,c) gdispGDrawChar(GDISP,x,y,s,f,c) + + /** + * @brief Draw a text character with a filled background. + * + * @param[in] g The display to use + * @param[in] x,y The position for the text + * @param[in] c The character to draw + * @param[in] font The font to use + * @param[in] color The color to use + * @param[in] bgcolor The background color to use + * + * @api + */ + void gdispGFillChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor); + #define gdispFillChar(x,y,s,f,c,b) gdispGFillChar(GDISP,x,y,s,f,c,b) + + /** + * @brief Draw a text string. + * + * @param[in] g The display to use + * @param[in] x,y The position for the text + * @param[in] str The string to draw + * @param[in] font The font to use + * @param[in] color The color to use + * + * @api + */ + void gdispGDrawString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color); + #define gdispDrawString(x,y,s,f,c) gdispGDrawString(GDISP,x,y,s,f,c) + + /** + * @brief Draw a text string. + * + * @param[in] g The display to use + * @param[in] x,y The position for the text + * @param[in] str The string to draw + * @param[in] font The font to use + * @param[in] color The color to use + * @param[in] bgcolor The background color to use + * + * @api + */ + void gdispGFillString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor); + #define gdispFillString(x,y,s,f,c,b) gdispGFillString(GDISP,x,y,s,f,c,b) + + /** + * @brief Draw a text string vertically centered within the specified box. + * + * @param[in] g The display to use + * @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] font The font to use + * @param[in] color The color to use + * @param[in] justify Justify the text left, center or right within the box + * + * @api + */ + void gdispGDrawStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify); + #define gdispDrawStringBox(x,y,cx,cy,s,f,c,j) gdispGDrawStringBox(GDISP,x,y,cx,cy,s,f,c,j) + + /** + * @brief Draw a text string vertically centered within the specified box. The box background is filled with the specified background color. + * @note The entire box is filled + * + * @param[in] g The display to use + * @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] font The font to use + * @param[in] color The color to use + * @param[in] bgColor The background color to use + * @param[in] justify Justify the text left, center or right within the box + * + * @api + */ + void gdispGFillStringBox(GDisplay *g, 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); + #define gdispFillStringBox(x,y,cx,cy,s,f,c,b,j) gdispGFillStringBox(GDISP,x,y,cx,cy,s,f,c,b,j) + + /** + * @brief Get a metric of a font. + * @return The metric requested in pixels. + * + * @param[in] font The font to test + * @param[in] metric The metric to measure + * + * @api + */ + coord_t gdispGetFontMetric(font_t font, fontmetric_t metric); + + /** + * @brief Get the pixel width of a character. + * @return The width of the character in pixels. Does not include any between character padding. + * + * @param[in] c The character to draw + * @param[in] font The font to use + * + * @api + */ + coord_t gdispGetCharWidth(char c, font_t font); + + /** + * @brief Get the pixel width of a string. + * @return The width of the string in pixels. + * + * @param[in] str The string to measure + * @param[in] font The font to use + * + * @api + */ + coord_t gdispGetStringWidth(const char* str, font_t font); + + /** + * @brief Find a font and return it. + * @details The supplied name is matched against the font name. A '*' will replace 0 or more characters. + * @return Returns a font or NULL if no matching font could be found. + * + * @param[in] name The font name to find. + * + * @note Wildcard matching will match the shortest possible match. + * + * @api + */ + font_t gdispOpenFont(const char *name); + + /** + * @brief Release a font after use. + * + * @param[in] font The font to release. + * + * @api + */ + void gdispCloseFont(font_t font); + + /** + * @brief Make a scaled copy of an existing font. + * @details Allocates memory for new font metadata using gfxAlloc, remember to close font after use! + * @return A new font or NULL if out of memory. + * + * @param[in] font The base font to use. + * @param[in] scale_x The scale factor in horizontal direction. + * @param[in] scale_y The scale factor in vertical direction. + */ + font_t gdispScaleFont(font_t font, uint8_t scale_x, uint8_t scale_y); + + /** + * @brief Get the name of the specified font. + * @returns The name of the font. + * + * @param[in] font The font to get the name for. + * + * @api + */ + const char *gdispGetFontName(font_t font); +#endif + +/* Extra Arc Functions */ + +#if GDISP_NEED_ARC || defined(__DOXYGEN__) + /** + * @brief Draw a rectangular box with rounded corners + * + * @param[in] g The display to use + * @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 gdispGDrawRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color); + #define gdispDrawRoundedBox(x,y,cx,cy,r,c) gdispGDrawRoundedBox(GDISP,x,y,cx,cy,r,c) + + /** + * @brief Draw a filled rectangular box with rounded corners + * + * @param[in] g The display to use + * @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 gdispGFillRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color); + #define gdispFillRoundedBox(x,y,cx,cy,r,c) gdispGFillRoundedBox(GDISP,x,y,cx,cy,r,c) +#endif + +/* + * Macro definitions + */ + +/* Now obsolete functions */ +#define gdispBlitArea(x, y, cx, cy, buffer) gdispGBlitArea(GDISP, x, y, cx, cy, 0, 0, cx, buffer) + +/* Macro definitions for common gets and sets */ + +/** + * @brief Set the display power mode. + * @note Ignored if not supported by the display. + * + * @param[in] g The display to use + * @param[in] powerMode The new power mode + * + * @api + */ +#define gdispGSetPowerMode(g, powerMode) gdispGControl((g), GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode)) +#define gdispSetPowerMode(powerMode) gdispGControl(GDISP, GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode)) + +/** + * @brief Set the display orientation. + * @note Ignored if not supported by the display. + * + * @param[in] g The display to use + * @param[in] newOrientation The new orientation + * + * @api + */ +#define gdispGSetOrientation(g, newOrientation) gdispGControl((g), GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation)) +#define gdispSetOrientation(newOrientation) gdispGControl(GDISP, GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation)) + +/** + * @brief Set the display backlight. + * @note Ignored if not supported by the display. + * + * @param[in] g The display to use + * @param[in] percent The new brightness (0 - 100%) + * + * @note For displays that only support backlight off and on, + * 0 = off, anything else = on + * + * @api + */ +#define gdispGSetBacklight(g, percent) gdispGControl((g), GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent)) +#define gdispSetBacklight(percent) gdispGControl(GDISP, GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent)) + +/** + * @brief Set the display contrast. + * @note Ignored if not supported by the display. + * + * @param[in] g The display to use + * @param[in] percent The new contrast (0 - 100%) + * + * @api + */ +#define gdispGSetContrast(g, percent) gdispGControl((g), GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent)) +#define gdispSetContrast(percent) gdispGControl(GDISP, GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent)) + +/** + * @brief Get the display width in pixels. + * + * @param[in] g The display to use + * + * @api + */ +#define gdispGGetWidth(g) (((GDISPControl *)(g))->Width) +#define gdispGetWidth() gdispGGetWidth(GDISP) + +/** + * @brief Get the display height in pixels. + * + * @param[in] g The display to use + * + * @api + */ +#define gdispGGetHeight(g) (((GDISPControl *)(g))->Height) +#define gdispGetHeight() gdispGGetHeight(GDISP) + +/** + * @brief Get the current display power mode. + * + * @param[in] g The display to use + * + * @api + */ +#define gdispGGetPowerMode(g) (((GDISPControl *)(g))->Powermode) +#define gdispGetPowerMode() gdispGGetPowerMode(GDISP) + +/** + * @brief Get the current display orientation. + * + * @param[in] g The display to use + * + * @api + */ +#define gdispGGetOrientation(g) (((GDISPControl *)(g))->Orientation) +#define gdispGetOrientation() gdispGGetOrientation(GDISP) + +/** + * @brief Get the current display backlight brightness. + * + * @param[in] g The display to use + * + * @api + */ +#define gdispGGetBacklight(g) (((GDISPControl *)(g))->Backlight) +#define gdispGetBacklight() gdispGGetBacklight(GDISP) + +/** + * @brief Get the current display contrast. + * + * @param[in] g The display to use + * + * @api + */ +#define gdispGGetContrast(g) (((GDISPControl *)(g))->Contrast) +#define gdispGetContrast() gdispGGetContrast(GDISP) + +/* More interesting macro's */ + +/** + * @brief Reset the clip area to the full screen + * + * @param[in] g The display to use + * + * @api + */ +#define gdispGUnsetClip(g) gdispGSetClip((g),0,0,gdispGGetWidth(g),gdispGGetHeight(g)) +#define gdispUnsetClip() gdispGUnsetClip(GDISP) + +#ifdef __cplusplus +} +#endif + +#if GDISP_NEED_IMAGE || defined(__DOXYGEN__) + #include "src/gdisp/image.h" +#endif + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_H */ +/** @} */ diff --git a/src/gdisp/gdisp.mk b/src/gdisp/sys_make.mk index a133ce37..a133ce37 100644 --- a/src/gdisp/gdisp.mk +++ b/src/gdisp/sys_make.mk diff --git a/src/gdisp/sys_options.h b/src/gdisp/sys_options.h new file mode 100644 index 00000000..a38e4c6f --- /dev/null +++ b/src/gdisp/sys_options.h @@ -0,0 +1,381 @@ +/* + * 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/sys_options.h + * @brief GDISP sub-system options header file. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_OPTIONS_H +#define _GDISP_OPTIONS_H + +/** + * @name GDISP Functionality to be included + * @{ + */ + /** + * @brief Should the startup logo be displayed + * + * @details Defaults to TRUE + */ + #ifndef GDISP_NEED_STARTUP_LOGO + #define GDISP_NEED_STARTUP_LOGO TRUE + #endif + /** + * @brief Should drawing operations be automatically flushed. + * @details Defaults to FALSE + * @note If set to FALSE and the controller requires flushing + * then the application must manually call @p gdispGFlush(). + * Setting this to TRUE causes GDISP to automatically flush + * after each drawing operation. Note this may be slow but enables + * an application to avoid having to manually call the flush routine. + * @note If TRUE and GDISP_NEED_TIMERFLUSH is also TRUE, this takes precedence. + * @note Most controllers don't need flushing which is why this is set to + * FALSE by default. + */ + #ifndef GDISP_NEED_AUTOFLUSH + #define GDISP_NEED_AUTOFLUSH FALSE + #endif + /** + * @brief Should drawing operations be automatically flushed on a timer. + * @details Defaults to FALSE, Can be set to FALSE or a timer period in milliseconds. + * @note The period should not be set too short or it will consume all your CPU. A + * value between 250 and 500 milliseconds would probably be suitable. + * @note If TRUE and GDISP_NEED_AUTOFLUSH is also TRUE, this is ineffective. + * @note Most controllers don't need flushing which is why this is set to + * FALSE by default. + */ + #ifndef GDISP_NEED_TIMERFLUSH + #define GDISP_NEED_TIMERFLUSH FALSE + #endif + /** + * @brief Should all operations be clipped to the screen and colors validated. + * @details Defaults to TRUE. + * @note If this is FALSE, any operations that extend beyond the + * edge of the screen will have undefined results. Any + * out-of-range colors will produce undefined results. + * @note This should always be left as the default (TRUE) unless you + * are a maniac for speed and you have thoroughly tested your code + * and it never overwrites the edges of the screen. + * @note Setting GDISP_NEED_CLIP to TRUE internally uses the same mechanism + * as this validation. There is no advantage in setting this FALSE if + * GDISP_NEED_CLIP is TRUE. + */ + #ifndef GDISP_NEED_VALIDATION + #define GDISP_NEED_VALIDATION TRUE + #endif + /** + * @brief Are clipping functions needed. + * @details Defaults to TRUE + */ + #ifndef GDISP_NEED_CLIP + #define GDISP_NEED_CLIP TRUE + #endif + /** + * @brief Streaming functions are needed + * @details Defaults to FALSE. + */ + #ifndef GDISP_NEED_STREAMING + #define GDISP_NEED_STREAMING FALSE + #endif + /** + * @brief Are text functions needed. + * @details Defaults to FALSE + * @note You must also define at least one font. + */ + #ifndef GDISP_NEED_TEXT + #define GDISP_NEED_TEXT FALSE + #endif + /** + * @brief Are circle functions needed. + * @details Defaults to FALSE + * @note Uses integer algorithms only. It does not use any trig or floating point. + */ + #ifndef GDISP_NEED_CIRCLE + #define GDISP_NEED_CIRCLE FALSE + #endif + /** + * @brief Are ellipse functions needed. + * @details Defaults to FALSE + * @note Uses integer algorithms only. It does not use any trig or floating point. + */ + #ifndef GDISP_NEED_ELLIPSE + #define GDISP_NEED_ELLIPSE FALSE + #endif + /** + * @brief Are arc functions needed. + * @details Defaults to FALSE + * @note This can be compiled using fully integer mathematics by + * defining GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG as TRUE. + * @note This can be compiled to use floating point but no trig functions + * by defining GFX_USE_GMISC and GMISC_NEED_FASTTRIG as TRUE. + * @note If neither of the above are defined it requires the maths library + * to be included in the link to provide floating point and trig support. + * ie include -lm in your compiler flags. + */ + #ifndef GDISP_NEED_ARC + #define GDISP_NEED_ARC FALSE + #endif + /** + * @brief Are convex polygon functions needed. + * @details Defaults to FALSE + * @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. + */ + #ifndef GDISP_NEED_CONVEX_POLYGON + #define GDISP_NEED_CONVEX_POLYGON FALSE + #endif + /** + * @brief Are scrolling functions needed. + * @details Defaults to FALSE + * @note This function must be supported by the low level GDISP driver + * you have included in your project. If it isn't, defining this + * option will cause a compile error. + */ + #ifndef GDISP_NEED_SCROLL + #define GDISP_NEED_SCROLL FALSE + #endif + /** + * @brief Is the capability to read pixels back needed. + * @details Defaults to FALSE + * @note This function must be supported by the low level GDISP driver + * you have included in your project. If it isn't, defining this + * option will cause a compile error. + */ + #ifndef GDISP_NEED_PIXELREAD + #define GDISP_NEED_PIXELREAD FALSE + #endif + /** + * @brief Control some aspect of the hardware operation. + * @details Defaults to FALSE + * @note This allows control of hardware specific features such as + * screen rotation, backlight levels, contrast etc + */ + #ifndef GDISP_NEED_CONTROL + #define GDISP_NEED_CONTROL FALSE + #endif + /** + * @brief Query some aspect of the hardware operation. + * @details Defaults to FALSE + * @note This allows query of hardware specific features + */ + #ifndef GDISP_NEED_QUERY + #define GDISP_NEED_QUERY FALSE + #endif + /** + * @brief Is the image interface required. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_IMAGE + #define GDISP_NEED_IMAGE FALSE + #endif +/** + * @} + * + * @name GDISP Multiple Display Support + * @{ + */ + /** + * @brief The total number of displays. + * @note This can be on just one type of controller or spread across several different controllers + */ + #ifndef GDISP_TOTAL_DISPLAYS + #define GDISP_TOTAL_DISPLAYS 1 + #endif + /** + * @brief The total number of controllers. + * @note If this is greater than one, all the hardware acceleration options below + * and the pixel format must be manually specified in your gfxconf.h along with + * @p GDISP_CONTROLLER_LIST. See the gdisp_lld_config.h in each driver to get a list + * of hardware capabilities for each driver in order to work out the common set across + * all the controllers you want to use. + */ + #ifndef GDISP_TOTAL_CONTROLLERS + #define GDISP_TOTAL_CONTROLLERS 1 + #endif + + #if defined(__DOXYGEN__) + /** + * @brief The list of controllers. + * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one. + * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS. + * @note See the gdisp_lld.c in each driver (near the top) to get the name of the VMT for a driver. + * @note Replace this example with your own definition in your gfxconf.h file. + */ + #define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_SSD1963 + /** + * @brief The number of displays for each controller. + * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one. + * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS. + * @note The sum of all the display counts must equal @p GDISP_TOTAL_DISPLAYS (3 for this example) + * or bad things will happen. + * @note Replace this example with your own definition in your gfxconf.h file. + */ + #define GDISP_CONTROLLER_DISPLAYS 2, 1 + #endif +/** + * @} + * + * @name GDISP Image Options + * @pre GDISP_NEED_IMAGE must be TRUE + * @{ + */ + /** + * @brief Is native image decoding required. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_IMAGE_NATIVE + #define GDISP_NEED_IMAGE_NATIVE FALSE + #endif + /** + * @brief Is GIF image decoding required. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_IMAGE_GIF + #define GDISP_NEED_IMAGE_GIF FALSE + #endif + /** + * @brief Is BMP image decoding required. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_IMAGE_BMP + #define GDISP_NEED_IMAGE_BMP FALSE + #endif + /** + * @brief Is JPG image decoding required. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_IMAGE_JPG + #define GDISP_NEED_IMAGE_JPG FALSE + #endif + /** + * @brief Is PNG image decoding required. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_IMAGE_PNG + #define GDISP_NEED_IMAGE_PNG FALSE + #endif + /** + * @brief Is memory accounting required during image decoding. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_IMAGE_ACCOUNTING + #define GDISP_NEED_IMAGE_ACCOUNTING FALSE + #endif +/** + * @} + * + * @name GDISP Text Rendering Options + * @{ + */ + /** + * @brief Enable UTF-8 support for text rendering. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_UTF8 + #define GDISP_NEED_UTF8 FALSE + #endif + + /** + * @brief Enable kerning for font rendering (improves character placement). + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_TEXT_KERNING + #define GDISP_NEED_TEXT_KERNING FALSE + #endif + + /** + * @brief Enable antialiased font support + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_ANTIALIAS + #define GDISP_NEED_ANTIALIAS FALSE + #endif + +/** + * @} + * + * @name GDISP Multi-Threading Options + * @{ + */ + /** + * @brief Do the drawing functions need to be thread-safe. + * @details Defaults to FALSE + */ + #ifndef GDISP_NEED_MULTITHREAD + #define GDISP_NEED_MULTITHREAD FALSE + #endif +/** + * @} + * + * @name GDISP Fonts + * @{ + */ + /** + * @brief Predefined built in fonts + * @note Turning off the ones you are not using can save program size. + */ + +/** + * @} + * + * @name GDISP Optional Sizing Parameters + * @{ + */ + /** + * @brief The size of pixel buffer (in pixels) used for optimization. + * @details Set to zero to guarantee disabling of the buffer. + * @note Depending on the driver and what operations the application + * needs, this buffer may never be allocated. + * @note Setting the size to zero may cause some operations to not + * compile eg. Scrolling if there is no hardware scroll support. + * @note Increasing the size will speedup certain operations + * at the expense of RAM. + * @note Currently only used to support scrolling on hardware without + * scrolling support, and to increase the speed of streaming + * operations on non-streaming hardware where there is a + * hardware supported bit-blit. + */ + #ifndef GDISP_LINEBUF_SIZE + #define GDISP_LINEBUF_SIZE 128 + #endif +/** + * @} + * + * @name GDISP Optional Low Level Driver Defines + * @{ + */ + /** + * @brief Define the default orientation for all displays in the system. + * @note GDISP_NEED_CONTROL must also be set (and the hardware must support it) + */ + // #define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE + /** + * @brief Set the screen height and width. + * @note Ignored by some low level GDISP drivers, optional for others. + * @note Where these values are allowed, a default is always provided be the low level driver. + * @note The list of GDISP low level drivers that allow these to be set are... + * WIN32, SSD1289, SSD1963, TestStub + */ + /* #define GDISP_SCREEN_WIDTH nnnn */ + /* #define GDISP_SCREEN_HEIGHT nnnn */ + /** + * @brief Define which bus interface to use. + * @details Only required by the SSD1963 driver. + * @note This will be replaced eventually by board definition files + */ + // #define GDISP_USE_FSMC + // #define GDISP_USE_GPIO +/** @} */ + +#endif /* _GDISP_OPTIONS_H */ +/** @} */ + diff --git a/src/gdisp/sys_rules.h b/src/gdisp/sys_rules.h new file mode 100644 index 00000000..83c95216 --- /dev/null +++ b/src/gdisp/sys_rules.h @@ -0,0 +1,85 @@ +/* + * 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/sys_rules.h + * @brief GDISP safety rules header file. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_RULES_H +#define _GDISP_RULES_H + +#if GFX_USE_GDISP + #if GDISP_TOTAL_CONTROLLERS > 1 + #ifndef GDISP_CONTROLLER_LIST + #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_LIST" + #endif + #ifndef GDISP_CONTROLLER_DISPLAYS + #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_DISPLAYS" + #endif + #ifndef GDISP_PIXELFORMAT + #error "GDISP Multiple Controllers: You must specify a value for GDISP_PIXELFORMAT" + #endif + #endif + #if GDISP_NEED_AUTOFLUSH && GDISP_NEED_TIMERFLUSH + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: Both GDISP_NEED_AUTOFLUSH and GDISP_NEED_TIMERFLUSH has been set. GDISP_NEED_TIMERFLUSH has disabled for you." + #endif + #undef GDISP_NEED_TIMERFLUSH + #define GDISP_NEED_TIMERFLUSH FALSE + #endif + #if GDISP_NEED_TIMERFLUSH + #if GDISP_NEED_TIMERFLUSH < 50 || GDISP_NEED_TIMERFLUSH > 1200 + #error "GDISP: GDISP_NEED_TIMERFLUSH has been set to an invalid value (FALSE, 50-1200)." + #endif + #if !GFX_USE_GTIMER + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: GDISP_NEED_TIMERFLUSH has been set but GFX_USE_GTIMER has not been set. It has been turned on for you." + #endif + #undef GFX_USE_GTIMER + #define GFX_USE_GTIMER TRUE + #undef GDISP_NEED_MULTITHREAD + #define GDISP_NEED_MULTITHREAD TRUE + #endif + #endif + #if GDISP_NEED_ANTIALIAS && !GDISP_NEED_PIXELREAD + #if GDISP_HARDWARE_PIXELREAD + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: GDISP_NEED_ANTIALIAS has been set but GDISP_NEED_PIXELREAD has not. It has been turned on for you." + #endif + #undef GDISP_NEED_PIXELREAD + #define GDISP_NEED_PIXELREAD TRUE + #else + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: GDISP_NEED_ANTIALIAS has been set but your hardware does not support reading back pixels. Anti-aliasing will only occur for filled characters." + #endif + #endif + #endif + #if (defined(GDISP_INCLUDE_FONT_SMALL) && GDISP_INCLUDE_FONT_SMALL) || (defined(GDISP_INCLUDE_FONT_LARGER) && GDISP_INCLUDE_FONT_LARGER) + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: An old font (Small or Larger) has been defined. A single default font of UI2 has been added instead." + #warning "GDISP: Please see <$(GFXLIB)/include/gdisp/fonts/fonts.h> for a list of available font names." + #endif + #undef GDISP_INCLUDE_FONT_UI2 + #define GDISP_INCLUDE_FONT_UI2 TRUE + #endif + #if GDISP_NEED_IMAGE + #if !GFX_USE_GFILE + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: GFX_USE_GFILE is required when GDISP_NEED_IMAGE is TRUE. It has been turned on for you." + #endif + #undef GFX_USE_GFILE + #define GFX_USE_GFILE TRUE + #endif + #endif +#endif + +#endif /* _GDISP_RULES_H */ +/** @} */ |