os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdigraphics.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdigraphics.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,422 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "directgdiadapter.h"
1.20 +#include "swdirectgdiengine.h"
1.21 +#include "swdirectgdiellipse.h"
1.22 +
1.23 +/**
1.24 +@see MDirectGdiEngine::Clear(const TRect&)
1.25 +*/
1.26 +void CSwDirectGdiEngine::Clear(const TRect& aRect)
1.27 + {
1.28 + TRect rcpy(aRect);
1.29 + rcpy.Move(iOrigin);
1.30 +
1.31 + DirectGdi::TBrushStyle tempbrushstyle = iBrushStyle;
1.32 + iBrushStyle = DirectGdi::ESolidBrush;
1.33 +
1.34 + RectFill(rcpy);
1.35 +
1.36 + iBrushStyle = tempbrushstyle;
1.37 + }
1.38 +
1.39 +/**
1.40 +@see MDirectGdiEngine::Clear()
1.41 +*/
1.42 +void CSwDirectGdiEngine::Clear()
1.43 + {
1.44 + TRect deviceRect;
1.45 + iDrawDevice->GetDrawRect(deviceRect);
1.46 + if ((iOrigin.iX!=0) || (iOrigin.iY!=0))
1.47 + {
1.48 + deviceRect.Move(-iOrigin);
1.49 + }
1.50 + Clear(deviceRect);
1.51 + }
1.52 +
1.53 +/**
1.54 +@see MDirectGdiEngine::Plot()
1.55 +*/
1.56 +void CSwDirectGdiEngine::Plot(const TPoint& aPoint)
1.57 + {
1.58 + TRect targetRect(aPoint + iOrigin, TSize(1,1));
1.59 + targetRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1);
1.60 + DoPlot(aPoint);
1.61 + }
1.62 +
1.63 +/**
1.64 +Draws a single point.
1.65 +
1.66 +@see Plot()
1.67 +
1.68 +@param aPoint The location to plot at.
1.69 +@panic DGDIAdapter 1013, if the point being plotted is out of bounds of the target (debug only).
1.70 + */
1.71 +void CSwDirectGdiEngine::DoPlot(const TPoint& aPoint)
1.72 + {
1.73 + const TSize oneByOne(1,1);
1.74 + const TPoint point(aPoint + iOrigin);
1.75 +
1.76 + TRect temp(point,oneByOne);
1.77 + if (iPenSize.iWidth > 1 || iPenSize.iHeight > 1)
1.78 + {
1.79 + temp.Grow(iPenSize.iWidth >> 1, iPenSize.iHeight >> 1);
1.80 + }
1.81 +
1.82 + const DirectGdi::TPenStyle oldPenStyle = iPenStyle;
1.83 + iPenStyle = DirectGdi::ESolidPen;
1.84 +
1.85 +#if defined(_DEBUG)
1.86 + TRect deviceRect;
1.87 + iDrawDevice->GetDrawRect(deviceRect);
1.88 +#endif
1.89 +
1.90 + TRect clipRect;
1.91 + const TInt limit = iDefaultRegionPtr->Count();
1.92 + for (TInt count = 0; count < limit; count++)
1.93 + {
1.94 + clipRect = (*iDefaultRegionPtr)[count];
1.95 + if (!clipRect.Intersects(temp))
1.96 + {
1.97 + continue;
1.98 + }
1.99 +
1.100 + clipRect.Intersection(temp);
1.101 + if (iPenSize == oneByOne)
1.102 + {
1.103 + if (clipRect.Contains(point))
1.104 + {
1.105 + GRAPHICS_ASSERT_DEBUG(point.iX >= deviceRect.iTl.iX, EDirectGdiPanicOutOfBounds);
1.106 + GRAPHICS_ASSERT_DEBUG(point.iY >= deviceRect.iTl.iY, EDirectGdiPanicOutOfBounds);
1.107 + GRAPHICS_ASSERT_DEBUG(point.iX <= deviceRect.iBr.iX, EDirectGdiPanicOutOfBounds);
1.108 + GRAPHICS_ASSERT_DEBUG(point.iY <= deviceRect.iBr.iY, EDirectGdiPanicOutOfBounds);
1.109 +
1.110 + iDrawDevice->WriteRgb(point.iX,point.iY,iPenColor, GcDrawMode(iDrawMode));
1.111 + }
1.112 + }
1.113 + else
1.114 + {
1.115 + PenDrawClipped(point, clipRect);
1.116 + }
1.117 +
1.118 + iDrawDevice->UpdateRegion(clipRect);
1.119 + }
1.120 +
1.121 + iPenStyle = oldPenStyle;
1.122 + }
1.123 +
1.124 +/**
1.125 +Clips the horizontal drawing of a line between two points.
1.126 +The vertical location must be inside the clip rect.
1.127 +
1.128 +@param aLeft The left hand side coordinate.
1.129 +@param aRight The right hand side coordinate.
1.130 +@param aClipRect The rectangle to which the line is clipped.
1.131 + */
1.132 +void CSwDirectGdiEngine::ClipFillLine(TPoint aLeft,TPoint aRight, TRect aClipRect)
1.133 + {
1.134 + if (aLeft.iY < aClipRect.iTl.iY || aLeft.iY >= aClipRect.iBr.iY)
1.135 + return;
1.136 +
1.137 + aLeft.iX = Max(aLeft.iX,aClipRect.iTl.iX);
1.138 + aRight.iX = Min(aRight.iX,aClipRect.iBr.iX-1);
1.139 + if (aLeft.iX > aRight.iX)
1.140 + {
1.141 + return;
1.142 + }
1.143 +
1.144 + TInt xcoord = aLeft.iX;
1.145 + TInt length = aRight.iX - aLeft.iX + 1;
1.146 + TPoint origin(iOrigin + iBrushOrigin);
1.147 + const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
1.148 +
1.149 + switch(iBrushStyle)
1.150 + {
1.151 + case DirectGdi::ESolidBrush:
1.152 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
1.153 + return;
1.154 + case DirectGdi::EPatternedBrush:
1.155 + {
1.156 + iBrushBitmap.BeginDataAccess();
1.157 + CBitwiseBitmap* brushBitmap = iBrushBitmap.Address();
1.158 + if (brushBitmap)
1.159 + {
1.160 + TRect sourcerect(aLeft,TSize(length,1));
1.161 + sourcerect.Move(-origin);
1.162 + DoBitBlt(aLeft,brushBitmap,iBrushBitmap.DataAddress(),iBrushBitmap.DataStride(),sourcerect);
1.163 + }
1.164 + iBrushBitmap.EndDataAccess(ETrue);
1.165 + return;
1.166 + }
1.167 + case DirectGdi::EHorizontalHatchBrush:
1.168 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
1.169 + if (Abs((aLeft.iY - origin.iY) % 3) == 2)
1.170 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,drawMode);
1.171 + return;
1.172 + case DirectGdi::EVerticalHatchBrush:
1.173 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
1.174 + while (Abs((xcoord - origin.iX) % 3) != 2)
1.175 + xcoord++;
1.176 + for (; xcoord < aLeft.iX + length; xcoord += 3)
1.177 + iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
1.178 + return;
1.179 + case DirectGdi::ESquareCrossHatchBrush:
1.180 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
1.181 + if (Abs((aLeft.iY - origin.iY) % 3) == 2)
1.182 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,drawMode);
1.183 + else
1.184 + {
1.185 + while (Abs((xcoord - origin.iX) % 3) != 2)
1.186 + xcoord++;
1.187 + for (; xcoord < aLeft.iX + length; xcoord += 3)
1.188 + iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
1.189 + }
1.190 + return;
1.191 + case DirectGdi::EForwardDiagonalHatchBrush:
1.192 + {
1.193 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
1.194 + TInt diff = (origin.iX + origin.iY - aLeft.iX - aLeft.iY) % 3;
1.195 + if (diff < 0)
1.196 + diff += 3;
1.197 + xcoord += diff;
1.198 + for (; xcoord < aLeft.iX + length; xcoord += 3)
1.199 + iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
1.200 + }
1.201 + return;
1.202 + case DirectGdi::ERearwardDiagonalHatchBrush:
1.203 + {
1.204 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
1.205 + TInt diff = (origin.iX - origin.iY - aLeft.iX + aLeft.iY) % 3;
1.206 + if (diff < 0)
1.207 + diff += 3;
1.208 + xcoord += diff;
1.209 + for (; xcoord < aLeft.iX + length; xcoord += 3)
1.210 + iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
1.211 + }
1.212 + return;
1.213 + case DirectGdi::EDiamondCrossHatchBrush:
1.214 + {
1.215 + iDrawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,drawMode);
1.216 + TInt sum = aLeft.iX + aLeft.iY - origin.iX - origin.iY;
1.217 + for (; xcoord < aLeft.iX + length; xcoord++,sum++)
1.218 + if ((sum & 1) == 0 && ((sum & 3) != 0 || ((xcoord-origin.iX) & 1) == 1))
1.219 + iDrawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,drawMode);
1.220 + }
1.221 + return;
1.222 + default:
1.223 + return;
1.224 + }
1.225 + }
1.226 +
1.227 +/**
1.228 +Creates the pen using the current pen size.
1.229 +
1.230 +@return KErrNoMermory if memory could not be allocated, KErrNone otherwise.
1.231 +*/
1.232 +TInt CSwDirectGdiEngine::PenAllocate()
1.233 + {
1.234 + ResetPenArray();
1.235 +
1.236 + if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1)
1.237 + {
1.238 + return KErrNone;
1.239 + }
1.240 +
1.241 + const TInt doublePenHeight = iPenSize.iHeight << 1;
1.242 +
1.243 + TInt* penArray = new TInt[doublePenHeight];
1.244 + if (penArray == NULL)
1.245 + {
1.246 + return KErrNoMemory;
1.247 + }
1.248 +
1.249 + SetPenArray(penArray);
1.250 +
1.251 + if (iPenSize.iWidth == 1 || iPenSize.iWidth == 2 || iPenSize.iHeight == 1 || iPenSize.iHeight == 2)
1.252 + {
1.253 + for (TInt count = 0; count < iPenSize.iHeight; count += 2)
1.254 + {
1.255 + iPenArray[doublePenHeight - count - 2] = 0;
1.256 + iPenArray[doublePenHeight - count - 1] = iPenSize.iWidth - 1;
1.257 + iPenArray[count] = 0;
1.258 + iPenArray[count + 1] = iPenSize.iWidth - 1;
1.259 + }
1.260 + }
1.261 + else
1.262 + {
1.263 + TPoint tl,tr,bl,br;
1.264 + TSwDirectGdiEllipse ellipse;
1.265 + ellipse.Construct(TRect(iPenSize));
1.266 + for (TInt count = 0; count < iPenSize.iHeight; count += 2)
1.267 + {
1.268 + //coverity[check_return]
1.269 + //coverity[unchecked_value]
1.270 + ellipse.NextStep(tl,tr,bl,br);
1.271 + iPenArray[doublePenHeight - count - 2] = bl.iX;
1.272 + iPenArray[doublePenHeight - count - 1] = br.iX;
1.273 + iPenArray[count] = tl.iX;
1.274 + iPenArray[count + 1] = tr.iX;
1.275 + }
1.276 + }
1.277 +
1.278 + return KErrNone;
1.279 + }
1.280 +
1.281 +/**
1.282 +Draws at a given point using the current settings, if within clipping rectangle.
1.283 +
1.284 +@pre The pen size is greater than one.
1.285 +
1.286 +@param aPoint The location to draw at.
1.287 +@param aClipRect The clipping rectangle.
1.288 +@panic DGDIAdapter 1016, if the current pen size is zero (debug only).
1.289 +*/
1.290 +void CSwDirectGdiEngine::PenDrawClipped(TPoint aPoint, const TRect& aClipRect)
1.291 + {
1.292 + GRAPHICS_ASSERT_DEBUG(iPenSize.iWidth > 0,EDirectGdiPanicZeroLength);
1.293 + GRAPHICS_ASSERT_DEBUG(iPenSize.iHeight > 0,EDirectGdiPanicZeroLength);
1.294 +
1.295 + aPoint.iX -= ((iPenSize.iWidth - 1) >> 1);
1.296 + aPoint.iY -= ((iPenSize.iHeight - 1) >> 1);
1.297 +
1.298 + if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1)
1.299 + {
1.300 + if ( (iPenStyle == DirectGdi::ESolidPen || (iDotMask & (1 << (iDotParam % iDotLength)))) &&
1.301 + aClipRect.Contains(aPoint) )
1.302 + {
1.303 + iDrawDevice->WriteRgb(aPoint.iX, aPoint.iY, iPenColor, GcDrawMode(iDrawMode));
1.304 + }
1.305 + }
1.306 + else if (iPenArray != NULL)
1.307 + {
1.308 + TInt yCoord = aPoint.iY;
1.309 + const TInt maxdim = Max(iPenSize.iWidth,iPenSize.iHeight);
1.310 + const TInt doublePenHeight = iPenSize.iHeight << 1;
1.311 +
1.312 + if (iPenStyle == DirectGdi::ESolidPen || (iDotMask & (1 << ((iDotParam / maxdim) % iDotLength))))
1.313 + {
1.314 + for (TInt ix = 0; ix < doublePenHeight; yCoord++, ix += 2)
1.315 + {
1.316 + if (yCoord >= aClipRect.iTl.iY && yCoord < aClipRect.iBr.iY)
1.317 + {
1.318 + TInt left = aPoint.iX + iPenArray[ix];
1.319 + TInt right = aPoint.iX + iPenArray[ix+1];
1.320 + if (left < aClipRect.iTl.iX)
1.321 + {
1.322 + left = aClipRect.iTl.iX;
1.323 + }
1.324 + if (right >= aClipRect.iBr.iX)
1.325 + {
1.326 + right = aClipRect.iBr.iX - 1;
1.327 + }
1.328 + if (left <= right)
1.329 + {
1.330 + iDrawDevice->WriteRgbMulti(left, yCoord, right - left + 1, 1, iPenColor, CGraphicsContext::EDrawModePEN);
1.331 + }
1.332 + }
1.333 + }
1.334 + }
1.335 + }
1.336 + else
1.337 + {
1.338 + TPoint tl,tr,bl,br;
1.339 + TSwDirectGdiEllipse ellipse;
1.340 + ellipse.Construct(TRect(aPoint,iPenSize));
1.341 + while (!ellipse.NextStep(tl,tr,bl,br))
1.342 + {
1.343 + if (tl.iY >= aClipRect.iTl.iY && tl.iY < aClipRect.iBr.iY)
1.344 + {
1.345 + if (tl.iX < aClipRect.iTl.iX)
1.346 + {
1.347 + tl.iX = aClipRect.iTl.iX;
1.348 + }
1.349 + if (tr.iX >= aClipRect.iBr.iX)
1.350 + {
1.351 + tr.iX = aClipRect.iBr.iX-1;
1.352 + }
1.353 + if (tl.iX <= tr.iX)
1.354 + {
1.355 + iDrawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
1.356 + }
1.357 + }
1.358 + if (bl.iY >= aClipRect.iTl.iY && bl.iY < aClipRect.iBr.iY)
1.359 + {
1.360 + if (bl.iX < aClipRect.iTl.iX)
1.361 + {
1.362 + bl.iX = aClipRect.iTl.iX;
1.363 + }
1.364 + if (br.iX >= aClipRect.iBr.iX)
1.365 + {
1.366 + br.iX = aClipRect.iBr.iX - 1;
1.367 + }
1.368 + if (bl.iX <= br.iX)
1.369 + {
1.370 + iDrawDevice->WriteRgbMulti(bl.iX,bl.iY,br.iX - bl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
1.371 + }
1.372 + }
1.373 + }
1.374 +
1.375 + if (tl.iY == bl.iY && tl.iY >= aClipRect.iTl.iY && tl.iY < aClipRect.iBr.iY)
1.376 + {
1.377 + if (tl.iX < aClipRect.iTl.iX)
1.378 + {
1.379 + tl.iX = aClipRect.iTl.iX;
1.380 + }
1.381 + if (tr.iX >= aClipRect.iBr.iX)
1.382 + {
1.383 + tr.iX = aClipRect.iBr.iX - 1;
1.384 + }
1.385 + if (tl.iX <= tr.iX)
1.386 + {
1.387 + iDrawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1, iPenColor, CGraphicsContext::EDrawModePEN);
1.388 + }
1.389 + }
1.390 + }
1.391 + }
1.392 +
1.393 +/**
1.394 +@panic DGDIAdapter 1016, if the current pen size is zero (debug only).
1.395 +*/
1.396 +void CSwDirectGdiEngine::PenDrawDeferred(TPoint aPoint,TInt* aArray, TInt aFirstElement)
1.397 + {
1.398 + GRAPHICS_ASSERT_DEBUG(iPenArray,EDirectGdiPanicZeroLength);
1.399 + GRAPHICS_ASSERT_DEBUG(iPenSize.iWidth > 0,EDirectGdiPanicZeroLength);
1.400 + GRAPHICS_ASSERT_DEBUG(iPenSize.iHeight > 0,EDirectGdiPanicZeroLength);
1.401 +
1.402 + aPoint.iX -= ((iPenSize.iWidth - 1) >> 1);
1.403 + const TInt doublepenheight = iPenSize.iHeight << 1;
1.404 +
1.405 + for (TInt ix = 0; ix < doublepenheight; ix++,aFirstElement++)
1.406 + {
1.407 + if (aFirstElement == doublepenheight)
1.408 + {
1.409 + aFirstElement = 0;
1.410 + }
1.411 + TInt newval = aPoint.iX + iPenArray[ix];
1.412 + if (newval < aArray[aFirstElement])
1.413 + {
1.414 + aArray[aFirstElement] = newval;
1.415 + }
1.416 +
1.417 + ix++;
1.418 + aFirstElement++;
1.419 + newval = aPoint.iX + iPenArray[ix];
1.420 + if (newval > aArray[aFirstElement])
1.421 + {
1.422 + aArray[aFirstElement] = newval;
1.423 + }
1.424 + }
1.425 + }