<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.ugfx.io/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tectu</id>
		<title>uGFX Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.ugfx.io/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tectu"/>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php/Special:Contributions/Tectu"/>
		<updated>2026-05-12T22:28:35Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=PushButton&amp;diff=1959</id>
		<title>PushButton</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=PushButton&amp;diff=1959"/>
				<updated>2024-09-09T13:51:19Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: Update example code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A push button is a stand-alone [[widgets|widget]] with a static size and a text where the text is drawn centered inside the button area. A push button can have the state '''pressed''' or '''unpressed'''.&lt;br /&gt;
&lt;br /&gt;
== API Reference ==&lt;br /&gt;
The API reference for the push button widget can be found [http://api.ugfx.org/group___button.html here].&lt;br /&gt;
&lt;br /&gt;
== Custom Draw Routines ==&lt;br /&gt;
The button widget predefines a number of custom draw routines. They can be set using &amp;lt;code&amp;gt;gwinSetCustomDraw()&amp;lt;/code&amp;gt; or by specifying the custom draw routine in the GWidgetInit structure during creation. Some require certain features to be turned on in your [[gfxconf.h]] file. The predefined custom draw routines are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Custom Draw Routine&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Requires&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Description&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_Normal&lt;br /&gt;
 |&lt;br /&gt;
 | The standard button look&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_Rounded&lt;br /&gt;
 | GDISP_NEED_ARC&lt;br /&gt;
 | A button with rounded corners&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_Ellipse&lt;br /&gt;
 | GDISP_NEED_ELLIPSE&lt;br /&gt;
 | An elliptical button&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_ArrowUp&lt;br /&gt;
 | GDISP_NEED_CONVEX_POLYGON&lt;br /&gt;
 | An up arrow&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_ArrowDown&lt;br /&gt;
 | GDISP_NEED_CONVEX_POLYGON&lt;br /&gt;
 | An down arrow&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_ArrowLeft&lt;br /&gt;
 | GDISP_NEED_CONVEX_POLYGON&lt;br /&gt;
 | An left arrow&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_ArrowRight&lt;br /&gt;
 | GDISP_NEED_CONVEX_POLYGON&lt;br /&gt;
 | An right arrow&lt;br /&gt;
 |-&lt;br /&gt;
 |gwinButtonDraw_Image&lt;br /&gt;
 | GDISP_NEED_IMAGE&lt;br /&gt;
 | An image button. The param must be a gdispImage pointer. See the API documentation for details.&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
== Cancel feature ==&lt;br /&gt;
The button implementation allows it to cancel a button pressed event: When you push a button but release it outside of it's area, the action is canceled. However, this feature can become a problem with touchscreen systems which have a lot of noise on the output coordinates. When you have a small button, the chance that just one point is outside of the area of a small button is very high.&lt;br /&gt;
&lt;br /&gt;
To fix this issue, there's the macro &amp;lt;code&amp;gt;GWIN_BUTTON_LAZY_RELEASE&amp;lt;/code&amp;gt; available. When you set it to '''TRUE''' in your [[gfxconf.h]], the cancel feature get's disabled.&lt;br /&gt;
&lt;br /&gt;
Of course the real solution is to fix the noise. One of the things that may help is reducing your SPI frequency if your touch is connected via SPI. There is a demo program that allows you to fine-tune the parameters for your touch driver in ''tools/ginput_touch_driver_test''. Compile and run it and each step will help you adjust one of the touch parameters. Unfortunately the parameters are not run-time changable. You need to run a test, alter the paremter, recompile and then run it again. Also don't try to do all the parameters at the same time as the setting of one can affect the setting of others - so do the tests one step at a time.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to use a push button widget:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GListener gl;&lt;br /&gt;
static GHandle   ghButton1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void) {&lt;br /&gt;
	GWidgetInit	wi;&lt;br /&gt;
 &lt;br /&gt;
	// Apply some default values for GWIN&lt;br /&gt;
	gwinWidgetClearInit(&amp;amp;wi);&lt;br /&gt;
	wi.g.show = TRUE;&lt;br /&gt;
 &lt;br /&gt;
	// Apply the button parameters	&lt;br /&gt;
	wi.g.width = 100;&lt;br /&gt;
	wi.g.height = 30;&lt;br /&gt;
	wi.g.y = 10;&lt;br /&gt;
	wi.g.x = 10;&lt;br /&gt;
	wi.text = &amp;quot;Push Button&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
	// Create the actual button&lt;br /&gt;
	ghButton1 = gwinButtonCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void) {&lt;br /&gt;
	GEvent* pe;&lt;br /&gt;
 &lt;br /&gt;
	// Initialize the display&lt;br /&gt;
	gfxInit();&lt;br /&gt;
 &lt;br /&gt;
	// Set the widget defaults&lt;br /&gt;
	gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
	gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
	gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
	// create the widget&lt;br /&gt;
	createWidgets();&lt;br /&gt;
 &lt;br /&gt;
	// We want to listen for widget events&lt;br /&gt;
	geventListenerInit(&amp;amp;gl);&lt;br /&gt;
	gwinAttachListener(&amp;amp;gl);&lt;br /&gt;
 &lt;br /&gt;
	while(1) {&lt;br /&gt;
		// Get an Event&lt;br /&gt;
		pe = geventEventWait(&amp;amp;gl, TIME_INFINITE);&lt;br /&gt;
 &lt;br /&gt;
		switch(pe-&amp;gt;type) {&lt;br /&gt;
			case GEVENT_GWIN_BUTTON:&lt;br /&gt;
				if (((GEventGWinButton*)pe)-&amp;gt;gwin == ghButton1) {&lt;br /&gt;
					// Our button has been pressed&lt;br /&gt;
					printf(&amp;quot;Button clicked\r\n&amp;quot;);&lt;br /&gt;
				}&lt;br /&gt;
				break;&lt;br /&gt;
 &lt;br /&gt;
			default:&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Pixmaps&amp;diff=1958</id>
		<title>Pixmaps</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Pixmaps&amp;diff=1958"/>
				<updated>2023-12-04T16:02:48Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: Fix broken URL&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pixmaps provide dynamic frame buffers. A pixmap of any size can by dynamically created and destroyed during runtime. A pixmap represents itself as a virtual display to the user. Hence a pixmap can be treated like a regular display and all the available [[GDISP]] drawing routines can be performed inside the pixmap frame buffer. A pixmap can be rendered at any location of a real display at any time.&lt;br /&gt;
&lt;br /&gt;
Note that pixmaps always use the system pixel format. See [[GDISP#Color_format|color formats]] for more information.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the pixmap can be found [https://api.ugfx.io/group___pixmap.html here].&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
In µGFX &amp;lt; v3.0, pixmaps are not supported when using the [[Getting_Started#Single_File_Inclusion|single file inclusion]] mechanism as pixmaps rely on multi-display capabilities.&lt;br /&gt;
&lt;br /&gt;
== Creating and destroying a pixmap ==&lt;br /&gt;
Pixmaps can be created and destroyed at any time during runtime using &amp;lt;code&amp;gt;gdispPixmapCreate()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gdispPixmapDelete()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Accessing the pixmap ==&lt;br /&gt;
A pixmap can be treated as either a virtual display or as a memory frame buffer surface.&lt;br /&gt;
&lt;br /&gt;
=== Virtual display ===&lt;br /&gt;
&amp;lt;code&amp;gt;gdispPixmapCreate()&amp;lt;/code&amp;gt; returns a [[GDISP#GDisplay|GDisplay]] pointer. Hence the pixmap can be treated like a regular display and all the [[GDISP]] operations (including orientations) can be used on a pixmap.&lt;br /&gt;
&lt;br /&gt;
=== Frame buffer surface ===&lt;br /&gt;
The memory of a created pixmap can be accessed directly in order to use it like a regular frame buffer surface. &amp;lt;code&amp;gt;gdispPixmapGetBits()&amp;lt;/code&amp;gt; returns a pointer to the first pixel of the pixmap.&lt;br /&gt;
&lt;br /&gt;
=== Image access ===&lt;br /&gt;
It's possible to treat a pixmap as an image. &amp;lt;code&amp;gt;gdispPixmapGetMemoryImage()&amp;lt;/code&amp;gt; returns a pointer to a native GDISP image (&amp;lt;code&amp;gt;gdispImage*&amp;lt;/code&amp;gt;). This allows to use a pixmap as the image for image rendering routines.&lt;br /&gt;
&lt;br /&gt;
== Displaying a pixmap ==&lt;br /&gt;
A pixmap can be displayed on a real display at any time using the &amp;lt;code&amp;gt;gdispBlitArea()&amp;lt;/code&amp;gt; function. Note that this call allows to display the pixmap at any location on the screen, not only at the display origin. Therefore, this can be used to implement scrolling and other animations.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example will show how to create a pixmap and access it both as a virtual display and as a frame buffer surface. Once the pixmap is created it will be blitted incrementally across the entire screen (The pixmap will move across the screen).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define PIXMAP_WIDTH	40&lt;br /&gt;
#define PIXMAP_HEIGHT	10&lt;br /&gt;
&lt;br /&gt;
static GDisplay* pixmap;&lt;br /&gt;
static pixel_t* surface;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    coord_t		width, height;&lt;br /&gt;
    coord_t		i, j;&lt;br /&gt;
&lt;br /&gt;
    // Initialize and clear the display&lt;br /&gt;
    gfxInit();&lt;br /&gt;
&lt;br /&gt;
    // Get the screen size&lt;br /&gt;
    width = gdispGetWidth();&lt;br /&gt;
    height = gdispGetHeight();&lt;br /&gt;
&lt;br /&gt;
    // Create a pixmap and get a pointer to the bits&lt;br /&gt;
    pixmap = gdispPixmapCreate(PIXMAP_WIDTH, PIXMAP_HEIGHT);&lt;br /&gt;
    surface = gdispPixmapGetBits(pixmap);&lt;br /&gt;
&lt;br /&gt;
    // A pixmap can be treated either as a virtual display or as a memory framebuffer surface.&lt;br /&gt;
    // We demonstrate writing to it using both methods.&lt;br /&gt;
&lt;br /&gt;
    // First demo drawing onto the surface directly&lt;br /&gt;
    for(j = 0; j &amp;lt; PIXMAP_HEIGHT; j++)&lt;br /&gt;
    	for(i = 0; i &amp;lt; PIXMAP_WIDTH; i++)&lt;br /&gt;
    		surface[j*PIXMAP_WIDTH + i] = RGB2COLOR(0, 255-i*(256/PIXMAP_WIDTH), j*(256/PIXMAP_HEIGHT));&lt;br /&gt;
&lt;br /&gt;
    // Secondly, show drawing a line on it like a virtual display&lt;br /&gt;
    gdispGDrawLine(pixmap, 0, 0, gdispGGetWidth(pixmap)-1, gdispGGetHeight(pixmap)-1, White);&lt;br /&gt;
    &lt;br /&gt;
    i = j = 0;&lt;br /&gt;
    while(TRUE) {&lt;br /&gt;
    	// Clear the old position&lt;br /&gt;
    	gdispFillArea(i, j, PIXMAP_WIDTH, PIXMAP_HEIGHT, Black);&lt;br /&gt;
&lt;br /&gt;
    	// Change the position&lt;br /&gt;
    	i += PIXMAP_WIDTH/2;&lt;br /&gt;
    	if (i &amp;gt;= width - PIXMAP_WIDTH/2) {&lt;br /&gt;
    		i %= width - PIXMAP_WIDTH/2;&lt;br /&gt;
    		j = (j + PIXMAP_HEIGHT/2) % (height - PIXMAP_HEIGHT/2);&lt;br /&gt;
    	}&lt;br /&gt;
&lt;br /&gt;
    	// Blit the pixmap to the real display at the new position&lt;br /&gt;
    	gdispBlitArea(i, j, PIXMAP_WIDTH, PIXMAP_HEIGHT, surface);&lt;br /&gt;
&lt;br /&gt;
    	// Wait&lt;br /&gt;
    	gfxSleepMilliseconds(100);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Clean up&lt;br /&gt;
    gdispPixmapDelete(pixmap);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Double buffering ==&lt;br /&gt;
Pixmaps can be used to implement application level double buffering if the underlying hardware doesn't support it. More information can be found in this [https://community.ugfx.io/topic/960-flicker community forum topic].&lt;br /&gt;
&lt;br /&gt;
[[Category:GDISP]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Creating_a_custom_rendering_routine&amp;diff=1957</id>
		<title>Creating a custom rendering routine</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Creating_a_custom_rendering_routine&amp;diff=1957"/>
				<updated>2023-08-20T12:39:05Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: Fix typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Every [[Widgets|widget]] comes with a custom render interface. The default style in which a widget is drawn is very basic and minimalistic in order to make it run on the even lowest performance systems smoothly. However, the custom render interface allows you to submit your own rendering routines. This does not only provide a very flexible way to render a widget matching to your systems performance, but it gives you also the possibility to render a widget matching your applications style.&lt;br /&gt;
&lt;br /&gt;
== The interface ==&lt;br /&gt;
Every widget provides a function to submit a custom rendering function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void* param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''CustomWidgetDrawFunction'' is a typedef'ed function pointer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
typedef void (*CustomWidgetDrawFunction)(GWidgetObject* gw, void* param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''param'' parameter can be used to pass a custom parameter such as an image pointer in case of you're rendering routine needs to draw an image. However, in most of the cases, this parameter will be '''NULL'''.&lt;br /&gt;
&lt;br /&gt;
'''''Note:''' The pointer to the custom rendering routine can also be passed through the initialization struct (the ''customDraw'' field).&lt;br /&gt;
&lt;br /&gt;
'''''Note:''' Do never use the &amp;lt;code&amp;gt;gwinDrawXxx()&amp;lt;/code&amp;gt; calls inside a rendering routine as this would lock the widget again. Use &amp;lt;code&amp;gt;gdispDrawXxx()&amp;lt;/code&amp;gt; instead ''&lt;br /&gt;
&lt;br /&gt;
== Widget information ==&lt;br /&gt;
In order to render the widget you need some information about it (eg. position, size, font, ...). All these information can be fetched from the ''GWidgetObject'' struct which is passed as a parameter to the custom rendering function. This is the only time where you're not only allowed to but even obligated to directly access the struct members directly instead of using the equivalent GWIN API calls to retrieve these information. Do never access struct members directly outside of the custom rendering routine!&lt;br /&gt;
&lt;br /&gt;
'''''Important:''' Do never use the &amp;lt;code&amp;gt;gwinDrawXxx()&amp;lt;/code&amp;gt; calls inside a rendering routine as this would lock the widget again. Use &amp;lt;code&amp;gt;gdispDrawXxx()&amp;lt;/code&amp;gt; instead.''&lt;br /&gt;
&lt;br /&gt;
To retrieve all the widget specific information the ''GWidgetObject'' struct needs to be casted to the actual widget type object.&lt;br /&gt;
&lt;br /&gt;
'''''Important:''' All drawing operations must take place inside of the widget area. Do not draw outside of the widget area.''&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
We are now going to show on a real world example how a custom rendering routine can be implemented. We will write a custom rendering routine for the button widget that will allow to display an icon on the left side of the text. We will keep it as simple as possible: We won't do color blending for gradients and other things that would make this look nicer in order to focus on the things that are actually important. The expected result can be seen in the image on the right.&lt;br /&gt;
[[File:Buttons custom rendering.png|thumbnail|The expected result. The ''Settings'' button on the right side is being pressed]]&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void myButtonRendering(GWidgetObject* gw, void* param)&lt;br /&gt;
{&lt;br /&gt;
	const GColorSet* colors;&lt;br /&gt;
&lt;br /&gt;
	// Get the icon/image. User must open the image beforehand.&lt;br /&gt;
	gdispImage* icon = (gdispImage*)param;&lt;br /&gt;
	if (!icon) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Get the appropriate color pallete from the widget style&lt;br /&gt;
	if (!gwinGetEnabled((GHandle)gw))&lt;br /&gt;
		colors = &amp;amp;gw-&amp;gt;pstyle-&amp;gt;disabled;&lt;br /&gt;
	else if ((gw-&amp;gt;g.flags &amp;amp; GBUTTON_FLG_PRESSED))&lt;br /&gt;
		colors = &amp;amp;gw-&amp;gt;pstyle-&amp;gt;pressed;&lt;br /&gt;
	else&lt;br /&gt;
		colors = &amp;amp;gw-&amp;gt;pstyle-&amp;gt;enabled;&lt;br /&gt;
&lt;br /&gt;
	// Draw the basic rectangle with border&lt;br /&gt;
	gdispGFillArea(gw-&amp;gt;g.display, gw-&amp;gt;g.x+1, gw-&amp;gt;g.y+1, gw-&amp;gt;g.width-2, gw-&amp;gt;g.height-2, colors-&amp;gt;fill);&lt;br /&gt;
	gdispGDrawBox(gw-&amp;gt;g.display, gw-&amp;gt;g.x, gw-&amp;gt;g.y, gw-&amp;gt;g.width, gw-&amp;gt;g.height, colors-&amp;gt;edge);&lt;br /&gt;
&lt;br /&gt;
	// Draw the string. Use StringBox() for proper justification and word-wrapping support&lt;br /&gt;
	gdispGDrawStringBox(gw-&amp;gt;g.display, gw-&amp;gt;g.x+gw-&amp;gt;g.height, gw-&amp;gt;g.y, gw-&amp;gt;g.width-gw-&amp;gt;g.height, gw-&amp;gt;g.height, gw-&amp;gt;text, gw-&amp;gt;g.font, colors-&amp;gt;text, justifyLeft);&lt;br /&gt;
&lt;br /&gt;
	// Draw the image&lt;br /&gt;
	gdispGImageDraw(gw-&amp;gt;g.display, icon, gw-&amp;gt;g.x+(gw-&amp;gt;g.height-icon-&amp;gt;width)/2, gw-&amp;gt;g.y+(gw-&amp;gt;g.height-icon-&amp;gt;height)/2, icon-&amp;gt;width, icon-&amp;gt;height, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
The following program will show how the same rendering routine can be applied to two buttons that are using two different icons:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GHandle ghButton1;&lt;br /&gt;
GHandle ghButton2;&lt;br /&gt;
gdispImage iconWrench;&lt;br /&gt;
gdispImage iconUgfx;&lt;br /&gt;
font_t font1;&lt;br /&gt;
font_t font2;&lt;br /&gt;
&lt;br /&gt;
void myButtonRendering(GWidgetObject* gw, void* param)&lt;br /&gt;
{&lt;br /&gt;
	const GColorSet* colors;&lt;br /&gt;
&lt;br /&gt;
	// Get the icon/image&lt;br /&gt;
	gdispImage* icon = (gdispImage*)param;&lt;br /&gt;
	if (!icon) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Get the appropriate color pallete from the widget style&lt;br /&gt;
	if (!gwinGetEnabled((GHandle)gw))&lt;br /&gt;
		colors = &amp;amp;gw-&amp;gt;pstyle-&amp;gt;disabled;&lt;br /&gt;
	else if ((gw-&amp;gt;g.flags &amp;amp; GBUTTON_FLG_PRESSED))&lt;br /&gt;
		colors = &amp;amp;gw-&amp;gt;pstyle-&amp;gt;pressed;&lt;br /&gt;
	else&lt;br /&gt;
		colors = &amp;amp;gw-&amp;gt;pstyle-&amp;gt;enabled;&lt;br /&gt;
&lt;br /&gt;
	// Draw the basic rectangle with border&lt;br /&gt;
	gdispGFillArea(gw-&amp;gt;g.display, gw-&amp;gt;g.x+1, gw-&amp;gt;g.y+1, gw-&amp;gt;g.width-2, gw-&amp;gt;g.height-2, colors-&amp;gt;fill);&lt;br /&gt;
	gdispGDrawBox(gw-&amp;gt;g.display, gw-&amp;gt;g.x, gw-&amp;gt;g.y, gw-&amp;gt;g.width, gw-&amp;gt;g.height, colors-&amp;gt;edge);&lt;br /&gt;
&lt;br /&gt;
	// Draw the string. Use StringBox() for proper justification and word-wrapping support&lt;br /&gt;
	gdispGDrawStringBox(gw-&amp;gt;g.display, gw-&amp;gt;g.x+gw-&amp;gt;g.height, gw-&amp;gt;g.y, gw-&amp;gt;g.width-gw-&amp;gt;g.height, gw-&amp;gt;g.height, gw-&amp;gt;text, gw-&amp;gt;g.font, colors-&amp;gt;text, justifyLeft);&lt;br /&gt;
&lt;br /&gt;
	// Draw the image&lt;br /&gt;
	gdispGImageDraw(gw-&amp;gt;g.display, icon, gw-&amp;gt;g.x+(gw-&amp;gt;g.height-icon-&amp;gt;width)/2, gw-&amp;gt;g.y+(gw-&amp;gt;g.height-icon-&amp;gt;height)/2, icon-&amp;gt;width, icon-&amp;gt;height, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static void createWidgets(void) {&lt;br /&gt;
	GWidgetInit	wi;&lt;br /&gt;
&lt;br /&gt;
	// Prepare the images&lt;br /&gt;
	gdispImageOpenFile(&amp;amp;iconWrench, &amp;quot;settings.gif&amp;quot;);&lt;br /&gt;
	gdispImageOpenFile(&amp;amp;iconUgfx, &amp;quot;padlock.gif&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	// Apply some default values for GWIN&lt;br /&gt;
	gwinWidgetClearInit(&amp;amp;wi);&lt;br /&gt;
	wi.g.show = TRUE;&lt;br /&gt;
&lt;br /&gt;
	// Create a regular button&lt;br /&gt;
	wi.g.width = 180;&lt;br /&gt;
	wi.g.height = 52;&lt;br /&gt;
	wi.g.y = 10;&lt;br /&gt;
	wi.g.x = 10;&lt;br /&gt;
	wi.customParam = &amp;amp;iconWrench;&lt;br /&gt;
	wi.customDraw = myButtonRendering;&lt;br /&gt;
	wi.text = &amp;quot;Setting&amp;quot;;&lt;br /&gt;
	ghButton1 = gwinButtonCreate(0, &amp;amp;wi);&lt;br /&gt;
&lt;br /&gt;
	// Create a regular button&lt;br /&gt;
	wi.g.width = 180;&lt;br /&gt;
	wi.g.height = 52;&lt;br /&gt;
	wi.g.y = 70;&lt;br /&gt;
	wi.g.x = 10;&lt;br /&gt;
	wi.customParam = &amp;amp;iconUgfx;&lt;br /&gt;
	wi.customDraw = myButtonRendering;&lt;br /&gt;
	wi.text = &amp;quot;Lock&amp;quot;;&lt;br /&gt;
	ghButton2 = gwinButtonCreate(0, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	gfxInit();&lt;br /&gt;
&lt;br /&gt;
	gwinSetDefaultFont(gdispOpenFont(&amp;quot;*&amp;quot;));&lt;br /&gt;
	gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
	gdispClear(White);&lt;br /&gt;
&lt;br /&gt;
	createWidgets();&lt;br /&gt;
&lt;br /&gt;
	while(1) {&lt;br /&gt;
		gfxSleepMilliseconds(250);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Graph&amp;diff=1956</id>
		<title>Graph</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Graph&amp;diff=1956"/>
				<updated>2023-05-04T20:47:18Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: Fix API doc link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Graph_demo_640x480.gif|right|thumb|Output of the graph demo. Click to see without artifacts.]]&lt;br /&gt;
The graph window allows to easily draw curves and other sets of data with different colors and shapes in a rectangular window. The graph doesn't take any user input.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the graph window can be found [https://api.ugfx.io/group___graph.html here].&lt;br /&gt;
&lt;br /&gt;
== Style ==&lt;br /&gt;
The graph window provides an interface to modify the appearance of the graph itself and the data it displays. This contains the following properties:&lt;br /&gt;
&lt;br /&gt;
* Point&lt;br /&gt;
** Type (None / Dot / Square / Circle)&lt;br /&gt;
** Radius&lt;br /&gt;
** Color&lt;br /&gt;
* Lines&lt;br /&gt;
** Type (None / Solid / Dot / Dash)&lt;br /&gt;
** Thickness&lt;br /&gt;
** Color&lt;br /&gt;
* X-Axis line&lt;br /&gt;
** Type (Solid / Dot / Dash)&lt;br /&gt;
** Thickness&lt;br /&gt;
** Color&lt;br /&gt;
* Y-Axis&lt;br /&gt;
** Type (Solid / Dot / Dash)&lt;br /&gt;
** Thickness&lt;br /&gt;
** Color&lt;br /&gt;
* X-Axis grid&lt;br /&gt;
** Type (Solid / Dot / Dash)&lt;br /&gt;
** Thickness&lt;br /&gt;
** Color&lt;br /&gt;
** Spacing&lt;br /&gt;
* Y-Axis grid&lt;br /&gt;
** Type (Solid / Dot / Dash)&lt;br /&gt;
** Thickness&lt;br /&gt;
** Color&lt;br /&gt;
** Spacing&lt;br /&gt;
* Flags&lt;br /&gt;
** Arrows&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example draws three curves with different colors and shapes within the same graph widget. Make sure you got the math library included into your build path (&amp;lt;code&amp;gt;-lm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// A set of data points that will be displayed in the graph&lt;br /&gt;
static const point data[5] = {&lt;br /&gt;
    { -40, -40 },&lt;br /&gt;
    { 70, 40 },&lt;br /&gt;
    { 140, 60 },&lt;br /&gt;
    { 210, 60 },&lt;br /&gt;
    { 280, 200 }&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
// The graph object&lt;br /&gt;
static GGraphObject g;&lt;br /&gt;
&lt;br /&gt;
// A graph styling&lt;br /&gt;
static GGraphStyle GraphStyle1 = {&lt;br /&gt;
    { GGRAPH_POINT_DOT, 0, Blue },          // Point&lt;br /&gt;
    { GGRAPH_LINE_NONE, 2, Gray },          // Line&lt;br /&gt;
    { GGRAPH_LINE_SOLID, 0, White },        // X axis&lt;br /&gt;
    { GGRAPH_LINE_SOLID, 0, White },        // Y axis&lt;br /&gt;
    { GGRAPH_LINE_DASH, 5, Gray, 50 },      // X grid&lt;br /&gt;
    { GGRAPH_LINE_DOT, 7, Yellow, 50 },     // Y grid&lt;br /&gt;
    GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS   // Flags&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Another graph styling &lt;br /&gt;
static const GGraphStyle GraphStyle2 = {&lt;br /&gt;
    { GGRAPH_POINT_SQUARE, 5, Red },        // Point&lt;br /&gt;
    { GGRAPH_LINE_DOT, 2, Pink },           // Line&lt;br /&gt;
    { GGRAPH_LINE_SOLID, 0, White },        // X axis&lt;br /&gt;
    { GGRAPH_LINE_SOLID, 0, White },        // Y axis&lt;br /&gt;
    { GGRAPH_LINE_DASH, 5, Gray, 50 },      // X grid&lt;br /&gt;
    { GGRAPH_LINE_DOT, 7, Yellow, 50 },     // Y grid&lt;br /&gt;
    GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS   // Flags&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
int main(void) {&lt;br /&gt;
    GHandle     gh;&lt;br /&gt;
    uint16_t    i;&lt;br /&gt;
 &lt;br /&gt;
    gfxInit();&lt;br /&gt;
 &lt;br /&gt;
    // Create the graph window&lt;br /&gt;
    {&lt;br /&gt;
        GWindowInit wi;&lt;br /&gt;
 &lt;br /&gt;
        wi.show = TRUE;&lt;br /&gt;
        wi.x = wi.y = 0;&lt;br /&gt;
        wi.width = gdispGetWidth();&lt;br /&gt;
        wi.height = gdispGetHeight();&lt;br /&gt;
        gh = gwinGraphCreate(&amp;amp;g, &amp;amp;wi);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // Set the graph origin and style&lt;br /&gt;
    gwinGraphSetOrigin(gh, gwinGetWidth(gh)/2, gwinGetHeight(gh)/2);&lt;br /&gt;
    gwinGraphSetStyle(gh, &amp;amp;GraphStyle1);&lt;br /&gt;
    gwinGraphDrawAxis(gh);&lt;br /&gt;
 &lt;br /&gt;
    // Draw a sine wave&lt;br /&gt;
    for(i = 0; i &amp;lt; gwinGetWidth(gh); i++) {&lt;br /&gt;
        gwinGraphDrawPoint(gh, i-gwinGetWidth(gh)/2, 80*sin(2*0.2*M_PI*i/180));&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // Modify the style&lt;br /&gt;
    gwinGraphStartSet(gh);&lt;br /&gt;
    GraphStyle1.point.color = Green;&lt;br /&gt;
    gwinGraphSetStyle(gh, &amp;amp;GraphStyle1);&lt;br /&gt;
 &lt;br /&gt;
    // Draw a different sine wave&lt;br /&gt;
    for(i = 0; i &amp;lt; gwinGetWidth(gh)*5; i++) {&lt;br /&gt;
        gwinGraphDrawPoint(gh, i/5-gwinGetWidth(gh)/2, 95*sin(2*0.2*M_PI*i/180));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Change to a completely different style&lt;br /&gt;
    gwinGraphStartSet(gh);&lt;br /&gt;
    gwinGraphSetStyle(gh, &amp;amp;GraphStyle2);&lt;br /&gt;
&lt;br /&gt;
    // Draw a set of points&lt;br /&gt;
    gwinGraphDrawPoints(gh, data, sizeof(data)/sizeof(data[0]));&lt;br /&gt;
 &lt;br /&gt;
    while(TRUE) {&lt;br /&gt;
        gfxSleepMilliseconds(100);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Window]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1955</id>
		<title>FreeBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1955"/>
				<updated>2022-06-06T13:29:58Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: Add missing parenthesis&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can be compiled into native FreeBSD applications. This is especially useful for developing µGFX applications on a Desktop machine.&lt;br /&gt;
The SDL2 library is used to spawn a desktop window. Mouse &amp;amp; keyboard inputs are supported.&lt;br /&gt;
&lt;br /&gt;
= Dependencies =&lt;br /&gt;
The following dependencies are required:&lt;br /&gt;
* GCC (eg. &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc10 lang/gcc10]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc11 lang/gcc11]&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/gmake/ devel/gmake]&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/sdl2 devel/sdl2]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Makefile =&lt;br /&gt;
A sample Makefile can be found under &amp;lt;code&amp;gt;/boards/base/FreeBSD-SDL/example/Makefile&amp;lt;/code&amp;gt;. Copy it to your project directory.&lt;br /&gt;
&lt;br /&gt;
From there, set the &amp;lt;code&amp;gt;GFXLIB&amp;lt;/code&amp;gt; variable in the Makefile to point to the root directory of the µGFX library.&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;GFXDEMO&amp;lt;/code&amp;gt; variable is set to non-empty (it has to point to one of the demo directories in &amp;lt;code&amp;gt;/demos&amp;lt;/code&amp;gt;, the corresponding demo will be compiled. If you want to compile your own application code, add the source files to the &amp;lt;code&amp;gt;SRC&amp;lt;/code&amp;gt; variable.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1954</id>
		<title>FreeBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1954"/>
				<updated>2021-09-24T00:14:42Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Makefile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can be compiled into native FreeBSD applications. This is especially useful for developing µGFX applications on a Desktop machine.&lt;br /&gt;
The SDL2 library is used to spawn a desktop window. Mouse &amp;amp; keyboard inputs are supported.&lt;br /&gt;
&lt;br /&gt;
= Dependencies =&lt;br /&gt;
The following dependencies are required:&lt;br /&gt;
* GCC (eg. &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc10 lang/gcc10]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc11 lang/gcc11]&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/gmake/ devel/gmake]&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/sdl2 devel/sdl2]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Makefile =&lt;br /&gt;
A sample Makefile can be found under &amp;lt;code&amp;gt;/boards/base/FreeBSD-SDL/example/Makefile&amp;lt;/code&amp;gt;. Copy it to your project directory.&lt;br /&gt;
&lt;br /&gt;
From there, set the &amp;lt;code&amp;gt;GFXLIB&amp;lt;/code&amp;gt; variable in the Makefile to point to the root directory of the µGFX library.&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;GFXDEMO&amp;lt;/code&amp;gt; variable is set to non-empty (it has to point to one of the demo directories in &amp;lt;code&amp;gt;/demos&amp;lt;/code&amp;gt;, the corresponding demo will be compiled. If you want to compile your own application code, add the source files to the &amp;lt;code&amp;gt;SRC&amp;lt;/code&amp;gt; variable.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GOS&amp;diff=1953</id>
		<title>GOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GOS&amp;diff=1953"/>
				<updated>2021-09-24T00:03:32Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Existing ports */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GOS is the module which builds the abstraction layer between µGFX and the underlying system. The underlying system can be an RTOS such as [http://chibios.org ChibiOS] or [http://freertos.org FreeRTOS], or also just a bare metal system. The GOS module allows to write completely platform independent application code.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GOS module can be found [http://api.ugfx.org/group___g_o_s.html here].&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
There are several configuration options for the GOS module inside the [[Configuration|configuration file]]. Note that none of these configuration settings need to be specified in 99% of the cases as everything comes with a reasonable default implementation/setting.&lt;br /&gt;
&lt;br /&gt;
=== Compiler ===&lt;br /&gt;
The &amp;lt;code&amp;gt;GFX_COMPILER&amp;lt;/code&amp;gt; configuration setting allows enabling compiler specific optimization code. Please note that this setting usually doesn't have to be set manually by the user as the used compiler will be auto-detected. If &amp;lt;code&amp;gt;GFX_SHOW_COMPILER&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; a compiler warning will be generated showing the name of the compiler that was manually set or automatically detected.&lt;br /&gt;
&lt;br /&gt;
Available values for &amp;lt;code&amp;gt;GFX_COMPILER&amp;lt;/code&amp;gt; are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Option&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Description&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_UNKNOWN&lt;br /&gt;
 |Unknown compiler. This is the default and should always work.&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_ACC&lt;br /&gt;
 |ACC Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_ALTIUM&lt;br /&gt;
 |Altium MicroBlaze C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_ALTIUMHW&lt;br /&gt;
 |Altium C-to-Hardware&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_AMSTERDAM&lt;br /&gt;
 |Amsterdam Compiler Kit&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_ARMCC&lt;br /&gt;
 |ARM Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_AZTEC&lt;br /&gt;
 |Aztec C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_BORLAND&lt;br /&gt;
 |Borland C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_CC65&lt;br /&gt;
 |CC65&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_CLANG&lt;br /&gt;
 |CLang (LLVM) compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_COMEAU&lt;br /&gt;
 |Comeau C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_COMPAQ&lt;br /&gt;
 |Compaq C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_COMPCERT&lt;br /&gt;
 |Compcert Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_CONVEX&lt;br /&gt;
 |Convex C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_CRAY&lt;br /&gt;
 |Cray C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_CYGWIN&lt;br /&gt;
 |Cygwin (x86) unix emulator compiler for windows&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_DAIB&lt;br /&gt;
 |Diab C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_DEC&lt;br /&gt;
 |The older DEC C Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_DICE&lt;br /&gt;
 |DICE C Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_DIGNUS&lt;br /&gt;
 |Dignus Systems C++ Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_DJGPP&lt;br /&gt;
 |DJGPP&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_DMARS&lt;br /&gt;
 |Digital Mars&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_EDG&lt;br /&gt;
 |EDG C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_EKOPATH&lt;br /&gt;
 |EKOPath Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_FUJITSU&lt;br /&gt;
 |Fujitsu C++ Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_GCC&lt;br /&gt;
 |Standard GCC/G++ (Also use this when using &amp;lt;code&amp;gt;arm-none-eabi-gcc&amp;lt;/code&amp;gt;)&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_GREENHILL&lt;br /&gt;
 |Green Hill C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_HIGHC&lt;br /&gt;
 |Metaware High C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_HP&lt;br /&gt;
 |HP C/aC++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_IAR&lt;br /&gt;
 |IAR C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_IBMXL&lt;br /&gt;
 |IBM XL C/C++ Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_IMAGECRAFT&lt;br /&gt;
 |ImageCraft C Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_INTEL&lt;br /&gt;
 |Intel ICC/ICPC Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_KAI&lt;br /&gt;
 |Kai C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_KEIL&lt;br /&gt;
 |Keil (use this when working with uVision IDE)&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_LCC&lt;br /&gt;
 |LCC&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_METROWORKS&lt;br /&gt;
 |Metroworks&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_MICROTEC&lt;br /&gt;
 |Microtec C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_MICROWAY&lt;br /&gt;
 |Microway NDP C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_MINGW32&lt;br /&gt;
 |MingW32 (x86) compiler for windows&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_MINGW64&lt;br /&gt;
 |MingW64 (x64) compiler for windows&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_MIPSPRO&lt;br /&gt;
 |MIPS Pro&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_MIRACLE&lt;br /&gt;
 |Miracle C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_MPW&lt;br /&gt;
 |MPW C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_NORCROFT&lt;br /&gt;
 |Norcroft ARM&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_NWCC&lt;br /&gt;
 |NWCC&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_OPEN64&lt;br /&gt;
 |Open64&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_OSS&lt;br /&gt;
 |Oracle Solaris Studio&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_PACIFIC&lt;br /&gt;
 |Pacific C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_PALM&lt;br /&gt;
 |Palm C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_PELLES&lt;br /&gt;
 |Pelles C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_PGCC&lt;br /&gt;
 |Portland PGCC/PGCPP&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_RENESAS&lt;br /&gt;
 |Renesas C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_SASC&lt;br /&gt;
 |SAS/C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_SCO&lt;br /&gt;
 |SCO OpenServer&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_SDCC&lt;br /&gt;
 |Small Device C Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_SN&lt;br /&gt;
 |SN Compiler&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_STRATUS&lt;br /&gt;
 |Stratus VOS C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_SYMANTEC&lt;br /&gt;
 |Symantec C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_TENDRA&lt;br /&gt;
 |TenDRA C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_THINK&lt;br /&gt;
 |Think C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_TI&lt;br /&gt;
 |Texas Instruments C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_TINYC&lt;br /&gt;
 |Tiny C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_TURBOC&lt;br /&gt;
 |Borland Turbo C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_ULTIMATE&lt;br /&gt;
 |Ultimate C/C++&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_USL&lt;br /&gt;
 |USL C&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_VBCC&lt;br /&gt;
 |VBCC&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_VS&lt;br /&gt;
 |Microsoft Visual Studio&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_WATCOM&lt;br /&gt;
 |Watcom&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_COMPILER_ZTC&lt;br /&gt;
 |Zortech C++&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== CPU ===&lt;br /&gt;
The &amp;lt;code&amp;gt;GFX_CPU&amp;lt;/code&amp;gt; configuration setting allows enabling CPU specific optimization code.&lt;br /&gt;
Available settings:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Option&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Description&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_UNKNOWN&lt;br /&gt;
 |Unknown CPU. This is the default setting.&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M0&lt;br /&gt;
 |Cortex M0&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M1&lt;br /&gt;
 |Cortex M1&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M2&lt;br /&gt;
 |Cortex M2&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M3&lt;br /&gt;
 |Cortex M3&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M4&lt;br /&gt;
 |Cortex M4&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M4_FP&lt;br /&gt;
 |Cortex M4 with hardware floating point unit&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M7&lt;br /&gt;
 |Cortex M7&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_CORTEX_M7_FP&lt;br /&gt;
 |Cortex M7 with hardware floating point unit&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_X86&lt;br /&gt;
 |Intel x86&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_X64&lt;br /&gt;
 |Intel x64&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_IA64&lt;br /&gt;
 |Intel Itanium&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_POWERPC32&lt;br /&gt;
 |PowerPC 32-Bit&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_POWERPC64&lt;br /&gt;
 |PowerPC 64-Bit&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_SPARC&lt;br /&gt;
 |Sparc&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Endian ===&lt;br /&gt;
The &amp;lt;code&amp;gt;GFX_CPU_ENDIAN&amp;lt;/code&amp;gt; setting enables optimisations that are CPU-endian specific. It does not need to be specified as reasonable defaults and various auto-detection will happen as required.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Option&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Description&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_ENDIAN_UNKNOWN&lt;br /&gt;
 |Unknown endianness. This is the default.&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_ENDIAN_LITTLE&lt;br /&gt;
 |Little endian&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_ENDIAN_BIG&lt;br /&gt;
 |Big endian&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_ENDIAN_WBDWL&lt;br /&gt;
 |Words are big endian, DWords are little endian. For example: Honeywell 316&lt;br /&gt;
 |-&lt;br /&gt;
 |GFX_CPU_ENDIAN_WLDWB&lt;br /&gt;
 |Words are little endian, DWords are big endian. For example: PDP-11&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Inlining ===&lt;br /&gt;
Certain functions of the µGFX library are inlined for performance reasons. Setting &amp;lt;code&amp;gt;GFX_NO_INLINE&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; will disable the inlining of all functions.&lt;br /&gt;
This setting should only be touched in case of there are any compile time errors for unsupported compilers. Disabling inlining will have huge impacts on performance.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
For code portability reasons the underlying system will be automatically initialized when &amp;lt;code&amp;gt;gosInit()&amp;lt;/code&amp;gt; is called unless &amp;lt;code&amp;gt;GFX_OS_NO_INIT&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
By default the GOS module will print out a warning during compile time to notify the user that he needs to make sure that his OS has been initialized before calling &amp;lt;code&amp;gt;gfxInit()&amp;lt;/code&amp;gt;. Setting &amp;lt;code&amp;gt;GFX_OS_INIT_NO_WARNING&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; will suppress this warning.&lt;br /&gt;
Note that this warning is only printed out when the GOS module cannot initialize the operating system automatically. This is the case when eg. the RAW32 port is used (see [[BareMetal]]) or when &amp;lt;code&amp;gt;GFX_OS_NO_INIT&amp;lt;/code&amp;gt; has been set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; to prevent &amp;lt;code&amp;gt;gfxInit()&amp;lt;/code&amp;gt; from initializing the underlying systems automatically.&lt;br /&gt;
&lt;br /&gt;
=== Extra functions ===&lt;br /&gt;
It is possible to submit code that is executed when µGFX is being initialized and deinitialized through &amp;lt;code&amp;gt;GFX_OS_EXTRA_INIT_FUNCTION&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GFX_OS_EXTRA_DEINIT_FUNCTION&amp;lt;/code&amp;gt;. The functions have to have no parameters and &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; as return type.&lt;br /&gt;
&lt;br /&gt;
=== Emulating Malloc ===&lt;br /&gt;
An uGFX application should '''always''' use &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; instead of the corresponding C library functions to ensure portability. However, sometimes external libraries are used within an uGFX applications. External libraries might call &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; which can lead to both compile-time and run-time errors when mixing with the corresponding uGFX functions due to multiple reasons:&lt;br /&gt;
* uGFX allows to compile programs without a clib&lt;br /&gt;
* On certain platforms uGFX will implements its own heap manager that cannot be used together with the clib one&lt;br /&gt;
&lt;br /&gt;
To avoid this problem, &amp;lt;code&amp;gt;GFX_EMULATE_MALLOC&amp;lt;/code&amp;gt; can be set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]].&lt;br /&gt;
When &amp;lt;code&amp;gt;GFX_EMULATE_MALLOC&amp;lt;/code&amp;gt; is enabled, the &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; functions will be defined as wrappers to the corresponding &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; functions:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if GFX_EMULATE_MALLOC&lt;br /&gt;
    #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    void* malloc(size_t size)&lt;br /&gt;
    {&lt;br /&gt;
        return gfxAlloc(size);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void free(void* ptr)&lt;br /&gt;
    {&lt;br /&gt;
        gfxFree(ptr);&lt;br /&gt;
    }&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Threading ==&lt;br /&gt;
It is highly recommended to use the uGFX API to create and manage threads. This way the application is fully portable. In most cases these are just 1:1 wrappers to the calls from the underlying operating systems so there is no  additional overhead.&lt;br /&gt;
&lt;br /&gt;
Please take a look at the [http://api.ugfx.org/master/group___g_o_s.html API reference] of the GOS module to learn about all the available functions.&lt;br /&gt;
&lt;br /&gt;
The following demos which can be found in the uGFX repository show how to properly use the threading API:&lt;br /&gt;
* ''/demos/modules/gos/threads''&lt;br /&gt;
* ''/demos/modules/gos/threads_advanced''&lt;br /&gt;
&lt;br /&gt;
=== Thread priority ===&lt;br /&gt;
The number of different thread priorities is not clearly defined as every underlying operating system implements this feature differently. However, the GOS module ensures that the following three priority levels are defined:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
LOW_PRIORITY&lt;br /&gt;
NORMAL_PRIORITY&lt;br /&gt;
HIGH_PRIORITY&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As thread priorities are usually implemented in form of integer variables, you can increment and decrement these defines in order to further split the thread priorities. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
/* Normal priority thread */&lt;br /&gt;
NORMAL_PRIORITY&lt;br /&gt;
&lt;br /&gt;
/* High priority thread */&lt;br /&gt;
HIGH_PRIORITY&lt;br /&gt;
&lt;br /&gt;
/* A thread that has a slightly higher priority than the normal priority but with a still smaller priority than the high priroty thread */&lt;br /&gt;
NORMAL_PRIORITY + 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Terminating a thread ===&lt;br /&gt;
The uGFX API does not provide any function to terminate a running thread. This is due to the fact that only very few operating systems provide the feature to terminate a running thread from within another thread. However, it's still possible to ''tell'' a thread to terminate itself. This can for example be accomplished by implementing a 'falling over the edge' algorithm where a variable is passed to the custom parameter of the thread function. The thread will frequently check this variable which tells whether the thread should return or not. As the variable is only passed as a pointer it can be modified out of another thread.&lt;br /&gt;
&lt;br /&gt;
The ''/demos/modules/gos/threads_advanced'' demo shows how to implement such an algorithm. Basically it looks like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
threadreturn_t threadFunction(void* param)&lt;br /&gt;
{	&lt;br /&gt;
	/* Cast the paramter into a bool pointer so we can use it */&lt;br /&gt;
	bool_t* doExit = (bool_t*)param;&lt;br /&gt;
&lt;br /&gt;
	/* Execute this until we shall be terminated */&lt;br /&gt;
	while (*doExit == FALSE) {&lt;br /&gt;
                /* Do the actual work... */&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Don't return anything (or return something) */&lt;br /&gt;
	return (threadreturn_t)0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
        bool_t exitThread = FALSE;&lt;br /&gt;
&lt;br /&gt;
        /* Start the thread and pass the variable as a parameter to tell the thread to terminate later */&lt;br /&gt;
        gfxThreadCreate(NULL, 128, NORMAL_PRIORITY, threadFunction, (void*)&amp;amp;exitThread);&lt;br /&gt;
&lt;br /&gt;
        /* Tell the thread to return */&lt;br /&gt;
        exitThread = TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Memory management ==&lt;br /&gt;
It is highly recommended to use the uGFX API for memory management. This way the application is fully portable. In most cases these calls are just 1:1 wrappers to the calls from the underlying operating system so there is no additional overhead.&lt;br /&gt;
Have a look at [[GOS#Emulating_Malloc|Emulating Malloc]] in case of you have to use external libraries that use &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Please take a look at the [[#API_reference|API reference]] of the GOS module to learn about all the available functions.&lt;br /&gt;
&lt;br /&gt;
== Existing ports ==&lt;br /&gt;
The following ports already exist and are part of the official repository:&lt;br /&gt;
&lt;br /&gt;
* BareMetal   (no OS at all)&lt;br /&gt;
* ChibiOS/RT&lt;br /&gt;
* CMSIS RTOS&lt;br /&gt;
* eCos&lt;br /&gt;
* Zephyr&lt;br /&gt;
* FreeRTOS&lt;br /&gt;
* Keil RTX&lt;br /&gt;
* NIOS-II&lt;br /&gt;
* rawrtos&lt;br /&gt;
* Arduino&lt;br /&gt;
* Teensy&lt;br /&gt;
* SylixOS&lt;br /&gt;
* Linux&lt;br /&gt;
* FreeBSD&lt;br /&gt;
* Mac OS X&lt;br /&gt;
* Windows&lt;br /&gt;
* And most likely more because we forgot to update this list.&lt;br /&gt;
&lt;br /&gt;
Please have a look at the '''Using µGFX on...''' section on the [[Main Page]] to find links to the corresponding articles that give information about each of these ports.&lt;br /&gt;
&lt;br /&gt;
=== BareMetal ===&lt;br /&gt;
It's possible to run µGFX directly on a bare-metal system without any underlying OS using the RAW32 port.&lt;br /&gt;
&lt;br /&gt;
== Porting ==&lt;br /&gt;
Porting uGFX to a new underlying system is fairly easy. Only a couple of functions and data types have to be implemented and declared.&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
void            gfxHalt(const char *msg);&lt;br /&gt;
void            gfxExit(void);&lt;br /&gt;
void*           gfxAlloc(size_t sz);&lt;br /&gt;
void*           gfxRealloc(void *p, size_t oldsz, size_t newsz);&lt;br /&gt;
void            gfxFree(void *ptr);&lt;br /&gt;
void            gfxYield(void);&lt;br /&gt;
void            gfxSleepMilliseconds(delaytime_t ms);&lt;br /&gt;
void            gfxSleepMicroseconds(delaytime_t ms);&lt;br /&gt;
systemticks_t   gfxSystemTicks(void);&lt;br /&gt;
systemticks_t   gfxMillisecondsToTicks(delaytime_t ms);&lt;br /&gt;
void            gfxSystemLock(void);&lt;br /&gt;
void            gfxSystemUnlock(void);&lt;br /&gt;
void            gfxMutexInit(gfxMutex *pmutex);&lt;br /&gt;
void            gfxMutexDestroy(gfxMutex *pmutex);&lt;br /&gt;
void            gfxMutexEnter(gfxMutex *pmutex);&lt;br /&gt;
void            gfxMutexExit(gfxMutex *pmutex);&lt;br /&gt;
void            gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit);&lt;br /&gt;
void            gfxSemDestroy(gfxSem *psem);&lt;br /&gt;
bool_t          gfxSemWait(gfxSem *psem, delaytime_t ms);&lt;br /&gt;
void            gfxSemSignal(gfxSem *psem);&lt;br /&gt;
void            gfxSemSignalI(gfxSem *psem);&lt;br /&gt;
semcount_t      gfxSemCounter(gfxSem *pSem);&lt;br /&gt;
semcount_t      gfxSemCounterI(gfxSem *pSem);&lt;br /&gt;
gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);&lt;br /&gt;
threadreturn_t  gfxThreadWait(gfxThreadHandle thread);&lt;br /&gt;
gfxThreadHandle gfxThreadMe(void)&lt;br /&gt;
void            gfxThreadClose(gfxThreadHandle thread);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
When creating a new port, taking a look at existing ones can help a lot. The existing ports can be found under ''/src/gos/''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Module]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1952</id>
		<title>FreeBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1952"/>
				<updated>2021-09-24T00:00:37Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can be compiled into native FreeBSD applications. This is especially useful for developing µGFX applications on a Desktop machine.&lt;br /&gt;
The SDL2 library is used to spawn a desktop window. Mouse &amp;amp; keyboard inputs are supported.&lt;br /&gt;
&lt;br /&gt;
= Dependencies =&lt;br /&gt;
The following dependencies are required:&lt;br /&gt;
* GCC (eg. &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc10 lang/gcc10]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc11 lang/gcc11]&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/gmake/ devel/gmake]&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/sdl2 devel/sdl2]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Makefile =&lt;br /&gt;
A sample Makefile can be found under &amp;lt;code&amp;gt;/boards/base/FreeBSD-SDL/example/Makefile&amp;lt;/code&amp;gt;. Copy it to your project directory.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1951</id>
		<title>FreeBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1951"/>
				<updated>2021-09-23T23:56:26Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Dependencies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can be compiled into native FreeBSD applications. This is especially useful for developing µGFX applications on a Desktop machine.&lt;br /&gt;
The SDL2 library is used to spawn a desktop window. Mouse &amp;amp; keyboard inputs are supported.&lt;br /&gt;
&lt;br /&gt;
= Dependencies =&lt;br /&gt;
The following dependencies are required:&lt;br /&gt;
* GCC (eg. &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc10 lang/gcc10]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;[https://www.freshports.org/lang/gcc11 lang/gcc11]&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/gmake/ devel/gmake]&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/sdl2 devel/sdl2]&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1950</id>
		<title>FreeBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1950"/>
				<updated>2021-09-23T23:54:15Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can be compiled into native FreeBSD applications. This is especially useful for developing µGFX applications on a Desktop machine.&lt;br /&gt;
The SDL2 library is used to spawn a desktop window. Mouse &amp;amp; keyboard inputs are supported.&lt;br /&gt;
&lt;br /&gt;
= Dependencies =&lt;br /&gt;
The following dependencies are required:&lt;br /&gt;
* GCC (eg. &amp;lt;code&amp;gt;devel/gcc10&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;devel/gcc11&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[https://www.freshports.org/devel/gmake/ devel/gmake]&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1949</id>
		<title>FreeBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=FreeBSD&amp;diff=1949"/>
				<updated>2021-09-23T23:52:22Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: Created page with &amp;quot;µGFX can be compiled into native FreeBSD applications. This is especially useful for developing µGFX applications on a Desktop machine. The SDL2 library is used to spawn a d...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can be compiled into native FreeBSD applications. This is especially useful for developing µGFX applications on a Desktop machine.&lt;br /&gt;
The SDL2 library is used to spawn a desktop window. Mouse &amp;amp; keyboard inputs are supported.&lt;br /&gt;
&lt;br /&gt;
= Dependencies =&lt;br /&gt;
As of today, we recommend using GCC for compiling µGFX applications on FreeBSD.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Main_Page&amp;diff=1948</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Main_Page&amp;diff=1948"/>
				<updated>2021-09-23T23:48:59Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;div-header&amp;quot;&amp;gt;Welcome to the µGFX wiki!&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot;&amp;gt;This is the official documentation of the [http://ugfx.io µGFX] library. Please note that this is just the documentation, the official project website can be found at [http://ugfx.io ugfx.io]. The API reference can be found at [http://api.ugfx.io api.ugfx.io].&lt;br /&gt;
&lt;br /&gt;
If you're new to µGFX, begin by reading [[Getting Started]].&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;width: 50%; float: left;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;General&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Getting Started]]&lt;br /&gt;
* [[Configuration]]&lt;br /&gt;
* [[Architecture]]&lt;br /&gt;
* [[Board File]]&lt;br /&gt;
* [[Types]]&lt;br /&gt;
* [[API Reference]]&lt;br /&gt;
* [[Changes from V2.x to V3.0]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;Using µGFX on...&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[BareMetal]]&lt;br /&gt;
* [[CMSIS RTOS]]&lt;br /&gt;
* [[ChibiOS/RT]]&lt;br /&gt;
* [[FreeRTOS]]&lt;br /&gt;
* [[RawOS]]&lt;br /&gt;
* [[eCos]]&lt;br /&gt;
* [[Zephyr]]&lt;br /&gt;
* [[Using_Keil_µVision_5_MDK-ARM|Keil RTX]]&lt;br /&gt;
* [[Teensy]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Linux]]&lt;br /&gt;
* [[Win32]]&lt;br /&gt;
* [[Mac OS X]]&lt;br /&gt;
* [[FreeBSD]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;Using IDEs&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Using Keil µVision 5 MDK-ARM|Keil µVision 5 MDK-ARM]]&lt;br /&gt;
* [[Using IAR embedded workbench|IAR embedded workbench]]&lt;br /&gt;
* [[Using Eclipse|Eclipse]]&lt;br /&gt;
* [[Using PSoC Creator|PSoC Creator]]&lt;br /&gt;
* [[Using ChibiStudio|ChibiStudio]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;Developer Guides&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Your First Compile - Windows]]&lt;br /&gt;
* [[Creating a custom rendering routine]]&lt;br /&gt;
* [[Creating a widget]]&lt;br /&gt;
* [[Use_uGFX_repository_as_Git_Submodule|Advanced git guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;µGFX Design Choices&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Display Driver Model]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;width: 50%; float: right;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-left: 5px;&amp;quot;&amp;gt;Modules&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-left: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[GWIN]]&lt;br /&gt;
** [[Windows]]&lt;br /&gt;
*** [[Console]]&lt;br /&gt;
*** [[Graph]]&lt;br /&gt;
** [[Widgets]]&lt;br /&gt;
*** [[Label]]&lt;br /&gt;
*** [[PushButton]]&lt;br /&gt;
*** [[RadioButton]]&lt;br /&gt;
*** [[CheckBox]]&lt;br /&gt;
*** [[List]]&lt;br /&gt;
*** [[Slider]]&lt;br /&gt;
*** [[Progressbar]]&lt;br /&gt;
*** [[ImageBox]]&lt;br /&gt;
*** [[TextEdit]]&lt;br /&gt;
*** [[Keyboard]]&lt;br /&gt;
** [[Containers]]&lt;br /&gt;
*** [[Container]]&lt;br /&gt;
*** [[Tabset]]&lt;br /&gt;
*** [[Frame]]&lt;br /&gt;
* [[GAUDIO]]&lt;br /&gt;
* [[GFILE]]&lt;br /&gt;
* [[GOS]]&lt;br /&gt;
* [[GDISP]]&lt;br /&gt;
** [[Drawing]]&lt;br /&gt;
** [[Font rendering]]&lt;br /&gt;
** [[Images]]&lt;br /&gt;
* [[GINPUT]]&lt;br /&gt;
* [[GTRANS]]&lt;br /&gt;
* [[GEVENT]]&lt;br /&gt;
* [[GTIMER]]&lt;br /&gt;
* [[GQUEUE]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Creating_a_widget&amp;diff=1947</id>
		<title>Creating a widget</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Creating_a_widget&amp;diff=1947"/>
				<updated>2021-09-09T10:09:12Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It's possible to implement custom widgets. A custom widget can be declared and implemented outside of the µGFX library. This means that it can be part of the actual project and that it's not necessary to do any modification of the µGFX library itself. The first half of this article will explain how widgets are implemented an whats needed to create a custom widget. The second half of the article is a step-by-step guide that will show how to actually implement a custom widget based on an example.&lt;br /&gt;
&lt;br /&gt;
It's vital that you've read the [[GWIN]] article and the corresponding sub-articles about [[windows]], [[widgets]] and [[containers]] before following this guide.&lt;br /&gt;
&lt;br /&gt;
'''''Note:''' If you just want to change the look of an existing widget, please have a look at [[Widgets#Widget_Style|WidgetStyles]] and [[Creating_a_custom_rendering_routine|custom rendering functions]].''&lt;br /&gt;
&lt;br /&gt;
== Theory of operation ==&lt;br /&gt;
A widget consists of three main parts: The '''object structure''', the '''VMT''' and the '''rendering routine'''.&lt;br /&gt;
A widget is usually split into two source files: The header file and the source file (for example &amp;lt;code&amp;gt;mywidget.h&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mywidget.c&amp;lt;/code&amp;gt;. The header file contains the '''object structure''' and the public API functions. The source file contains the '''VMT''', the '''rendering routine''' and the implementations of all the required functions.&lt;br /&gt;
&lt;br /&gt;
=== Object structure ===&lt;br /&gt;
The C language is not object oriented - yet it's possible to write object oriented software without any problems. The philosophy is to create a struct which is ''the object'' and to pass that struct as the first parameter to any function that has to have access to the object. A widget is an object and hence it needs a struct that defines the object. The only thing that makes the widget object struct become a ''widget'' struct is that the very first field is a &amp;lt;code&amp;gt;GWidgetObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct StatusbarObject_t {&lt;br /&gt;
    GWidgetObject w;  // Base Class&lt;br /&gt;
} StatusbarObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Note that it is '''absolutely mandatory''' that the &amp;lt;code&amp;gt;GWidgetObject&amp;lt;/code&amp;gt; is the very first field in the struct. This is needed to implement inheritance and polymorphism. After that first field you can add any field you want to the widget object struct. For example, a slider would add fields to hold the ''minimum'', ''maximum'' and ''current'' value. A list widget would hold a list of items here. A text edit (line edit) would hold the current cursor position and so on. In terms of an object oriented language this is the &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt; area of the class.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct widgetObject_t {&lt;br /&gt;
    GWidgetObject w;  // Base Class&lt;br /&gt;
&lt;br /&gt;
    uint8_t  myVariable1;&lt;br /&gt;
    char*    someOtherStuff;&lt;br /&gt;
    uint16_t currentValue;&lt;br /&gt;
} WidgetObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;GWidgetObject&amp;lt;/code&amp;gt; itself is based on a &amp;lt;code&amp;gt;GWindowObject&amp;lt;/code&amp;gt; as explained in the article about [[widgets]]. Therefore, the following attributes are already part of our &amp;lt;code&amp;gt;WidgetObject&amp;lt;/code&amp;gt; and don't need to be added manually:&lt;br /&gt;
* Position relative to parent (x, y)&lt;br /&gt;
* Dimensions (width, height)&lt;br /&gt;
* Parent&lt;br /&gt;
* [[Font_rendering|Font]]&lt;br /&gt;
* Text&lt;br /&gt;
* [[Widgets#Widget_Style|WidgetStyle]]&lt;br /&gt;
* [[Widgets#Tag|Widget Tag]]&lt;br /&gt;
* Flags&lt;br /&gt;
The widget object is the widget itself: It's what the user of the widget will create an instance of. The widget object must be available to the outside world. Therefore, the widget object must be declared in the header file (referred to as &amp;lt;code&amp;gt;mywidget.h&amp;lt;/code&amp;gt; above).&lt;br /&gt;
&lt;br /&gt;
==== Flags ====&lt;br /&gt;
The flags need some explanation: The &amp;lt;code&amp;gt;GWindowObject&amp;lt;/code&amp;gt; contains a field of the type &amp;lt;code&amp;gt;uint32_t&amp;lt;/code&amp;gt; and can therefore represent 32 flags. Some of these flags are used by the GWIN module internally to store certain information like the enable state, the visibility, whether the widget was allocated dynamically and so on. However, the first 8 bits are reserved for widget internal use. For example, the [[PushButton|pushbutton widget]] uses one of these bits to keep record of the pressed/release state. The [[Label|label widget]] uses the flags to keep the information whether the a border around the text should be rendered and so on.&lt;br /&gt;
Flags are usually used to define the state of a widget and are therefore often used in the rendering routine. For example, the [[PushButton]] widget uses the flags to store the ''pressed/released'' state. As it's possible to create a [[custom rendering routine]] outside of the widget the author of the custom rendering routine needs to have access to those flags. Therefore, the flags should be defined in the header file.&lt;br /&gt;
&lt;br /&gt;
=== VMT ===&lt;br /&gt;
The VMT ([https://en.wikipedia.org/wiki/Virtual_method_table virtual method table]) is a mechanism to implement dynamic function binding. In case of C it's a simple struct containing [https://en.wikipedia.org/wiki/Function_pointer function pointers]. The VMT technique allows to implement ''virtual methods'' in our C-classes.&lt;br /&gt;
The VMT is defined by the GWIN module. The custom widget simply creates an instance of that struct and fills in the functions pointers.&lt;br /&gt;
The GWIN module defines a VMT for each type of GWIN element: [[Window]], [[widget]] and [[container]]. As a widget inherits from the window the widget VMT actually contains the window VMT. The VMTs declarations look like this (taken from ''/src/gwin/gwin_class.h''):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * @brief   The Virtual Method Table for a GWIN window&lt;br /&gt;
 * @{&lt;br /&gt;
 */&lt;br /&gt;
typedef struct gwinVMT {&lt;br /&gt;
    const char *        classname;                      /**&amp;lt; The GWIN classname (mandatory) */&lt;br /&gt;
    size_t              size;                           /**&amp;lt; The size of the class object */&lt;br /&gt;
    void (*Destroy)     (GWindowObject *gh);            /**&amp;lt; The GWIN destroy function (optional) */&lt;br /&gt;
    void (*Redraw)      (GWindowObject *gh);            /**&amp;lt; The GWIN redraw routine (optional) */&lt;br /&gt;
    void (*AfterClear)  (GWindowObject *gh);            /**&amp;lt; The GWIN after-clear function (optional) */&lt;br /&gt;
} gwinVMT;&lt;br /&gt;
/** @} */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @brief   The Virtual Method Table for a widget&lt;br /&gt;
 * @note    A widget must have a destroy function. Either use @p _gwidgetDestroy() or use your own function&lt;br /&gt;
 *          which internally calls @p _gwidgetDestroy().&lt;br /&gt;
 * @note    A widget must have a redraw function. Use @p _gwidgetRedraw().&lt;br /&gt;
 * @note    If toggleroles != 0, ToggleAssign(), ToggleGet() and one or both of ToggleOff() and ToggleOn() must be specified.&lt;br /&gt;
 * @note    If dialroles != 0, DialAssign(), DialGet() and DialMove() must be specified.&lt;br /&gt;
 * @{&lt;br /&gt;
 */&lt;br /&gt;
typedef struct gwidgetVMT {&lt;br /&gt;
    struct gwinVMT                  g;                                                                  /**&amp;lt; This is still a GWIN */&lt;br /&gt;
    void (*DefaultDraw)             (GWidgetObject *gw, void *param);                                   /**&amp;lt; The default drawing routine (mandatory) */&lt;br /&gt;
    #if GINPUT_NEED_MOUSE&lt;br /&gt;
        struct {&lt;br /&gt;
            void (*MouseDown)       (GWidgetObject *gw, coord_t x, coord_t y);                          /**&amp;lt; Process mouse down events (optional) */&lt;br /&gt;
            void (*MouseUp)         (GWidgetObject *gw, coord_t x, coord_t y);                          /**&amp;lt; Process mouse up events (optional) */&lt;br /&gt;
            void (*MouseMove)       (GWidgetObject *gw, coord_t x, coord_t y);                          /**&amp;lt; Process mouse move events (optional) */&lt;br /&gt;
        };&lt;br /&gt;
    #endif&lt;br /&gt;
    #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD&lt;br /&gt;
        struct {&lt;br /&gt;
            void (*KeyboardEvent)   (GWidgetObject *gw, GEventKeyboard *pke);                           /**&amp;lt; Process keyboard events (optional) */&lt;br /&gt;
        };&lt;br /&gt;
    #endif&lt;br /&gt;
    #if GINPUT_NEED_TOGGLE&lt;br /&gt;
        struct {&lt;br /&gt;
            uint16_t                toggleroles;                                                        /**&amp;lt; The roles supported for toggles (0-&amp;gt;toggleroles-1) */&lt;br /&gt;
            void (*ToggleAssign)    (GWidgetObject *gw, uint16_t role, uint16_t instance);              /**&amp;lt; Assign a toggle to a role (optional) */&lt;br /&gt;
            uint16_t (*ToggleGet)   (GWidgetObject *gw, uint16_t role);                                 /**&amp;lt; Return the instance for a particular role (optional) */&lt;br /&gt;
            void (*ToggleOff)       (GWidgetObject *gw, uint16_t role);                                 /**&amp;lt; Process toggle off events (optional) */&lt;br /&gt;
            void (*ToggleOn)        (GWidgetObject *gw, uint16_t role);                                 /**&amp;lt; Process toggle on events (optional) */&lt;br /&gt;
        };&lt;br /&gt;
    #endif&lt;br /&gt;
    #if GINPUT_NEED_DIAL&lt;br /&gt;
        struct {&lt;br /&gt;
            uint16_t                dialroles;                                                          /**&amp;lt; The roles supported for dials (0-&amp;gt;dialroles-1) */&lt;br /&gt;
            void (*DialAssign)      (GWidgetObject *gw, uint16_t role, uint16_t instance);              /**&amp;lt; Test the role and save the dial instance handle (optional) */&lt;br /&gt;
            uint16_t (*DialGet)     (GWidgetObject *gw, uint16_t role);                                 /**&amp;lt; Return the instance for a particular role (optional) */&lt;br /&gt;
            void (*DialMove)        (GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max);   /**&amp;lt; Process dial move events (optional) */&lt;br /&gt;
        };&lt;br /&gt;
    #endif&lt;br /&gt;
} gwidgetVMT;&lt;br /&gt;
/** @} */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @brief   The Virtual Method Table for a container&lt;br /&gt;
 * @note    A container must have a destroy function. Either use @p _gcontainerDestroy() or use your own function&lt;br /&gt;
 *          which internally calls @p _gcontainerDestroy().&lt;br /&gt;
 * @note    A container must have a gwin redraw function. Use @p _containerRedraw().&lt;br /&gt;
 * @note    If toggleroles != 0, ToggleAssign(), ToggleGet() and one or both of ToggleOff() and ToggleOn() must be specified.&lt;br /&gt;
 * @note    If dialroles != 0, DialAssign(), DialGet() and DialMove() must be specified.&lt;br /&gt;
 * @{&lt;br /&gt;
 */&lt;br /&gt;
typedef struct gcontainerVMT {&lt;br /&gt;
    gwidgetVMT  gw;&lt;br /&gt;
    coord_t (*LeftBorder)       (GHandle gh);                           /**&amp;lt; The size of the left border (mandatory) */&lt;br /&gt;
    coord_t (*TopBorder)        (GHandle gh);                           /**&amp;lt; The size of the top border (mandatory) */&lt;br /&gt;
    coord_t (*RightBorder)      (GHandle gh);                           /**&amp;lt; The size of the right border (mandatory) */&lt;br /&gt;
    coord_t (*BottomBorder)     (GHandle gh);                           /**&amp;lt; The size of the bottom border (mandatory) */&lt;br /&gt;
    void (*NotifyAdd)           (GHandle gh, GHandle ghChild);          /**&amp;lt; Notification that a child has been added (optional) */&lt;br /&gt;
    void (*NotifyDelete)        (GHandle gh, GHandle ghChild);          /**&amp;lt; Notification that a child has been deleted (optional) */&lt;br /&gt;
} gcontainerVMT;&lt;br /&gt;
/** @} */&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Note how the VMTs reflect the inheritance of the GWIN elements: [[Windows]], [[widgets]] and [[containers]]. If you want to implement a widget, you don't have to implement the container VMT.&lt;br /&gt;
&lt;br /&gt;
As the VMT is private to the widget itself it's declared in the source file (earlier referred to as &amp;lt;code&amp;gt;mywidget.c&amp;lt;/code&amp;gt;). To have access to the different predefined VMTs the source file must include the file ''src/gwin/gwin_class.h'': &amp;lt;code&amp;gt;#include &amp;quot;src/gwin/gwin_class.h&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Function pointers ====&lt;br /&gt;
The function pointer declarations in the VMT specify the signature of a function (the return type and the parameters the function takes). In order to be able to register a function in the VMT, the function must match that exact signature. Let's have a look at the function to render/draw the widget:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void (*DefaultDraw) (GWidgetObject* gw, void* param);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This means that our own function that we will write to render the widget must look like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void myRenderingFunction(GWidgetObject* gw, void* param) { ... }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Note that the function pointer in the VMT doesn't specify the name of the function. The name '''DefaultDraw''' is only used internally by the GWIN module to ''call'' the function. You can assign a function with any name as long as the function signature matches the one from the function pointer declaration.&lt;br /&gt;
Once a function has been declared it can be added to the VMT by simply typing the actual function name in the corresponding field in the VMT:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot; highlight=&amp;quot;1,16&amp;quot;&amp;gt;&lt;br /&gt;
void myRenderingFunction(GWidgetObject* gw, void* param)&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
static const gwidgetVMT mywidgetVMT = {&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;MyWideget&amp;quot;,                // The classname&lt;br /&gt;
        sizeof(MyWidgetObject),     // The object size&lt;br /&gt;
        _gwidgetDestroy,            // The destroy routine&lt;br /&gt;
        _gwidgetRedraw,             // The redraw routine&lt;br /&gt;
        0,                          // The after-clear routine&lt;br /&gt;
    },&lt;br /&gt;
    myRenderingFunction,            // The default drawing routine&lt;br /&gt;
    #if GINPUT_NEED_MOUSE&lt;br /&gt;
        {&lt;br /&gt;
            0,                      // Process mouse down events&lt;br /&gt;
            0,                      // Process mouse up events&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Available functions ====&lt;br /&gt;
The following table contains a short explanation for each field in the VMT:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; style=&amp;quot;white-space: nowrap;&amp;quot;|Name&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; style=&amp;quot;white-space: nowrap;&amp;quot;|Type&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; style=&amp;quot;white-space: nowrap;&amp;quot;|Required&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; style=&amp;quot;white-space: nowrap;&amp;quot;|Description&lt;br /&gt;
 |-&lt;br /&gt;
 |classname&lt;br /&gt;
 |const char*&lt;br /&gt;
 |Yes&lt;br /&gt;
 |The name of the class (the widget name).&lt;br /&gt;
 |-&lt;br /&gt;
 |size&lt;br /&gt;
 |size_t&lt;br /&gt;
 |Yes&lt;br /&gt;
 |The size of the class (usually &amp;lt;code&amp;gt;sizeof(WidgetObject)&amp;lt;/code&amp;gt;).&lt;br /&gt;
 |-&lt;br /&gt;
 |Destroy&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |Yes&lt;br /&gt;
 |A function that is called when the object is destroyed. Use &amp;lt;code&amp;gt;_gwidgetDestroy&amp;lt;/code&amp;gt; as a default value.&lt;br /&gt;
 |-&lt;br /&gt;
 |Redraw&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |Yes&lt;br /&gt;
 |A function that is called when the need to be redrawn. Note that for widget types this '''is not''' the rendering routine. Use &amp;lt;code&amp;gt;_gwidgetRedraw&amp;lt;/code&amp;gt; as a default value.&lt;br /&gt;
 |-&lt;br /&gt;
 |AfterClear&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |No&lt;br /&gt;
 |A function that will be called after the widget has been redrawn. Can be used to manually redraw some features as [[windows]] don't know how to draw themselves. Example: [[graph]].&lt;br /&gt;
 |-&lt;br /&gt;
 |DefaultDraw&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |Yes&lt;br /&gt;
 |The default rendering function for a widget.&lt;br /&gt;
 |-&lt;br /&gt;
 |MouseDown&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |No&lt;br /&gt;
 |The function that is called when a ''mouse-down'' event occurs inside the widget area. Coordinates passed as parameters are relative to the widgets coordinates.&lt;br /&gt;
 |-&lt;br /&gt;
 |MouseUp&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |No&lt;br /&gt;
 |The function that is called when a ''mouse-up'' event occurs inside the widget area. Coordinates passed as parameters are relative to the widgets coordinates.&lt;br /&gt;
 |-&lt;br /&gt;
 |MouseMove&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |No&lt;br /&gt;
 |The function that is called when a ''mouse-move'' event occurs inside the widget area. Coordinates passed as parameters are relative to the widgets coordinates.&lt;br /&gt;
 |-&lt;br /&gt;
 |KeyboardEvent&lt;br /&gt;
 |Function Pointer&lt;br /&gt;
 |No&lt;br /&gt;
 |The function that is called when a keyboard key has been pressed while the widget has focus. Note that the source of the key press can be a physical keyboard connected through the [[GINPUT]] module or the [[keyboard]] widget.&lt;br /&gt;
 |-&lt;br /&gt;
 |}&lt;br /&gt;
Note that the ''&amp;quot;Required&amp;quot;'' value just specified whether the value can be a null pointer or not. The VMT struct '''must be fully filled'''. See the example in the second part of this article.&lt;br /&gt;
&lt;br /&gt;
=== Rendering routine ===&lt;br /&gt;
This is the part that usually takes the most time when writing a custom widget: The rendering routine. A widget '''must''' have at least one built-in rendering routine which is registered as the ''default rendering routine'' in the VMT. The rendering routine is the function which draws/paints the widget on the screen. This function is called by the GWIN module whenever the widget needs to be redrawn (eg. when the visibility changed).&lt;br /&gt;
&lt;br /&gt;
For further information about rendering routines it's recommended to carefully read the article about [[custom rendering routine]]s.&lt;br /&gt;
&lt;br /&gt;
=== Creating the widget ===&lt;br /&gt;
So far we looked at how a widget is defined and how the VMT is filled in. However, we still need to actually ''create'' the widget so we can use it - the widget needs a constructor. The constructor (from here on also referred to as ''&amp;quot;the create function&amp;quot;'') is responsible for allocation and initializing the widget object and therefore the &amp;lt;code&amp;gt;GWidgetObject&amp;lt;/code&amp;gt; base class.&lt;br /&gt;
The create function has to follow a couple of rules in order to blend into the GWIN module:&lt;br /&gt;
* It returns a GHandle ''(See [[GWIN#GHandle|GHandle]])''&lt;br /&gt;
* It takes a &amp;lt;code&amp;gt;GDisplay*&amp;lt;/code&amp;gt; pointer ''(See [[GDISP#GDisplay|GDisplay]])''&lt;br /&gt;
* It takes a pointer to the widget object which it initializes&lt;br /&gt;
* It takes a pointer to a &amp;lt;code&amp;gt;GWidgetInit&amp;lt;/code&amp;gt; structure ''(See [[Widgets#Initialization|widget initialization]])''&lt;br /&gt;
* If the widget object pointer is a null pointer the function has to dynamically allocate the widget object&lt;br /&gt;
An example would look like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
GHandle mywidgetGCreate(GDisplay* g, WidgetObject* wo, GWidgetInit* pInit)&lt;br /&gt;
{&lt;br /&gt;
    // Create the base class (the actual widget)&lt;br /&gt;
    if (!(wo = (WidgetObject*)_gwidgetCreate(g, &amp;amp;wo-&amp;gt;w, pInit, &amp;amp;mywidgetVMT))) {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initialize the object struct&lt;br /&gt;
    wo-&amp;gt;myVariable1 = 0;&lt;br /&gt;
    wo-&amp;gt;currentValue = 0;&lt;br /&gt;
&lt;br /&gt;
    // Set the initial visibility&lt;br /&gt;
    gwinSetVisible((GHandle)wo, pInit-&amp;gt;g.show);&lt;br /&gt;
&lt;br /&gt;
    // Return a proper GHandle&lt;br /&gt;
    return (GHandle)wo;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Furthermore, it's recommended to have a &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; that creates an alias for the create function that doesn't take the &amp;lt;code&amp;gt;GDisplay*&amp;lt;/code&amp;gt; pointer but uses the default display instead:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define mywidgetCreate(so, pI) mywidgetGCreate(GDISP, so, pI)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Besides those rules it's possible to pass additional parameters that change the behavior of the widget. For example, the [[frame]] widget takes an additional ''flags'' parameters which specify whether there are close and min-max buttons in the widget decoration.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Various examples can be found in the download section: https://community.ugfx.io/files/category/1-%C2%B5gfx-library/&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=ROMFS&amp;diff=1946</id>
		<title>ROMFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=ROMFS&amp;diff=1946"/>
				<updated>2021-08-23T18:02:10Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ROMFS is used to store files in the flash (or anywhere else) of your target system. The file system (the files and folders it contains) are listed in a file called &amp;lt;code&amp;gt;romfs_files.h&amp;lt;/code&amp;gt; which you have to provide yourself.&lt;br /&gt;
All files you want in your ROMFS must be converted into a C array which then is #include'd into &amp;lt;code&amp;gt;romfs_files.h&amp;lt;/code&amp;gt;. This is done using the &amp;lt;code&amp;gt;file2c&amp;lt;/code&amp;gt; program which is part of the µGFX repository. It can be found under &amp;lt;code&amp;gt;/tools/file2c&amp;lt;/code&amp;gt; and it comes with precompiled binaries for Linux and Windows. However, note that we do not take any responsibility for the binaries, use them on your own risk!&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the usage of file2c:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
file2c [-dbcs] [-n name] [-f file] [inputfile] [outputfile]&lt;br /&gt;
        -?      This help&lt;br /&gt;
        -h      This help&lt;br /&gt;
        -d      Add a directory entry for the ROM file system&lt;br /&gt;
        -b      Break the arrays for compilers that won't handle large arrays&lt;br /&gt;
        -c      Declare as const (useful to ensure they end up in Flash)&lt;br /&gt;
        -s      Declare as static&lt;br /&gt;
        -n name Use &amp;quot;name&amp;quot; as the name of the array&lt;br /&gt;
        -f file Use &amp;quot;file&amp;quot; as the filename in the ROM directory entry&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Any binary can be converted to a C-Header file using the following command. In this example we convert a GIF image. Note that the file will not be image decoded, the binary information is just expressed as a C-Array so we can include it into our project.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./file2c -dcs image.gif image.h&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
A simple &amp;lt;code&amp;gt;romfs_file.h&amp;lt;/code&amp;gt; looks like the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the list of files for ROMFS.&lt;br /&gt;
 *&lt;br /&gt;
 * The files have been converted using...&lt;br /&gt;
 * 		file2c -dcs infile outfile&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;quot;image1.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image2.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image3.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The ROMFS does not provide directory handling as this would bloat. However, you can create a directory hierarchy yourself by changing the file names. For example, instead of &amp;lt;code&amp;gt;myFile.h&amp;lt;/code&amp;gt; you can name it &amp;lt;code&amp;gt;dir1/dir2/myfile.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GFILE]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=ROMFS&amp;diff=1945</id>
		<title>ROMFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=ROMFS&amp;diff=1945"/>
				<updated>2021-08-23T18:01:43Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ROMFS is used to store files in the flash (or anywhere else) of your target system. The file system (the files and folders it contains) are listed in a file called &amp;lt;code&amp;gt;romfs_files.h&amp;lt;/code&amp;gt; which you have to provide yourself.&lt;br /&gt;
All files you want in your ROMFS must be converted into a C header file which then is #include'd into &amp;lt;code&amp;gt;romfs_files.h&amp;lt;/code&amp;gt;. This is done using the &amp;lt;code&amp;gt;file2c&amp;lt;/code&amp;gt; program which is part of the µGFX repository. It can be found under &amp;lt;code&amp;gt;/tools/file2c&amp;lt;/code&amp;gt; and it comes with precompiled binaries for Linux and Windows. However, note that we do not take any responsibility for the binaries, use them on your own risk!&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the usage of file2c:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
file2c [-dbcs] [-n name] [-f file] [inputfile] [outputfile]&lt;br /&gt;
        -?      This help&lt;br /&gt;
        -h      This help&lt;br /&gt;
        -d      Add a directory entry for the ROM file system&lt;br /&gt;
        -b      Break the arrays for compilers that won't handle large arrays&lt;br /&gt;
        -c      Declare as const (useful to ensure they end up in Flash)&lt;br /&gt;
        -s      Declare as static&lt;br /&gt;
        -n name Use &amp;quot;name&amp;quot; as the name of the array&lt;br /&gt;
        -f file Use &amp;quot;file&amp;quot; as the filename in the ROM directory entry&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Any binary can be converted to a C-Header file using the following command. In this example we convert a GIF image. Note that the file will not be image decoded, the binary information is just expressed as a C-Array so we can include it into our project.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./file2c -dcs image.gif image.h&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
A simple &amp;lt;code&amp;gt;romfs_file.h&amp;lt;/code&amp;gt; looks like the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the list of files for ROMFS.&lt;br /&gt;
 *&lt;br /&gt;
 * The files have been converted using...&lt;br /&gt;
 * 		file2c -dcs infile outfile&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;quot;image1.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image2.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image3.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The ROMFS does not provide directory handling as this would bloat. However, you can create a directory hierarchy yourself by changing the file names. For example, instead of &amp;lt;code&amp;gt;myFile.h&amp;lt;/code&amp;gt; you can name it &amp;lt;code&amp;gt;dir1/dir2/myfile.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GFILE]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GTRANS&amp;diff=1944</id>
		<title>GTRANS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GTRANS&amp;diff=1944"/>
				<updated>2021-08-23T17:25:52Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* API reference */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GTRANS module allows to manage language translations. The language of an application can be changed dynamically during runtime using the GTRANS module.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GTRANS module can be found [http://api.ugfx.io/group___g_t_r_a_n_s.html here].&lt;br /&gt;
&lt;br /&gt;
== Intended usage ==&lt;br /&gt;
Each translation is specified by a &amp;lt;code&amp;gt;transTable&amp;lt;/code&amp;gt; struct which is essentially a table of strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct transTable {&lt;br /&gt;
    unsigned numEntries;     // The number of strings that this table contains&lt;br /&gt;
    const char** strings;    // The translated strings&lt;br /&gt;
} transTable;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A translatable application needs to have a base language. All translations happen relative to that base language. The base language is specified using &amp;lt;code&amp;gt;gtransSetBaseLanguage()&amp;lt;/code&amp;gt;. The current language of the application is set using &amp;lt;code&amp;gt;gtransSetLanguage()&amp;lt;/code&amp;gt;.&lt;br /&gt;
The actual translations take place by calling &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;. A string contained in the translation table of the base language is passed to &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;. The function returns the corresponding string of the current language that was set using &amp;lt;code&amp;gt;gtransSetLanguage()&amp;lt;/code&amp;gt; or the passed string if none was found.&lt;br /&gt;
&lt;br /&gt;
A wrapper macro named &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; around &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; is available to make writing and reading translatable applications easier:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define gt(str) gtransString(str)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
Calling &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; directly) uses the &amp;lt;code&amp;gt;strcmp()&amp;lt;/code&amp;gt; function of the standard C library to compare strings. This operation can take a lot of time. For performance critical applications or low-resource systems the application translation speed can be optimized by using &amp;lt;code&amp;gt;gtransIndex()&amp;lt;/code&amp;gt; (instead of &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;) which directly takes the index of the string in the translation table. However, this introduces the limitation that each string in each of the translation tables need to be at the same position (the same index). Using &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; allows to have translation tables of unequal sizes due to the nature of the translation being based on string comparison rather than index accessing of the table.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Complete examples can be found under ''/demos/modules/gtrans/'' in the uGFX library directory.&lt;br /&gt;
&lt;br /&gt;
=== Basic Example ===&lt;br /&gt;
The following code is a very simple usage example showing how the GTRANS module is used. This is a very minimalistic example with no dependencies other than the [[GDISP]] module to interface a display.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define COLOR_BACKGROUND    Silver&lt;br /&gt;
#define COLOR_TEXT          Black&lt;br /&gt;
&lt;br /&gt;
gFont font;&lt;br /&gt;
&lt;br /&gt;
// English Translation&lt;br /&gt;
static const char* EnglishStrings[] = {&lt;br /&gt;
    &amp;quot;Welcome&amp;quot;,&lt;br /&gt;
    &amp;quot;The temperature is %d degrees&amp;quot;,&lt;br /&gt;
    &amp;quot;Goodbye&amp;quot;,&lt;br /&gt;
    &amp;quot;This is a translated uGFX application&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable EnglishTranslation = { sizeof(EnglishStrings)/sizeof(EnglishStrings[0]), EnglishStrings };&lt;br /&gt;
&lt;br /&gt;
// German translation&lt;br /&gt;
static const char* GermanStrings[] = {&lt;br /&gt;
    &amp;quot;Herzlich Willkommen&amp;quot;,&lt;br /&gt;
    &amp;quot;Die Temperatur beträgt %d Grad&amp;quot;,&lt;br /&gt;
    &amp;quot;Auf Wiedersehen&amp;quot;,&lt;br /&gt;
    &amp;quot;Das ist eine übersetzte uGFX Anwendung&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable GermanTranslation = { sizeof(GermanStrings)/sizeof(GermanStrings[0]), GermanStrings };&lt;br /&gt;
&lt;br /&gt;
// French translation&lt;br /&gt;
static const char* FrenchStrings[] = {&lt;br /&gt;
    &amp;quot;Bienvenue&amp;quot;,&lt;br /&gt;
    &amp;quot;La température est de %d degrés&amp;quot;,&lt;br /&gt;
    &amp;quot;Au revoir&amp;quot;,&lt;br /&gt;
    &amp;quot;Ceci est une application traduit uGFX&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable FrenchTranslation = { sizeof(FrenchStrings)/sizeof(FrenchStrings[0]), FrenchStrings };&lt;br /&gt;
&lt;br /&gt;
void updateText()&lt;br /&gt;
{&lt;br /&gt;
    coord_t width = 400;&lt;br /&gt;
    coord_t height = 30;&lt;br /&gt;
&lt;br /&gt;
    // Translate some basic strings&lt;br /&gt;
    gdispFillStringBox(20,  20, width, height, gt(&amp;quot;Welcome&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
    gdispFillStringBox(20,  60, width, height, gt(&amp;quot;This is a translated uGFX application&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
    gdispFillStringBox(20, 100, width, height, gt(&amp;quot;Goodbye&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
&lt;br /&gt;
    // A more complex example using string formatting&lt;br /&gt;
    char buffer[128];&lt;br /&gt;
    sprintf(buffer, gt(&amp;quot;The temperature is %d degrees&amp;quot;), 18);&lt;br /&gt;
    gdispFillStringBox(20, 140, width, height, buffer, font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    // Initialize the uGFX library&lt;br /&gt;
    gfxInit();&lt;br /&gt;
    gdispClear(COLOR_BACKGROUND);&lt;br /&gt;
&lt;br /&gt;
    // Take the first font we find&lt;br /&gt;
    font = gdispOpenFont(&amp;quot;*&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // Set the base language of the application&lt;br /&gt;
    gtransSetBaseLanguage(&amp;amp;EnglishTranslation);&lt;br /&gt;
&lt;br /&gt;
    // Loop through the languages&lt;br /&gt;
    while (TRUE) {&lt;br /&gt;
        // English&lt;br /&gt;
        gtransSetLanguage(&amp;amp;EnglishTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
&lt;br /&gt;
        // German&lt;br /&gt;
        gtransSetLanguage(&amp;amp;GermanTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
&lt;br /&gt;
        // French&lt;br /&gt;
        gtransSetLanguage(&amp;amp;FrenchTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example with widgets ===&lt;br /&gt;
The GTRANS module can also be used to translate widget texts. GWIN doesn't do anything with the text set by &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; except displaying it. Therefore, the &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; respectively) function can be used directly inside of the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; call. When the current language changes, the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; function must be re-called manually. There's currently no way to tell GWIN to automatically use the string for the currently active language as this would add a lot of overhead to both the GWIN core module as well as to each widget rendering function in order to support parameter substitution.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
gwinSetText(ghMyButton, gt(&amp;quot;The temperature is %d degrees&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GTRANS&amp;diff=1943</id>
		<title>GTRANS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GTRANS&amp;diff=1943"/>
				<updated>2021-08-23T13:57:14Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Basic Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GTRANS module allows to manage language translations. The language of an application can be changed dynamically during runtime using the GTRANS module.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GTRANS module can be found [http://api.ugfx.org/group___g_t_r_a_n_s.html here].&lt;br /&gt;
&lt;br /&gt;
== Intended usage ==&lt;br /&gt;
Each translation is specified by a &amp;lt;code&amp;gt;transTable&amp;lt;/code&amp;gt; struct which is essentially a table of strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct transTable {&lt;br /&gt;
    unsigned numEntries;     // The number of strings that this table contains&lt;br /&gt;
    const char** strings;    // The translated strings&lt;br /&gt;
} transTable;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A translatable application needs to have a base language. All translations happen relative to that base language. The base language is specified using &amp;lt;code&amp;gt;gtransSetBaseLanguage()&amp;lt;/code&amp;gt;. The current language of the application is set using &amp;lt;code&amp;gt;gtransSetLanguage()&amp;lt;/code&amp;gt;.&lt;br /&gt;
The actual translations take place by calling &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;. A string contained in the translation table of the base language is passed to &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;. The function returns the corresponding string of the current language that was set using &amp;lt;code&amp;gt;gtransSetLanguage()&amp;lt;/code&amp;gt; or the passed string if none was found.&lt;br /&gt;
&lt;br /&gt;
A wrapper macro named &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; around &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; is available to make writing and reading translatable applications easier:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define gt(str) gtransString(str)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
Calling &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; directly) uses the &amp;lt;code&amp;gt;strcmp()&amp;lt;/code&amp;gt; function of the standard C library to compare strings. This operation can take a lot of time. For performance critical applications or low-resource systems the application translation speed can be optimized by using &amp;lt;code&amp;gt;gtransIndex()&amp;lt;/code&amp;gt; (instead of &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;) which directly takes the index of the string in the translation table. However, this introduces the limitation that each string in each of the translation tables need to be at the same position (the same index). Using &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; allows to have translation tables of unequal sizes due to the nature of the translation being based on string comparison rather than index accessing of the table.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Complete examples can be found under ''/demos/modules/gtrans/'' in the uGFX library directory.&lt;br /&gt;
&lt;br /&gt;
=== Basic Example ===&lt;br /&gt;
The following code is a very simple usage example showing how the GTRANS module is used. This is a very minimalistic example with no dependencies other than the [[GDISP]] module to interface a display.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define COLOR_BACKGROUND    Silver&lt;br /&gt;
#define COLOR_TEXT          Black&lt;br /&gt;
&lt;br /&gt;
gFont font;&lt;br /&gt;
&lt;br /&gt;
// English Translation&lt;br /&gt;
static const char* EnglishStrings[] = {&lt;br /&gt;
    &amp;quot;Welcome&amp;quot;,&lt;br /&gt;
    &amp;quot;The temperature is %d degrees&amp;quot;,&lt;br /&gt;
    &amp;quot;Goodbye&amp;quot;,&lt;br /&gt;
    &amp;quot;This is a translated uGFX application&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable EnglishTranslation = { sizeof(EnglishStrings)/sizeof(EnglishStrings[0]), EnglishStrings };&lt;br /&gt;
&lt;br /&gt;
// German translation&lt;br /&gt;
static const char* GermanStrings[] = {&lt;br /&gt;
    &amp;quot;Herzlich Willkommen&amp;quot;,&lt;br /&gt;
    &amp;quot;Die Temperatur beträgt %d Grad&amp;quot;,&lt;br /&gt;
    &amp;quot;Auf Wiedersehen&amp;quot;,&lt;br /&gt;
    &amp;quot;Das ist eine übersetzte uGFX Anwendung&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable GermanTranslation = { sizeof(GermanStrings)/sizeof(GermanStrings[0]), GermanStrings };&lt;br /&gt;
&lt;br /&gt;
// French translation&lt;br /&gt;
static const char* FrenchStrings[] = {&lt;br /&gt;
    &amp;quot;Bienvenue&amp;quot;,&lt;br /&gt;
    &amp;quot;La température est de %d degrés&amp;quot;,&lt;br /&gt;
    &amp;quot;Au revoir&amp;quot;,&lt;br /&gt;
    &amp;quot;Ceci est une application traduit uGFX&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable FrenchTranslation = { sizeof(FrenchStrings)/sizeof(FrenchStrings[0]), FrenchStrings };&lt;br /&gt;
&lt;br /&gt;
void updateText()&lt;br /&gt;
{&lt;br /&gt;
    coord_t width = 400;&lt;br /&gt;
    coord_t height = 30;&lt;br /&gt;
&lt;br /&gt;
    // Translate some basic strings&lt;br /&gt;
    gdispFillStringBox(20,  20, width, height, gt(&amp;quot;Welcome&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
    gdispFillStringBox(20,  60, width, height, gt(&amp;quot;This is a translated uGFX application&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
    gdispFillStringBox(20, 100, width, height, gt(&amp;quot;Goodbye&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
&lt;br /&gt;
    // A more complex example using string formatting&lt;br /&gt;
    char buffer[128];&lt;br /&gt;
    sprintf(buffer, gt(&amp;quot;The temperature is %d degrees&amp;quot;), 18);&lt;br /&gt;
    gdispFillStringBox(20, 140, width, height, buffer, font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    // Initialize the uGFX library&lt;br /&gt;
    gfxInit();&lt;br /&gt;
    gdispClear(COLOR_BACKGROUND);&lt;br /&gt;
&lt;br /&gt;
    // Take the first font we find&lt;br /&gt;
    font = gdispOpenFont(&amp;quot;*&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // Set the base language of the application&lt;br /&gt;
    gtransSetBaseLanguage(&amp;amp;EnglishTranslation);&lt;br /&gt;
&lt;br /&gt;
    // Loop through the languages&lt;br /&gt;
    while (TRUE) {&lt;br /&gt;
        // English&lt;br /&gt;
        gtransSetLanguage(&amp;amp;EnglishTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
&lt;br /&gt;
        // German&lt;br /&gt;
        gtransSetLanguage(&amp;amp;GermanTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
&lt;br /&gt;
        // French&lt;br /&gt;
        gtransSetLanguage(&amp;amp;FrenchTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example with widgets ===&lt;br /&gt;
The GTRANS module can also be used to translate widget texts. GWIN doesn't do anything with the text set by &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; except displaying it. Therefore, the &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; respectively) function can be used directly inside of the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; call. When the current language changes, the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; function must be re-called manually. There's currently no way to tell GWIN to automatically use the string for the currently active language as this would add a lot of overhead to both the GWIN core module as well as to each widget rendering function in order to support parameter substitution.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
gwinSetText(ghMyButton, gt(&amp;quot;The temperature is %d degrees&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GEVENT&amp;diff=1942</id>
		<title>GEVENT</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GEVENT&amp;diff=1942"/>
				<updated>2021-08-20T15:00:13Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* A closer look */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GEVENT module is a very powerful event system. It provides a way to create a '''many-to-many''' relationships between sources and listeners. This allows to create user interfaces which use different hardware controls such as buttons '''AND''' touchscreen inputs at the same time very easily.&lt;br /&gt;
&lt;br /&gt;
The following guide will use terms like '''listener''' and '''sources'''. If you are not familiar with those terms or if you never worked with an event system before, please read the [[GEVENT FAQ]] first.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GEVENT module can be found [http://api.ugfx.io/group___g_e_v_e_n_t.html here].&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Using GEVENT is a simple three step process:&lt;br /&gt;
&lt;br /&gt;
#Create one or more listeners&lt;br /&gt;
#Attach one or more sources to this/those listeners&lt;br /&gt;
#Wait for events&lt;br /&gt;
But let's take a closer look to these steps:&lt;br /&gt;
&lt;br /&gt;
== A closer look ==&lt;br /&gt;
After we have enabled the GEVENT module in the [[Configuration|configuration file]], we have to create at least one listener. A listener is that part of an event system which does something when a certain event has been triggered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
void geventListenerInit(GListener* pl);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Okay, so now we have a working listener but it's currently not listening to any event. We can now attach any event to that listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
gBool geventAttachSource(GListener* pl, GSourceHandle gsh, gU32 flags);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And now we're ready to take off. We can now use the &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; routine to wait for an event:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
GEvent* geventEventWait(GListener* pl, gDelay timeout);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Please note that the &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; routine is a polling routine (therefore the timeout parameter). Furthermore, the current implementation of GEVENT does not provide an event queue. An event which is triggered while you are not listening for events using &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; will simply be skipped. The reason to implement this behavior can be found in the memory and CPU usage of such a system. However, GEVENT is not meant for critical event tasks but only for user space applications.&lt;br /&gt;
&lt;br /&gt;
== A real world example ==&lt;br /&gt;
You're asking why we created a many-to-many event system? Let me show you...&lt;br /&gt;
&lt;br /&gt;
Let's asume you're building some media player device. It's very likely that you will have hardware controlls (buttons, a slider or a dial) to control the volume. However, somewhere you want to be able to control the volume over a touchscreen input as well. You would now have to create two different callbacks and update the value of one versus the other. Sure, it's no problem to do that indeed, but wouldn't it be simpler just to attach two sources to one listener? ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Module]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GEVENT&amp;diff=1941</id>
		<title>GEVENT</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GEVENT&amp;diff=1941"/>
				<updated>2021-08-20T14:59:12Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* A closer look */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GEVENT module is a very powerful event system. It provides a way to create a '''many-to-many''' relationships between sources and listeners. This allows to create user interfaces which use different hardware controls such as buttons '''AND''' touchscreen inputs at the same time very easily.&lt;br /&gt;
&lt;br /&gt;
The following guide will use terms like '''listener''' and '''sources'''. If you are not familiar with those terms or if you never worked with an event system before, please read the [[GEVENT FAQ]] first.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GEVENT module can be found [http://api.ugfx.io/group___g_e_v_e_n_t.html here].&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Using GEVENT is a simple three step process:&lt;br /&gt;
&lt;br /&gt;
#Create one or more listeners&lt;br /&gt;
#Attach one or more sources to this/those listeners&lt;br /&gt;
#Wait for events&lt;br /&gt;
But let's take a closer look to these steps:&lt;br /&gt;
&lt;br /&gt;
== A closer look ==&lt;br /&gt;
After we have enabled the GEVENT module in the [[Configuration|configuration file]], we have to create at least one listener. A listener is that part of an event system which does something when a certain event has been triggered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
void geventListenerInit(GListener *pl);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Okay, so now we have a working listener but it's currently not listening to any event. We can now attach any event to that listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
gBool geventAttachSource(GListener *pl, GSourceHandle gsh, unsigned flags);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And now we're ready to take off. We can now use the &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; routine to wait for an event:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
GEvent* geventEventWait(GListener *pl, systime_t timeout);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Please note that the &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; routine is a polling routine (therefore the timeout parameter). Furthermore, the current implementation of GEVENT does not provide an event queue. An event which is triggered while you are not listening for events using &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; will simply be skipped. The reason to implement this behavior can be found in the memory and CPU usage of such a system. However, GEVENT is not meant for critical event tasks but only for user space applications.&lt;br /&gt;
&lt;br /&gt;
== A real world example ==&lt;br /&gt;
You're asking why we created a many-to-many event system? Let me show you...&lt;br /&gt;
&lt;br /&gt;
Let's asume you're building some media player device. It's very likely that you will have hardware controlls (buttons, a slider or a dial) to control the volume. However, somewhere you want to be able to control the volume over a touchscreen input as well. You would now have to create two different callbacks and update the value of one versus the other. Sure, it's no problem to do that indeed, but wouldn't it be simpler just to attach two sources to one listener? ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Module]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GEVENT&amp;diff=1940</id>
		<title>GEVENT</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GEVENT&amp;diff=1940"/>
				<updated>2021-08-20T14:58:07Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* API reference */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GEVENT module is a very powerful event system. It provides a way to create a '''many-to-many''' relationships between sources and listeners. This allows to create user interfaces which use different hardware controls such as buttons '''AND''' touchscreen inputs at the same time very easily.&lt;br /&gt;
&lt;br /&gt;
The following guide will use terms like '''listener''' and '''sources'''. If you are not familiar with those terms or if you never worked with an event system before, please read the [[GEVENT FAQ]] first.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GEVENT module can be found [http://api.ugfx.io/group___g_e_v_e_n_t.html here].&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Using GEVENT is a simple three step process:&lt;br /&gt;
&lt;br /&gt;
#Create one or more listeners&lt;br /&gt;
#Attach one or more sources to this/those listeners&lt;br /&gt;
#Wait for events&lt;br /&gt;
But let's take a closer look to these steps:&lt;br /&gt;
&lt;br /&gt;
== A closer look ==&lt;br /&gt;
After we have enabled the GEVENT module in the [[Configuration|configuration file]], we have to create at least one listener. A listener is that part of an event system which does something when a certain event has been triggered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
void geventListenerInit(GListener *pl);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Okay, so now we have a working listener but it's currently not listening to any event. We can now attach any event to that listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
bool_t geventAttachSource(GListener *pl, GSourceHandle gsh, unsigned flags);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And now we're ready to take off. We can now use the &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; routine to wait for an event:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
GEvent* geventEventWait(GListener *pl, systime_t timeout);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Please note that the &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; routine is a polling routine (therefore the timeout parameter). Furthermore, the current implementation of GEVENT does not provide an event queue. An event which is triggered while you are not listening for events using &amp;lt;code&amp;gt;geventEventWait()&amp;lt;/code&amp;gt; will simply be skipped. The reason to implement this behavior can be found in the memory and CPU usage of such a system. However, GEVENT is not meant for critical event tasks but only for user space applications.&lt;br /&gt;
&lt;br /&gt;
== A real world example ==&lt;br /&gt;
You're asking why we created a many-to-many event system? Let me show you...&lt;br /&gt;
&lt;br /&gt;
Let's asume you're building some media player device. It's very likely that you will have hardware controlls (buttons, a slider or a dial) to control the volume. However, somewhere you want to be able to control the volume over a touchscreen input as well. You would now have to create two different callbacks and update the value of one versus the other. Sure, it's no problem to do that indeed, but wouldn't it be simpler just to attach two sources to one listener? ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Module]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Containers&amp;diff=1939</id>
		<title>Containers</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Containers&amp;diff=1939"/>
				<updated>2021-08-19T13:56:58Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Note:''' Make sure you read the [[Widgets|widget]] article first!''&lt;br /&gt;
&lt;br /&gt;
The container class is based on the widget. The main property of a container is that it can hold children. A child window inherits the attributes and properties of the parent.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The reference of the common container API can be found [http://api.ugfx.io/group___containers.html here].&lt;br /&gt;
&lt;br /&gt;
== Container Implementations ==&lt;br /&gt;
These are the currently implemented containers:&lt;br /&gt;
* [[Container]]&lt;br /&gt;
* [[Frame]]&lt;br /&gt;
* [[Tabset]]&lt;br /&gt;
&lt;br /&gt;
== Container creation ==&lt;br /&gt;
Each container provides a creation call with is named &amp;lt;code&amp;gt;gwinXxxCreate()&amp;lt;/code&amp;gt; where Xxx is the name of the container. The first parameter is either a pointer to a static container object or ''NULL''. If ''NULL'', the object will be allocated dynamically from the heap.&lt;br /&gt;
The second parameter is a pointer to a &amp;lt;code&amp;gt;GWidgetInit&amp;lt;/code&amp;gt; struct. This struct contains all the attributes which are needed to create the container (position, size, font, colors...):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
typedef struct GWidgetInit {&lt;br /&gt;
    GWindowInit                g;			// The GWIN initializer&lt;br /&gt;
    const char*                text;			// The initial text&lt;br /&gt;
    CustomWidgetDrawFunction   customDraw;		// A custom draw function - use NULL for the standard&lt;br /&gt;
    void*                      customParam;		// A parameter for the custom draw function (default = NULL)&lt;br /&gt;
    const GWidgetStyle*        customStyle;		// A custom style to use - use NULL for the default style&lt;br /&gt;
} GWidgetInit;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As the container class is based on the [[Widgets|widget]] and therefore the [[Windows|window]] class, the widget initialization structure contains a window initialization structure. See [[Windows#Window_creation|window creation]] to learn more about the window initialization structure.&amp;lt;br/&amp;gt;&lt;br /&gt;
Examples on how to use this struct correctly can be found on each container documentation page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gwinDestroy()&amp;lt;/code&amp;gt; can be used to destroy a window that is no longer needed.&lt;br /&gt;
&lt;br /&gt;
== Coordinates ==&lt;br /&gt;
The coordinates of a child are always relative to it's parent.&lt;br /&gt;
&lt;br /&gt;
As a container can have a border, &amp;lt;code&amp;gt;gwinGetInnerWidth&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gwinGetInnerHeight&amp;lt;/code&amp;gt; can be used to retrieve the dimensions of the container area that is relevant for the children.&lt;br /&gt;
&lt;br /&gt;
== Visibility ==&lt;br /&gt;
The children inherit the visibility state of their parent. However, a child can still be invisible although his parent is visible by using &amp;lt;code&amp;gt;gwinHide()&amp;lt;/code&amp;gt; on the child itself.&lt;br /&gt;
&lt;br /&gt;
== Enable state ==&lt;br /&gt;
The children inherit the enable state of their parent. However, a child can still be disabled although his parent is enabled by using &amp;lt;code&amp;gt;gwinDisable()&amp;lt;/code&amp;gt; on the child itself.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GWIN]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Label&amp;diff=1938</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Label&amp;diff=1938"/>
				<updated>2021-08-19T13:38:45Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* API reference */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A label is a simple rectangular widget which takes no input. The label will automatically redraw it the text changed. If the label is smaller than the text it displays, the text gets clipped.&lt;br /&gt;
The text of the label can be set using the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; routine.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the label widget can be found [http://api.ugfx.io/group___label.html here].&lt;br /&gt;
&lt;br /&gt;
== Border ==&lt;br /&gt;
The default drawing routine of the labels allows to enable or disable a border. This can be done using &amp;lt;code&amp;gt;gwinLabelSetBorder()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Auto scale ==&lt;br /&gt;
Applying a size of 0 to the width or the height of the label will automatically set the corresponding dimension to fit the entire label text. Updating the label text will update the label dimensions each time.&lt;br /&gt;
Note: If the the board is enabled the auto-sizing feature of the label will certainly change the look of the application.&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
By default the text of the label is left justified. The justification of the label text can be controlled through different built-in rendering functions.&lt;br /&gt;
&lt;br /&gt;
The following rendering functions are available:&lt;br /&gt;
* gwinLabelDrawJustifiedLeft&lt;br /&gt;
* gwinLabelDrawJustifiedRight&lt;br /&gt;
* gwinLabelDrawJustifiedCenter&lt;br /&gt;
&lt;br /&gt;
== Font size and color ==&lt;br /&gt;
As with any other widget the look-and-feel of the label widget can be fully customized. The font can be changed by using &amp;lt;code&amp;gt;gwinSetFont()&amp;lt;/code&amp;gt; and the font color is controlled through the [[Widgets#Widget_Style|widget styles]]. The widget rendering can be fully customized by implementing a [[Creating_a_custom_rendering_routine|custom rendering routine]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Often you want to display multiple text elements below each other where an element consists of a static text which will always be the same and some variable one. The static text is called the attribute and can be optionally set through &amp;lt;code&amp;gt;gwinLabelSetAttribute()&amp;lt;/code&amp;gt; once you enabled this feature in your [[configuration|configuration file]]. The function does also take a tab parameter which allows to align multiple labels vertically as the following example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current IP: 192.168.1.42&lt;br /&gt;
Netmask:    255.255.255.0&lt;br /&gt;
DHCP:       On&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''IMPORTANT:''' Use of the attribute capability is discouraged. This feature should be considered deprecated and will be removed in future releases. The proper way of doing this is using two separate labels.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to create a label.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GHandle ghLabel1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void)&lt;br /&gt;
{&lt;br /&gt;
    GWidgetInit wi;&lt;br /&gt;
    gwinWidgetClearInit(&amp;amp;wi);&lt;br /&gt;
 &lt;br /&gt;
    // Apply the label parameters&lt;br /&gt;
    wi.g.show = gTrue;&lt;br /&gt;
    wi.g.y = 10;&lt;br /&gt;
    wi.g.x = 10;&lt;br /&gt;
    wi.g.width = 100;&lt;br /&gt;
    wi.g.height = 20;&lt;br /&gt;
    wi.text = &amp;quot;Label 1&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Create the actual label&lt;br /&gt;
    ghLabel1 = gwinLabelCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    // Initialize the uGFX library&lt;br /&gt;
    gfxInit();&lt;br /&gt;
 &lt;br /&gt;
    // Set the widget defaults&lt;br /&gt;
    gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
    gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
    gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
    // Create the widget&lt;br /&gt;
    createWidgets();&lt;br /&gt;
 &lt;br /&gt;
    while(1) {&lt;br /&gt;
        gwinSetText(ghLabel1, &amp;quot;This is some text&amp;quot;, gTrue);&lt;br /&gt;
        gfxSleepMilliseconds(1000);&lt;br /&gt;
&lt;br /&gt;
        gwinSetText(ghLabel1, &amp;quot;Aaaand some other text&amp;quot;, gTrue);&lt;br /&gt;
        gfxSleepMilliseconds(1000);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Label&amp;diff=1937</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Label&amp;diff=1937"/>
				<updated>2021-08-19T13:28:45Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A label is a simple rectangular widget which takes no input. The label will automatically redraw it the text changed. If the label is smaller than the text it displays, the text gets clipped.&lt;br /&gt;
The text of the label can be set using the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; routine.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the label widget can be found [http://api.ugfx.org/group___label.html here].&lt;br /&gt;
&lt;br /&gt;
== Border ==&lt;br /&gt;
The default drawing routine of the labels allows to enable or disable a border. This can be done using &amp;lt;code&amp;gt;gwinLabelSetBorder()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Auto scale ==&lt;br /&gt;
Applying a size of 0 to the width or the height of the label will automatically set the corresponding dimension to fit the entire label text. Updating the label text will update the label dimensions each time.&lt;br /&gt;
Note: If the the board is enabled the auto-sizing feature of the label will certainly change the look of the application.&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
By default the text of the label is left justified. The justification of the label text can be controlled through different built-in rendering functions.&lt;br /&gt;
&lt;br /&gt;
The following rendering functions are available:&lt;br /&gt;
* gwinLabelDrawJustifiedLeft&lt;br /&gt;
* gwinLabelDrawJustifiedRight&lt;br /&gt;
* gwinLabelDrawJustifiedCenter&lt;br /&gt;
&lt;br /&gt;
== Font size and color ==&lt;br /&gt;
As with any other widget the look-and-feel of the label widget can be fully customized. The font can be changed by using &amp;lt;code&amp;gt;gwinSetFont()&amp;lt;/code&amp;gt; and the font color is controlled through the [[Widgets#Widget_Style|widget styles]]. The widget rendering can be fully customized by implementing a [[Creating_a_custom_rendering_routine|custom rendering routine]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Often you want to display multiple text elements below each other where an element consists of a static text which will always be the same and some variable one. The static text is called the attribute and can be optionally set through &amp;lt;code&amp;gt;gwinLabelSetAttribute()&amp;lt;/code&amp;gt; once you enabled this feature in your [[configuration|configuration file]]. The function does also take a tab parameter which allows to align multiple labels vertically as the following example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current IP: 192.168.1.42&lt;br /&gt;
Netmask:    255.255.255.0&lt;br /&gt;
DHCP:       On&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''IMPORTANT:''' Use of the attribute capability is discouraged. This feature should be considered deprecated and will be removed in future releases. The proper way of doing this is using two separate labels.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to create a label.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GHandle ghLabel1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void)&lt;br /&gt;
{&lt;br /&gt;
    GWidgetInit wi;&lt;br /&gt;
    gwinWidgetClearInit(&amp;amp;wi);&lt;br /&gt;
 &lt;br /&gt;
    // Apply the label parameters&lt;br /&gt;
    wi.g.show = gTrue;&lt;br /&gt;
    wi.g.y = 10;&lt;br /&gt;
    wi.g.x = 10;&lt;br /&gt;
    wi.g.width = 100;&lt;br /&gt;
    wi.g.height = 20;&lt;br /&gt;
    wi.text = &amp;quot;Label 1&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Create the actual label&lt;br /&gt;
    ghLabel1 = gwinLabelCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    // Initialize the uGFX library&lt;br /&gt;
    gfxInit();&lt;br /&gt;
 &lt;br /&gt;
    // Set the widget defaults&lt;br /&gt;
    gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
    gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
    gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
    // Create the widget&lt;br /&gt;
    createWidgets();&lt;br /&gt;
 &lt;br /&gt;
    while(1) {&lt;br /&gt;
        gwinSetText(ghLabel1, &amp;quot;This is some text&amp;quot;, gTrue);&lt;br /&gt;
        gfxSleepMilliseconds(1000);&lt;br /&gt;
&lt;br /&gt;
        gwinSetText(ghLabel1, &amp;quot;Aaaand some other text&amp;quot;, gTrue);&lt;br /&gt;
        gfxSleepMilliseconds(1000);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Label&amp;diff=1936</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Label&amp;diff=1936"/>
				<updated>2021-08-19T13:28:29Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A label is a simple rectangular widget which takes no input. The label will automatically redraw it the text changed. If the label is smaller than the text it displays, the text gets clipped.&lt;br /&gt;
The text of the label can be set using the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; routine.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the label widget can be found [http://api.ugfx.org/group___label.html here].&lt;br /&gt;
&lt;br /&gt;
== Border ==&lt;br /&gt;
The default drawing routine of the labels allows to enable or disable a border. This can be done using &amp;lt;code&amp;gt;gwinLabelSetBorder()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Auto scale ==&lt;br /&gt;
Applying a size of 0 to the width or the height of the label will automatically set the corresponding dimension to fit the entire label text. Updating the label text will update the label dimensions each time.&lt;br /&gt;
Note: If the the board is enabled the auto-sizing feature of the label will certainly change the look of the application.&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
By default the text of the label is left justified. The justification of the label text can be controlled through different built-in rendering functions.&lt;br /&gt;
&lt;br /&gt;
The following rendering functions are available:&lt;br /&gt;
* gwinLabelDrawJustifiedLeft&lt;br /&gt;
* gwinLabelDrawJustifiedRight&lt;br /&gt;
* gwinLabelDrawJustifiedCenter&lt;br /&gt;
&lt;br /&gt;
== Font size and color ==&lt;br /&gt;
As with any other widget the look-and-feel of the label widget can be fully customized. The font can be changed by using &amp;lt;code&amp;gt;gwinSetFont()&amp;lt;/code&amp;gt; and the font color is controlled through the [[Widgets#Widget_Style|widget styles]]. The widget rendering can be fully customized by implementing a [[Creating_a_custom_rendering_routine|custom rendering routine]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Often you want to display multiple text elements below each other where an element consists of a static text which will always be the same and some variable one. The static text is called the attribute and can be optionally set through &amp;lt;code&amp;gt;gwinLabelSetAttribute()&amp;lt;/code&amp;gt; once you enabled this feature in your [[configuration|configuration file]]. The function does also take a tab parameter which allows to align multiple labels vertically as the following example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current IP: 192.168.1.42&lt;br /&gt;
Netmask:    255.255.255.0&lt;br /&gt;
DHCP:       On&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''IMPORTANT:''' Use of the attribute capability is discouraged. This feature should be considered deprecated and will be removed in future releases. The proper way of doing this is using two separate labels.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to create a label.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GHandle ghLabel1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void)&lt;br /&gt;
{&lt;br /&gt;
    GWidgetInit wi;&lt;br /&gt;
    gwinWidgetClearInit(&amp;amp;wi);&lt;br /&gt;
 &lt;br /&gt;
    // Apply the label parameters&lt;br /&gt;
    wi.g.show = gTrue;&lt;br /&gt;
    wi.g.y = 10;&lt;br /&gt;
    wi.g.x = 10;&lt;br /&gt;
    wi.g.width = 100;&lt;br /&gt;
    wi.g.height = 20;&lt;br /&gt;
    wi.text = &amp;quot;Label 1&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Create the actual label&lt;br /&gt;
    ghLabel1 = gwinLabelCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    // Initialize the uGFX library&lt;br /&gt;
    gfxInit();&lt;br /&gt;
 &lt;br /&gt;
    // Set the widget defaults&lt;br /&gt;
    gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
    gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
    gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
    // Create the widget&lt;br /&gt;
    createWidgets();&lt;br /&gt;
 &lt;br /&gt;
    while(1) {&lt;br /&gt;
        gwinSetText(ghLabel1, &amp;quot;This is some text&amp;quot;, TRUE);&lt;br /&gt;
        gfxSleepMilliseconds(1000);&lt;br /&gt;
        gwinSetText(ghLabel1, &amp;quot;Aaaand some other text&amp;quot;, TRUE);&lt;br /&gt;
        gfxSleepMilliseconds(1000);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1935</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1935"/>
				<updated>2021-08-12T14:44:16Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Rendering */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Pre-Processor ==&lt;br /&gt;
For pre-processing related boolean operations (eg. &amp;lt;code&amp;gt;#if MY_FEATURE&amp;lt;/code&amp;gt;) use &amp;lt;code&amp;gt;GFXON&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GFXOFF&amp;lt;/code&amp;gt; accordingly.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI8&amp;lt;/code&amp;gt; || Signed integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU8&amp;lt;/code&amp;gt; || Unsigned integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI16&amp;lt;/code&amp;gt; || Signed integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU16&amp;lt;/code&amp;gt; || Unsigned integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI32&amp;lt;/code&amp;gt; || Signed integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU32&amp;lt;/code&amp;gt; || Unsigned integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gAny&amp;lt;/code&amp;gt; || Any type that fits into a memory pointer by type casting.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gPtr&amp;lt;/code&amp;gt; || A pointer to something in memory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gPtrDiff&amp;lt;/code&amp;gt; || The difference between two pointers.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gTicks&amp;lt;/code&amp;gt; || Type to represent a number of system ticks.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gDelay&amp;lt;/code&amp;gt; || Type to represent a a delay. The unit depends on the semantics for example number of ticks or milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gMemSize&amp;lt;/code&amp;gt; || Type to represent a size of memory (in bytes).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFileSize&amp;lt;/code&amp;gt; || Type to represent the size of a file (in bytes).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A (cartesian) coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gPoint&amp;lt;/code&amp;gt; || A point on the drawing canvas (x &amp;amp; y).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gRect&amp;lt;/code&amp;gt; || A rectangle (top left / bottom right).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gSize&amp;lt;/code&amp;gt; || A size of an area (width &amp;amp; height).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gArea&amp;lt;/code&amp;gt; || An area (top left / width &amp;amp; height).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1934</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1934"/>
				<updated>2021-08-12T14:42:30Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Basic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Pre-Processor ==&lt;br /&gt;
For pre-processing related boolean operations (eg. &amp;lt;code&amp;gt;#if MY_FEATURE&amp;lt;/code&amp;gt;) use &amp;lt;code&amp;gt;GFXON&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GFXOFF&amp;lt;/code&amp;gt; accordingly.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI8&amp;lt;/code&amp;gt; || Signed integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU8&amp;lt;/code&amp;gt; || Unsigned integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI16&amp;lt;/code&amp;gt; || Signed integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU16&amp;lt;/code&amp;gt; || Unsigned integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI32&amp;lt;/code&amp;gt; || Signed integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU32&amp;lt;/code&amp;gt; || Unsigned integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gAny&amp;lt;/code&amp;gt; || Any type that fits into a memory pointer by type casting.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gPtr&amp;lt;/code&amp;gt; || A pointer to something in memory.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gPtrDiff&amp;lt;/code&amp;gt; || The difference between two pointers.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gTicks&amp;lt;/code&amp;gt; || Type to represent a number of system ticks.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gDelay&amp;lt;/code&amp;gt; || Type to represent a a delay. The unit depends on the semantics for example number of ticks or milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gMemSize&amp;lt;/code&amp;gt; || Type to represent a size of memory (in bytes).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFileSize&amp;lt;/code&amp;gt; || Type to represent the size of a file (in bytes).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1933</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1933"/>
				<updated>2021-08-11T09:28:16Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Pre-Processor ==&lt;br /&gt;
For pre-processing related boolean operations (eg. &amp;lt;code&amp;gt;#if MY_FEATURE&amp;lt;/code&amp;gt;) use &amp;lt;code&amp;gt;GFXON&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GFXOFF&amp;lt;/code&amp;gt; accordingly.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI8&amp;lt;/code&amp;gt; || Signed integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU8&amp;lt;/code&amp;gt; || Unsigned integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI16&amp;lt;/code&amp;gt; || Signed integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU16&amp;lt;/code&amp;gt; || Unsigned integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI32&amp;lt;/code&amp;gt; || Signed integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU32&amp;lt;/code&amp;gt; || Unsigned integer at least 32 bits wide.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gTicks&amp;lt;/code&amp;gt; || Type to represent a number of system ticks.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gDelay&amp;lt;/code&amp;gt; || Type to represent a a delay. The unit depends on the semantics for example number of ticks or milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gMemSize&amp;lt;/code&amp;gt; || Type to represent a size of memory (in bytes).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFileSize&amp;lt;/code&amp;gt; || Type to represent the size of a file (in bytes).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=BareMetal&amp;diff=1932</id>
		<title>BareMetal</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=BareMetal&amp;diff=1932"/>
				<updated>2021-08-11T09:27:25Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can run on any system without any underlying OS or RTOS. The '''RAW32''' port provides all the required implementations to run on a bare metal system. The only thing required to implement by the user are two small functions which are used to calculate delays. See [[#SysTick]].&lt;br /&gt;
&lt;br /&gt;
The '''RAW32''' port also provides a multi-tasker that you can use in your own applications. The threads created are co-operative (non-preemptive) threads (you have to use &amp;lt;code&amp;gt;gfxSleepMilliseconds()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;gfxYield()&amp;lt;/code&amp;gt; to give another task a chance to run). See [[GOS#Threading|GOS]].&lt;br /&gt;
&lt;br /&gt;
== Using RAW32 ==&lt;br /&gt;
To run µGFX on a bare-metal platform without any underlying operating system, the Raw32 port has to be enabled by setting &amp;lt;code&amp;gt;GFX_USE_OS_RAW32&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
== Memory Management ==&lt;br /&gt;
µGFX can run either completely on static memory or on dynamic memory. While the first is very important for security and time critical applications it can be very tedious in generic applications. The RAW32 provides a memory manager to work with dynamic memory on any bare metal system. The following two configuration options are available:&lt;br /&gt;
* Use the µGFX built-in memory manager&lt;br /&gt;
* Use the C runtime library memory manager&lt;br /&gt;
&lt;br /&gt;
Which one is used depends on the value of &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; inside of the [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
=== Built-in memory manager ===&lt;br /&gt;
When &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; is set to a value greater than 0 then the built-in memory manager of µGFX is used. In this case the value of &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; specifies the size of the memory pool which the built-in memory manager will use.&lt;br /&gt;
&lt;br /&gt;
=== C runtime library memory manager ===&lt;br /&gt;
When &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; is set to 0 then the memory manager of the C runtime library will be used. In that case &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; are just wrappers around &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Note that many C library implementations of &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; have bugs that cause them to crash if the stack is changed (as it is for threading as required by µGFX). For this reason, if you are getting strange crashes it is advisable to use the built-in memory manager and to avoid using ''malloc()'' and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; in your own code (use &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; instead).&lt;br /&gt;
&lt;br /&gt;
== SysTick ==&lt;br /&gt;
Some parts of the µGFX library require how much time passed by. For this access to the systems tick counter (SysTick) is required. To give µGFX the ability to calculate how much time passed the following to functions need to be implemented in the users application code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
gTicks gfxSystemTicks(void);&lt;br /&gt;
gTicks gfxMillisecondsToTicks(delaytime_t ms);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The first one, &amp;lt;code&amp;gt;gfxSystemTicks()&amp;lt;/code&amp;gt;, needs to return the current value of the systick counter. The second one, &amp;lt;code&amp;gt;gfxMillisecondsToTicks()&amp;lt;/code&amp;gt; needs to convert the provided value in milliseconds to systicks.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
The following is an example showing how to implement the two functions when using an STM32F4 microcontroller using the STM32Cube HAL. Note that in this case the systick was set up to be incremented once every millisecond. If your systick updates in a different interval you need to do the corresponding calculations in ''gfxMillisecondsToTicks()''.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx_hal.h&amp;quot;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
gTicks gfxSystemTicks(void)&lt;br /&gt;
{&lt;br /&gt;
	return HAL_GetTick();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gTicks gfxMillisecondsToTicks(gDelay ms)&lt;br /&gt;
{&lt;br /&gt;
	return ms;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' It is important that &amp;lt;code&amp;gt;gfx.h&amp;lt;/code&amp;gt; is included after &amp;lt;code&amp;gt;stm32f4xx_hal.h&amp;lt;/code&amp;gt; to avoid naming conflicts when using the CubeHAL with µGFX.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1931</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1931"/>
				<updated>2021-08-06T18:21:16Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Pre-Processor ==&lt;br /&gt;
For pre-processing related boolean operations (eg. &amp;lt;code&amp;gt;#if MY_FEATURE&amp;lt;/code&amp;gt;) use &amp;lt;code&amp;gt;GFXON&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GFXOFF&amp;lt;/code&amp;gt; accordingly.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI8&amp;lt;/code&amp;gt; || Signed integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU8&amp;lt;/code&amp;gt; || Unsigned integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI16&amp;lt;/code&amp;gt; || Signed integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU16&amp;lt;/code&amp;gt; || Unsigned integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI32&amp;lt;/code&amp;gt; || Signed integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU32&amp;lt;/code&amp;gt; || Unsigned integer at least 32 bits wide.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gTicks&amp;lt;/code&amp;gt; || Type to represent a number of system ticks.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gMemSize&amp;lt;/code&amp;gt; || Type to represent a size of memory (in bytes).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFileSize&amp;lt;/code&amp;gt; || Type to represent the size of a file (in bytes).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Label&amp;diff=1930</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Label&amp;diff=1930"/>
				<updated>2021-08-06T18:20:28Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A label is a simple rectangular widget which takes no input. The label will automatically redraw it the text changed. If the label is smaller than the text it displays, the text gets clipped.&lt;br /&gt;
The text of the label can be set using the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; routine.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the label widget can be found [http://api.ugfx.org/group___label.html here].&lt;br /&gt;
&lt;br /&gt;
== Border ==&lt;br /&gt;
The default drawing routine of the labels allows to enable or disable a border. This can be done using &amp;lt;code&amp;gt;gwinLabelSetBorder()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Auto scale ==&lt;br /&gt;
Applying a size of 0 to the width or the height of the label will automatically set the corresponding dimension to fit the entire label text. Updating the label text will update the label dimensions each time.&lt;br /&gt;
Note: If the the board is enabled the auto-sizing feature of the label will certainly change the look of the application.&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
By default the text of the label is left justified. The justification of the label text can be controlled through different built-in rendering functions.&lt;br /&gt;
&lt;br /&gt;
The following rendering functions are available:&lt;br /&gt;
* gwinLabelDrawJustifiedLeft&lt;br /&gt;
* gwinLabelDrawJustifiedRight&lt;br /&gt;
* gwinLabelDrawJustifiedCenter&lt;br /&gt;
&lt;br /&gt;
== Font size and color ==&lt;br /&gt;
As with any other widget the look-and-feel of the label widget can be fully customized. The font can be changed by using &amp;lt;code&amp;gt;gwinSetFont()&amp;lt;/code&amp;gt; and the font color is controlled through the [[Widgets#Widget_Style|widget styles]]. The widget rendering can be fully customized by implementing a [[Creating_a_custom_rendering_routine|custom rendering routine]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Often you want to display multiple text elements below each other where an element consists of a static text which will always be the same and some variable one. The static text is called the attribute and can be optionally set through &amp;lt;code&amp;gt;gwinLabelSetAttribute()&amp;lt;/code&amp;gt; once you enabled this feature in your [[configuration|configuration file]]. The function does also take a tab parameter which allows to align multiple labels vertically as the following example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current IP: 192.168.1.42&lt;br /&gt;
Netmask:    255.255.255.0&lt;br /&gt;
DHCP:       On&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''IMPORTANT:''' Use of the attribute capability is discouraged. This feature should be considered deprecated and will be removed in future releases. The proper way of doing this is using two separate labels.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to create a label.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GHandle ghLabel1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void)&lt;br /&gt;
{&lt;br /&gt;
	GWidgetInit		wi;&lt;br /&gt;
 &lt;br /&gt;
	// Apply some default values for GWIN&lt;br /&gt;
	wi.customDraw = 0;&lt;br /&gt;
	wi.customParam = 0;&lt;br /&gt;
	wi.customStyle = 0;&lt;br /&gt;
	wi.g.show = gTrue;&lt;br /&gt;
 &lt;br /&gt;
	// Apply the label parameters	&lt;br /&gt;
	wi.g.y = 10;&lt;br /&gt;
	wi.g.x = 10;&lt;br /&gt;
	wi.g.width = 100;&lt;br /&gt;
	wi.g.height = 20;&lt;br /&gt;
	wi.text = &amp;quot;Label 1&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
	// Create the actual label&lt;br /&gt;
	ghLabel1 = gwinLabelCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	// Initialize the uGFX library&lt;br /&gt;
	gfxInit();&lt;br /&gt;
 &lt;br /&gt;
	// Set the widget defaults&lt;br /&gt;
	gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
	gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
	gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
	// Create the widget&lt;br /&gt;
	createWidgets();&lt;br /&gt;
 &lt;br /&gt;
	while(1) {&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;This is some text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;Aaaand some other text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Label&amp;diff=1929</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Label&amp;diff=1929"/>
				<updated>2021-08-06T18:20:12Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Border */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A label is a simple rectangular widget which takes no input. The label will automatically redraw it the text changed. If the label is smaller than the text it displays, the text gets clipped.&lt;br /&gt;
The text of the label can be set using the ''gwinSetText()'' routine.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the label widget can be found [http://api.ugfx.org/group___label.html here].&lt;br /&gt;
&lt;br /&gt;
== Border ==&lt;br /&gt;
The default drawing routine of the labels allows to enable or disable a border. This can be done using &amp;lt;code&amp;gt;gwinLabelSetBorder()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Auto scale ==&lt;br /&gt;
Applying a size of 0 to the width or the height of the label will automatically set the corresponding dimension to fit the entire label text. Updating the label text will update the label dimensions each time.&lt;br /&gt;
Note: If the the board is enabled the auto-sizing feature of the label will certainly change the look of the application.&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
By default the text of the label is left justified. The justification of the label text can be controlled through different built-in rendering functions.&lt;br /&gt;
&lt;br /&gt;
The following rendering functions are available:&lt;br /&gt;
* gwinLabelDrawJustifiedLeft&lt;br /&gt;
* gwinLabelDrawJustifiedRight&lt;br /&gt;
* gwinLabelDrawJustifiedCenter&lt;br /&gt;
&lt;br /&gt;
== Font size and color ==&lt;br /&gt;
As with any other widget the look-and-feel of the label widget can be fully customized. The font can be changed by using &amp;lt;code&amp;gt;gwinSetFont()&amp;lt;/code&amp;gt; and the font color is controlled through the [[Widgets#Widget_Style|widget styles]]. The widget rendering can be fully customized by implementing a [[Creating_a_custom_rendering_routine|custom rendering routine]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Often you want to display multiple text elements below each other where an element consists of a static text which will always be the same and some variable one. The static text is called the attribute and can be optionally set through &amp;lt;code&amp;gt;gwinLabelSetAttribute()&amp;lt;/code&amp;gt; once you enabled this feature in your [[configuration|configuration file]]. The function does also take a tab parameter which allows to align multiple labels vertically as the following example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current IP: 192.168.1.42&lt;br /&gt;
Netmask:    255.255.255.0&lt;br /&gt;
DHCP:       On&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''IMPORTANT:''' Use of the attribute capability is discouraged. This feature should be considered deprecated and will be removed in future releases. The proper way of doing this is using two separate labels.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to create a label.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GHandle ghLabel1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void)&lt;br /&gt;
{&lt;br /&gt;
	GWidgetInit		wi;&lt;br /&gt;
 &lt;br /&gt;
	// Apply some default values for GWIN&lt;br /&gt;
	wi.customDraw = 0;&lt;br /&gt;
	wi.customParam = 0;&lt;br /&gt;
	wi.customStyle = 0;&lt;br /&gt;
	wi.g.show = gTrue;&lt;br /&gt;
 &lt;br /&gt;
	// Apply the label parameters	&lt;br /&gt;
	wi.g.y = 10;&lt;br /&gt;
	wi.g.x = 10;&lt;br /&gt;
	wi.g.width = 100;&lt;br /&gt;
	wi.g.height = 20;&lt;br /&gt;
	wi.text = &amp;quot;Label 1&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
	// Create the actual label&lt;br /&gt;
	ghLabel1 = gwinLabelCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	// Initialize the uGFX library&lt;br /&gt;
	gfxInit();&lt;br /&gt;
 &lt;br /&gt;
	// Set the widget defaults&lt;br /&gt;
	gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
	gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
	gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
	// Create the widget&lt;br /&gt;
	createWidgets();&lt;br /&gt;
 &lt;br /&gt;
	while(1) {&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;This is some text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;Aaaand some other text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Label&amp;diff=1928</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Label&amp;diff=1928"/>
				<updated>2021-08-06T18:10:53Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A label is a simple rectangular widget which takes no input. The label will automatically redraw it the text changed. If the label is smaller than the text it displays, the text gets clipped.&lt;br /&gt;
The text of the label can be set using the ''gwinSetText()'' routine.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the label widget can be found [http://api.ugfx.org/group___label.html here].&lt;br /&gt;
&lt;br /&gt;
== Border ==&lt;br /&gt;
The default drawing routine of the labels allows to enable or disable a border. This can be done using gwinLabelSetBorder(). &lt;br /&gt;
&lt;br /&gt;
== Auto scale ==&lt;br /&gt;
Applying a size of 0 to the width or the height of the label will automatically set the corresponding dimension to fit the entire label text. Updating the label text will update the label dimensions each time.&lt;br /&gt;
Note: If the the board is enabled the auto-sizing feature of the label will certainly change the look of the application.&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
By default the text of the label is left justified. The justification of the label text can be controlled through different built-in rendering functions.&lt;br /&gt;
&lt;br /&gt;
The following rendering functions are available:&lt;br /&gt;
* gwinLabelDrawJustifiedLeft&lt;br /&gt;
* gwinLabelDrawJustifiedRight&lt;br /&gt;
* gwinLabelDrawJustifiedCenter&lt;br /&gt;
&lt;br /&gt;
== Font size and color ==&lt;br /&gt;
As with any other widget the look-and-feel of the label widget can be fully customized. The font can be changed by using &amp;lt;code&amp;gt;gwinSetFont()&amp;lt;/code&amp;gt; and the font color is controlled through the [[Widgets#Widget_Style|widget styles]]. The widget rendering can be fully customized by implementing a [[Creating_a_custom_rendering_routine|custom rendering routine]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Often you want to display multiple text elements below each other where an element consists of a static text which will always be the same and some variable one. The static text is called the attribute and can be optionally set through &amp;lt;code&amp;gt;gwinLabelSetAttribute()&amp;lt;/code&amp;gt; once you enabled this feature in your [[configuration|configuration file]]. The function does also take a tab parameter which allows to align multiple labels vertically as the following example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current IP: 192.168.1.42&lt;br /&gt;
Netmask:    255.255.255.0&lt;br /&gt;
DHCP:       On&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''IMPORTANT:''' Use of the attribute capability is discouraged. This feature should be considered deprecated and will be removed in future releases. The proper way of doing this is using two separate labels.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to create a label.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GHandle ghLabel1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void)&lt;br /&gt;
{&lt;br /&gt;
	GWidgetInit		wi;&lt;br /&gt;
 &lt;br /&gt;
	// Apply some default values for GWIN&lt;br /&gt;
	wi.customDraw = 0;&lt;br /&gt;
	wi.customParam = 0;&lt;br /&gt;
	wi.customStyle = 0;&lt;br /&gt;
	wi.g.show = gTrue;&lt;br /&gt;
 &lt;br /&gt;
	// Apply the label parameters	&lt;br /&gt;
	wi.g.y = 10;&lt;br /&gt;
	wi.g.x = 10;&lt;br /&gt;
	wi.g.width = 100;&lt;br /&gt;
	wi.g.height = 20;&lt;br /&gt;
	wi.text = &amp;quot;Label 1&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
	// Create the actual label&lt;br /&gt;
	ghLabel1 = gwinLabelCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	// Initialize the uGFX library&lt;br /&gt;
	gfxInit();&lt;br /&gt;
 &lt;br /&gt;
	// Set the widget defaults&lt;br /&gt;
	gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
	gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
	gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
	// Create the widget&lt;br /&gt;
	createWidgets();&lt;br /&gt;
 &lt;br /&gt;
	while(1) {&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;This is some text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;Aaaand some other text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Label&amp;diff=1927</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Label&amp;diff=1927"/>
				<updated>2021-08-06T18:10:33Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Attribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A label is a simple rectangular widget which takes no input. The label will automatically redraw it the text changed. If the label is smaller than the text it displays, the text gets clipped.&lt;br /&gt;
The text of the label can be set using the ''gwinSetText()'' routine.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the label widget can be found [http://api.ugfx.org/group___label.html here].&lt;br /&gt;
&lt;br /&gt;
== Border ==&lt;br /&gt;
The default drawing routine of the labels allows to enable or disable a border. This can be done using gwinLabelSetBorder(). &lt;br /&gt;
&lt;br /&gt;
== Auto scale ==&lt;br /&gt;
Applying a size of 0 to the width or the height of the label will automatically set the corresponding dimension to fit the entire label text. Updating the label text will update the label dimensions each time.&lt;br /&gt;
Note: If the the board is enabled the auto-sizing feature of the label will certainly change the look of the application.&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
By default the text of the label is left justified. The justification of the label text can be controlled through different built-in rendering functions.&lt;br /&gt;
&lt;br /&gt;
The following rendering functions are available:&lt;br /&gt;
* gwinLabelDrawJustifiedLeft&lt;br /&gt;
* gwinLabelDrawJustifiedRight&lt;br /&gt;
* gwinLabelDrawJustifiedCenter&lt;br /&gt;
&lt;br /&gt;
== Font size and color ==&lt;br /&gt;
As with any other widget the look-and-feel of the label widget can be fully customized. The font can be changed by using &amp;lt;code&amp;gt;gwinSetFont()&amp;lt;/code&amp;gt; and the font color is controlled through the [[Widgets#Widget_Style|widget styles]]. The widget rendering can be fully customized by implementing a [[Creating_a_custom_rendering_routine|custom rendering routine]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Often you want to display multiple text elements below each other where an element consists of a static text which will always be the same and some variable one. The static text is called the attribute and can be optionally set through &amp;lt;code&amp;gt;gwinLabelSetAttribute()&amp;lt;/code&amp;gt; once you enabled this feature in your [[configuration|configuration file]]. The function does also take a tab parameter which allows to align multiple labels vertically as the following example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current IP: 192.168.1.42&lt;br /&gt;
Netmask:    255.255.255.0&lt;br /&gt;
DHCP:       On&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''IMPORTANT:''' Use of the attribute capability is discouraged. This feature should be considered deprecated and will be removed in future releases. The proper way of doing this is using two separate labels.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
The following example shows how to create a label.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static GHandle ghLabel1;&lt;br /&gt;
 &lt;br /&gt;
static void createWidgets(void)&lt;br /&gt;
{&lt;br /&gt;
	GWidgetInit		wi;&lt;br /&gt;
 &lt;br /&gt;
	// Apply some default values for GWIN&lt;br /&gt;
	wi.customDraw = 0;&lt;br /&gt;
	wi.customParam = 0;&lt;br /&gt;
	wi.customStyle = 0;&lt;br /&gt;
	wi.g.show = TRUE;&lt;br /&gt;
 &lt;br /&gt;
	// Apply the label parameters	&lt;br /&gt;
	wi.g.y = 10;&lt;br /&gt;
	wi.g.x = 10;&lt;br /&gt;
	wi.g.width = 100;&lt;br /&gt;
	wi.g.height = 20;&lt;br /&gt;
	wi.text = &amp;quot;Label 1&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
	// Create the actual label&lt;br /&gt;
	ghLabel1 = gwinLabelCreate(NULL, &amp;amp;wi);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	// Initialize the uGFX library&lt;br /&gt;
	gfxInit();&lt;br /&gt;
 &lt;br /&gt;
	// Set the widget defaults&lt;br /&gt;
	gwinSetDefaultFont(gdispOpenFont(&amp;quot;UI2&amp;quot;));&lt;br /&gt;
	gwinSetDefaultStyle(&amp;amp;WhiteWidgetStyle, FALSE);&lt;br /&gt;
	gdispClear(White);&lt;br /&gt;
 &lt;br /&gt;
	// Create the widget&lt;br /&gt;
	createWidgets();&lt;br /&gt;
 &lt;br /&gt;
	while(1) {&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;This is some text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
		gwinSetText(ghLabel1, &amp;quot;Aaaand some other text&amp;quot;, TRUE);&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Widget]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=BareMetal&amp;diff=1926</id>
		<title>BareMetal</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=BareMetal&amp;diff=1926"/>
				<updated>2021-08-06T17:46:58Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* SysTick */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can run on any system without any underlying OS or RTOS. The '''RAW32''' port provides all the required implementations to run on a bare metal system. The only thing required to implement by the user are two small functions which are used to calculate delays. See [[#SysTick]].&lt;br /&gt;
&lt;br /&gt;
The '''RAW32''' port also provides a multi-tasker that you can use in your own applications. The threads created are co-operative (non-preemptive) threads (you have to use &amp;lt;code&amp;gt;gfxSleepMilliseconds()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;gfxYield()&amp;lt;/code&amp;gt; to give another task a chance to run). See [[GOS#Threading|GOS]].&lt;br /&gt;
&lt;br /&gt;
== Using RAW32 ==&lt;br /&gt;
To run µGFX on a bare-metal platform without any underlying operating system, the Raw32 port has to be enabled by setting &amp;lt;code&amp;gt;GFX_USE_OS_RAW32&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
== Memory Management ==&lt;br /&gt;
µGFX can run either completely on static memory or on dynamic memory. While the first is very important for security and time critical applications it can be very tedious in generic applications. The RAW32 provides a memory manager to work with dynamic memory on any bare metal system. The following two configuration options are available:&lt;br /&gt;
* Use the µGFX built-in memory manager&lt;br /&gt;
* Use the C runtime library memory manager&lt;br /&gt;
&lt;br /&gt;
Which one is used depends on the value of &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; inside of the [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
=== Built-in memory manager ===&lt;br /&gt;
When &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; is set to a value greater than 0 then the built-in memory manager of µGFX is used. In this case the value of &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; specifies the size of the memory pool which the built-in memory manager will use.&lt;br /&gt;
&lt;br /&gt;
=== C runtime library memory manager ===&lt;br /&gt;
When &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; is set to 0 then the memory manager of the C runtime library will be used. In that case &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; are just wrappers around &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Note that many C library implementations of &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; have bugs that cause them to crash if the stack is changed (as it is for threading as required by µGFX). For this reason, if you are getting strange crashes it is advisable to use the built-in memory manager and to avoid using ''malloc()'' and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; in your own code (use &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; instead).&lt;br /&gt;
&lt;br /&gt;
== SysTick ==&lt;br /&gt;
Some parts of the µGFX library require how much time passed by. For this access to the systems tick counter (SysTick) is required. To give µGFX the ability to calculate how much time passed the following to functions need to be implemented in the users application code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
gTicks gfxSystemTicks(void);&lt;br /&gt;
gTicks gfxMillisecondsToTicks(delaytime_t ms);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The first one, &amp;lt;code&amp;gt;gfxSystemTicks()&amp;lt;/code&amp;gt;, needs to return the current value of the systick counter. The second one, &amp;lt;code&amp;gt;gfxMillisecondsToTicks()&amp;lt;/code&amp;gt; needs to convert the provided value in milliseconds to systicks.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
The following is an example showing how to implement the two functions when using an STM32F4 microcontroller using the STM32Cube HAL. Note that in this case the systick was set up to be incremented once every millisecond. If your systick updates in a different interval you need to do the corresponding calculations in ''gfxMillisecondsToTicks()''.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx_hal.h&amp;quot;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
gTicks gfxSystemTicks(void)&lt;br /&gt;
{&lt;br /&gt;
	return HAL_GetTick();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gTicks gfxMillisecondsToTicks(delaytime_t ms)&lt;br /&gt;
{&lt;br /&gt;
	return ms;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' It is important that &amp;lt;code&amp;gt;gfx.h&amp;lt;/code&amp;gt; is included after &amp;lt;code&amp;gt;stm32f4xx_hal.h&amp;lt;/code&amp;gt; to avoid naming conflicts when using the CubeHAL with µGFX.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=BareMetal&amp;diff=1925</id>
		<title>BareMetal</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=BareMetal&amp;diff=1925"/>
				<updated>2021-08-06T17:46:44Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* SysTick */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX can run on any system without any underlying OS or RTOS. The '''RAW32''' port provides all the required implementations to run on a bare metal system. The only thing required to implement by the user are two small functions which are used to calculate delays. See [[#SysTick]].&lt;br /&gt;
&lt;br /&gt;
The '''RAW32''' port also provides a multi-tasker that you can use in your own applications. The threads created are co-operative (non-preemptive) threads (you have to use &amp;lt;code&amp;gt;gfxSleepMilliseconds()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;gfxYield()&amp;lt;/code&amp;gt; to give another task a chance to run). See [[GOS#Threading|GOS]].&lt;br /&gt;
&lt;br /&gt;
== Using RAW32 ==&lt;br /&gt;
To run µGFX on a bare-metal platform without any underlying operating system, the Raw32 port has to be enabled by setting &amp;lt;code&amp;gt;GFX_USE_OS_RAW32&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
== Memory Management ==&lt;br /&gt;
µGFX can run either completely on static memory or on dynamic memory. While the first is very important for security and time critical applications it can be very tedious in generic applications. The RAW32 provides a memory manager to work with dynamic memory on any bare metal system. The following two configuration options are available:&lt;br /&gt;
* Use the µGFX built-in memory manager&lt;br /&gt;
* Use the C runtime library memory manager&lt;br /&gt;
&lt;br /&gt;
Which one is used depends on the value of &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; inside of the [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
=== Built-in memory manager ===&lt;br /&gt;
When &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; is set to a value greater than 0 then the built-in memory manager of µGFX is used. In this case the value of &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; specifies the size of the memory pool which the built-in memory manager will use.&lt;br /&gt;
&lt;br /&gt;
=== C runtime library memory manager ===&lt;br /&gt;
When &amp;lt;code&amp;gt;GFX_OS_HEAP_SIZE&amp;lt;/code&amp;gt; is set to 0 then the memory manager of the C runtime library will be used. In that case &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; are just wrappers around &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Note that many C library implementations of &amp;lt;code&amp;gt;malloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; have bugs that cause them to crash if the stack is changed (as it is for threading as required by µGFX). For this reason, if you are getting strange crashes it is advisable to use the built-in memory manager and to avoid using ''malloc()'' and &amp;lt;code&amp;gt;free()&amp;lt;/code&amp;gt; in your own code (use &amp;lt;code&amp;gt;gfxAlloc()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gfxFree()&amp;lt;/code&amp;gt; instead).&lt;br /&gt;
&lt;br /&gt;
== SysTick ==&lt;br /&gt;
Some parts of the µGFX library require how much time passed by. For this access to the systems tick counter (SysTick) is required. To give µGFX the ability to calculate how much time passed the following to functions need to be implemented in the users application code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
systemticks_t gfxSystemTicks(void);&lt;br /&gt;
systemticks_t gfxMillisecondsToTicks(delaytime_t ms);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The first one, &amp;lt;code&amp;gt;gfxSystemTicks()&amp;lt;/code&amp;gt;, needs to return the current value of the systick counter. The second one, &amp;lt;code&amp;gt;gfxMillisecondsToTicks()&amp;lt;/code&amp;gt; needs to convert the provided value in milliseconds to systicks.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
The following is an example showing how to implement the two functions when using an STM32F4 microcontroller using the STM32Cube HAL. Note that in this case the systick was set up to be incremented once every millisecond. If your systick updates in a different interval you need to do the corresponding calculations in ''gfxMillisecondsToTicks()''.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx_hal.h&amp;quot;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
gTicks gfxSystemTicks(void)&lt;br /&gt;
{&lt;br /&gt;
	return HAL_GetTick();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gTicks gfxMillisecondsToTicks(delaytime_t ms)&lt;br /&gt;
{&lt;br /&gt;
	return ms;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' It is important that &amp;lt;code&amp;gt;gfx.h&amp;lt;/code&amp;gt; is included after &amp;lt;code&amp;gt;stm32f4xx_hal.h&amp;lt;/code&amp;gt; to avoid naming conflicts when using the CubeHAL with µGFX.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1924</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1924"/>
				<updated>2021-08-06T16:20:24Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Rendering */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Pre-Processor ==&lt;br /&gt;
For pre-processing related boolean operations (eg. &amp;lt;code&amp;gt;#if MY_FEATURE&amp;lt;/code&amp;gt;) use &amp;lt;code&amp;gt;GFXON&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GFXOFF&amp;lt;/code&amp;gt; accordingly.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI8&amp;lt;/code&amp;gt; || Signed integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU8&amp;lt;/code&amp;gt; || Unsigned integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI16&amp;lt;/code&amp;gt; || Signed integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU16&amp;lt;/code&amp;gt; || Unsigned integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI32&amp;lt;/code&amp;gt; || Signed integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU32&amp;lt;/code&amp;gt; || Unsigned integer at least 32 bits wide.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gTicks&amp;lt;/code&amp;gt; || A type to represent a number of system ticks.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GINPUT&amp;diff=1923</id>
		<title>GINPUT</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GINPUT&amp;diff=1923"/>
				<updated>2021-08-03T18:53:26Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* API reference */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Ginput architecture.png|right|frame|GINPUT architecture]]&lt;br /&gt;
GINPUT is a powerful module which provides an easy way to interface different hardware peripherals such as touchscreens to the rest of the library. It provides everything which these peripherals need in order to operate properly such as calibration routines for the touchscreens.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GINPUT module can be found [http://api.ugfx.io/group___g_i_n_p_u_t.html here].&lt;br /&gt;
&lt;br /&gt;
== Touchscreen ==&lt;br /&gt;
A touchscreen can be interfaced very easily through the GINPUT module. It doesn't matter if it is a [http://en.wikipedia.org/wiki/Touchscreen#Resistive resistive], [http://en.wikipedia.org/wiki/Touchscreen#Capacitive capacitive] or any other touchscreen technology.&lt;br /&gt;
&lt;br /&gt;
=== Board file ===&lt;br /&gt;
The GINPUT module requires a [[Board File|board file]] for each driver instance. A board file template and corresponding examples can be found under ''/drivers/ginput/touch/xxx/''.&lt;br /&gt;
&lt;br /&gt;
=== Calibration ===&lt;br /&gt;
See [[Touchscreen Calibration]].&lt;br /&gt;
&lt;br /&gt;
== Digital input ==&lt;br /&gt;
Also known as the ''Toggle'' driver. This driver can be used to interface common digital inputs (GPIOs). Mostly this driver is used to attach hardware buttons to a [[GWIN]] [[Widgets|widget]].&lt;br /&gt;
&lt;br /&gt;
== Analog input ==&lt;br /&gt;
Also known as the ''Dial'' driver. This driver can be used to interface slow analog inputs. Mostly this driver is used to attach an analog peripheral such as a potentiometer or a sensor to a [[GWIN]] [[Widgets|widget]].&lt;br /&gt;
It can also be used on digital inputs that emulate a graduated ratio output such as a digital &amp;quot;click&amp;quot; wheel (rotary encoder).&lt;br /&gt;
&lt;br /&gt;
== Keyboard ==&lt;br /&gt;
The keyboard driver allows to interface physical keyboards to a µGFX application.&lt;br /&gt;
Note that there's also a virtual keyboard widget that provides an on-screen keyboard with customizable layouts. See [[keyboard]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Module]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Use_uGFX_repository_as_Git_Submodule&amp;diff=1922</id>
		<title>Use uGFX repository as Git Submodule</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Use_uGFX_repository_as_Git_Submodule&amp;diff=1922"/>
				<updated>2021-08-03T16:59:50Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* The Problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following article is a guide on how to add the uGFX repository as a submodule in an existing git repository. This guide was written by one of our users. Check out his tech [http://wolinlabs.com/blog/ blog].&lt;br /&gt;
&lt;br /&gt;
== The Problem ==&lt;br /&gt;
I am writing firmware for  an embedded system which uses the uGFX graphics library.  I use Git for source control, and wanted to use a Git submodule  to embed uGFX's repository into my source repository.  Additionally, I wanted to be able to add some custom board and driver files to uGFX which are needed for my project, but are of no value to uGFX (and won't be pushed back to their repository).&lt;br /&gt;
&lt;br /&gt;
Initially, I merely added a Git submodule to my local repository, made some changes and commited them to the submodule's master branch.  This worked smashingly... until I tried to make a local clone of my repository, using the recursive switch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
git clone --recursive myrepo myrepo_clone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and got an error:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
fatal: reference is not a tree: ca025c09ca2b7b82ca086309eeb0696d674cb1d0&lt;br /&gt;
Unable to checkout 'ca025c09ca2b7b82ca086309eeb0696d674cb1d0' in submodule path 'ugfx_submodule'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The problem is that my changes to the submodule's master branch are in my local repository, but when Git tries to clone the uGFX submodule, it gets source from the Bitbucket repository, which obviously does not have my changes.&lt;br /&gt;
&lt;br /&gt;
What I'm doing seems to me like a pretty common situation/workflow. Surprisingly, when I searched, I did not find  documentation/examples about how to set this up properly so that recursive clones would work, etc.&lt;br /&gt;
&lt;br /&gt;
'''Here's  my requirements in more detail:'''&lt;br /&gt;
# I need to get code from the uGFX Bitbucket repository's master branch, pull in changes from that branch when available, and integrate them into my product after testing.&lt;br /&gt;
# I need to be able to add code to the local uGFX tree and keep these additions under source control, but not push them back to the uGFX repository (my code is specific to my project and proprietary h/w, trust me, uGFX doesn't  want it. =)&lt;br /&gt;
# Other users must be able to clone my repository. They don't have to be able to update the uGFX tree with the Bitbucket changes (I will handle when those changes are integrated) - although they could if they made minor modifications to their repository.&lt;br /&gt;
&lt;br /&gt;
== My Solution ==&lt;br /&gt;
I came up  with a workable solution,  involving a version of &lt;br /&gt;
[https://felipec.wordpress.com/2014/05/11/git-triangular-workflows Triangular Workflow], using an upstream repository. I used a Raspberry Pi + Raspbian for the upstream repository because I had one on my network running DNS/DHCP and thought it would be cool, you could just as easily use a second local repository on your disk, Bitbucket/Github, etc.&lt;br /&gt;
&lt;br /&gt;
'''Here are the specifics for my solution:'''&lt;br /&gt;
* Create an upstream Git server. I used a Raspberry Pi and put the repos on a USB stick, because it was convenient, starting with [http://www.instructables.com/id/GitPi-A-Private-Git-Server-on-Raspberry-Pi/?ALLSTEPS this article]. I added some enhancements from [https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server the Git book], like adding a git user and some authorized public ssh keys, etc...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Make two bare repositories on the Git server, for this example call them myproduct.git and myproduct_ugfx.git&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Push my repository's master branch to the myproduct.git repository. I didn't write this part down, but I believe I just added a remote for origin and pushed the master branch:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
git remote add origin git@pi-b:/mnt/git_repos/myproduct.git&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* From the top directory of my repository, I add the uGFX submodule&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
git submodule add https://git.ugfx.io/ugfx/ugfx.git ugfx_submodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* cd into the submodule's directory, and change the name of the submodule's master branch to updates&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
git branch -m master updates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Rename the remote origin to bitbucket, which the updates (formerly master) branch tracks&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
git remote rename origin bitbucket&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* At this point, run &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;git branch -vv&amp;lt;/span&amp;gt; as a check, and it should show one branch named updates which tracks remote bitbucket's master branch&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The submodule no longer has a master branch or origin. I wanted the submodule master branch to track my Pi Git server's uGFX repository, so I add a remote for origin, create a master branch, and push the master branch to the server (telling it to track that branch):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
git remote add origin git@pi-b:/mnt/git_repos/myproduct_ugfx.git&lt;br /&gt;
git checkout -b master &lt;br /&gt;
git push -u origin master&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Now that I've pushed the submodule to my server, I change the uGFX submodule to point to my server, so when people clone the whole repo with --recursive, they get  my master branch with my additions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
git config remote.origin.url git@pi-b:/mnt/git_repos/myproduct_ugfx.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
At this point, I wanted to add a few files to the uGFX tree. I add them to the master branch, commit, and push (which goes to the Pi repository.) Remember to also go up a direcotry, outside of the submodule, run &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;git submodule sync&amp;lt;/span&amp;gt; (not sure if that's necessary), and then commit+push those changes to the main/outer repo.&lt;br /&gt;
&lt;br /&gt;
Now, when there are changes on the Bitbucket repository, in the submodule I can pull them into my local updates branch, then when I've tested them and want to integrate them into the my product, I can merge updates with master, then commit and push master to the Pi repository.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Local recursive clones (like the one above that caused the initial error) will now work. If someone wants to clone the myproduct repository from the Pi, provided they have access to the Pi (see Git book for adding an ssh key) they can do it with&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
git clone --recursive git@pi-b:/mnt/git_repos/myproduct.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [https://felipec.wordpress.com/2014/05/11/git-triangular-workflows Triangular workflow example]&lt;br /&gt;
* [http://wolinlabs.com/blog Ross Wolin's Tech Blog]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=GTRANS&amp;diff=1921</id>
		<title>GTRANS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=GTRANS&amp;diff=1921"/>
				<updated>2021-08-03T15:46:20Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GTRANS module allows to manage language translations. The language of an application can be changed dynamically during runtime using the GTRANS module.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference of the GTRANS module can be found [http://api.ugfx.org/group___g_t_r_a_n_s.html here].&lt;br /&gt;
&lt;br /&gt;
== Intended usage ==&lt;br /&gt;
Each translation is specified by a &amp;lt;code&amp;gt;transTable&amp;lt;/code&amp;gt; struct which is essentially a table of strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct transTable {&lt;br /&gt;
    unsigned numEntries;     // The number of strings that this table contains&lt;br /&gt;
    const char** strings;    // The translated strings&lt;br /&gt;
} transTable;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A translatable application needs to have a base language. All translations happen relative to that base language. The base language is specified using &amp;lt;code&amp;gt;gtransSetBaseLanguage()&amp;lt;/code&amp;gt;. The current language of the application is set using &amp;lt;code&amp;gt;gtransSetLanguage()&amp;lt;/code&amp;gt;.&lt;br /&gt;
The actual translations take place by calling &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;. A string contained in the translation table of the base language is passed to &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;. The function returns the corresponding string of the current language that was set using &amp;lt;code&amp;gt;gtransSetLanguage()&amp;lt;/code&amp;gt; or the passed string if none was found.&lt;br /&gt;
&lt;br /&gt;
A wrapper macro named &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; around &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; is available to make writing and reading translatable applications easier:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define gt(str) gtransString(str)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
Calling &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; directly) uses the &amp;lt;code&amp;gt;strcmp()&amp;lt;/code&amp;gt; function of the standard C library to compare strings. This operation can take a lot of time. For performance critical applications or low-resource systems the application translation speed can be optimized by using &amp;lt;code&amp;gt;gtransIndex()&amp;lt;/code&amp;gt; (instead of &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt;) which directly takes the index of the string in the translation table. However, this introduces the limitation that each string in each of the translation tables need to be at the same position (the same index). Using &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; allows to have translation tables of unequal sizes due to the nature of the translation being based on string comparison rather than index accessing of the table.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Complete examples can be found under ''/demos/modules/gtrans/'' in the uGFX library directory.&lt;br /&gt;
&lt;br /&gt;
=== Basic Example ===&lt;br /&gt;
The following code is a very simple usage example showing how the GTRANS module is used. This is a very minimalistic example with no dependencies other than the [[GDISP]] module to interface a display.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define COLOR_BACKGROUND    Silver&lt;br /&gt;
#define COLOR_TEXT          Black&lt;br /&gt;
&lt;br /&gt;
font_t font;&lt;br /&gt;
&lt;br /&gt;
// English Translation&lt;br /&gt;
static const char* EnglishStrings[] = {&lt;br /&gt;
    &amp;quot;Welcome&amp;quot;,&lt;br /&gt;
    &amp;quot;The temperature is %d degrees&amp;quot;,&lt;br /&gt;
    &amp;quot;Goodbye&amp;quot;,&lt;br /&gt;
    &amp;quot;This is a translated uGFX application&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable EnglishTranslation = { sizeof(EnglishStrings)/sizeof(EnglishStrings[0]), EnglishStrings };&lt;br /&gt;
&lt;br /&gt;
// German translation&lt;br /&gt;
static const char* GermanStrings[] = {&lt;br /&gt;
    &amp;quot;Herzlich Willkommen&amp;quot;,&lt;br /&gt;
    &amp;quot;Die Temperatur beträgt %d Grad&amp;quot;,&lt;br /&gt;
    &amp;quot;Auf Wiedersehen&amp;quot;,&lt;br /&gt;
    &amp;quot;Das ist eine übersetzte uGFX Anwendung&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable GermanTranslation = { sizeof(GermanStrings)/sizeof(GermanStrings[0]), GermanStrings };&lt;br /&gt;
&lt;br /&gt;
// French translation&lt;br /&gt;
static const char* FrenchStrings[] = {&lt;br /&gt;
    &amp;quot;Bienvenue&amp;quot;,&lt;br /&gt;
    &amp;quot;La température est de %d degrés&amp;quot;,&lt;br /&gt;
    &amp;quot;Au revoir&amp;quot;,&lt;br /&gt;
    &amp;quot;Ceci est une application traduit uGFX&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
static const transTable FrenchTranslation = { sizeof(FrenchStrings)/sizeof(FrenchStrings[0]), FrenchStrings };&lt;br /&gt;
&lt;br /&gt;
void updateText()&lt;br /&gt;
{&lt;br /&gt;
    coord_t width = 400;&lt;br /&gt;
    coord_t height = 30;&lt;br /&gt;
&lt;br /&gt;
    // Translate some basic strings&lt;br /&gt;
    gdispFillStringBox(20,  20, width, height, gt(&amp;quot;Welcome&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
    gdispFillStringBox(20,  60, width, height, gt(&amp;quot;This is a translated uGFX application&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
    gdispFillStringBox(20, 100, width, height, gt(&amp;quot;Goodbye&amp;quot;), font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
&lt;br /&gt;
    // A more complex example using string formatting&lt;br /&gt;
    char buffer[128];&lt;br /&gt;
    sprintf(buffer, gt(&amp;quot;The temperature is %d degrees&amp;quot;), 18);&lt;br /&gt;
    gdispFillStringBox(20, 140, width, height, buffer, font, COLOR_TEXT, COLOR_BACKGROUND, justifyLeft);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    // Initialize the uGFX library&lt;br /&gt;
    gfxInit();&lt;br /&gt;
    gdispClear(COLOR_BACKGROUND);&lt;br /&gt;
&lt;br /&gt;
    // Take the first font we find&lt;br /&gt;
    font = gdispOpenFont(&amp;quot;*&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // Set the base language of the application&lt;br /&gt;
    gtransSetBaseLanguage(&amp;amp;EnglishTranslation);&lt;br /&gt;
&lt;br /&gt;
    // Loop through the languages&lt;br /&gt;
    while (TRUE) {&lt;br /&gt;
        // English&lt;br /&gt;
        gtransSetLanguage(&amp;amp;EnglishTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
&lt;br /&gt;
        // German&lt;br /&gt;
        gtransSetLanguage(&amp;amp;GermanTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
&lt;br /&gt;
        // French&lt;br /&gt;
        gtransSetLanguage(&amp;amp;FrenchTranslation);&lt;br /&gt;
        updateText();&lt;br /&gt;
        gfxSleepMilliseconds(3000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example with widgets ===&lt;br /&gt;
The GTRANS module can also be used to translate widget texts. GWIN doesn't do anything with the text set by &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; except displaying it. Therefore, the &amp;lt;code&amp;gt;gtransString()&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;gt()&amp;lt;/code&amp;gt; respectively) function can be used directly inside of the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; call. When the current language changes, the &amp;lt;code&amp;gt;gwinSetText()&amp;lt;/code&amp;gt; function must be re-called manually. There's currently no way to tell GWIN to automatically use the string for the currently active language as this would add a lot of overhead to both the GWIN core module as well as to each widget rendering function in order to support parameter substitution.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
gwinSetText(ghMyButton, gt(&amp;quot;The temperature is %d degrees&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1920</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1920"/>
				<updated>2021-08-02T15:49:48Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Pre-Processor ==&lt;br /&gt;
For pre-processing related boolean operations (eg. &amp;lt;code&amp;gt;#if MY_FEATURE&amp;lt;/code&amp;gt;) use &amp;lt;code&amp;gt;GFXON&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GFXOFF&amp;lt;/code&amp;gt; accordingly.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI8&amp;lt;/code&amp;gt; || Signed integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU8&amp;lt;/code&amp;gt; || Unsigned integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI16&amp;lt;/code&amp;gt; || Signed integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU16&amp;lt;/code&amp;gt; || Unsigned integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI32&amp;lt;/code&amp;gt; || Signed integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU32&amp;lt;/code&amp;gt; || Unsigned integer at least 32 bits wide.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1919</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1919"/>
				<updated>2021-08-02T15:45:32Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Basic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI8&amp;lt;/code&amp;gt; || Signed integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU8&amp;lt;/code&amp;gt; || Unsigned integer at least 8 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI16&amp;lt;/code&amp;gt; || Signed integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU16&amp;lt;/code&amp;gt; || Unsigned integer at least 16 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gI32&amp;lt;/code&amp;gt; || Signed integer at least 32 bits wide.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gU32&amp;lt;/code&amp;gt; || Unsigned integer at least 32 bits wide.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1918</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1918"/>
				<updated>2021-08-02T15:39:53Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Basic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1917</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1917"/>
				<updated>2021-08-02T15:39:44Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Basic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Types&amp;diff=1916</id>
		<title>Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Types&amp;diff=1916"/>
				<updated>2021-08-02T15:39:03Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: Created page with &amp;quot;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types expos...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;µGFX allows to write applications (eg. GUIs) that are completely portable as the library itself is highly agnostic. To achieve this goal, users should rely on the types exposed by µGFX as much as possible to prevent problems when migration to different systems.&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gBool&amp;lt;/code&amp;gt; || A boolean value. Use &amp;lt;code&amp;gt;gTrue&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gFalse&amp;lt;/code&amp;gt; for assignments &amp;amp; comparisons respectively.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rendering ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gCoord&amp;lt;/code&amp;gt; || A type to express a coordinate in pixels.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gColor&amp;lt;/code&amp;gt; || A color.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gFont&amp;lt;/code&amp;gt; || A font. See [[Font_rendering|font rendering]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gImage&amp;lt;/code&amp;gt; || An image. See [[Images|images]].&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Images&amp;diff=1915</id>
		<title>Images</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Images&amp;diff=1915"/>
				<updated>2021-08-02T15:38:56Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Color Palettes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GDISP module comes with a built-in image decoder. The decoder allows it to open an image of various formats and display it. As the [[GFILE]] module is being used internally, the image can be stored on different sources such as the internal flash or external memory like an SD card.&lt;br /&gt;
&lt;br /&gt;
Before you continue to read this documentation, please consider using the [[ImageBox]] widget as it is much simpler to use.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference for the image support can be found [http://api.ugfx.org/group___image.html here].&lt;br /&gt;
&lt;br /&gt;
== RAM Usage ==&lt;br /&gt;
Image decoders use RAM to decode and display images. Whilst the image handlers have been written from scratch to use as little RAM as possible, for small microcontrollers with limited RAM the image formats used should be choosen carefully. The image handlers do not allocate RAM to store the full decompressed bitmap as do most other image decoders, instead the image is decoded again if it needs to be displayed. The only RAM used therefore is:&lt;br /&gt;
*Some RAM to hold information on the image itself - typically 200 to 300 bytes. This RAM is maintained while the image is opened. It may vary slightly for some images with some image formats (due to holding palettes etc).&lt;br /&gt;
*RAM allocated during the decoding process and freed once the decoding is done. The GIF image format requires around 12K of RAM to decode an image. BMP and NATIVE images do not require any extra RAM for decoding.&lt;br /&gt;
*If you decide to cache the image then RAM is required for the full decoded image. This should not be considered for low memory micros. For example, caching a 320x240 image on a 2 bytes per pixel display will take 150K of RAM (plus the normal decoding RAM).&lt;br /&gt;
*Stack space. You may need to increase your available stack space if you get exceptions when trying to decode images. Some image formats require a few hundred bytes of stack space to decode an image.&lt;br /&gt;
&lt;br /&gt;
Our image decoders have been written from the ground up to keep the image decoders as lean and mean as possible. Our current decoders use significantly less than other decoding libraries available. &lt;br /&gt;
&lt;br /&gt;
=== Accounting ===&lt;br /&gt;
It is possible to examine the exact amount of memory that is used by an image. Setting &amp;lt;code&amp;gt;GDISP_NEED_IMAGE_ACCOUNTING&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]] will add the two members ''memused'' and ''maxmemused'' to the image struct (the ''gdispImage'' data type). The first one gives information about the '''currently''' used memory, the second one keeps track of the '''maximum''' amount of memory that was ever used by this image.&lt;br /&gt;
&lt;br /&gt;
== Caching ==&lt;br /&gt;
It's possible to cache a decoded image into your ram using the '''gdispImageCache()''' call. When you don't cache an image, it will always be re-read again from flash, decoded and then displayed. When you cache your image, you just have to load it from RAM and display it. This is way faster, especially for PNG, JPG and GIF formats since these require quite complex decoding algorithms. However, caching an image requires A LOT of RAM. Especially when you're using multiframe GIF images or large sized images.&lt;br /&gt;
&lt;br /&gt;
If you cache your image you still have to open() the image before it can be displayed. When close() is called, it will free all memory used by the decoder including any cached images.&lt;br /&gt;
&lt;br /&gt;
Calling the caching routine doesn't guarantee that the image will be cached. For example, if not enough RAM is available the image won't be cached. Since caching is fully optional, the image will still be drawn when you call the drawing routine. It will simply be decoded again.&lt;br /&gt;
&lt;br /&gt;
== A word about close() ==&lt;br /&gt;
The &amp;lt;code&amp;gt;gdispImageClose()&amp;lt;/code&amp;gt; function performs a complete cleanup. Calling this routine will not only clean up all memory used by the decoder and the caching, it will also close the file system. Therefore, this should really just be called when you're done with the image and you won't re-draw it for a longer time period.&lt;br /&gt;
&lt;br /&gt;
== Color Palettes ==&lt;br /&gt;
Certain image formats support color palettes. The following functions are available to access and modify the color palettes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint16_t   gdispImageGetPaletteSize(gdispImage *img);&lt;br /&gt;
gColor     gdispImageGetPalette(gdispImage *img, uint16_t index);&lt;br /&gt;
gBool      gdispImageAdjustPalette(gdispImage *img, uint16_t index, color_t newColor);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Please check the [[Images#API_reference|API reference]] to learn more about these functions.&lt;br /&gt;
&lt;br /&gt;
== Image formats ==&lt;br /&gt;
µGFX does currently come with the following image decoders:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Format&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Description&lt;br /&gt;
 |-&lt;br /&gt;
 |BMP&lt;br /&gt;
 |Including BMP1, BMP4, BMP4_RLE, BMP8, BMP8_RLE, BMP16, BMP24, BMP32&lt;br /&gt;
 |-&lt;br /&gt;
 |GIF&lt;br /&gt;
 |Including transparency and multi-frame support (animations)&lt;br /&gt;
 |-&lt;br /&gt;
 |PNG&lt;br /&gt;
 |Including transparency and alpha support&lt;br /&gt;
 |-&lt;br /&gt;
 |NATIVE&lt;br /&gt;
 |Uses the display drivers native format. See below.&lt;br /&gt;
 |-&lt;br /&gt;
 |}&lt;br /&gt;
We plan to add decoders for other formats such as JPG in the future.&lt;br /&gt;
&lt;br /&gt;
=== NATIVE ===&lt;br /&gt;
The native image format consists of an 8 byte header followed by an array of bytes in the format your display controller accepts. Whilst hardware dependant, this format displays extremely quickly and with the least amount of RAM usage. It is ideal for images stored in FLASH. The header is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{ 'N', 'I', width.hi, width.lo, height.hi, height.lo, format.hi, format.lo }&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where the format word is equal to &amp;lt;code&amp;gt;GDISP_PIXELFORMAT&amp;lt;/code&amp;gt; which is defined in the &amp;lt;code&amp;gt;conf.h&amp;lt;/code&amp;gt; file of your GDISP driver.&lt;br /&gt;
&lt;br /&gt;
=== BMP ===&lt;br /&gt;
The BMP format is very performance friendly as it is a bitmap of pixels. There's only little to no decoding required to display a BMP image. Therefore, it is often used for UI designs.&lt;br /&gt;
The advantage over the [[#NATIVE|Native]] format is it's portability.&lt;br /&gt;
&lt;br /&gt;
=== GIF ===&lt;br /&gt;
The GIF decoder can handle animated images and transparency out of the box.&lt;br /&gt;
&lt;br /&gt;
==== Animated images ====&lt;br /&gt;
The GIF decoder simply advances the image pointer by one frame on each &amp;lt;code&amp;gt;gdispImageDraw()&amp;lt;/code&amp;gt; call. Therefore, displaying an animated image is simply a matter of calling &amp;lt;code&amp;gt;gdispDrawImage()&amp;lt;/code&amp;gt; in a loop. However, the user manually has to impliment the delay before loading the next image. This can be done like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
while (1) {&lt;br /&gt;
    gdispImageDraw(&amp;amp;myImage, 0, 0, myImage.width, myImage.height, 0, 0)&lt;br /&gt;
    delay = gdispImageNext(&amp;amp;myImage);&lt;br /&gt;
&lt;br /&gt;
    gfxSleepMilliseconds(delay);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' This is just an illustrative example. A real world program would have to check for error return codes etc. A full example can be found under ''/demos/modules/gdisp/images_animated''.&lt;br /&gt;
&lt;br /&gt;
=== PNG ===&lt;br /&gt;
The PNG image decoder can handle all PNG features including transparency except for interlacing. All the various PNG sub-formats and features can be turned on or off in the [[Configuration|configuration file]] in order to decrease code size. By default all supported formats are enabled whenever PNG images are enabled.&lt;br /&gt;
&lt;br /&gt;
==== Alpha &amp;amp; Transparency ====&lt;br /&gt;
The decoder supports both transparency and alpha. When a background color is specified in the PNG file alpha and transparency are handled by color blending with the background color. If a background color has not been specified by the PNG file then any pixel alpha below &amp;lt;code&amp;gt;GDISP_NEED_PNG_ALPHACLIFF&amp;lt;/code&amp;gt; is just not displayed.&lt;br /&gt;
&lt;br /&gt;
==== RAM usage ====&lt;br /&gt;
Compared to other formats such as BMP or GIF, PNG images require vast amounts of RAM to be decoded. Therefore, using PNG images is usually discouraged on very small embedded systems where RAM is a scarce resource.&lt;br /&gt;
&lt;br /&gt;
PNG images have the following RAM requirements:&lt;br /&gt;
* 64 bytes (or less) for the &amp;lt;code&amp;gt;gdispImage&amp;lt;/code&amp;gt; structure and internal PNG image information&lt;br /&gt;
* Around 34k bytes + 2 image scan lines used only during image decoding&lt;br /&gt;
This means that even super huge PNG images of say 3072x2304 can be fully decoded and displayed using around 40k bytes of RAM.&lt;br /&gt;
&lt;br /&gt;
Unfortunately there is nothing that can be done to further reduce the amount of RAM usage. There are a couple of big memory hogs in PNG decoding...&lt;br /&gt;
* A sliding window of 32K is needed for the inflate decompression. While some images may use less, because the inflate window size is non-deterministic while decoding the maximum sliding window has to be allocated up front.&lt;br /&gt;
* 2 scan lines of uncompressed data are required to perform PNG filtering. For a 16-bit RGB with alpha that amounts to (1 + 8 bytes per pixel * width) * 2. Obviously for an 8-bit palette based PNG it is (1 + 1 * width) * 2, and for a 1-bit palette PNG it is image (1 + width / 8) * 2&lt;br /&gt;
Unfortunately these overheads cannot be reduced as they are required by the PNG specification.&lt;br /&gt;
&lt;br /&gt;
Most PNG decoders (and decoder libraries) require:&lt;br /&gt;
# A full copy of the input file in memory&lt;br /&gt;
# The PNG header information and palette storage overheads&lt;br /&gt;
# The 32K sliding window and scanline buffers (although this is often integrated into #4 below)&lt;br /&gt;
# A full copy of the decompressed byte stream in memory&lt;br /&gt;
# A full copy of the output image in PNG color format after scanline filtering&lt;br /&gt;
# A full copy of the output image in output device color format.&lt;br /&gt;
Obviously this is a huge amount of RAM, well beyond the capabilities of most embedded devices. We therefore wrote our decoder from scratch to remove those overheads where-ever possible. For our decoder we only need #2 and #3 and furthermore #3 is only needed while the decoding is actually happening.&lt;br /&gt;
&lt;br /&gt;
==== GIF vs. PNG ====&lt;br /&gt;
We have not performed any speed tests comparing GIF's with PNG's. Both use similar technology to decode the image but the differences will determine the relative speeds. They use different compression algorithm's. GIF is also 8-bit palette pixel format only whereas PNG supports a multitude of internal pixel formats. Both support transparency but only PNG supports alpha blending. With GIF we support interlacing but not with PNG due to complexity. GIF supports animation, PNG does not. In conclusion, the differences in decoding speed between PNG and GIF is going to depend very much on the actual image.&lt;br /&gt;
&lt;br /&gt;
There is however one exception to the above, when a GIF image is cached to RAM using &amp;lt;code&amp;gt;gdispImageCache()&amp;lt;/code&amp;gt; we cache the decompressed byte stream. For PNG we cache the compressed byte stream. In this situation it is likely that cached GIF images will display faster than cached PNG images but will take more RAM to cache.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
The following code pieces shows how to use the GDISP image decoder correctly. Please refer to the [[GFILE]] article to learn how to use the different file systems.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * The image file must be stored on a GFILE file-system.&lt;br /&gt;
 * Use either GFILE_NEED_NATIVEFS or GFILE_NEED_ROMFS (or both).&lt;br /&gt;
 *&lt;br /&gt;
 * The ROMFS uses the file &amp;quot;romfs_files.h&amp;quot; to describe the set of files in the ROMFS.&lt;br /&gt;
 */&lt;br /&gt;
 &lt;br /&gt;
static gdispImage myImage;&lt;br /&gt;
 &lt;br /&gt;
int main(void) {&lt;br /&gt;
	gCoord swidth, sheight;&lt;br /&gt;
 &lt;br /&gt;
	// Initialize uGFX and the underlying system&lt;br /&gt;
	gfxInit();&lt;br /&gt;
 &lt;br /&gt;
	// Get the display dimensions&lt;br /&gt;
	swidth = gdispGetWidth();&lt;br /&gt;
	sheight = gdispGetHeight();&lt;br /&gt;
 &lt;br /&gt;
	// Set up IO for our image&lt;br /&gt;
	gdispImageOpenFile(&amp;amp;myImage, &amp;quot;myImage.bmp&amp;quot;);&lt;br /&gt;
	gdispImageDraw(&amp;amp;myImage, 0, 0, swidth, sheight, 0, 0);&lt;br /&gt;
	gdispImageClose(&amp;amp;myImage);&lt;br /&gt;
 &lt;br /&gt;
	while(1) {&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
When troubleshooting, please check the return value of '''each''' function in order to track down the problem.&lt;br /&gt;
&lt;br /&gt;
=== No image is shown ===&lt;br /&gt;
It is possible that the program compiles fine and that it runs without any crashes, but no image is being displayed. This behavior can be caused by a variety of different issues:&lt;br /&gt;
* The corresponding decoder has not been enabled in the [[Configuration|configuration file]]&lt;br /&gt;
* The image could not be opened&lt;br /&gt;
* The image decoder could not allocate enough memory&lt;br /&gt;
* When loading an image from a file, it's possible that the maximum number of file handles has been reached and opening the file fails. In that case, increase &amp;lt;code&amp;gt;GFILE_MAX_GFILES&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]] or close an already opened file that is no longer needed.&lt;br /&gt;
&lt;br /&gt;
[[Category:GDISP]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Images&amp;diff=1914</id>
		<title>Images</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Images&amp;diff=1914"/>
				<updated>2021-08-02T15:38:35Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GDISP module comes with a built-in image decoder. The decoder allows it to open an image of various formats and display it. As the [[GFILE]] module is being used internally, the image can be stored on different sources such as the internal flash or external memory like an SD card.&lt;br /&gt;
&lt;br /&gt;
Before you continue to read this documentation, please consider using the [[ImageBox]] widget as it is much simpler to use.&lt;br /&gt;
&lt;br /&gt;
== API reference ==&lt;br /&gt;
The API reference for the image support can be found [http://api.ugfx.org/group___image.html here].&lt;br /&gt;
&lt;br /&gt;
== RAM Usage ==&lt;br /&gt;
Image decoders use RAM to decode and display images. Whilst the image handlers have been written from scratch to use as little RAM as possible, for small microcontrollers with limited RAM the image formats used should be choosen carefully. The image handlers do not allocate RAM to store the full decompressed bitmap as do most other image decoders, instead the image is decoded again if it needs to be displayed. The only RAM used therefore is:&lt;br /&gt;
*Some RAM to hold information on the image itself - typically 200 to 300 bytes. This RAM is maintained while the image is opened. It may vary slightly for some images with some image formats (due to holding palettes etc).&lt;br /&gt;
*RAM allocated during the decoding process and freed once the decoding is done. The GIF image format requires around 12K of RAM to decode an image. BMP and NATIVE images do not require any extra RAM for decoding.&lt;br /&gt;
*If you decide to cache the image then RAM is required for the full decoded image. This should not be considered for low memory micros. For example, caching a 320x240 image on a 2 bytes per pixel display will take 150K of RAM (plus the normal decoding RAM).&lt;br /&gt;
*Stack space. You may need to increase your available stack space if you get exceptions when trying to decode images. Some image formats require a few hundred bytes of stack space to decode an image.&lt;br /&gt;
&lt;br /&gt;
Our image decoders have been written from the ground up to keep the image decoders as lean and mean as possible. Our current decoders use significantly less than other decoding libraries available. &lt;br /&gt;
&lt;br /&gt;
=== Accounting ===&lt;br /&gt;
It is possible to examine the exact amount of memory that is used by an image. Setting &amp;lt;code&amp;gt;GDISP_NEED_IMAGE_ACCOUNTING&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]] will add the two members ''memused'' and ''maxmemused'' to the image struct (the ''gdispImage'' data type). The first one gives information about the '''currently''' used memory, the second one keeps track of the '''maximum''' amount of memory that was ever used by this image.&lt;br /&gt;
&lt;br /&gt;
== Caching ==&lt;br /&gt;
It's possible to cache a decoded image into your ram using the '''gdispImageCache()''' call. When you don't cache an image, it will always be re-read again from flash, decoded and then displayed. When you cache your image, you just have to load it from RAM and display it. This is way faster, especially for PNG, JPG and GIF formats since these require quite complex decoding algorithms. However, caching an image requires A LOT of RAM. Especially when you're using multiframe GIF images or large sized images.&lt;br /&gt;
&lt;br /&gt;
If you cache your image you still have to open() the image before it can be displayed. When close() is called, it will free all memory used by the decoder including any cached images.&lt;br /&gt;
&lt;br /&gt;
Calling the caching routine doesn't guarantee that the image will be cached. For example, if not enough RAM is available the image won't be cached. Since caching is fully optional, the image will still be drawn when you call the drawing routine. It will simply be decoded again.&lt;br /&gt;
&lt;br /&gt;
== A word about close() ==&lt;br /&gt;
The &amp;lt;code&amp;gt;gdispImageClose()&amp;lt;/code&amp;gt; function performs a complete cleanup. Calling this routine will not only clean up all memory used by the decoder and the caching, it will also close the file system. Therefore, this should really just be called when you're done with the image and you won't re-draw it for a longer time period.&lt;br /&gt;
&lt;br /&gt;
== Color Palettes ==&lt;br /&gt;
Certain image formats support color palettes. The following functions are available to access and modify the color palettes:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint16_t   gdispImageGetPaletteSize(gdispImage *img);&lt;br /&gt;
color_t    gdispImageGetPalette(gdispImage *img, uint16_t index);&lt;br /&gt;
bool_t     gdispImageAdjustPalette(gdispImage *img, uint16_t index, color_t newColor);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Please check the [[Images#API_reference|API reference]] to learn more about these functions.&lt;br /&gt;
&lt;br /&gt;
== Image formats ==&lt;br /&gt;
µGFX does currently come with the following image decoders:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Format&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Description&lt;br /&gt;
 |-&lt;br /&gt;
 |BMP&lt;br /&gt;
 |Including BMP1, BMP4, BMP4_RLE, BMP8, BMP8_RLE, BMP16, BMP24, BMP32&lt;br /&gt;
 |-&lt;br /&gt;
 |GIF&lt;br /&gt;
 |Including transparency and multi-frame support (animations)&lt;br /&gt;
 |-&lt;br /&gt;
 |PNG&lt;br /&gt;
 |Including transparency and alpha support&lt;br /&gt;
 |-&lt;br /&gt;
 |NATIVE&lt;br /&gt;
 |Uses the display drivers native format. See below.&lt;br /&gt;
 |-&lt;br /&gt;
 |}&lt;br /&gt;
We plan to add decoders for other formats such as JPG in the future.&lt;br /&gt;
&lt;br /&gt;
=== NATIVE ===&lt;br /&gt;
The native image format consists of an 8 byte header followed by an array of bytes in the format your display controller accepts. Whilst hardware dependant, this format displays extremely quickly and with the least amount of RAM usage. It is ideal for images stored in FLASH. The header is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{ 'N', 'I', width.hi, width.lo, height.hi, height.lo, format.hi, format.lo }&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where the format word is equal to &amp;lt;code&amp;gt;GDISP_PIXELFORMAT&amp;lt;/code&amp;gt; which is defined in the &amp;lt;code&amp;gt;conf.h&amp;lt;/code&amp;gt; file of your GDISP driver.&lt;br /&gt;
&lt;br /&gt;
=== BMP ===&lt;br /&gt;
The BMP format is very performance friendly as it is a bitmap of pixels. There's only little to no decoding required to display a BMP image. Therefore, it is often used for UI designs.&lt;br /&gt;
The advantage over the [[#NATIVE|Native]] format is it's portability.&lt;br /&gt;
&lt;br /&gt;
=== GIF ===&lt;br /&gt;
The GIF decoder can handle animated images and transparency out of the box.&lt;br /&gt;
&lt;br /&gt;
==== Animated images ====&lt;br /&gt;
The GIF decoder simply advances the image pointer by one frame on each &amp;lt;code&amp;gt;gdispImageDraw()&amp;lt;/code&amp;gt; call. Therefore, displaying an animated image is simply a matter of calling &amp;lt;code&amp;gt;gdispDrawImage()&amp;lt;/code&amp;gt; in a loop. However, the user manually has to impliment the delay before loading the next image. This can be done like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
while (1) {&lt;br /&gt;
    gdispImageDraw(&amp;amp;myImage, 0, 0, myImage.width, myImage.height, 0, 0)&lt;br /&gt;
    delay = gdispImageNext(&amp;amp;myImage);&lt;br /&gt;
&lt;br /&gt;
    gfxSleepMilliseconds(delay);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' This is just an illustrative example. A real world program would have to check for error return codes etc. A full example can be found under ''/demos/modules/gdisp/images_animated''.&lt;br /&gt;
&lt;br /&gt;
=== PNG ===&lt;br /&gt;
The PNG image decoder can handle all PNG features including transparency except for interlacing. All the various PNG sub-formats and features can be turned on or off in the [[Configuration|configuration file]] in order to decrease code size. By default all supported formats are enabled whenever PNG images are enabled.&lt;br /&gt;
&lt;br /&gt;
==== Alpha &amp;amp; Transparency ====&lt;br /&gt;
The decoder supports both transparency and alpha. When a background color is specified in the PNG file alpha and transparency are handled by color blending with the background color. If a background color has not been specified by the PNG file then any pixel alpha below &amp;lt;code&amp;gt;GDISP_NEED_PNG_ALPHACLIFF&amp;lt;/code&amp;gt; is just not displayed.&lt;br /&gt;
&lt;br /&gt;
==== RAM usage ====&lt;br /&gt;
Compared to other formats such as BMP or GIF, PNG images require vast amounts of RAM to be decoded. Therefore, using PNG images is usually discouraged on very small embedded systems where RAM is a scarce resource.&lt;br /&gt;
&lt;br /&gt;
PNG images have the following RAM requirements:&lt;br /&gt;
* 64 bytes (or less) for the &amp;lt;code&amp;gt;gdispImage&amp;lt;/code&amp;gt; structure and internal PNG image information&lt;br /&gt;
* Around 34k bytes + 2 image scan lines used only during image decoding&lt;br /&gt;
This means that even super huge PNG images of say 3072x2304 can be fully decoded and displayed using around 40k bytes of RAM.&lt;br /&gt;
&lt;br /&gt;
Unfortunately there is nothing that can be done to further reduce the amount of RAM usage. There are a couple of big memory hogs in PNG decoding...&lt;br /&gt;
* A sliding window of 32K is needed for the inflate decompression. While some images may use less, because the inflate window size is non-deterministic while decoding the maximum sliding window has to be allocated up front.&lt;br /&gt;
* 2 scan lines of uncompressed data are required to perform PNG filtering. For a 16-bit RGB with alpha that amounts to (1 + 8 bytes per pixel * width) * 2. Obviously for an 8-bit palette based PNG it is (1 + 1 * width) * 2, and for a 1-bit palette PNG it is image (1 + width / 8) * 2&lt;br /&gt;
Unfortunately these overheads cannot be reduced as they are required by the PNG specification.&lt;br /&gt;
&lt;br /&gt;
Most PNG decoders (and decoder libraries) require:&lt;br /&gt;
# A full copy of the input file in memory&lt;br /&gt;
# The PNG header information and palette storage overheads&lt;br /&gt;
# The 32K sliding window and scanline buffers (although this is often integrated into #4 below)&lt;br /&gt;
# A full copy of the decompressed byte stream in memory&lt;br /&gt;
# A full copy of the output image in PNG color format after scanline filtering&lt;br /&gt;
# A full copy of the output image in output device color format.&lt;br /&gt;
Obviously this is a huge amount of RAM, well beyond the capabilities of most embedded devices. We therefore wrote our decoder from scratch to remove those overheads where-ever possible. For our decoder we only need #2 and #3 and furthermore #3 is only needed while the decoding is actually happening.&lt;br /&gt;
&lt;br /&gt;
==== GIF vs. PNG ====&lt;br /&gt;
We have not performed any speed tests comparing GIF's with PNG's. Both use similar technology to decode the image but the differences will determine the relative speeds. They use different compression algorithm's. GIF is also 8-bit palette pixel format only whereas PNG supports a multitude of internal pixel formats. Both support transparency but only PNG supports alpha blending. With GIF we support interlacing but not with PNG due to complexity. GIF supports animation, PNG does not. In conclusion, the differences in decoding speed between PNG and GIF is going to depend very much on the actual image.&lt;br /&gt;
&lt;br /&gt;
There is however one exception to the above, when a GIF image is cached to RAM using &amp;lt;code&amp;gt;gdispImageCache()&amp;lt;/code&amp;gt; we cache the decompressed byte stream. For PNG we cache the compressed byte stream. In this situation it is likely that cached GIF images will display faster than cached PNG images but will take more RAM to cache.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
The following code pieces shows how to use the GDISP image decoder correctly. Please refer to the [[GFILE]] article to learn how to use the different file systems.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#include &amp;quot;gfx.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * The image file must be stored on a GFILE file-system.&lt;br /&gt;
 * Use either GFILE_NEED_NATIVEFS or GFILE_NEED_ROMFS (or both).&lt;br /&gt;
 *&lt;br /&gt;
 * The ROMFS uses the file &amp;quot;romfs_files.h&amp;quot; to describe the set of files in the ROMFS.&lt;br /&gt;
 */&lt;br /&gt;
 &lt;br /&gt;
static gdispImage myImage;&lt;br /&gt;
 &lt;br /&gt;
int main(void) {&lt;br /&gt;
	gCoord swidth, sheight;&lt;br /&gt;
 &lt;br /&gt;
	// Initialize uGFX and the underlying system&lt;br /&gt;
	gfxInit();&lt;br /&gt;
 &lt;br /&gt;
	// Get the display dimensions&lt;br /&gt;
	swidth = gdispGetWidth();&lt;br /&gt;
	sheight = gdispGetHeight();&lt;br /&gt;
 &lt;br /&gt;
	// Set up IO for our image&lt;br /&gt;
	gdispImageOpenFile(&amp;amp;myImage, &amp;quot;myImage.bmp&amp;quot;);&lt;br /&gt;
	gdispImageDraw(&amp;amp;myImage, 0, 0, swidth, sheight, 0, 0);&lt;br /&gt;
	gdispImageClose(&amp;amp;myImage);&lt;br /&gt;
 &lt;br /&gt;
	while(1) {&lt;br /&gt;
		gfxSleepMilliseconds(1000);&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
When troubleshooting, please check the return value of '''each''' function in order to track down the problem.&lt;br /&gt;
&lt;br /&gt;
=== No image is shown ===&lt;br /&gt;
It is possible that the program compiles fine and that it runs without any crashes, but no image is being displayed. This behavior can be caused by a variety of different issues:&lt;br /&gt;
* The corresponding decoder has not been enabled in the [[Configuration|configuration file]]&lt;br /&gt;
* The image could not be opened&lt;br /&gt;
* The image decoder could not allocate enough memory&lt;br /&gt;
* When loading an image from a file, it's possible that the maximum number of file handles has been reached and opening the file fails. In that case, increase &amp;lt;code&amp;gt;GFILE_MAX_GFILES&amp;lt;/code&amp;gt; in the [[Configuration|configuration file]] or close an already opened file that is no longer needed.&lt;br /&gt;
&lt;br /&gt;
[[Category:GDISP]]&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Main_Page&amp;diff=1913</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Main_Page&amp;diff=1913"/>
				<updated>2021-08-02T15:27:44Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;div-header&amp;quot;&amp;gt;Welcome to the µGFX wiki!&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot;&amp;gt;This is the official documentation of the [http://ugfx.io µGFX] library. Please note that this is just the documentation, the official project website can be found at [http://ugfx.io ugfx.io]. The API reference can be found at [http://api.ugfx.io api.ugfx.io].&lt;br /&gt;
&lt;br /&gt;
If you're new to µGFX, begin by reading [[Getting Started]].&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;width: 50%; float: left;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;General&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Getting Started]]&lt;br /&gt;
* [[Configuration]]&lt;br /&gt;
* [[Architecture]]&lt;br /&gt;
* [[Board File]]&lt;br /&gt;
* [[Types]]&lt;br /&gt;
* [[API Reference]]&lt;br /&gt;
* [[Changes from V2.x to V3.0]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;Using µGFX on...&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[BareMetal]]&lt;br /&gt;
* [[CMSIS RTOS]]&lt;br /&gt;
* [[ChibiOS/RT]]&lt;br /&gt;
* [[FreeRTOS]]&lt;br /&gt;
* [[RawOS]]&lt;br /&gt;
* [[eCos]]&lt;br /&gt;
* [[Zephyr]]&lt;br /&gt;
* [[Using_Keil_µVision_5_MDK-ARM|Keil RTX]]&lt;br /&gt;
* [[Teensy]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Linux]]&lt;br /&gt;
* [[Win32]]&lt;br /&gt;
* [[Mac OS X]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;Using IDEs&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Using Keil µVision 5 MDK-ARM|Keil µVision 5 MDK-ARM]]&lt;br /&gt;
* [[Using IAR embedded workbench|IAR embedded workbench]]&lt;br /&gt;
* [[Using Eclipse|Eclipse]]&lt;br /&gt;
* [[Using PSoC Creator|PSoC Creator]]&lt;br /&gt;
* [[Using ChibiStudio|ChibiStudio]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;Developer Guides&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Your First Compile - Windows]]&lt;br /&gt;
* [[Creating a custom rendering routine]]&lt;br /&gt;
* [[Creating a widget]]&lt;br /&gt;
* [[Use_uGFX_repository_as_Git_Submodule|Advanced git guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;µGFX Design Choices&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-right: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Display Driver Model]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;width: 50%; float: right;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-header&amp;quot; style=&amp;quot;margin-left: 5px;&amp;quot;&amp;gt;Modules&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;div-block&amp;quot; style=&amp;quot;margin-left: 5px;&amp;quot;&amp;gt;&lt;br /&gt;
* [[GWIN]]&lt;br /&gt;
** [[Windows]]&lt;br /&gt;
*** [[Console]]&lt;br /&gt;
*** [[Graph]]&lt;br /&gt;
** [[Widgets]]&lt;br /&gt;
*** [[Label]]&lt;br /&gt;
*** [[PushButton]]&lt;br /&gt;
*** [[RadioButton]]&lt;br /&gt;
*** [[CheckBox]]&lt;br /&gt;
*** [[List]]&lt;br /&gt;
*** [[Slider]]&lt;br /&gt;
*** [[Progressbar]]&lt;br /&gt;
*** [[ImageBox]]&lt;br /&gt;
*** [[TextEdit]]&lt;br /&gt;
*** [[Keyboard]]&lt;br /&gt;
** [[Containers]]&lt;br /&gt;
*** [[Container]]&lt;br /&gt;
*** [[Tabset]]&lt;br /&gt;
*** [[Frame]]&lt;br /&gt;
* [[GAUDIO]]&lt;br /&gt;
* [[GFILE]]&lt;br /&gt;
* [[GOS]]&lt;br /&gt;
* [[GDISP]]&lt;br /&gt;
** [[Drawing]]&lt;br /&gt;
** [[Font rendering]]&lt;br /&gt;
** [[Images]]&lt;br /&gt;
* [[GINPUT]]&lt;br /&gt;
* [[GTRANS]]&lt;br /&gt;
* [[GEVENT]]&lt;br /&gt;
* [[GTIMER]]&lt;br /&gt;
* [[GQUEUE]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Font_rendering&amp;diff=1912</id>
		<title>Font rendering</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Font_rendering&amp;diff=1912"/>
				<updated>2021-07-30T13:47:40Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Anti-Aliasing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Features ==&lt;br /&gt;
The µGFX font rendering engine provides the following features:&lt;br /&gt;
&lt;br /&gt;
=== Word-Wrapping ===&lt;br /&gt;
The word wrapping feature can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_WORDWRAP&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Word wrapping only has an effect when using &amp;lt;code&amp;gt;gdispDrawStringBox()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;gdispFillStringBox()&amp;lt;/code&amp;gt;. When the word wrapping feature is not enabled the string will simply be cut-off at the border of the specified box.&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Unicode Unicode] support can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_UTF8&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Unicode support allows to display fonts of many different languages such as English, French, German, Russian (Cyrillic), Chinese, Japanese and so on.&lt;br /&gt;
For information about cyrillic font support, see [[Cyrillic]].&lt;br /&gt;
&lt;br /&gt;
=== Anti-Aliasing ===&lt;br /&gt;
To use the anti-aliasing font feature, the following three conditions have to be fulfilled:&lt;br /&gt;
# Using an anti-aliased font&lt;br /&gt;
# &amp;lt;code&amp;gt;GDISP_NEED_ANTIALIAS&amp;lt;/code&amp;gt; needs to be set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;&lt;br /&gt;
# Either have &amp;lt;code&amp;gt;GDISP_NEED_PIXELREAD&amp;lt;/code&amp;gt; set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; or using one of the [[Drawing#Text|text drawing functions]] that have a background color parameter.&lt;br /&gt;
&lt;br /&gt;
Note that you can use normal (non anti-aliased) fonts along with anti-aliased ones without any problems.&lt;br /&gt;
&lt;br /&gt;
=== Kerning ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Kerning Kerning] support can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_KERNING&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== TrueType-Font support ===&lt;br /&gt;
Any [http://en.wikipedia.org/wiki/TrueType TrueType-Font] available in a *.ttf or a *.bdf file format can be used in uGFX. See [[Font_rendering#Adding Fonts|Adding Fonts]].&lt;br /&gt;
&lt;br /&gt;
== Fonts ==&lt;br /&gt;
Every font that's available in a .ttf or .bdf format can be displayed through µGFX. However, we already added a bunch of fonts in different sizes and versions which should cover most use cases. Use the '''Font name''' as the parameter of the &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt; routine. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Font&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Font name&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 10&lt;br /&gt;
 |DejaVuSans10&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12&lt;br /&gt;
 |DejaVuSans12&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Bold&lt;br /&gt;
 |DejaVuSansBold12&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Anti-Aliased&lt;br /&gt;
 |DejaVuSans12_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Anti-Aliased Bold&lt;br /&gt;
 |DejaVuSansBold12_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 16&lt;br /&gt;
 |DejaVuSans16&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 16 Anti-Aliased&lt;br /&gt;
 |DejaVuSans16_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 20&lt;br /&gt;
 |DejaVuSans20&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 20 Anti-Aliased&lt;br /&gt;
 |DejaVuSans20_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 24&lt;br /&gt;
 |DejaVuSans24&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 24 Anti-Aliased&lt;br /&gt;
 |DejaVuSans24_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 32&lt;br /&gt;
 |DejaVuSans32&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 32 Anti-Aliased&lt;br /&gt;
 |DejaVuSans32_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 10x20&lt;br /&gt;
 |fixed_10x20&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 7x14&lt;br /&gt;
 |fixed_7x14&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 5x8&lt;br /&gt;
 |fixed_5x8&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1&lt;br /&gt;
 |UI1&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1 Double&lt;br /&gt;
 |UI1 Double&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1 Narrow&lt;br /&gt;
 |UI1 Narrow&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2&lt;br /&gt;
 |UI2&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2 Double&lt;br /&gt;
 |UI2 Double&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2 Narrow&lt;br /&gt;
 |UI2 Narrow&lt;br /&gt;
 |-&lt;br /&gt;
 |Large numbers&lt;br /&gt;
 |LargeNumbers&lt;br /&gt;
 |}&lt;br /&gt;
Note that each of these fonts has to be enabled in your [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
The UI fonts are created by the µGFX developers to provide a default font. The UI fonts stand under the GFX license and should therefore be used in preference to other fonts if suitable. The other fonts are under their own respective licenses.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Before you can use a font, you first have to open it by calling &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
gFont font = gdispOpenFont(&amp;quot;DejaVuSans32_aa&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' When the font name specified could not be found, the last enabled font in the [[Configuration|configuration file]] will be used.''&lt;br /&gt;
&lt;br /&gt;
You should call &amp;lt;code&amp;gt;gdispCloseFont()&amp;lt;/code&amp;gt; to release any allocated resources if you don't need a font any longer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
gdispCloseFont(font);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
After opening a font, the font variable can now be passed to any API call that takes a font parameter. You may start by reading through the basic [[Drawing#Text|GDISP text drawing routines]] before you take a look at the different [[GWIN|GWIN]] system.&lt;br /&gt;
&lt;br /&gt;
== Adding fonts ==&lt;br /&gt;
The following step-by-step guide will lead you through the process of adding a custom *.ttf font. This guide works for every font, not only ASCII but also cyrillic and any other unicode compatible ones.&lt;br /&gt;
&lt;br /&gt;
=== 1. Acquire a font ===&lt;br /&gt;
First of all, you'll need a font in the *.ttf source. You can find plenty of these using google. Please notice their licenses.&lt;br /&gt;
&lt;br /&gt;
=== 2. Convert the font ===&lt;br /&gt;
The next step is to convert the font into a format that can be understood by the µGFX decoder. This can be done very easily using our [http://fonts.ugfx.org online converter].&lt;br /&gt;
The converter allows you to set the font size, enable or disable anti-aliasing and filter for certain characters. Filtering un-needed characters is essential to keep the font size low. This [http://en.wikipedia.org/wiki/Basic_multilingual_plane#Basic_Multilingual_Plane table] might help you choose the correct character range. A click on the button «Get .c file» will offer you a C file to download after a few moments. Please click that button just once. It can take up to a minute to convert a larger font.&lt;br /&gt;
&lt;br /&gt;
=== 3. Implement the font ===&lt;br /&gt;
Place the downloaded c file inside your project directory and name it '''userfonts.h'''. Alternatively write a '''userfonts.h''' file that includes each of your downloaded font c files. In your [[gfxconf.h]], enable the following setting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#define GDISP_INCLUDE_USER_FONTS	TRUE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4. Open the font ===&lt;br /&gt;
You can now open and use this font as any other one. If you're curious about the parameter of &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt;, you can either use the ''full_name'' or the ''short_name'' field that can be found in the struct at the very bottom of the C file (first and second entry).&lt;br /&gt;
Please note that you need to configure your text editor to operate in UTF-8 mode, when you want to display those fonts successfully.&lt;br /&gt;
&lt;br /&gt;
For a more detailed guide on how to add your own font, see [[Cyrillic]].&lt;br /&gt;
&lt;br /&gt;
== Font metrics ==&lt;br /&gt;
The GDISP API provides several function to retrieve information about font metrics:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
typedef enum fontmetric {&lt;br /&gt;
    fontHeight,&lt;br /&gt;
    fontDescendersHeight,&lt;br /&gt;
    fontLineSpacing,&lt;br /&gt;
    fontCharPadding,&lt;br /&gt;
    fontMinWidth,&lt;br /&gt;
    fontMaxWidth,&lt;br /&gt;
    fontBaselineX,&lt;br /&gt;
    fontBaselineY&lt;br /&gt;
} fontmetric_t;&lt;br /&gt;
&lt;br /&gt;
gCoord gdispGetFontMetric(gFont font, fontmetric_t metric);&lt;br /&gt;
gCoord gdispGetCharWidth(char c, gFont font);&lt;br /&gt;
gCoord gdispGetStringWidth(const char* str, gFont font);&lt;br /&gt;
gCoord gdispGetStringWidthCount(const char* str, gFont font, uint16_t count);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:GDISP]]&lt;br /&gt;
&lt;br /&gt;
== Disclaimer ==&lt;br /&gt;
µGFX comes with a built-in support of [https://code.google.com/p/mcufont/ mcufont]. The author of the mcufont project provides a re-licensed version of his works to the µGFX projects.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Font_rendering&amp;diff=1911</id>
		<title>Font rendering</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Font_rendering&amp;diff=1911"/>
				<updated>2021-07-30T13:46:57Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Features ==&lt;br /&gt;
The µGFX font rendering engine provides the following features:&lt;br /&gt;
&lt;br /&gt;
=== Word-Wrapping ===&lt;br /&gt;
The word wrapping feature can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_WORDWRAP&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Word wrapping only has an effect when using &amp;lt;code&amp;gt;gdispDrawStringBox()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;gdispFillStringBox()&amp;lt;/code&amp;gt;. When the word wrapping feature is not enabled the string will simply be cut-off at the border of the specified box.&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Unicode Unicode] support can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_UTF8&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Unicode support allows to display fonts of many different languages such as English, French, German, Russian (Cyrillic), Chinese, Japanese and so on.&lt;br /&gt;
For information about cyrillic font support, see [[Cyrillic]].&lt;br /&gt;
&lt;br /&gt;
=== Anti-Aliasing ===&lt;br /&gt;
To use the anti-aliasing font feature, the following three conditions have to be fulfilled:&lt;br /&gt;
# Using an anti-aliased font&lt;br /&gt;
# &amp;lt;code&amp;gt;GDISP_NEED_ANTIALIAS&amp;lt;/code&amp;gt; needs to be set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;&lt;br /&gt;
# Either have &amp;lt;code&amp;gt;GDISP_NEED_PIXELREAD&amp;lt;/code&amp;gt; set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; or using one of the [[Drawing#Text|text drawing functions]] that have a background color parameter.&lt;br /&gt;
&lt;br /&gt;
Note that you can use normal (not anti-aliased) fonts along with anti-aliased ones without any problems.&lt;br /&gt;
&lt;br /&gt;
=== Kerning ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Kerning Kerning] support can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_KERNING&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== TrueType-Font support ===&lt;br /&gt;
Any [http://en.wikipedia.org/wiki/TrueType TrueType-Font] available in a *.ttf or a *.bdf file format can be used in uGFX. See [[Font_rendering#Adding Fonts|Adding Fonts]].&lt;br /&gt;
&lt;br /&gt;
== Fonts ==&lt;br /&gt;
Every font that's available in a .ttf or .bdf format can be displayed through µGFX. However, we already added a bunch of fonts in different sizes and versions which should cover most use cases. Use the '''Font name''' as the parameter of the &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt; routine. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Font&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Font name&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 10&lt;br /&gt;
 |DejaVuSans10&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12&lt;br /&gt;
 |DejaVuSans12&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Bold&lt;br /&gt;
 |DejaVuSansBold12&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Anti-Aliased&lt;br /&gt;
 |DejaVuSans12_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Anti-Aliased Bold&lt;br /&gt;
 |DejaVuSansBold12_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 16&lt;br /&gt;
 |DejaVuSans16&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 16 Anti-Aliased&lt;br /&gt;
 |DejaVuSans16_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 20&lt;br /&gt;
 |DejaVuSans20&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 20 Anti-Aliased&lt;br /&gt;
 |DejaVuSans20_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 24&lt;br /&gt;
 |DejaVuSans24&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 24 Anti-Aliased&lt;br /&gt;
 |DejaVuSans24_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 32&lt;br /&gt;
 |DejaVuSans32&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 32 Anti-Aliased&lt;br /&gt;
 |DejaVuSans32_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 10x20&lt;br /&gt;
 |fixed_10x20&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 7x14&lt;br /&gt;
 |fixed_7x14&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 5x8&lt;br /&gt;
 |fixed_5x8&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1&lt;br /&gt;
 |UI1&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1 Double&lt;br /&gt;
 |UI1 Double&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1 Narrow&lt;br /&gt;
 |UI1 Narrow&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2&lt;br /&gt;
 |UI2&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2 Double&lt;br /&gt;
 |UI2 Double&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2 Narrow&lt;br /&gt;
 |UI2 Narrow&lt;br /&gt;
 |-&lt;br /&gt;
 |Large numbers&lt;br /&gt;
 |LargeNumbers&lt;br /&gt;
 |}&lt;br /&gt;
Note that each of these fonts has to be enabled in your [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
The UI fonts are created by the µGFX developers to provide a default font. The UI fonts stand under the GFX license and should therefore be used in preference to other fonts if suitable. The other fonts are under their own respective licenses.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Before you can use a font, you first have to open it by calling &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
gFont font = gdispOpenFont(&amp;quot;DejaVuSans32_aa&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' When the font name specified could not be found, the last enabled font in the [[Configuration|configuration file]] will be used.''&lt;br /&gt;
&lt;br /&gt;
You should call &amp;lt;code&amp;gt;gdispCloseFont()&amp;lt;/code&amp;gt; to release any allocated resources if you don't need a font any longer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
gdispCloseFont(font);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
After opening a font, the font variable can now be passed to any API call that takes a font parameter. You may start by reading through the basic [[Drawing#Text|GDISP text drawing routines]] before you take a look at the different [[GWIN|GWIN]] system.&lt;br /&gt;
&lt;br /&gt;
== Adding fonts ==&lt;br /&gt;
The following step-by-step guide will lead you through the process of adding a custom *.ttf font. This guide works for every font, not only ASCII but also cyrillic and any other unicode compatible ones.&lt;br /&gt;
&lt;br /&gt;
=== 1. Acquire a font ===&lt;br /&gt;
First of all, you'll need a font in the *.ttf source. You can find plenty of these using google. Please notice their licenses.&lt;br /&gt;
&lt;br /&gt;
=== 2. Convert the font ===&lt;br /&gt;
The next step is to convert the font into a format that can be understood by the µGFX decoder. This can be done very easily using our [http://fonts.ugfx.org online converter].&lt;br /&gt;
The converter allows you to set the font size, enable or disable anti-aliasing and filter for certain characters. Filtering un-needed characters is essential to keep the font size low. This [http://en.wikipedia.org/wiki/Basic_multilingual_plane#Basic_Multilingual_Plane table] might help you choose the correct character range. A click on the button «Get .c file» will offer you a C file to download after a few moments. Please click that button just once. It can take up to a minute to convert a larger font.&lt;br /&gt;
&lt;br /&gt;
=== 3. Implement the font ===&lt;br /&gt;
Place the downloaded c file inside your project directory and name it '''userfonts.h'''. Alternatively write a '''userfonts.h''' file that includes each of your downloaded font c files. In your [[gfxconf.h]], enable the following setting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#define GDISP_INCLUDE_USER_FONTS	TRUE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4. Open the font ===&lt;br /&gt;
You can now open and use this font as any other one. If you're curious about the parameter of &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt;, you can either use the ''full_name'' or the ''short_name'' field that can be found in the struct at the very bottom of the C file (first and second entry).&lt;br /&gt;
Please note that you need to configure your text editor to operate in UTF-8 mode, when you want to display those fonts successfully.&lt;br /&gt;
&lt;br /&gt;
For a more detailed guide on how to add your own font, see [[Cyrillic]].&lt;br /&gt;
&lt;br /&gt;
== Font metrics ==&lt;br /&gt;
The GDISP API provides several function to retrieve information about font metrics:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
typedef enum fontmetric {&lt;br /&gt;
    fontHeight,&lt;br /&gt;
    fontDescendersHeight,&lt;br /&gt;
    fontLineSpacing,&lt;br /&gt;
    fontCharPadding,&lt;br /&gt;
    fontMinWidth,&lt;br /&gt;
    fontMaxWidth,&lt;br /&gt;
    fontBaselineX,&lt;br /&gt;
    fontBaselineY&lt;br /&gt;
} fontmetric_t;&lt;br /&gt;
&lt;br /&gt;
gCoord gdispGetFontMetric(gFont font, fontmetric_t metric);&lt;br /&gt;
gCoord gdispGetCharWidth(char c, gFont font);&lt;br /&gt;
gCoord gdispGetStringWidth(const char* str, gFont font);&lt;br /&gt;
gCoord gdispGetStringWidthCount(const char* str, gFont font, uint16_t count);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:GDISP]]&lt;br /&gt;
&lt;br /&gt;
== Disclaimer ==&lt;br /&gt;
µGFX comes with a built-in support of [https://code.google.com/p/mcufont/ mcufont]. The author of the mcufont project provides a re-licensed version of his works to the µGFX projects.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	<entry>
		<id>https://wiki.ugfx.io/index.php?title=Font_rendering&amp;diff=1910</id>
		<title>Font rendering</title>
		<link rel="alternate" type="text/html" href="https://wiki.ugfx.io/index.php?title=Font_rendering&amp;diff=1910"/>
				<updated>2021-07-30T13:46:47Z</updated>
		
		<summary type="html">&lt;p&gt;Tectu: /* Font metrics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Features ==&lt;br /&gt;
The µGFX font rendering engine provides the following features:&lt;br /&gt;
&lt;br /&gt;
=== Word-Wrapping ===&lt;br /&gt;
The word wrapping feature can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_WORDWRAP&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Word wrapping only has an effect when using &amp;lt;code&amp;gt;gdispDrawStringBox()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;gdispFillStringBox()&amp;lt;/code&amp;gt;. When the word wrapping feature is not enabled the string will simply be cut-off at the border of the specified box.&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Unicode Unicode] support can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_UTF8&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Unicode support allows to display fonts of many different languages such as English, French, German, Russian (Cyrillic), Chinese, Japanese and so on.&lt;br /&gt;
For information about cyrillic font support, see [[Cyrillic]].&lt;br /&gt;
&lt;br /&gt;
=== Anti-Aliasing ===&lt;br /&gt;
To use the anti-aliasing font feature, the following three conditions have to be fulfilled:&lt;br /&gt;
# Using an anti-aliased font&lt;br /&gt;
# &amp;lt;code&amp;gt;GDISP_NEED_ANTIALIAS&amp;lt;/code&amp;gt; needs to be set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;&lt;br /&gt;
# Either have &amp;lt;code&amp;gt;GDISP_NEED_PIXELREAD&amp;lt;/code&amp;gt; set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt; or using one of the [[Drawing#Text|text drawing functions]] that have a background color parameter.&lt;br /&gt;
&lt;br /&gt;
Note that you can use normal (not anti-aliased) fonts along with anti-aliased ones without any problems.&lt;br /&gt;
&lt;br /&gt;
=== Kerning ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Kerning Kerning] support can be enabled by setting &amp;lt;code&amp;gt;GDISP_NEED_TEXT_KERNING&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== TrueType-Font support ===&lt;br /&gt;
Any [http://en.wikipedia.org/wiki/TrueType TrueType-Font] available in a *.ttf or a *.bdf file format can be used in uGFX. See [[Font_rendering#Adding Fonts|Adding Fonts]].&lt;br /&gt;
&lt;br /&gt;
== Fonts ==&lt;br /&gt;
Every font that's available in a .ttf or .bdf format can be displayed through µGFX. However, we already added a bunch of fonts in different sizes and versions which should cover most use cases. Use the '''Font name''' as the parameter of the &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt; routine. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Font&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot;|Font name&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 10&lt;br /&gt;
 |DejaVuSans10&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12&lt;br /&gt;
 |DejaVuSans12&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Bold&lt;br /&gt;
 |DejaVuSansBold12&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Anti-Aliased&lt;br /&gt;
 |DejaVuSans12_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 12 Anti-Aliased Bold&lt;br /&gt;
 |DejaVuSansBold12_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 16&lt;br /&gt;
 |DejaVuSans16&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 16 Anti-Aliased&lt;br /&gt;
 |DejaVuSans16_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 20&lt;br /&gt;
 |DejaVuSans20&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 20 Anti-Aliased&lt;br /&gt;
 |DejaVuSans20_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 24&lt;br /&gt;
 |DejaVuSans24&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 24 Anti-Aliased&lt;br /&gt;
 |DejaVuSans24_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 32&lt;br /&gt;
 |DejaVuSans32&lt;br /&gt;
 |-&lt;br /&gt;
 |DejaVu Sans 32 Anti-Aliased&lt;br /&gt;
 |DejaVuSans32_aa&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 10x20&lt;br /&gt;
 |fixed_10x20&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 7x14&lt;br /&gt;
 |fixed_7x14&lt;br /&gt;
 |-&lt;br /&gt;
 |Fixed 5x8&lt;br /&gt;
 |fixed_5x8&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1&lt;br /&gt;
 |UI1&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1 Double&lt;br /&gt;
 |UI1 Double&lt;br /&gt;
 |-&lt;br /&gt;
 |UI1 Narrow&lt;br /&gt;
 |UI1 Narrow&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2&lt;br /&gt;
 |UI2&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2 Double&lt;br /&gt;
 |UI2 Double&lt;br /&gt;
 |-&lt;br /&gt;
 |UI2 Narrow&lt;br /&gt;
 |UI2 Narrow&lt;br /&gt;
 |-&lt;br /&gt;
 |Large numbers&lt;br /&gt;
 |LargeNumbers&lt;br /&gt;
 |}&lt;br /&gt;
Note that each of these fonts has to be enabled in your [[Configuration|configuration file]].&lt;br /&gt;
&lt;br /&gt;
The UI fonts are created by the µGFX developers to provide a default font. The UI fonts stand under the GFX license and should therefore be used in preference to other fonts if suitable. The other fonts are under their own respective licenses.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Before you can use a font, you first have to open it by calling &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
font_t font = gdispOpenFont(&amp;quot;DejaVuSans32_aa&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''''Note:''' When the font name specified could not be found, the last enabled font in the [[Configuration|configuration file]] will be used.''&lt;br /&gt;
&lt;br /&gt;
You should call &amp;lt;code&amp;gt;gdispCloseFont()&amp;lt;/code&amp;gt; to release any allocated resources if you don't need a font any longer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
gdispCloseFont(font);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
After opening a font, the font variable can now be passed to any API call that takes a font parameter. You may start by reading through the basic [[Drawing#Text|GDISP text drawing routines]] before you take a look at the different [[GWIN|GWIN]] system.&lt;br /&gt;
&lt;br /&gt;
== Adding fonts ==&lt;br /&gt;
The following step-by-step guide will lead you through the process of adding a custom *.ttf font. This guide works for every font, not only ASCII but also cyrillic and any other unicode compatible ones.&lt;br /&gt;
&lt;br /&gt;
=== 1. Acquire a font ===&lt;br /&gt;
First of all, you'll need a font in the *.ttf source. You can find plenty of these using google. Please notice their licenses.&lt;br /&gt;
&lt;br /&gt;
=== 2. Convert the font ===&lt;br /&gt;
The next step is to convert the font into a format that can be understood by the µGFX decoder. This can be done very easily using our [http://fonts.ugfx.org online converter].&lt;br /&gt;
The converter allows you to set the font size, enable or disable anti-aliasing and filter for certain characters. Filtering un-needed characters is essential to keep the font size low. This [http://en.wikipedia.org/wiki/Basic_multilingual_plane#Basic_Multilingual_Plane table] might help you choose the correct character range. A click on the button «Get .c file» will offer you a C file to download after a few moments. Please click that button just once. It can take up to a minute to convert a larger font.&lt;br /&gt;
&lt;br /&gt;
=== 3. Implement the font ===&lt;br /&gt;
Place the downloaded c file inside your project directory and name it '''userfonts.h'''. Alternatively write a '''userfonts.h''' file that includes each of your downloaded font c files. In your [[gfxconf.h]], enable the following setting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c&amp;gt;&lt;br /&gt;
#define GDISP_INCLUDE_USER_FONTS	TRUE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4. Open the font ===&lt;br /&gt;
You can now open and use this font as any other one. If you're curious about the parameter of &amp;lt;code&amp;gt;gdispOpenFont()&amp;lt;/code&amp;gt;, you can either use the ''full_name'' or the ''short_name'' field that can be found in the struct at the very bottom of the C file (first and second entry).&lt;br /&gt;
Please note that you need to configure your text editor to operate in UTF-8 mode, when you want to display those fonts successfully.&lt;br /&gt;
&lt;br /&gt;
For a more detailed guide on how to add your own font, see [[Cyrillic]].&lt;br /&gt;
&lt;br /&gt;
== Font metrics ==&lt;br /&gt;
The GDISP API provides several function to retrieve information about font metrics:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
typedef enum fontmetric {&lt;br /&gt;
    fontHeight,&lt;br /&gt;
    fontDescendersHeight,&lt;br /&gt;
    fontLineSpacing,&lt;br /&gt;
    fontCharPadding,&lt;br /&gt;
    fontMinWidth,&lt;br /&gt;
    fontMaxWidth,&lt;br /&gt;
    fontBaselineX,&lt;br /&gt;
    fontBaselineY&lt;br /&gt;
} fontmetric_t;&lt;br /&gt;
&lt;br /&gt;
gCoord gdispGetFontMetric(gFont font, fontmetric_t metric);&lt;br /&gt;
gCoord gdispGetCharWidth(char c, gFont font);&lt;br /&gt;
gCoord gdispGetStringWidth(const char* str, gFont font);&lt;br /&gt;
gCoord gdispGetStringWidthCount(const char* str, gFont font, uint16_t count);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:GDISP]]&lt;br /&gt;
&lt;br /&gt;
== Disclaimer ==&lt;br /&gt;
µGFX comes with a built-in support of [https://code.google.com/p/mcufont/ mcufont]. The author of the mcufont project provides a re-licensed version of his works to the µGFX projects.&lt;/div&gt;</summary>
		<author><name>Tectu</name></author>	</entry>

	</feed>