Saturday, May 23, 2020

Displaying Basic 2D Shapes Using emWin

Hello Everyone, In the last two posts, we have learned how to display text and display images using the emWin framework under a simulated environment using Code::Blocks. If you have not seen those blog posts, I would recommend you first have a look at them.
Getting Started with emWin using Code::Blocks
Draw Bitmap Images using emWin

Now in this blog post, I will show you to use some other basic 2D APIs to draw some basic 2D shapes, such as rectangle, triangle, polygon, ellipse, pie chart, etc.
Basic 2D Shapes
- Draw horizontal and vertical Gradients
- Draw rectangles
- Change Pen Size
- Draw Pixel and Points
Basic 2D Shapes
/**
* @function test_draw_basic_routine
* @brief Test Basic 2D Drawing Routines
*/
void test_draw_basic_routine( void )
{
/// Basic Drawing Routines ///
GUI_Clear();
/// Draw a rectangle with horizontal color gradient
GUI_DrawGradientH(0, 0, 63, 63, GUI_LIGHTCYAN, GUI_DARKCYAN);
custom_delay();
/// Draw a rectangle with vertical color gradient
GUI_DrawGradientV(64, 0, 127, 63, GUI_LIGHTCYAN, GUI_DARKCYAN);
custom_delay();
/// Draw a rectangle with rounded corners filled with a horizontal color gradient
GUI_DrawGradientRoundedH(128, 0, 191, 63, 20, GUI_LIGHTBLUE, GUI_DARKBLUE);
custom_delay();
/// Draw a rectangle with rounded corners filled with a horizontal color gradient
GUI_DrawGradientRoundedV(192, 0, 255, 63, 20, GUI_LIGHTBLUE, GUI_DARKBLUE);
custom_delay();
/// Draw a Pixel at a specified position
GUI_DrawPixel(256, 0);
custom_delay();
/// Draw a Point with the Current Pen Size
/// At the moment Pen Size is 1, so first we will change the Pen Size
/// Change Pen Size to 10
GUI_SetPenSize(10);
GUI_DrawPoint(288, 32);
custom_delay();
}


Draw Lines
/**
* @function test_draw_line
* @brief Test different Draw Line API
*/
void test_draw_line( void )
{
/// Drawing Lines ///
GUI_Clear();
/// Draw Horizontal Line with 1 pixel thickness
GUI_SetColor(GUI_RED);
GUI_DrawHLine( 32, 32, 280); // x1 > x0 else nothing will be displayed
/// Draw Line
GUI_DrawLine(0, 0, LCD_GetXSize(), LCD_GetYSize() );
/// Draws a line from the current (x, y) position to an endpoint specified
/// by X-distance and Y-distance in the current window (relative coordinates)
GUI_DrawLineRel( 200, 200);
/// Draw Vertical Line
GUI_DrawVLine( LCD_GetXSize()/2, 0, LCD_GetYSize() );
/// Line Style: Only works with GUI_DrawLine function
GUI_SetLineStyle(GUI_LS_DASH);
GUI_DrawLine(0, 0, LCD_GetXSize()/2, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_DOT);
GUI_DrawLine(0, 0, LCD_GetXSize()/3, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_DASHDOT);
GUI_DrawLine(0, 0, LCD_GetXSize()/4, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_DASHDOTDOT);
GUI_DrawLine(0, 0, LCD_GetXSize()/5, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_SOLID);
custom_delay();
}

Draw Circles
/**
* @function test_draw_circle
* @brief Test Circle Draw APIs
*/
void test_draw_circle( void )
{
/// Drawing Circles ///
int i;
GUI_Clear();
GUI_SetColor(GUI_LIGHTCYAN);
/// Filled Circle
GUI_SetColor(GUI_DARKMAGENTA);
GUI_FillCircle( LCD_GetXSize()/2, LCD_GetYSize()/2, 20 );
for( i=30; i< LCD_GetXSize()/2; i+=10 )
{
/// Normal Circle
GUI_DrawCircle( LCD_GetXSize()/2, LCD_GetYSize()/2, i);
}
custom_delay();
}

Draw Ellipses
/**
* @function test_draw_ellipses
* @brief Test Ellipse Draw APIs
*/
void test_draw_ellipses( void )
{
/// Drawing Ellipses ///
GUI_Clear();
GUI_SetColor(GUI_RED);
GUI_FillEllipse(100, 180, 50, 70);
GUI_SetColor(GUI_MAGENTA);
GUI_DrawEllipse(100, 180, 50, 70);
GUI_SetColor(GUI_YELLOW);
GUI_FillEllipse(100, 180, 10, 50);
custom_delay();
}

Draw Polygon
/**
* @function test_draw_polygon
* @brief Test Polygon Draw APIs
*/
void test_draw_polygon( void )
{
/// Drawing Polygons ///
int i;
GUI_Clear();
const GUI_POINT aPoints[] = {
{ 40, 20 },
{ 0, 20 },
{ 20, 0 }
};
// This will be used to save the source pointer
GUI_POINT aEnlargedPoints[GUI_COUNTOF(aPoints)];
GUI_SetColor(GUI_LIGHTBLUE);
GUI_FillPolygon( aPoints, GUI_COUNTOF(aPoints), 0, 0 );
GUI_SetDrawMode(GUI_DM_XOR);
GUI_FillPolygon(aPoints, GUI_COUNTOF(aPoints), 140, 110);
GUI_SetColor(GUI_WHITE);
for( i=1; i<10; i++ )
{
GUI_EnlargePolygon(aEnlargedPoints, aPoints, GUI_COUNTOF(aPoints), i*5 );
GUI_FillPolygon(aEnlargedPoints, GUI_COUNTOF(aPoints), 140, 110);
}
/// Reset Drawing Mode back to Normal
GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);
custom_delay();
}

Draw Pie Chart
void test_draw_pie_chart( void )
{
int i, start_angle, stop_angle;
const unsigned aValues[] = { 100, 135, 190, 240, 340, 360};
const GUI_COLOR aColors[] = { GUI_BLUE, GUI_GREEN, GUI_RED, GUI_CYAN, GUI_MAGENTA, GUI_YELLOW };
for (i = 0; i < GUI_COUNTOF(aValues); i++)
{
start_angle = (i == 0) ? 0 : aValues[i - 1];
stop_angle = aValues[i];
GUI_SetColor(aColors[i]);
GUI_DrawPie(LCD_GetXSize()/2, LCD_GetYSize()/2, LCD_GetYSize()/2, start_angle, stop_angle, 0);
}
}

Draw Line Graph
void test_draw_graph( void )
{
int x[LCD_GetXSize()];
int i;
GUI_Clear();
GUI_SetColor(GUI_RED);
for (i = 0; i < GUI_COUNTOF(x); i++)
{
x[i] = rand() % LCD_GetYSize()/2;
}
GUI_DrawGraph(x, GUI_COUNTOF(x), 0, 0 );
}

Draw Bitmap Images
There is a separate blog post to draw bitmap images on the display, click here to read the blog post link.

The following is the complete Code::Blocks program, also watch the video given below to view how the complete program runs.
#include <stdlib.h>
#include "GUI.h"
#define RECOMMENDED_MEMORY (1024L * 5)
extern GUI_CONST_STORAGE GUI_BITMAP bmimage01;
extern GUI_CONST_STORAGE GUI_BITMAP bmimage04;
extern GUI_CONST_STORAGE GUI_BITMAP bmSTLogo;
/*Local Function Declaration*/
void custom_delay( void );
void test_print_text( void );
void test_draw_basic_routine( void );
void test_draw_rectangle( void );
void test_draw_bitmap( void );
void test_draw_line( void );
void test_draw_polygon( void );
void test_draw_circle( void );
void test_draw_ellipses( void );
void test_draw_graph( void );
void test_draw_pie_chart( void );
void MainTask(void)
{
int i;
GUI_Init();
if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY)
{
GUI_ErrorOut("Not enough memory available.");
return;
}
test_print_text();
test_draw_basic_routine();
test_draw_rectangle();
test_draw_bitmap();
test_draw_line();
test_draw_polygon();
test_draw_circle();
test_draw_ellipses();
test_draw_graph();
test_draw_pie_chart();
while(1);
}
/*Local Function Definition*/
/**
* @function custom_delay
* @brief User Delay of fixed value
*/
void custom_delay( void )
{
GUI_Delay(1000);
}
/**
* @function test_print_text
* @brief Display Text on the Screen
*/
void test_print_text( void )
{
GUI_Clear();
GUI_SetFont(&GUI_Font32_1);
GUI_SetColor(GUI_LIGHTCYAN);
GUI_DispStringHCenterAt("2D Graphics Example", LCD_GetXSize()/2, 0);
GUI_GotoXY(0, 32);
GUI_DispString("LCD Size X = ");
GUI_DispDec( LCD_GetXSize(), 3 );
GUI_DispString(", LCD Size Y = ");
GUI_DispDec( LCD_GetYSize(), 3 );
custom_delay();
}
/**
* @function test_draw_basic_routine
* @brief Test Basic 2D Drawing Routines
*/
void test_draw_basic_routine( void )
{
/// Basic Drawing Routines ///
GUI_Clear();
/// Draw a rectangle with horizontal color gradient
GUI_DrawGradientH(0, 0, 63, 63, GUI_LIGHTCYAN, GUI_DARKCYAN);
custom_delay();
/// Draw a rectangle with vertical color gradient
GUI_DrawGradientV(64, 0, 127, 63, GUI_LIGHTCYAN, GUI_DARKCYAN);
custom_delay();
/// Draw a rectangle with rounded corners filled with a horizontal color gradient
GUI_DrawGradientRoundedH(128, 0, 191, 63, 20, GUI_LIGHTBLUE, GUI_DARKBLUE);
custom_delay();
/// Draw a rectangle with rounded corners filled with a horizontal color gradient
GUI_DrawGradientRoundedV(192, 0, 255, 63, 20, GUI_LIGHTBLUE, GUI_DARKBLUE);
custom_delay();
/// Draw a Pixel at a specified position
GUI_DrawPixel(256, 0);
custom_delay();
/// Draw a Point with the Current Pen Size
/// At the moment Pen Size is 1, so first we will change the Pen Size
/// Change Pen Size to 10
GUI_SetPenSize(10);
GUI_DrawPoint(288, 32);
custom_delay();
}
/**
* @function test_draw_rectangle
* @brief Test Rectangle Drawing functions/API
*/
void test_draw_rectangle( void )
{
/// Draw Rectangle ///
GUI_SetPenSize(1); /// Reset Pen Size to 1
GUI_SetColor(GUI_RED);
GUI_DrawRect(0, 64, 63, 127);
custom_delay();
/// Another way to draw a Rectangle
GUI_SetColor(GUI_YELLOW);
GUI_RECT rect = { 64, 64, 127, 127};
GUI_DrawRectEx( &rect );
custom_delay();
/// Draw Rounded Rectangle
GUI_DrawRoundedRect(128, 64, 255, 127, 10);
custom_delay();
/// Draw Frame with Rounded Corner
GUI_SetColor(GUI_RED);
GUI_DrawRoundedFrame(256, 64, 383, 127, 10, 10);
custom_delay();
/// Draw Filled Rectangle
GUI_SetColor(GUI_CYAN);
GUI_FillRect(0, 127, 63, 191);
custom_delay();
/// Another way to draw a filled Rectangle
GUI_SetColor(GUI_YELLOW);
GUI_RECT rect2 = { 64, 127, 127, 191};
GUI_FillRectEx( &rect2 );
custom_delay();
/// Draw Filled Rounded Rectangle
GUI_FillRoundedRect(128, 127, 255, 191, 10);
/// Inverted Rectangle
GUI_SetColor(GUI_RED);
GUI_InvertRect(256, 127, 383, 191);
GUI_DrawRect(256, 127, 383, 191);
custom_delay();
}
/**
* @function test_draw_bitmap
* @brief Test bitmap related APIs
*/
void test_draw_bitmap( void )
{
/// Drawing Bitmaps ///
/// Generate Bitmap C file using bmp converter tool
GUI_Clear();
GUI_DrawBitmap(&bmimage01, 0, 0);
custom_delay();
GUI_Clear();
GUI_DrawBitmap(&bmimage04, 0, 0);
custom_delay();
GUI_Clear();
GUI_DrawBitmap(&bmSTLogo, 0, 0);
custom_delay();
/// Magnify the Bitmap Image
GUI_Clear();
GUI_DrawBitmapMag(&bmSTLogo, 0, 0, 2, 2);
custom_delay();
}
/**
* @function test_draw_line
* @brief Test different Draw Line API
*/
void test_draw_line( void )
{
/// Drawing Lines ///
GUI_Clear();
/// Draw Horizontal Line with 1 pixel thickness
GUI_SetColor(GUI_RED);
GUI_DrawHLine( 32, 32, 280); // x1 > x0 else nothing will be displayed
/// Draw Line
GUI_DrawLine(0, 0, LCD_GetXSize(), LCD_GetYSize() );
/// Draws a line from the current (x, y) position to an endpoint specified
/// by X-distance and Y-distance in the current window (relative coordinates)
GUI_DrawLineRel( 200, 200);
/// Draw Vertical Line
GUI_DrawVLine( LCD_GetXSize()/2, 0, LCD_GetYSize() );
/// Line Style: Only works with GUI_DrawLine function
GUI_SetLineStyle(GUI_LS_DASH);
GUI_DrawLine(0, 0, LCD_GetXSize()/2, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_DOT);
GUI_DrawLine(0, 0, LCD_GetXSize()/3, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_DASHDOT);
GUI_DrawLine(0, 0, LCD_GetXSize()/4, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_DASHDOTDOT);
GUI_DrawLine(0, 0, LCD_GetXSize()/5, LCD_GetYSize() );
GUI_SetLineStyle(GUI_LS_SOLID);
custom_delay();
}
/**
* @function test_draw_circle
* @brief Test Circle Draw APIs
*/
void test_draw_circle( void )
{
/// Drawing Circles ///
int i;
GUI_Clear();
GUI_SetColor(GUI_LIGHTCYAN);
/// Filled Circle
GUI_SetColor(GUI_DARKMAGENTA);
GUI_FillCircle( LCD_GetXSize()/2, LCD_GetYSize()/2, 20 );
for( i=30; i< LCD_GetXSize()/2; i+=10 )
{
/// Normal Circle
GUI_DrawCircle( LCD_GetXSize()/2, LCD_GetYSize()/2, i);
}
custom_delay();
}
/**
* @function test_draw_ellipses
* @brief Test Ellipse Draw APIs
*/
void test_draw_ellipses( void )
{
/// Drawing Ellipses ///
GUI_Clear();
GUI_SetColor(GUI_RED);
GUI_FillEllipse(100, 180, 50, 70);
GUI_SetColor(GUI_MAGENTA);
GUI_DrawEllipse(100, 180, 50, 70);
GUI_SetColor(GUI_YELLOW);
GUI_FillEllipse(100, 180, 10, 50);
custom_delay();
}
/**
* @function test_draw_polygon
* @brief Test Polygon Draw APIs
*/
void test_draw_polygon( void )
{
/// Drawing Polygons ///
int i;
GUI_Clear();
const GUI_POINT aPoints[] = {
{ 40, 20 },
{ 0, 20 },
{ 20, 0 }
};
// This will be used to save the source pointer
GUI_POINT aEnlargedPoints[GUI_COUNTOF(aPoints)];
GUI_SetColor(GUI_LIGHTBLUE);
GUI_FillPolygon( aPoints, GUI_COUNTOF(aPoints), 0, 0 );
GUI_SetDrawMode(GUI_DM_XOR);
GUI_FillPolygon(aPoints, GUI_COUNTOF(aPoints), 140, 110);
GUI_SetColor(GUI_WHITE);
for( i=1; i<10; i++ )
{
GUI_EnlargePolygon(aEnlargedPoints, aPoints, GUI_COUNTOF(aPoints), i*5 );
GUI_FillPolygon(aEnlargedPoints, GUI_COUNTOF(aPoints), 140, 110);
}
/// Reset Drawing Mode back to Normal
GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);
custom_delay();
}
/**
* @function test_draw_graph
* @brief Test Draw Graph API, this will be useful in plotting sensor data
*/
void test_draw_graph( void )
{
/// Draw Graph ////
int x[LCD_GetXSize()];
int i;
GUI_Clear();
GUI_SetColor(GUI_RED);
for (i = 0; i < GUI_COUNTOF(x); i++)
{
x[i] = rand() % LCD_GetYSize()/2;
}
GUI_DrawGraph(x, GUI_COUNTOF(x), 0, 0 );
custom_delay();
}
/**
* @function test_draw_pie_chart
* @brief Test Draw Pie Chart Functions
*/
void test_draw_pie_chart( void )
{
/// Draw Pie Chart ///
int i, start_angle, stop_angle;
const unsigned aValues[] = { 90, 135, 190, 240, 340, 360};
const GUI_COLOR aColors[] = { GUI_BLUE, GUI_GREEN, GUI_RED, GUI_CYAN, GUI_MAGENTA, GUI_YELLOW };
GUI_Clear();
for (i = 0; i < GUI_COUNTOF(aValues); i++)
{
start_angle = (i == 0) ? 0 : aValues[i - 1];
stop_angle = aValues[i];
GUI_SetColor(aColors[i]);
GUI_DrawPie(LCD_GetXSize()/2, LCD_GetYSize()/2, LCD_GetYSize()/2, start_angle, stop_angle, 0);
custom_delay();
}
custom_delay();
}



No comments:

Post a Comment