--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/bitgdi/sbit/ROUNDREC.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,230 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <fntstore.h>
+#include <bitmap.h>
+#include <bitstd.h>
+#include <bitdev.h>
+#include "BITPANIC.H"
+#include <bitdraw.h>
+#include <graphics/fbsrasterizer.h>
+
+/**
+Draws and fills a rectangle with rounded corners.
+
+The function provides a concrete implementation of the pure virtual
+function <code>CGraphicsContext::DrawRoundRect()</code>. The function
+behaviour is the same as documented in that class.
+*/
+EXPORT_C void CFbsBitGc::DrawRoundRect(const TRect& aRect,const TSize& aSize)
+ {
+ if (CheckDevice(aRect))
+ return;
+
+ TSize ellsize(aSize);
+ ellsize.iWidth <<= 1;
+ ellsize.iHeight <<= 1;
+
+ if (ellsize.iWidth < 3 || ellsize.iHeight < 3)
+ {
+ DrawRect(aRect);
+ return;
+ }
+
+ if (aRect.Width() < ellsize.iWidth && aRect.Height() < ellsize.iHeight)
+ {
+ DrawEllipse(aRect);
+ return;
+ }
+
+ TRect rcpy(aRect);
+ rcpy.Move(iOrigin);
+ iDevice->TruncateRect(rcpy);
+ ellsize.iWidth = Min(rcpy.Width(),ellsize.iWidth);
+ ellsize.iHeight = Min(rcpy.Height(),ellsize.iHeight);
+
+ TRect clippedBoundingRect(rcpy);
+ clippedBoundingRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1);
+ if (!clippedBoundingRect.Intersects(iUserClipRect))
+ return;
+
+ SetupDevice();
+ iDevice->DrawingBegin(&iBrushBitmap);
+ CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
+
+ if (iBrushStyle != ENullBrush)
+ RoundRectFill(rcpy,ellsize);
+
+ if (iPenStyle != ENullPen && iPenSize.iWidth > 0 && iPenSize.iHeight > 0)
+ RoundRectOutline(rcpy,ellsize);
+
+ if (brushRasterizer)
+ {
+ brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
+ }
+ iDevice->DrawingEnd(&iBrushBitmap);
+ }
+
+// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
+void CFbsBitGc::RoundRectFill(const TRect& aRect,TSize aSize)
+ {
+ TRect rcpy(aRect);
+ if (iPenSize.iWidth < 1 || iPenSize.iHeight < 1)
+ rcpy.Grow(1,1);
+ AddRect(rcpy);
+
+ if (rcpy.iBr.iX - rcpy.iTl.iX < aSize.iWidth)
+ aSize.iWidth = rcpy.Width();
+ if (rcpy.iBr.iY - rcpy.iTl.iY < aSize.iHeight)
+ aSize.iHeight = rcpy.Height();
+
+ TInt xoff = rcpy.Width() - aSize.iWidth;
+ TInt yoff = rcpy.Height() - aSize.iHeight;
+ TPoint tl,tr,bl,br;
+ TInt prevlev = 0;
+ TBool draw = EFalse;
+
+ const TInt limit = iDefaultRegionPtr->Count();
+ for (TInt count = 0; count < limit; count++)
+ {
+ iClipRect = (*iDefaultRegionPtr)[count];
+ if (UserClipRect(iClipRect))
+ continue;
+ if (!iClipRect.Intersects(aRect))
+ continue;
+
+ draw = ETrue;
+ iClipRect.Intersection(aRect);
+
+ TEllipse ellipse;
+ ellipse.Construct(TRect(rcpy.iTl,rcpy.iTl + aSize));
+ ellipse.SingleStep(tl,tr,bl,br);
+ prevlev = tl.iY;
+
+ while (!ellipse.SingleStep(tl,tr,bl,br))
+ {
+ if (tl.iY == prevlev)
+ continue;
+
+ tl.iX++;
+ tr.iX += xoff - 1;
+ bl.iX++;
+ bl.iY += yoff;
+ br.iX += xoff - 1;
+ br.iY += yoff;
+
+ ClipFillLine(tl,tr);
+ ClipFillLine(bl,br);
+
+ prevlev = tl.iY;
+ }
+
+ iDevice->iDrawDevice->UpdateRegion(iClipRect);
+ }
+
+ if (!draw)
+ return;
+
+ if (tl.iY >= bl.iY)
+ {
+ tl.iY--;
+ br.iY++;
+ }
+
+ tl.iX++;
+ tl.iY++;
+ br.iX += xoff;
+ br.iY += yoff;
+
+ RectFill(TRect(tl,br));
+ }
+
+void CFbsBitGc::RoundRectOutline(const TRect& aRect,TSize aSize)
+ {
+ TRect rcpy(aRect);
+ const TInt halfpenwidth = (iPenSize.iWidth + 1) >> 1;
+ const TInt halfpenheight = (iPenSize.iWidth + 1) >> 1;
+ rcpy.Grow(halfpenwidth,halfpenheight);
+ AddRect(rcpy);
+
+ if (aRect.Width() < aSize.iWidth)
+ aSize.iWidth = aRect.Width();
+ if (aRect.Height() < aSize.iHeight)
+ aSize.iHeight = aRect.Height();
+
+ TPoint tl,tr,bl,br;
+ const TInt xoff = aRect.Width() - aSize.iWidth;
+ const TInt yoff = aRect.Height() - aSize.iHeight;
+ const TInt dotparam = iDotParam;
+
+ const TInt limit = iDefaultRegionPtr->Count();
+ for (TInt count = 0; count < limit; count++)
+ {
+ iClipRect = (*iDefaultRegionPtr)[count];
+ if (!iClipRect.Intersects(rcpy))
+ continue;
+ iClipRect.Intersection(rcpy);
+ if (UserClipRect(iClipRect))
+ continue;
+
+ iDotParam = Max(iPenSize.iWidth >> 1,iPenSize.iHeight >> 1);
+ TInt column = aRect.iTl.iX + (aSize.iWidth >> 1);
+ TInt lastcolumn = aRect.iTl.iX + xoff + (aSize.iWidth >> 1);
+
+ for (; column < lastcolumn; column++)
+ {
+ PenDrawClipped(TPoint(column,aRect.iTl.iY));
+ PenDrawClipped(TPoint(column,aRect.iBr.iY - 1));
+ iDotParam += iDotDirection;
+ }
+
+ TEllipse ellipse;
+ ellipse.Construct(TRect(aRect.iTl,aRect.iTl + aSize));
+ while (!ellipse.SingleStep(tl,tr,bl,br))
+ {
+ tr.iX += xoff;
+ bl.iY += yoff;
+ br.iX += xoff;
+ br.iY += yoff;
+
+ PenDrawClipped(tl);
+ PenDrawClipped(tr);
+ PenDrawClipped(bl);
+ PenDrawClipped(br);
+
+ iDotParam += iDotDirection;
+ }
+
+ if (tl.iY >= bl.iY)
+ {
+ tl.iY--;
+ bl.iY++;
+ }
+
+ bl.iY += yoff;
+
+ for (column = tl.iY + 1; column < bl.iY; column++)
+ {
+ PenDrawClipped(TPoint(aRect.iTl.iX,column));
+ PenDrawClipped(TPoint(aRect.iBr.iX - 1,column));
+ iDotParam += iDotDirection;
+ }
+
+ iDevice->iDrawDevice->UpdateRegion(iClipRect);
+ }
+
+ iDotParam = dotparam;
+ }
+