Drawing Olympic Rings by Using GDI APIs

Posted by admin on August 9, 2012

As we know, the region in MiniGUI is formed by non-intersected rectangles and meets the x-y-banned rule. Using polygon or enclosed curve generator can regard each scan line as a rectangle with the height of one. Thus, we can use these generators to build complex region. Now, we will introduce how to draw the interlinked Olympic rings based on MiniGUI functions.

Firstly, use InitFreeClipRectList (heap,size) function to initialize the private block data heap used to allocate clipping rectangles. In this function, heap is the pointer to a BLOCKHEAP structure, and size is the size of the heap.

Secondly, use InitClipRgn (PCLIPRGN pRgn, PBLOCKHEAP pFreeList) function to initialize a clipping region. Here, pRgn is the pointer to the CLIPRGN structure to be initialized, and pFreeList is the pointer to the initialized private block data heap.

MiniGUI uses existed enclosed curve generator to implement complex region generating functions. Using such functions we can initialize certain region as circle, ellipse, or polygon region. During this processes, we only need to initialize certain region as circle. The function is InitCircleRegion (PCLIPRGN dst,int x,int y,int r). Here, dst is the pointer to the region to be initialized, x and y are the center of the circle, and r is the radius of the circle.

Then, use SubtractRegion (CLIPRGN * rgnD, const CLIPRGN * rgnM, const CLIPRGN * rgnS) function to subtract a circle region from another in order to get the ring region, which is the basic region of the interlinked Olympic rings. Based on the ring region, use IntersectRegion (PCLIPRGN pRstRgn, const CLIPRGN * pRgn1, const CLIPRGN * pRgn2) function to obtain the intersection regions of the rings. Then, you can get the complex regions of the interlinked Olympic rings.

After get the complex regions of the interlinked Olympic rings, you can use SelectClipRegion (HDC hdc, const CLIPRGN * pRgn) function to select into a DC as the clipped region.

Based on MiniGUI function SetBrushColor (hdc, color) and FillBox (HDC hdc, int x,int y,int w,int h), you can set the brush color of a DC as blue, yellow, black, green or red separately to fill the different rectangle boxes.

At last, use EmptyClipRgn (PCLIPRGN pRgn) function to empty the clip region, and release the certain clipping region. Note: don't forget to use DestroyFreeClipRectList (heap) function in order to destroy the private block data heap.

Now the interlinked Olympic rings based on MiniGUI functions is finished, the figure and the partial codes building the interlinked Olympic rings as follow. For more information, please see MGDesktop.

Source Code

static BLOCKHEAP my_cliprc_heap;

static void GDIDemo_Region (HWND hWnd, HDC hdc)
    CLIPRGN my_cliprgn1;
    CLIPRGN my_cliprgn2;


    /* Creat private heap of clipped rectangle for the region */
    InitFreeClipRectList (&my_cliprc_heap, 100);
    /* Initialize the region, and specify the region uses the created private heap */
    InitClipRgn (&my_cliprgn1, &my_cliprc_heap);
    InitClipRgn (&my_cliprgn2, &my_cliprc_heap);

    /* Intialize two region with circle region respectively */
    InitCircleRegion (&my_cliprgn1, 130, 175, 50);
    InitCircleRegion (&my_cliprgn2, 130, 175, 40);
    /* Substract region 2 from region1, and select the result into DC */
    SubtractRegion (&my_cliprgn1, &my_cliprgn1, &my_cliprgn2);
    SelectClipRegion (hdc, &my_cliprgn1);
    /* Fill region 1 with blue brush */
    SetBrushColor (hdc, PIXEL_blue);
    FillBox (hdc, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);

    /* Empty regions, and release the special clipped rectangle  */
    EmptyClipRgn ( &my_cliprgn1);
    EmptyClipRgn ( &my_cliprgn2);
    /* Destroy the privite leap of clipped rectangle */



Function Summarize

void GUIAPI InitClipRgn(PCLIPRGN pRgn, PBLOCKHEAP pFreeList)
BOOL GUIAPI InitCircleRegion(PCLIPRGN dst,int x,int y,int r)
BOOL GUIAPI SubtractRegion(CLIPRGN * rgnD, const CLIPRGN * rgnM, const CLIPRGN * rgnS)
IntersectRegion (PCLIPRGN pRstRgn, const CLIPRGN * pRgn1, const CLIPRGN * pRgn2)
void GUIAPI SelectClipRegion(HDC hdc, const CLIPRGN * pRgn)
MiniGUI SetBrushColor(hdc, color)
void GUIAPI FillBox(HDC hdc, int x,int y,int w,int h)
void GUIAPI EmptyClipRgn(PCLIPRGN pRgn)