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) 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> #include "bitgcextradata.h" /** Clears a rectangular area. The cleared area is filled with the current brush colour.The function provides a concrete implementation of the pure virtual function CBitmapContext::Clear(const TRect& aRect). The function behaviour is the same as documented in that class. */ EXPORT_C void CFbsBitGc::Clear(const TRect& aRect) { if (CheckDevice(aRect)) return; TRect rcpy(aRect); rcpy.Move(iOrigin); if (UserClipRect(rcpy)) return; TBrushStyle tempbrushstyle = iBrushStyle; iBrushStyle = ESolidBrush; SetupDevice(); iDevice->DrawingBegin(); RectFill(rcpy); iDevice->DrawingEnd(); iBrushStyle = tempbrushstyle; } /** Clears the whole bitmap or a rectangular area of a bitmap. The cleared area is filled with the current brush colour. The function provides a concrete implementation of the pure virtual function CBitmapContext::Clear(). The function behaviour is the same as documented in that class. @see CBitmapContext::Clear() */ EXPORT_C void CFbsBitGc::Clear() { TRect deviceRect; iDevice->iDrawDevice->GetDrawRect(deviceRect); if ((iOrigin.iX!=0) || (iOrigin.iY!=0)) { deviceRect.Move(-iOrigin); } Clear(deviceRect); } /** Draws a single point. The point is drawn with the current pen settings using the current drawing mode.The function provides a concrete implementation of the pure virtual function CGraphicsContext::Plot(). The function behaviour is the same as documented in that class. */ EXPORT_C void CFbsBitGc::Plot(const TPoint& aPoint) { if (iPenStyle == ENullPen || (iPenSize.iWidth == 0 && iPenSize.iHeight == 0)) return; CheckDevice(); TRect plotRect(aPoint + iOrigin,TSize(1,1)); plotRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1); if (!plotRect.Intersects(iUserClipRect)) return; SetupDevice(); iDevice->DrawingBegin(); DoPlot(aPoint); iDevice->DrawingEnd(); } void CFbsBitGc::DoPlot(const TPoint& aPoint) { CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; const TSize oneByOne(1,1); const TPoint point(aPoint + iOrigin); TRect temp(point,oneByOne); if (iPenSize.iWidth > 1 || iPenSize.iHeight > 1) temp.Grow(iPenSize.iWidth >> 1,iPenSize.iHeight >> 1); AddRect(temp); const CGraphicsContext::TPenStyle penStyle = iPenStyle; iPenStyle = CGraphicsContext::ESolidPen; #if defined(_DEBUG) TRect deviceRect; drawDevice->GetDrawRect(deviceRect); #endif const TInt limit = iDefaultRegionPtr->Count(); for (TInt count = 0; count < limit; count++) { iClipRect = (*iDefaultRegionPtr)[count]; if (!iClipRect.Intersects(temp)) continue; iClipRect.Intersection(temp); if (UserClipRect(iClipRect)) continue; if (iPenSize == oneByOne) { if (iClipRect.Contains(point)) { BG_ASSERT_DEBUG(point.iX >= deviceRect.iTl.iX, EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(point.iY >= deviceRect.iTl.iY, EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(point.iX <= deviceRect.iBr.iX, EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(point.iY <= deviceRect.iBr.iY, EBitgdiPanicOutOfBounds); drawDevice->WriteRgb(point.iX,point.iY,iPenColor,iDrawMode); } } else if (iPenSize.iWidth > 0 && iPenSize.iHeight > 0) PenDrawClipped(point); drawDevice->UpdateRegion(iClipRect); } iPenStyle = penStyle; } /** Sets the shadow area. @param aRegion The region defining the shadow area. */ EXPORT_C void CFbsBitGc::ShadowArea(const TRegion* aRegion) { ShadowFadeArea(aRegion,CFbsDrawDevice::EShadow); } /** Sets the fade area. @param aRegion The region defining the fade area. */ EXPORT_C void CFbsBitGc::FadeArea(const TRegion* aRegion) { ShadowFadeArea(aRegion,CFbsDrawDevice::EFade); } void CFbsBitGc::ShadowFadeArea(const TRegion* aRegion,TInt8 aShadowMode) { if (!aRegion || aRegion->CheckError()) return; CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; CheckDevice(); TRect deviceRect; drawDevice->GetDrawRect(deviceRect); TInt8 shadowMode = iShadowMode; iShadowMode = aShadowMode; CGraphicsAccelerator* ga = GraphicsAccelerator(); SetupDevice(); iDevice->DrawingBegin(); const TInt limit = aRegion->Count(); TInt count; //use Graphics accelerator if available if(ga) { if(iShadowMode & CFbsDrawDevice::EFade) { TInt gaOperationResult = KErrUnknown; iDevice->DrawingEnd(); TGopFadeParams gopFadeParams; gopFadeParams.iScale = iFadeWhiteMap-iFadeBlackMap+1; gopFadeParams.iOffset = iFadeBlackMap; for (count = 0; count < limit; count++) { iClipRect = (*aRegion)[count]; iClipRect.Move(iOrigin); if(!iClipRect.Intersects(deviceRect)) continue; iClipRect.Intersection(deviceRect); AddRect(iClipRect); gaOperationResult = ga->Operation(TGopFadeRect(iClipRect,gopFadeParams)); if(gaOperationResult != KErrNone) break; } if(gaOperationResult == KErrNone) goto finish; iDevice->DrawingBegin(); } } //use graphics contex for (count = 0; count < limit; count++) { iClipRect = (*aRegion)[count]; iClipRect.Move(iOrigin); if(!iClipRect.Intersects(deviceRect)) continue; iClipRect.Intersection(deviceRect); AddRect(iClipRect); drawDevice->ShadowArea(iClipRect); drawDevice->UpdateRegion(iClipRect); } iDevice->DrawingEnd(); finish: iShadowMode = shadowMode; } // if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method void CFbsBitGc::ClipFillLine(TPoint aLeft,TPoint aRight) { if (iBrushStyle == ENullBrush || aLeft.iY < iClipRect.iTl.iY || aLeft.iY >= iClipRect.iBr.iY) return; aLeft.iX = Max(aLeft.iX,iClipRect.iTl.iX); aRight.iX = Min(aRight.iX,iClipRect.iBr.iX-1); if (aLeft.iX > aRight.iX) return; BG_ASSERT_DEBUG(iUserClipRect.Contains(aLeft),EBitgdiPanicOutOfBounds); TInt xcoord = aLeft.iX; TInt length = aRight.iX - aLeft.iX + 1; TPoint origin(iOrigin + iBrushOrigin); BG_ASSERT_DEBUG(aLeft.iX + length <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds); CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; switch(iBrushStyle) { case ESolidBrush: drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode); return; case EPatternedBrush: { CBitwiseBitmap* brushBitmap = iBrushBitmap.Address(); BG_ASSERT_ALWAYS(iBrushUsed,EBitgdiPanicInvalidBitmap); BG_ASSERT_ALWAYS(brushBitmap != NULL,EBitgdiPanicInvalidBitmap); TRect sourcerect(aLeft,TSize(length,1)); sourcerect.Move(-origin); DoBitBlt(aLeft,brushBitmap,iBrushBitmap.DataAddress(),iBrushBitmap.DataStride(),sourcerect); return; } case EHorizontalHatchBrush: drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode); if (Abs((aLeft.iY - origin.iY) % 3) == 2) drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,iDrawMode); return; case EVerticalHatchBrush: drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode); while (Abs((xcoord - origin.iX) % 3) != 2) xcoord++; for (; xcoord < aLeft.iX + length; xcoord += 3) drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode); return; case ESquareCrossHatchBrush: drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode); if (Abs((aLeft.iY - origin.iY) % 3) == 2) drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,iDrawMode); else { while (Abs((xcoord - origin.iX) % 3) != 2) xcoord++; for (; xcoord < aLeft.iX + length; xcoord += 3) drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode); } return; case EForwardDiagonalHatchBrush: { drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode); TInt diff = (origin.iX + origin.iY - aLeft.iX - aLeft.iY) % 3; if (diff < 0) diff += 3; xcoord += diff; for (; xcoord < aLeft.iX + length; xcoord += 3) drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode); } return; case ERearwardDiagonalHatchBrush: { drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode); TInt diff = (origin.iX - origin.iY - aLeft.iX + aLeft.iY) % 3; if (diff < 0) diff += 3; xcoord += diff; for (; xcoord < aLeft.iX + length; xcoord += 3) drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode); } return; case EDiamondCrossHatchBrush: { drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode); TInt sum = aLeft.iX + aLeft.iY - origin.iX - origin.iY; for (; xcoord < aLeft.iX + length; xcoord++,sum++) if ((sum & 1) == 0 && ((sum & 3) != 0 || ((xcoord-origin.iX) & 1) == 1)) drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode); } return; default: return; } } void CFbsBitGc::PenAllocate() { iFbsBitGcExtraData->ResetPenArray(); if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1) return; const TInt doublepenheight = iPenSize.iHeight << 1; TInt* penArray = new TInt[doublepenheight]; if (!penArray) return; iFbsBitGcExtraData->SetPenArray(penArray); if (iPenSize.iWidth == 1 || iPenSize.iWidth == 2 || iPenSize.iHeight == 1 || iPenSize.iHeight == 2) { TInt* bitGcPenArray = iFbsBitGcExtraData->PenArray(); for (TInt count = 0; count < iPenSize.iHeight; count += 2) { bitGcPenArray[doublepenheight - count - 2] = 0; bitGcPenArray[doublepenheight - count - 1] = iPenSize.iWidth - 1; bitGcPenArray[count] = 0; bitGcPenArray[count + 1] = iPenSize.iWidth - 1; } } else { TPoint tl,tr,bl,br; TEllipse ellipse; ellipse.Construct(TRect(iPenSize)); TInt* bitGcPenArray = iFbsBitGcExtraData->PenArray(); for (TInt count = 0; count < iPenSize.iHeight; count += 2) { //coverity[check_return] //coverity[unchecked_value] ellipse.NextStep(tl,tr,bl,br); bitGcPenArray[doublepenheight - count - 2] = bl.iX; bitGcPenArray[doublepenheight - count - 1] = br.iX; bitGcPenArray[count] = tl.iX; bitGcPenArray[count + 1] = tr.iX; } } } void CFbsBitGc::PenDrawClipped(TPoint aPoint) { BG_ASSERT_DEBUG(iPenSize.iWidth > 0,EBitgdiPanicZeroLength); BG_ASSERT_DEBUG(iPenSize.iHeight > 0,EBitgdiPanicZeroLength); aPoint.iX -= ((iPenSize.iWidth - 1) >> 1); aPoint.iY -= ((iPenSize.iHeight - 1) >> 1); BG_ASSERT_DEBUG(iClipRect.iTl.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(iClipRect.iTl.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(iClipRect.iBr.iX <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(iClipRect.iBr.iY <= iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds); CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1) { if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << (iDotParam % iDotLength)))) if (iClipRect.Contains(aPoint)) drawDevice->WriteRgb(aPoint.iX,aPoint.iY,iPenColor,iDrawMode); } else if (iFbsBitGcExtraData->PenArray()) { TInt ycoord = aPoint.iY; const TInt maxdim = Max(iPenSize.iWidth,iPenSize.iHeight); const TInt doublepenheight = iPenSize.iHeight << 1; if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / maxdim) % iDotLength)))) { for (TInt ix = 0; ix < doublepenheight; ycoord++,ix += 2) { if (ycoord >= iClipRect.iTl.iY && ycoord < iClipRect.iBr.iY) { TInt left = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix]; TInt right = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix+1]; if (left < iClipRect.iTl.iX) left = iClipRect.iTl.iX; if (right >= iClipRect.iBr.iX) right = iClipRect.iBr.iX - 1; if (left <= right) drawDevice->WriteRgbMulti(left,ycoord,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN); } } } } else { TPoint tl,tr,bl,br; TEllipse ellipse; ellipse.Construct(TRect(aPoint,iPenSize)); while (!ellipse.NextStep(tl,tr,bl,br)) { if (tl.iY >= iClipRect.iTl.iY && tl.iY < iClipRect.iBr.iY) { if (tl.iX < iClipRect.iTl.iX) tl.iX = iClipRect.iTl.iX; if (tr.iX >= iClipRect.iBr.iX) tr.iX = iClipRect.iBr.iX-1; if (tl.iX <= tr.iX) drawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN); } if (bl.iY >= iClipRect.iTl.iY && bl.iY < iClipRect.iBr.iY) { if (bl.iX < iClipRect.iTl.iX) bl.iX = iClipRect.iTl.iX; if (br.iX >= iClipRect.iBr.iX) br.iX = iClipRect.iBr.iX - 1; if (bl.iX <= br.iX) drawDevice->WriteRgbMulti(bl.iX,bl.iY,br.iX - bl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN); } } if (tl.iY == bl.iY && tl.iY >= iClipRect.iTl.iY && tl.iY < iClipRect.iBr.iY) { if (tl.iX < iClipRect.iTl.iX) tl.iX = iClipRect.iTl.iX; if (tr.iX >= iClipRect.iBr.iX) tr.iX = iClipRect.iBr.iX - 1; if (tl.iX <= tr.iX) drawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN); } } } void CFbsBitGc::PenDrawDeferred(TPoint aPoint,TInt* aArray,TInt aFirstElement) { BG_ASSERT_DEBUG(iFbsBitGcExtraData->PenArray(),EBitgdiPanicZeroLength); BG_ASSERT_DEBUG(iPenSize.iWidth > 0,EBitgdiPanicZeroLength); BG_ASSERT_DEBUG(iPenSize.iHeight > 0,EBitgdiPanicZeroLength); BG_ASSERT_DEBUG(iClipRect.iTl.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(iClipRect.iTl.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(iClipRect.iBr.iX <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds); BG_ASSERT_DEBUG(iClipRect.iBr.iY <= iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds); aPoint.iX -= ((iPenSize.iWidth - 1) >> 1); const TInt doublepenheight = iPenSize.iHeight << 1; for (TInt ix = 0; ix < doublepenheight; ix++,aFirstElement++) { if (aFirstElement == doublepenheight) aFirstElement = 0; TInt newval = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix]; if (newval < aArray[aFirstElement]) aArray[aFirstElement] = newval; ix++; aFirstElement++; newval = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix]; if (newval > aArray[aFirstElement]) aArray[aFirstElement] = newval; } } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CGraphicsContext_2() { CBitmapContext::Reserved_CGraphicsContext_2(); } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CBitmapContext_1() { CBitmapContext::Reserved_CBitmapContext_1(); } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CBitmapContext_2() { CBitmapContext::Reserved_CBitmapContext_2(); } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CBitmapContext_3() { CBitmapContext::Reserved_CBitmapContext_3(); } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_1() { } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_2() { } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_3() { } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_4() { } //Default implementation of reserved virtual EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_5() { }