Draw the US flag using GDI
Posted
by Oren Leavitt
on October 10th, 2001
Environment: Win32 (VC++ 6 project)
Just for fun, or perhaps even useful, here is a function to draw the US flag to a given HDC, in a given RECT. Looks best on a hi-rez device. Would look great embedded as a static control in a dialog, as a backdrop for an MDI app, a screensaver, or draw it to printer DC for a hardcopy. Cheers!
//////////////////////////////////////////////////////////////// // // Draws the Star-Spangled Banner. // // Params: // hdc - The patriotic device context. // pRect - Rect in DC to draw Old Glory to. // //////////////////////////////////////////////////////////////// // Sines & cosines for the angles of the five-pointed stars #define SIN72 0.95106 #define COS72 0.30902 #define SIN144 0.58779 #define COS144 -0.80902 #define STARSIZE 0.67 // scale factor for the size of the stars void DrawOldGlory(HDC hdc, RECT * pRect) { HPEN hpenOld; HBRUSH hbrRed, hbrWhite, hbrBlue, hbrOld; int x0 = pRect->left; int y0 = pRect->top; int x1 = pRect->right; int y1 = pRect->bottom; int cx = x1 - x0; int cy = y1 - y0; int i, j, x, y, xx, yy; int cxStarBox, cyStarBox; int nOldFillMode; // Create some colors for us to work with. hbrRed = CreateSolidBrush(RGB(255, 0, 0)); hbrWhite = CreateSolidBrush(RGB(255, 255, 255)); hbrBlue = CreateSolidBrush(RGB(0, 0, 128)); // Hide the default pen so that we don't get // black borders around the filled shapes. // Whenever a rectangle is drawn, we'll add one pixel to the // right and bottom to fill in for the missing pen. hpenOld = (HPEN) SelectObject(hdc, GetStockObject(NULL_PEN)); // Draw white background. hbrOld = (HBRUSH) SelectObject(hdc, hbrWhite); Rectangle(hdc, x0, y0, x1 + 1, y1 + 1); // Draw the seven red stripes. SelectObject(hdc, hbrRed); for (i = 0; i < 13; i++) if ((i & 1) == 0) Rectangle(hdc, x0, y0 + (i * cy) / 13, x1 + 1, y0 + ((i + 1) * cy) / 13 + 1); // Draw blue box. // Size it so that it covers two fifths of the flag length and // the top seven stripes vertically. cxStarBox = (2 * cx) / 5; cyStarBox = (7 * cy) / 13 + 1; SelectObject(hdc, hbrBlue); Rectangle(hdc, x0, y0, x0 + cxStarBox, y0 + cyStarBox); // Draw fifty stars in the blue box. SelectObject(hdc, hbrWhite); // We're going to draw the stars with just a five point polygon. // Select the 'winding' fill mode so that the centers of the stars // get filled too. nOldFillMode = SetPolyFillMode(hdc, WINDING); // Shrink the blue box rect a bit to give some border around the stars. x0 += cxStarBox / 25; y0 += cyStarBox / 25; cxStarBox *= 23; cxStarBox /= 25; cyStarBox *= 23; cyStarBox /= 25; y = y0; // Now, divide the box into a grid of 11 x 9 squares and place a star // in every other square, like on a checker board. for (j = 1; j <= 9; j++) { yy = y0 + (j * cyStarBox) / 9; x = x0; for (i = 1; i <= 11; i++) { xx = x0 + (i * cxStarBox) / 11; // Determine 'black' or 'white' square status by checking to see // if the sum of 'i' and 'j' is odd or even. // This ensures that the square colors of each row are always // staggered regardless of whether there is an odd or even number // of squares in each row. if (((i + j) & 1) == 0) { // Get the width and height of the current square. int w = xx - x; int h = yy - y; // Use the smaller of the two (width or height) as a basis // for the radius of the star. double r = (w < h) ? (double)w * STARSIZE : (double)h * STARSIZE; // Find the center of the current square. int centerX = (x + xx) / 2; int centerY = (y + yy) / 2; POINT pts[5]; // Calculate the actual points for the stars by rotating the // radius around the center point using the pre-computed // sines & cosines. pts[0].x = centerX; pts[0].y = centerY - (int)(r); pts[1].x = centerX + (int)(r * SIN144); pts[1].y = centerY - (int)(r * COS144); pts[2].x = centerX - (int)(r * SIN72); pts[2].y = centerY - (int)(r * COS72); pts[3].x = centerX + (int)(r * SIN72); pts[3].y = pts[2].y; pts[4].x = centerX - (int)(r * SIN144); pts[4].y = pts[1].y; // Finally, draw the filled polygon. Polygon(hdc, pts, 5); } x = xx; } y = yy; } // Clean up. SetPolyFillMode(hdc, nOldFillMode); SelectObject(hdc, (HBRUSH) hbrOld); SelectObject(hdc, (HPEN) hpenOld); DeleteObject(hbrBlue); DeleteObject(hbrWhite); DeleteObject(hbrRed); }

Comments
There are no comments yet. Be the first to comment!