os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdigraphics.cpp
First public contribution.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "directgdiadapter.h"
17 #include "swdirectgdiengine.h"
18 #include "swdirectgdiellipse.h"
21 @see MDirectGdiEngine::Clear(const TRect&)
23 void CSwDirectGdiEngine::Clear(const TRect& aRect)
28 DirectGdi::TBrushStyle tempbrushstyle = iBrushStyle;
29 iBrushStyle = DirectGdi::ESolidBrush;
33 iBrushStyle = tempbrushstyle;
37 @see MDirectGdiEngine::Clear()
39 void CSwDirectGdiEngine::Clear()
42 iDrawDevice->GetDrawRect(deviceRect);
43 if ((iOrigin.iX!=0) || (iOrigin.iY!=0))
45 deviceRect.Move(-iOrigin);
51 @see MDirectGdiEngine::Plot()
53 void CSwDirectGdiEngine::Plot(const TPoint& aPoint)
55 TRect targetRect(aPoint + iOrigin, TSize(1,1));
56 targetRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1);
65 @param aPoint The location to plot at.
66 @panic DGDIAdapter 1013, if the point being plotted is out of bounds of the target (debug only).
68 void CSwDirectGdiEngine::DoPlot(const TPoint& aPoint)
70 const TSize oneByOne(1,1);
71 const TPoint point(aPoint + iOrigin);
73 TRect temp(point,oneByOne);
74 if (iPenSize.iWidth > 1 || iPenSize.iHeight > 1)
76 temp.Grow(iPenSize.iWidth >> 1, iPenSize.iHeight >> 1);
79 const DirectGdi::TPenStyle oldPenStyle = iPenStyle;
80 iPenStyle = DirectGdi::ESolidPen;
84 iDrawDevice->GetDrawRect(deviceRect);
88 const TInt limit = iDefaultRegionPtr->Count();
89 for (TInt count = 0; count < limit; count++)
91 clipRect = (*iDefaultRegionPtr)[count];
92 if (!clipRect.Intersects(temp))
97 clipRect.Intersection(temp);
98 if (iPenSize == oneByOne)
100 if (clipRect.Contains(point))
102 GRAPHICS_ASSERT_DEBUG(point.iX >= deviceRect.iTl.iX, EDirectGdiPanicOutOfBounds);
103 GRAPHICS_ASSERT_DEBUG(point.iY >= deviceRect.iTl.iY, EDirectGdiPanicOutOfBounds);
104 GRAPHICS_ASSERT_DEBUG(point.iX <= deviceRect.iBr.iX, EDirectGdiPanicOutOfBounds);
105 GRAPHICS_ASSERT_DEBUG(point.iY <= deviceRect.iBr.iY, EDirectGdiPanicOutOfBounds);
107 iDrawDevice->WriteRgb(point.iX,point.iY,iPenColor, GcDrawMode(iDrawMode));
112 PenDrawClipped(point, clipRect);
115 iDrawDevice->UpdateRegion(clipRect);
118 iPenStyle = oldPenStyle;
122 Clips the horizontal drawing of a line between two points.
123 The vertical location must be inside the clip rect.
125 @param aLeft The left hand side coordinate.
126 @param aRight The right hand side coordinate.
127 @param aClipRect The rectangle to which the line is clipped.
129 void CSwDirectGdiEngine::ClipFillLine(TPoint aLeft,TPoint aRight, TRect aClipRect)
131 if (aLeft.iY < aClipRect.iTl.iY || aLeft.iY >= aClipRect.iBr.iY)
134 aLeft.iX = Max(aLeft.iX,aClipRect.iTl.iX);
135 aRight.iX = Min(aRight.iX,aClipRect.iBr.iX-1);
136 if (aLeft.iX > aRight.iX)
141 TInt xcoord = aLeft.iX;
142 TInt length = aRight.iX - aLeft.iX + 1;
143 TPoint origin(iOrigin + iBrushOrigin);
144 const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
148 case DirectGdi::ESolidBrush:
149 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
151 case DirectGdi::EPatternedBrush:
153 iBrushBitmap.BeginDataAccess();
154 CBitwiseBitmap* brushBitmap = iBrushBitmap.Address();
157 TRect sourcerect(aLeft,TSize(length,1));
158 sourcerect.Move(-origin);
159 DoBitBlt(aLeft,brushBitmap,iBrushBitmap.DataAddress(),iBrushBitmap.DataStride(),sourcerect);
161 iBrushBitmap.EndDataAccess(ETrue);
164 case DirectGdi::EHorizontalHatchBrush:
165 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
166 if (Abs((aLeft.iY - origin.iY) % 3) == 2)
167 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,drawMode);
169 case DirectGdi::EVerticalHatchBrush:
170 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
171 while (Abs((xcoord - origin.iX) % 3) != 2)
173 for (; xcoord < aLeft.iX + length; xcoord += 3)
174 iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
176 case DirectGdi::ESquareCrossHatchBrush:
177 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
178 if (Abs((aLeft.iY - origin.iY) % 3) == 2)
179 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,drawMode);
182 while (Abs((xcoord - origin.iX) % 3) != 2)
184 for (; xcoord < aLeft.iX + length; xcoord += 3)
185 iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
188 case DirectGdi::EForwardDiagonalHatchBrush:
190 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
191 TInt diff = (origin.iX + origin.iY - aLeft.iX - aLeft.iY) % 3;
195 for (; xcoord < aLeft.iX + length; xcoord += 3)
196 iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
199 case DirectGdi::ERearwardDiagonalHatchBrush:
201 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
202 TInt diff = (origin.iX - origin.iY - aLeft.iX + aLeft.iY) % 3;
206 for (; xcoord < aLeft.iX + length; xcoord += 3)
207 iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
210 case DirectGdi::EDiamondCrossHatchBrush:
212 iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
213 TInt sum = aLeft.iX + aLeft.iY - origin.iX - origin.iY;
214 for (; xcoord < aLeft.iX + length; xcoord++,sum++)
215 if ((sum & 1) == 0 && ((sum & 3) != 0 || ((xcoord-origin.iX) & 1) == 1))
216 iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
225 Creates the pen using the current pen size.
227 @return KErrNoMermory if memory could not be allocated, KErrNone otherwise.
229 TInt CSwDirectGdiEngine::PenAllocate()
233 if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1)
238 const TInt doublePenHeight = iPenSize.iHeight << 1;
240 TInt* penArray = new TInt[doublePenHeight];
241 if (penArray == NULL)
246 SetPenArray(penArray);
248 if (iPenSize.iWidth == 1 || iPenSize.iWidth == 2 || iPenSize.iHeight == 1 || iPenSize.iHeight == 2)
250 for (TInt count = 0; count < iPenSize.iHeight; count += 2)
252 iPenArray[doublePenHeight - count - 2] = 0;
253 iPenArray[doublePenHeight - count - 1] = iPenSize.iWidth - 1;
254 iPenArray[count] = 0;
255 iPenArray[count + 1] = iPenSize.iWidth - 1;
261 TSwDirectGdiEllipse ellipse;
262 ellipse.Construct(TRect(iPenSize));
263 for (TInt count = 0; count < iPenSize.iHeight; count += 2)
265 //coverity[check_return]
266 //coverity[unchecked_value]
267 ellipse.NextStep(tl,tr,bl,br);
268 iPenArray[doublePenHeight - count - 2] = bl.iX;
269 iPenArray[doublePenHeight - count - 1] = br.iX;
270 iPenArray[count] = tl.iX;
271 iPenArray[count + 1] = tr.iX;
279 Draws at a given point using the current settings, if within clipping rectangle.
281 @pre The pen size is greater than one.
283 @param aPoint The location to draw at.
284 @param aClipRect The clipping rectangle.
285 @panic DGDIAdapter 1016, if the current pen size is zero (debug only).
287 void CSwDirectGdiEngine::PenDrawClipped(TPoint aPoint, const TRect& aClipRect)
289 GRAPHICS_ASSERT_DEBUG(iPenSize.iWidth > 0,EDirectGdiPanicZeroLength);
290 GRAPHICS_ASSERT_DEBUG(iPenSize.iHeight > 0,EDirectGdiPanicZeroLength);
292 aPoint.iX -= ((iPenSize.iWidth - 1) >> 1);
293 aPoint.iY -= ((iPenSize.iHeight - 1) >> 1);
295 if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1)
297 if ( (iPenStyle == DirectGdi::ESolidPen || (iDotMask & (1 << (iDotParam % iDotLength)))) &&
298 aClipRect.Contains(aPoint) )
300 iDrawDevice->WriteRgb(aPoint.iX, aPoint.iY, iPenColor, GcDrawMode(iDrawMode));
303 else if (iPenArray != NULL)
305 TInt yCoord = aPoint.iY;
306 const TInt maxdim = Max(iPenSize.iWidth,iPenSize.iHeight);
307 const TInt doublePenHeight = iPenSize.iHeight << 1;
309 if (iPenStyle == DirectGdi::ESolidPen || (iDotMask & (1 << ((iDotParam / maxdim) % iDotLength))))
311 for (TInt ix = 0; ix < doublePenHeight; yCoord++, ix += 2)
313 if (yCoord >= aClipRect.iTl.iY && yCoord < aClipRect.iBr.iY)
315 TInt left = aPoint.iX + iPenArray[ix];
316 TInt right = aPoint.iX + iPenArray[ix+1];
317 if (left < aClipRect.iTl.iX)
319 left = aClipRect.iTl.iX;
321 if (right >= aClipRect.iBr.iX)
323 right = aClipRect.iBr.iX - 1;
327 iDrawDevice->WriteRgbMulti(left, yCoord, right - left + 1, 1, iPenColor, CGraphicsContext::EDrawModePEN);
336 TSwDirectGdiEllipse ellipse;
337 ellipse.Construct(TRect(aPoint,iPenSize));
338 while (!ellipse.NextStep(tl,tr,bl,br))
340 if (tl.iY >= aClipRect.iTl.iY && tl.iY < aClipRect.iBr.iY)
342 if (tl.iX < aClipRect.iTl.iX)
344 tl.iX = aClipRect.iTl.iX;
346 if (tr.iX >= aClipRect.iBr.iX)
348 tr.iX = aClipRect.iBr.iX-1;
352 iDrawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
355 if (bl.iY >= aClipRect.iTl.iY && bl.iY < aClipRect.iBr.iY)
357 if (bl.iX < aClipRect.iTl.iX)
359 bl.iX = aClipRect.iTl.iX;
361 if (br.iX >= aClipRect.iBr.iX)
363 br.iX = aClipRect.iBr.iX - 1;
367 iDrawDevice->WriteRgbMulti(bl.iX,bl.iY,br.iX - bl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
372 if (tl.iY == bl.iY && tl.iY >= aClipRect.iTl.iY && tl.iY < aClipRect.iBr.iY)
374 if (tl.iX < aClipRect.iTl.iX)
376 tl.iX = aClipRect.iTl.iX;
378 if (tr.iX >= aClipRect.iBr.iX)
380 tr.iX = aClipRect.iBr.iX - 1;
384 iDrawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1, iPenColor, CGraphicsContext::EDrawModePEN);
391 @panic DGDIAdapter 1016, if the current pen size is zero (debug only).
393 void CSwDirectGdiEngine::PenDrawDeferred(TPoint aPoint,TInt* aArray, TInt aFirstElement)
395 GRAPHICS_ASSERT_DEBUG(iPenArray,EDirectGdiPanicZeroLength);
396 GRAPHICS_ASSERT_DEBUG(iPenSize.iWidth > 0,EDirectGdiPanicZeroLength);
397 GRAPHICS_ASSERT_DEBUG(iPenSize.iHeight > 0,EDirectGdiPanicZeroLength);
399 aPoint.iX -= ((iPenSize.iWidth - 1) >> 1);
400 const TInt doublepenheight = iPenSize.iHeight << 1;
402 for (TInt ix = 0; ix < doublepenheight; ix++,aFirstElement++)
404 if (aFirstElement == doublepenheight)
408 TInt newval = aPoint.iX + iPenArray[ix];
409 if (newval < aArray[aFirstElement])
411 aArray[aFirstElement] = newval;
416 newval = aPoint.iX + iPenArray[ix];
417 if (newval > aArray[aFirstElement])
419 aArray[aFirstElement] = newval;