author | Gareth Stockwell <gareth.stockwell@accenture.com> |
Fri, 22 Oct 2010 11:38:29 +0100 | |
branch | bug235_bringup_0 |
changeset 206 | c170e304623f |
parent 0 | 5d03bc08d59c |
permissions | -rw-r--r-- |
// Copyright (c) 2007-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 "directgdiadapter.h" #include "swdirectgdiengine.h" /** @see MDirectGdiEngine::CopyRect() */ void CSwDirectGdiEngine::CopyRect(const TPoint& aOffset, const TRect& aRect) { TRect deviceRect; iDrawDevice->GetDrawRect(deviceRect); const TPoint back(TPoint(0,0) - aOffset); TRect rcpy(aRect); rcpy.Move(iOrigin); rcpy.Intersection(deviceRect); ((TRegion*)iDefaultRegionPtr)->Sort(aOffset); TRect targetRect(rcpy); targetRect.Move(aOffset); targetRect.BoundingRect(rcpy); TRect clipRect(0,0,0,0); const TInt limit = iDefaultRegionPtr->Count(); for(TInt count = 0; count < limit; count++) { clipRect = (*iDefaultRegionPtr)[count]; clipRect.Move(back); if (!clipRect.Intersects(rcpy)) { continue; } clipRect.Intersection(rcpy); DirectGdi::TDrawMode drawMode = iDrawMode; iDrawMode = DirectGdi::EDrawModeWriteAlpha; DoCopyRect(aOffset, clipRect); iDrawMode = drawMode; // restore the previous draw mode clipRect.Move(aOffset); iDrawDevice->UpdateRegion(clipRect); } } /** @see CopyRect() @panic DGDIAdapter 1013, if aRect or aOffset are outside of the destination bounds (debug only). */ void CSwDirectGdiEngine::DoCopyRect(const TPoint& aOffset, const TRect& aRect) { #ifdef _DEBUG TRect deviceRect; iDrawDevice->GetDrawRect(deviceRect); #endif GRAPHICS_ASSERT_DEBUG(aRect.iTl.iX >= deviceRect.iTl.iX, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(aRect.iTl.iY >= deviceRect.iTl.iY, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(aRect.iBr.iX <= deviceRect.iBr.iX, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(aRect.iBr.iY <= deviceRect.iBr.iY, EDirectGdiPanicOutOfBounds); TRect offsetRect(aRect); offsetRect.Move(aOffset); GRAPHICS_ASSERT_DEBUG(offsetRect.iTl.iX >= deviceRect.iTl.iX, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(offsetRect.iTl.iY >= deviceRect.iTl.iY, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(offsetRect.iBr.iX <= deviceRect.iBr.iX, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(offsetRect.iBr.iY <= deviceRect.iBr.iY, EDirectGdiPanicOutOfBounds); TInt y1 = aRect.iTl.iY; TInt y2 = aRect.iBr.iY; TInt yinc = 1; // default y2>y1 if (aOffset.iY > 0) // y1>y2 { y1 = aRect.iBr.iY - 1; y2 = aRect.iTl.iY - 1; yinc = -1; } const TInt width = aRect.Width(); const TInt xoffset = aRect.iTl.iX + aOffset.iX; const TDisplayMode dispMode = ScanLineBufferDisplayMode(iDrawDevice); TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer(); for (TInt row = y1; row != y2; row += yinc) { iDrawDevice->ReadLine(aRect.iTl.iX, row, width, scanLineBuffer, dispMode); iDrawDevice->WriteLine(xoffset, row + aOffset.iY, width, scanLineBuffer, GcDrawMode(iDrawMode)); } } /** @see MDirectGdiEngine::DrawRect() */ void CSwDirectGdiEngine::DrawRect(const TRect& aRect) { TRect rcpy(aRect); iBrushBitmap.BeginDataAccess(); if ((iPenSize.iWidth == 1) && (iPenSize.iHeight == 1) && iPenStyle != DirectGdi::ENullPen) { const TInt width = rcpy.Width(); const TInt height = rcpy.Height(); const TPoint currentLinePosition = iLinePosition; if (iPenStyle != DirectGdi::ESolidPen) { iDotParam = 0; } DoDrawLine(rcpy.iTl,TPoint(rcpy.iBr.iX,rcpy.iTl.iY),ETrue); // top if (height > 2 && width > 1) { DoDrawLine(TPoint(rcpy.iBr.iX-1,rcpy.iTl.iY+1),TPoint(rcpy.iBr.iX-1,rcpy.iBr.iY-1),ETrue); // right } if (height > 1) { DoDrawLine(TPoint(rcpy.iBr.iX-1,rcpy.iBr.iY-1),TPoint(rcpy.iTl.iX-1,rcpy.iBr.iY-1),ETrue); // bottom } if (height > 2) { DoDrawLine(TPoint(rcpy.iTl.iX,rcpy.iBr.iY-2),rcpy.iTl,ETrue); // left } // Restore internal line position in case it has been modified by DoDrawLine(). // DrawRect() should not be modifying it. iLinePosition = currentLinePosition; if (width < 3 || height < 3) { goto nofill; } rcpy.Shrink(1,1); rcpy.Move(iOrigin); } else if ((iPenStyle != DirectGdi::ENullPen) && (iPenSize.iWidth >= 1 && iPenSize.iHeight >= 1)) { rcpy.Move(iOrigin); const DirectGdi::TBrushStyle tempbrushstyle = iBrushStyle; const TRgb tempbrushColor = iBrushColor; const DirectGdi::TDrawMode tempdrawmode = iDrawMode; const TInt halfpenwidth = (iPenSize.iWidth - 1) >> 1; const TInt halfpenheight = (iPenSize.iHeight - 1) >> 1; const TInt otherhalfwidth = (iPenSize.iWidth >> 1) + 1; const TInt otherhalfheight = (iPenSize.iHeight >> 1) + 1; rcpy.iBr.iX--; rcpy.iBr.iY--; if (((rcpy.iBr.iY - rcpy.iTl.iY) <= (iPenSize.iHeight + 1)) || ((rcpy.iBr.iX - rcpy.iTl.iX) <= (iPenSize.iWidth + 1))) { iBrushColor = iPenColor; iBrushStyle = DirectGdi::ESolidBrush; if(iDrawMode != DirectGdi::EDrawModeWriteAlpha) { iDrawMode = DirectGdi::EDrawModePEN; } rcpy.iTl.iX -= halfpenwidth; rcpy.iTl.iY -= halfpenheight; rcpy.iBr.iX += otherhalfwidth; rcpy.iBr.iY += otherhalfheight; RectFill(rcpy); } else { // In the event the pen outline is semi-transparent, we must do the fill first so that the // outline is blended over the top. RectFill(rcpy); iBrushColor = iPenColor; iBrushStyle = DirectGdi::ESolidBrush; if(iDrawMode != DirectGdi::EDrawModeWriteAlpha) { iDrawMode = DirectGdi::EDrawModePEN; } RectFill(TRect(rcpy.iTl.iX - halfpenwidth,rcpy.iTl.iY - halfpenheight,rcpy.iBr.iX + otherhalfwidth,rcpy.iTl.iY + otherhalfheight)); // top RectFill(TRect(rcpy.iTl.iX - halfpenwidth,rcpy.iTl.iY + otherhalfheight,rcpy.iTl.iX + otherhalfwidth,rcpy.iBr.iY - halfpenheight)); // left RectFill(TRect(rcpy.iBr.iX - halfpenwidth,rcpy.iTl.iY + otherhalfheight,rcpy.iBr.iX + otherhalfwidth,rcpy.iBr.iY - halfpenheight)); // right RectFill(TRect(rcpy.iTl.iX - halfpenwidth,rcpy.iBr.iY - halfpenheight,rcpy.iBr.iX + otherhalfwidth,rcpy.iBr.iY + otherhalfheight)); // bottom } iBrushStyle = tempbrushstyle; iBrushColor = tempbrushColor; iDrawMode = tempdrawmode; goto nofill; } else { rcpy.Move(iOrigin); } RectFill(rcpy); nofill: iBrushBitmap.EndDataAccess(ETrue); } /** Fills the given area using the current brush. @param aRect The area to fill. @panic DGDIAdapter 1013, if the a clipping rectangle is fully outside of the destination bounds (debug only). @panic DGDIAdapter 7, if using EPatternedBrush with no brush pattern bitmap. */ void CSwDirectGdiEngine::RectFill(const TRect& aRect) { if (aRect.IsEmpty() || iBrushStyle == DirectGdi::ENullBrush) { return; } const TPoint origin = iOrigin + iBrushOrigin; const TInt limit = iDefaultRegionPtr->Count(); TRect clipRect(0,0,0,0); for (TInt count = 0; count < limit; count++) { clipRect = (*iDefaultRegionPtr)[count]; if (!clipRect.Intersects(aRect)) { continue; } clipRect.Intersection(aRect); #ifdef _DEBUG TRect deviceRect; iDrawDevice->GetDrawRect(deviceRect); GRAPHICS_ASSERT_DEBUG(clipRect.iTl.iX >= deviceRect.iTl.iX, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(clipRect.iTl.iY >= deviceRect.iTl.iY, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(clipRect.iBr.iX <= deviceRect.iBr.iX, EDirectGdiPanicOutOfBounds); GRAPHICS_ASSERT_DEBUG(clipRect.iBr.iY <= deviceRect.iBr.iY, EDirectGdiPanicOutOfBounds); #endif TInt xcoord = clipRect.iTl.iX; TInt ycoord = clipRect.iTl.iY; const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode); switch(iBrushStyle) { case DirectGdi::ESolidBrush: iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,clipRect.iTl.iY, clipRect.Width(),clipRect.Height(),iBrushColor,drawMode); break; case DirectGdi::EPatternedBrush: { iBrushBitmap.BeginDataAccess(); CBitwiseBitmap* brushbitmap = iBrushBitmap.Address(); GRAPHICS_ASSERT_ALWAYS(brushbitmap != NULL, EDirectGdiPanicInvalidBitmap); TRect sourcerect(clipRect); sourcerect.Move(-origin); DoBitBlt(clipRect.iTl,brushbitmap,iBrushBitmap.DataAddress(),iBrushBitmap.DataStride(),sourcerect); iBrushBitmap.EndDataAccess(ETrue); break; } case DirectGdi::EHorizontalHatchBrush: iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,clipRect.iTl.iY, clipRect.Width(),clipRect.Height(),iBrushColor,drawMode); while (Abs((ycoord - origin.iY) % 3) != 2) { ycoord++; } for (; ycoord < clipRect.iBr.iY; ycoord += 3) { iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,ycoord,clipRect.Width(),1,iPenColor,drawMode); } break; case DirectGdi::EVerticalHatchBrush: iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,clipRect.iTl.iY, clipRect.Width(),clipRect.Height(),iBrushColor,drawMode); while (Abs((xcoord - origin.iX) % 3) != 2) { xcoord++; } for (; xcoord < clipRect.iBr.iX; xcoord += 3) { iDrawDevice->WriteRgbMulti(xcoord,clipRect.iTl.iY,1,clipRect.Height(),iPenColor,drawMode); } break; case DirectGdi::ESquareCrossHatchBrush: iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,clipRect.iTl.iY, clipRect.Width(),clipRect.Height(),iBrushColor,drawMode); while (Abs((ycoord - origin.iY) % 3) != 2) { ycoord++; } for (; ycoord < clipRect.iBr.iY; ycoord += 3) // horizontal lines { iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,ycoord,clipRect.Width(),1,iPenColor,drawMode); } ycoord = clipRect.iTl.iY; while (Abs((ycoord - origin.iY) % 3) != 2 && ycoord < clipRect.iBr.iY) // above the top horizontal line { xcoord = clipRect.iTl.iX; while (Abs((xcoord - origin.iX) % 3) != 2) { xcoord++; } for (; xcoord < clipRect.iBr.iX; xcoord += 3) { iDrawDevice->WriteRgb(xcoord,ycoord,iPenColor,drawMode); } ycoord++; } ycoord += 3; for (; ycoord < clipRect.iBr.iY; ycoord += 3) // between the top and bottom horizontals { xcoord = clipRect.iTl.iX; while (Abs((xcoord - origin.iX) % 3) != 2) { xcoord++; } for (; xcoord < clipRect.iBr.iX; xcoord += 3) { iDrawDevice->WriteRgbMulti(xcoord,ycoord - 2,1,2,iPenColor,drawMode); } } ycoord -= 3; while (ycoord < clipRect.iBr.iY) // below the bottom horizontal { xcoord = clipRect.iTl.iX; while (Abs((xcoord - origin.iX) % 3) != 2) { xcoord++; } for (; xcoord < clipRect.iBr.iX; xcoord += 3) { iDrawDevice->WriteRgb(xcoord,ycoord,iPenColor,drawMode); } ycoord++; } break; case DirectGdi::EForwardDiagonalHatchBrush: iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,clipRect.iTl.iY, clipRect.Width(),clipRect.Height(),iBrushColor,drawMode); for (; ycoord < clipRect.iBr.iY; ycoord++) { xcoord = clipRect.iTl.iX; TInt diff = (origin.iX + origin.iY - xcoord - ycoord) % 3; if (diff < 0) { diff += 3; } xcoord += diff; for (; xcoord < clipRect.iBr.iX; xcoord += 3) { iDrawDevice->WriteRgb(xcoord,ycoord,iPenColor,drawMode); } } break; case DirectGdi::ERearwardDiagonalHatchBrush: iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,clipRect.iTl.iY, clipRect.Width(),clipRect.Height(),iBrushColor,drawMode); for (; ycoord < clipRect.iBr.iY; ycoord++) { xcoord = clipRect.iTl.iX; TInt diff = (origin.iX - origin.iY - xcoord + ycoord) % 3; if (diff < 0) { diff += 3; } xcoord += diff; for (; xcoord < clipRect.iBr.iX; xcoord += 3) { iDrawDevice->WriteRgb(xcoord,ycoord,iPenColor,drawMode); } } break; case DirectGdi::EDiamondCrossHatchBrush: { iDrawDevice->WriteRgbMulti(clipRect.iTl.iX,clipRect.iTl.iY, clipRect.Width(),clipRect.Height(),iBrushColor,drawMode); TInt sum = xcoord + ycoord - origin.iX - origin.iY; for (; ycoord < clipRect.iBr.iY; ycoord++,sum++) { TInt currentsum = sum; for (xcoord = clipRect.iTl.iX; xcoord < clipRect.iBr.iX; xcoord++,currentsum++) { if((currentsum & 1) == 0 && ((currentsum & 3) != 0 || ((xcoord-origin.iX) & 1) == 1)) { iDrawDevice->WriteRgb(xcoord,ycoord,iPenColor,drawMode); } } } break; } default: return; } iDrawDevice->UpdateRegion(clipRect); } }