2009-07-30

Draw rounded rectangles with GdiPlusX

Bob Powell, in his great website site says: "the trick here is to use a GraphicsPath object to assemble a collection of  lines and arcs that make up the rounded rectangle shape.

Arcs are used to round off the corners, so you have to position the lines 1 radius, whatever that may be, from the actual corner."


The code below shows Bob's function converted to VFP and GdiPlusX, to obtain this result:






LOCAL loBmp AS xfcBitmap, loGfx AS xfcGraphics
WITH _SCREEN.SYSTEM.Drawing AS xfcDrawing
 * create a New Bitmap
 loBmp = .Bitmap.New(200,170)
 * get a Graphics object for Drawing
 loGfx = .Graphics.fromImage(loBmp)
 * clear the Drawing canvas
 loGfx.CLEAR(.COLOR.LightCoral)
 * Draw the rounded rectangle
 =DrawRoundRect(loGfx, .Pens.blue, 20, 30, 150, 100, 20)
 * save image to file
 loBmp.SAVE("roundedrect.png", .Imaging.ImageFormat.Png)
ENDWITH
RUN /N explorer.EXE RoundedRect.png



FUNCTION DrawRoundRect(toGfx AS xfcGraphics, toPen AS xfcPen, ;
  tnX, tnY, tnWidth, tnHeight, tnRadius)
 * adapted by cesar from bob powell's sample taken from
 * http://www.bobpowell.net/roundrects.htm

 LOCAL logPath AS xfcGraphicsPath
 logPath = _SCREEN.SYSTEM.Drawing.Drawing2d.GraphicsPath.New()

 WITH logPath
  .AddLine(tnX + tnRadius, tnY, tnX + tnWidth - (tnRadius*2), tnY)
  .AddArc(tnX + tnWidth - (tnRadius*2), tnY, tnRadius*2, tnRadius*2, 270, 90)
  .AddLine(tnX + tnWidth, tnY + tnRadius, tnX + tnWidth, tnY + tnHeight - (tnRadius*2))
  .AddArc(tnX + tnWidth - (tnRadius*2), tnY + tnHeight - (tnRadius*2), tnRadius*2, tnRadius*2,0,90)
  .AddLine(tnX + tnWidth - (tnRadius*2), tnY + tnHeight, tnX + tnRadius, tnY + tnHeight)
  .AddArc(tnX, tnY + tnHeight - (tnRadius*2), tnRadius*2, tnRadius*2, 90, 90)
  .AddLine(tnX, tnY + tnHeight - (tnRadius*2), tnX, tnY + tnRadius)
  .AddArc(tnX, tnY, tnRadius*2, tnRadius*2, 180, 90)
  .closefigure()
 ENDWITH
 toGfx.DrawPath(toPen, logPath)
ENDFUNC


The above function receives a xfcPen object to draw the rounded rectangle. In order to draw a filled rounded rectangle, all we need is to add a small tweak in the above function to use a brush object instead a pen, and call the FillPath function instead of DrawPath.

No comments:

Post a Comment