Update contrib.
1 // Copyright (c) 2008-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 "directgdigcwrapper.h"
18 #include <graphics/lookuptable.h>
19 #include <graphics/directgdidriver.h>
20 #include <graphics/directgdidrawablesource.h>
21 #include <graphics/sgresourceinternal.h>
22 #include "mwsgraphicscontexttodirectgdimappings.h"
25 CDirectGdiGcWrapper* CDirectGdiGcWrapper::NewL()
27 CDirectGdiGcWrapper* self = new(ELeave) CDirectGdiGcWrapper;
28 CleanupStack::PushL(self);
29 CDirectGdiDriver* driver = CDirectGdiDriver::Static();
30 User::LeaveIfNull(driver);
31 self->iContext = CDirectGdiContext::NewL(*driver);
32 self->iErrorCode = KErrNone;
33 self->iGcBuf = CBufSeg::NewL(512);
35 //Default in BitGdi was 128 for the blackMap and 255 for the whiteMap
36 //SetFadingParameters shows how the fade color is computed
37 self->iFadeColor.SetInternal(0x80FFFFFF);
39 self->iLut = PtrTo16BitNormalisationTable();
40 CleanupStack::Pop(self);
44 CDirectGdiGcWrapper::~CDirectGdiGcWrapper()
48 for (TInt i = 0; i < iDrawableSources.Count(); ++i)
50 iDrawableSources[i]->Close();
52 iDrawableSources.ResetAndDestroy();
53 iClippingRegion.Close();
56 TAny* CDirectGdiGcWrapper::ResolveObjectInterface(TUint aTypeId)
60 case MWsGraphicsContext::EWsObjectInterfaceId:
61 return static_cast<MWsGraphicsContext*>(this);
62 case MWsFader::EWsObjectInterfaceId:
63 return static_cast<MWsFader*>(this);
64 case MWsDrawableSourceProvider::EWsObjectInterfaceId:
65 return static_cast<MWsDrawableSourceProvider*>(this);
66 case MWsTextCursor::EWsObjectInterfaceId:
67 return static_cast<MWsTextCursor*>(this);
72 void CDirectGdiGcWrapper::BitBlt(const TPoint& aDestPos, const CFbsBitmap& aSourceBitmap)
74 iContext->BitBlt(aDestPos, aSourceBitmap);
77 void CDirectGdiGcWrapper::BitBlt(const TPoint& aDestPos, const CFbsBitmap& aSourceBitmap, const TRect& aSourceRect)
79 iContext->BitBlt(aDestPos, aSourceBitmap, aSourceRect);
82 void CDirectGdiGcWrapper::BitBltMasked(const TPoint& aDestPos, const CFbsBitmap& aSourceBitmap, const TRect& aSourceRect, const CFbsBitmap& aMaskBitmap, TBool aInvertMask)
84 iContext->BitBltMasked(aDestPos, aSourceBitmap, aSourceRect, aMaskBitmap, aInvertMask);
87 void CDirectGdiGcWrapper::BitBltMasked(const TPoint& aDestPos, const CFbsBitmap& aSourceBitmap, const TRect& aSourceRect, const CFbsBitmap& aMaskBitmap, const TPoint& aMaskPos)
89 iContext->BitBltMasked(aDestPos, aSourceBitmap, aSourceRect, aMaskBitmap, aMaskPos);
92 void CDirectGdiGcWrapper::ResetClippingRegion()
94 iContext->ResetClippingRegion();
97 void CDirectGdiGcWrapper::Clear()
102 void CDirectGdiGcWrapper::Clear(const TRect& aRect)
104 iContext->Clear(aRect);
107 void CDirectGdiGcWrapper::ResetBrushPattern()
109 iContext->ResetBrushPattern();
112 void CDirectGdiGcWrapper::ResetFont()
114 iContext->ResetFont();
117 void CDirectGdiGcWrapper::DrawArc(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
119 iContext->DrawArc(aRect, aStart, aEnd);
122 void CDirectGdiGcWrapper::DrawPie(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
124 iContext->DrawPie(aRect, aStart, aEnd);
127 void CDirectGdiGcWrapper::DrawBitmap(const TRect& aDestRect, const CFbsBitmap& aSourceBitmap)
129 iContext->DrawBitmap(aDestRect, aSourceBitmap);
132 void CDirectGdiGcWrapper::DrawBitmap(const TRect& aDestRect, const CFbsBitmap& aSourceBitmap, const TRect& aSourceRect)
134 iContext->DrawBitmap(aDestRect, aSourceBitmap, aSourceRect);
137 void CDirectGdiGcWrapper::DrawBitmapMasked(const TRect& aDestRect, const CFbsBitmap& aSourceBitmap, const TRect& aSourceRect, const CFbsBitmap& aMaskBitmap, TBool aInvertMask)
139 iContext->DrawBitmapMasked(aDestRect, aSourceBitmap, aSourceRect, aMaskBitmap, aInvertMask);
142 void CDirectGdiGcWrapper::DrawRoundRect(const TRect& aRect, const TSize& aEllipse)
144 iContext->DrawRoundRect(aRect, aEllipse);
147 void CDirectGdiGcWrapper::DrawPolyLine(const TArray<TPoint>& aPointList)
149 iContext->DrawPolyLine(aPointList);
152 void CDirectGdiGcWrapper::DrawPolyLineNoEndPoint(const TArray<TPoint>& aPointList)
154 iContext->DrawPolyLineNoEndPoint(aPointList);
157 void CDirectGdiGcWrapper::DrawPolygon(const TArray<TPoint>& aPointList, TFillRule aFillRule)
159 iContext->DrawPolygon(aPointList, MWsGraphicsContextToDirectGdiMappings::Convert(aFillRule));
162 void CDirectGdiGcWrapper::DrawEllipse(const TRect& aRect)
164 iContext->DrawEllipse(aRect);
167 void CDirectGdiGcWrapper::DrawLine(const TPoint& aStart, const TPoint& aEnd)
169 iContext->DrawLine(aStart, aEnd);
172 void CDirectGdiGcWrapper::DrawLineTo(const TPoint& aPoint)
174 iContext->DrawLineTo(aPoint);
177 void CDirectGdiGcWrapper::DrawLineBy(const TPoint& aVector)
179 iContext->DrawLineBy(aVector);
182 void CDirectGdiGcWrapper::DrawRect(const TRect& aRect)
184 iContext->DrawRect(aRect);
187 void CDirectGdiGcWrapper::DrawText(const TDesC& aText, const TTextParameters* aParam)
189 iContext->DrawText(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam));
192 void CDirectGdiGcWrapper::DrawText(const TDesC& aText, const TTextParameters* aParam, const TPoint& aPosition)
194 iContext->DrawText(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aPosition);
197 void CDirectGdiGcWrapper::DrawText(const TDesC& aText, const TTextParameters* aParam, const TRect& aClipRect)
199 iContext->DrawText(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aClipRect);
202 void CDirectGdiGcWrapper::DrawText(const TDesC& aText, const TTextParameters* aParam, const TRect& aClipFillRect, TInt aBaselineOffset, TTextAlign aHrz, TInt aMargin)
204 iContext->DrawText(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aClipFillRect, aBaselineOffset, MWsGraphicsContextToDirectGdiMappings::Convert(aHrz), aMargin);
207 void CDirectGdiGcWrapper::DrawTextVertical(const TDesC& aText, const TTextParameters* aParam, TBool aUp)
209 iContext->DrawTextVertical(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aUp);
212 void CDirectGdiGcWrapper::DrawTextVertical(const TDesC& aText, const TTextParameters* aParam, const TPoint& aPosition, TBool aUp)
214 iContext->DrawTextVertical(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aPosition, aUp);
217 void CDirectGdiGcWrapper::DrawTextVertical(const TDesC& aText, const TTextParameters* aParam, const TRect& aClipRect, TBool aUp)
219 iContext->DrawTextVertical(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aClipRect, aUp);
222 void CDirectGdiGcWrapper::DrawTextVertical(const TDesC& aText, const TTextParameters* aParam, const TRect& aClipRect, TInt aBaselineOffset, TBool aUp, TTextAlign aVert, TInt aMargin)
224 iContext->DrawTextVertical(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aClipRect, aBaselineOffset, aUp, MWsGraphicsContextToDirectGdiMappings::Convert(aVert), aMargin);
227 void CDirectGdiGcWrapper::DrawTextVertical(const TDesC& aText, const TTextParameters* aParam, const TRect& aClipRect, TInt aBaselineOffset, TInt aTextWidth, TBool aUp, TTextAlign aVert, TInt aMargin)
229 iContext->DrawTextVertical(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aClipRect, aBaselineOffset, aTextWidth, aUp, MWsGraphicsContextToDirectGdiMappings::Convert(aVert), aMargin);
232 void CDirectGdiGcWrapper::MoveTo(const TPoint& aPoint)
234 iContext->MoveTo(aPoint);
237 void CDirectGdiGcWrapper::MoveBy(const TPoint& aVector)
239 iContext->MoveBy(aVector);
242 void CDirectGdiGcWrapper::Plot(const TPoint& aPoint)
244 iContext->Plot(aPoint);
247 void CDirectGdiGcWrapper::Reset()
252 void CDirectGdiGcWrapper::SetBrushColor(const TRgb& aColor)
254 iContext->SetBrushColor(aColor);
257 void CDirectGdiGcWrapper::SetBrushOrigin(const TPoint& aOrigin)
259 iContext->SetBrushOrigin(aOrigin);
262 void CDirectGdiGcWrapper::SetBrushStyle(TBrushStyle aBrushStyle)
264 iContext->SetBrushStyle(MWsGraphicsContextToDirectGdiMappings::Convert(aBrushStyle));
267 void CDirectGdiGcWrapper::SetClippingRegion(const TRegion& aRegion)
269 CDirectGdiDriver* driver = CDirectGdiDriver::Static();
270 driver->GetError(); //make sure that an error has been received
271 iContext->SetClippingRegion(aRegion);
272 TInt err = driver->GetError();
276 iClippingRegion.Copy(aRegion);
280 void CDirectGdiGcWrapper::SetDrawMode(TDrawMode aDrawMode)
282 iContext->SetDrawMode(MWsGraphicsContextToDirectGdiMappings::LossyConvert(aDrawMode));
285 void CDirectGdiGcWrapper::SetOrigin(const TPoint& aPoint)
287 iContext->SetOrigin(aPoint);
291 void CDirectGdiGcWrapper::SetPenColor(const TRgb& aColor)
293 iContext->SetPenColor(aColor);
296 void CDirectGdiGcWrapper::SetPenStyle(TPenStyle aPenStyle)
298 iContext->SetPenStyle(MWsGraphicsContextToDirectGdiMappings::Convert(aPenStyle));
301 void CDirectGdiGcWrapper::SetPenSize(const TSize& aSize)
303 iContext->SetPenSize(aSize);
306 void CDirectGdiGcWrapper::SetTextShadowColor(const TRgb& aColor)
308 iContext->SetTextShadowColor(aColor);
311 void CDirectGdiGcWrapper::SetCharJustification(TInt aExcessWidth, TInt aNumChars)
313 iContext->SetCharJustification(aExcessWidth, aNumChars);
316 void CDirectGdiGcWrapper::SetWordJustification(TInt aExcessWidth, TInt aNumGaps)
318 iContext->SetWordJustification(aExcessWidth, aNumGaps);
321 void CDirectGdiGcWrapper::SetUnderlineStyle(TFontUnderline aUnderlineStyle)
323 iContext->SetUnderlineStyle(MWsGraphicsContextToDirectGdiMappings::Convert(aUnderlineStyle));
326 void CDirectGdiGcWrapper::SetStrikethroughStyle(TFontStrikethrough aStrikethroughStyle)
328 iContext->SetStrikethroughStyle(MWsGraphicsContextToDirectGdiMappings::Convert(aStrikethroughStyle));
331 void CDirectGdiGcWrapper::SetBrushPattern(const CFbsBitmap& aBitmap)
333 iContext->SetBrushPattern(aBitmap);
336 void CDirectGdiGcWrapper::SetBrushPattern(TInt aFbsBitmapHandle)
338 iContext->SetBrushPattern(aFbsBitmapHandle);
341 void CDirectGdiGcWrapper::SetFont(const CFont* aFont)
343 iContext->SetFont(aFont);
346 void CDirectGdiGcWrapper::CopyRect(const TPoint& aOffset, const TRect& aRect)
348 iContext->CopyRect(aOffset, aRect);
351 void CDirectGdiGcWrapper::UpdateJustification(const TDesC& aText, const TTextParameters* aParam)
353 iContext->UpdateJustification(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam));
356 void CDirectGdiGcWrapper::UpdateJustificationVertical(const TDesC& aText, const TTextParameters* aParam, TBool aUp)
358 iContext->UpdateJustificationVertical(aText, MWsGraphicsContextToDirectGdiMappings::Convert(aParam), aUp);
361 void CDirectGdiGcWrapper::SetFontNoDuplicate(const CFont* aFont)
363 iContext->SetFontNoDuplicate(static_cast<const CDirectGdiFont*>(aFont));
366 TBool CDirectGdiGcWrapper::HasBrushPattern() const
368 return iContext->HasBrushPattern();
371 TBool CDirectGdiGcWrapper::HasFont() const
373 return iContext->HasFont();
376 TRgb CDirectGdiGcWrapper::BrushColor() const
378 return iContext->BrushColor();
381 TRgb CDirectGdiGcWrapper::PenColor() const
383 return iContext->PenColor();
386 TRgb CDirectGdiGcWrapper::TextShadowColor() const
388 return iContext->TextShadowColor();
391 TInt CDirectGdiGcWrapper::CreateDrawableSource(const TSgDrawableId& aDrawableId, TAny*& aSource)
393 CDirectGdiDriver* driver = CDirectGdiDriver::Static();
398 RDirectGdiDrawableSource* drawableSource = new RDirectGdiDrawableSource(*driver);
404 //check usage flags if the drawable is an RSgImage
406 TInt res = image.Open(aDrawableId);
410 res = image.GetInfo(info);
412 if (res == KErrNone && !(info.iUsage & ESgUsageWindowGcSource))
414 res = KErrNotSupported;
419 delete drawableSource;
424 RSgDrawable drawable;
425 res = drawable.Open(aDrawableId, ESgDoNotRestrictUsage);
428 delete drawableSource;
431 res = drawableSource->Create(drawable);
435 delete drawableSource;
438 res = iDrawableSources.InsertInAddressOrder(drawableSource);
441 drawableSource->Close();
442 delete drawableSource;
445 aSource = drawableSource;
449 void CDirectGdiGcWrapper::CloseDrawableSource(TAny* aSource)
451 RDirectGdiDrawableSource* drawableSource = static_cast<RDirectGdiDrawableSource*>(aSource);
452 TInt index = iDrawableSources.FindInAddressOrder(drawableSource);
453 if (index != KErrNotFound)
455 drawableSource->Close();
456 delete drawableSource;
457 iDrawableSources.Remove(index);
461 void CDirectGdiGcWrapper::DrawResource(const TAny* aSource, const TPoint& aPos, CWindowGc::TGraphicsRotation aRotation)
463 const RDirectGdiDrawableSource* drawableSource = static_cast<const RDirectGdiDrawableSource*>(aSource);
464 TInt index = iDrawableSources.FindInAddressOrder(drawableSource);
465 if (index == KErrNotFound)
467 STD_ASSERT_DEBUG(0, EPluginPanicInvalidDrawableSource);
470 iContext->DrawResource(aPos, *drawableSource, (DirectGdi::TGraphicsRotation)aRotation);
473 void CDirectGdiGcWrapper::DrawResource(const TAny* aSource, const TRect& aRect, CWindowGc::TGraphicsRotation aRotation)
475 const RDirectGdiDrawableSource* drawableSource = static_cast<const RDirectGdiDrawableSource*>(aSource);
476 TInt index = iDrawableSources.FindInAddressOrder(drawableSource);
477 if (index == KErrNotFound)
479 STD_ASSERT_DEBUG(0, EPluginPanicInvalidDrawableSource);
482 iContext->DrawResource(aRect, *drawableSource, (DirectGdi::TGraphicsRotation)aRotation);
485 void CDirectGdiGcWrapper::DrawResource(const TAny* aSource, const TRect& aRectDest, const TRect& aRectSrc, CWindowGc::TGraphicsRotation aRotation)
487 const RDirectGdiDrawableSource* drawableSource = static_cast<const RDirectGdiDrawableSource*>(aSource);
488 TInt index = iDrawableSources.FindInAddressOrder(drawableSource);
489 if (index == KErrNotFound)
491 STD_ASSERT_DEBUG(0, EPluginPanicInvalidDrawableSource);
494 iContext->DrawResource(aRectDest, *drawableSource, aRectSrc, (DirectGdi::TGraphicsRotation)aRotation);
497 void CDirectGdiGcWrapper::DrawResource(const TAny* aSource, const TRect& aRect, const TDesC8& aDes)
499 const RDirectGdiDrawableSource* drawableSource = static_cast<const RDirectGdiDrawableSource*>(aSource);
500 TInt index = iDrawableSources.FindInAddressOrder(drawableSource);
501 if (index == KErrNotFound)
503 STD_ASSERT_DEBUG(0, EPluginPanicInvalidDrawableSource);
506 iContext->DrawResource(aRect, *drawableSource, aDes);
510 Sets the error code. If the error code is already set to a value other
511 than KErrNone, the error code will not be modified.
513 @param aErr The error code to set.
515 @post The error code has been set.
517 void CDirectGdiGcWrapper::SetError(TInt aError)
519 if (aError != KErrNone && iErrorCode == KErrNone)
526 Returns the first error code (set as the result of calling some CDirectGdiGcWrapper API), if any,
527 since the last call to this function or, if it has not previously been called, since
528 the CDirectGdiGcWrapper was constructed. Calling this function clears the error code.
530 @post The error code has been reset after being read.
532 @return The first error code, if any, since the last call to this function or,
533 if it has not previously been called, since the CDirectGdiGcWrapper was constructed.
534 KErrNone will indicate that no such error has occurred.
536 TInt CDirectGdiGcWrapper::GetError()
538 TInt err = iErrorCode;
539 iErrorCode = KErrNone;
543 TPoint CDirectGdiGcWrapper::Origin() const
548 const TRegion& CDirectGdiGcWrapper::ClippingRegion()
550 return iClippingRegion;
553 TInt CDirectGdiGcWrapper::Push()
555 // the buf format is len+data where data is written by the GC's ExternalizeL()
557 CBufBase& buf = *iGcBuf;
558 const TInt start = buf.Size();
559 RBufWriteStream out(buf,start);
560 TRAPD(err,out.WriteInt32L(0));
563 TRAP(err,iContext->ExternalizeL(out));
565 if(err) //rollback addition
567 buf.Delete(start,buf.Size()-start);
571 TRAP_IGNORE(out.CommitL();) // can't see this failing
572 TPckgBuf<TInt32> pckg(buf.Size()-sizeof(TInt32)-start);
573 buf.Write(start,pckg);
578 void CDirectGdiGcWrapper::Pop()
580 CBufBase& buf = *iGcBuf;
585 RBufReadStream in(buf,ofs);
586 TRAPD(err,chunk = in.ReadInt32L());
589 STD_ASSERT_DEBUG(err != 0, EPluginPanicPopGcSettings);
592 if(ofs+sizeof(TInt32)+chunk >= buf.Size()) // the last chunk?
594 TRAP_IGNORE(iContext->InternalizeL(in));
595 buf.Delete(ofs,buf.Size()-ofs);
598 ofs += chunk + sizeof(TInt32);
602 //Default method of fading simply uses bitgdi to perform fading
603 void CDirectGdiGcWrapper::FadeArea(const TRegion& aRegion)
605 if (!&aRegion || aRegion.CheckError())
609 iContext->SetClippingRegion(aRegion);
610 iContext->SetPenStyle(DirectGdi::ENullPen);
611 iContext->SetBrushStyle(DirectGdi::ESolidBrush);
612 iContext->SetBrushColor(iFadeColor);
613 iContext->DrawRect(aRegion.BoundingRect());
616 //Default method of fading expects two TUint8's describing the black/white map
617 //as possible fading parameters
618 void CDirectGdiGcWrapper::SetFadingParameters(const TDesC8& aData)
620 TPckgBuf<TFadingParams> buf;
622 TFadingParams parameters = buf();
624 //Situations where blackMap > whiteMap are NOT supported
625 if (parameters.blackMap > parameters.whiteMap)
627 TUint8 oldMap = parameters.blackMap;
628 parameters.blackMap = parameters.whiteMap;
629 parameters.whiteMap = oldMap;
632 //CFbsBitGc::FadeArea() does the following per color component:
633 // dst = dst * (whiteMap - blackMap) + blackMap;
635 //To achieve the same effect using MWsGraphicsContext we draw a rectangle
636 //with specific intensity and alpha values:
637 // dst = dst * (1 - alpha) + intensity * alpha;
639 // alpha = 1 - whiteMap + blackMap;
640 // intensity = blackMap / alpha;
642 // alpha = 1 - whiteMap + blackMap;
643 TInt alpha = 255 - parameters.whiteMap + parameters.blackMap;
644 // intensity = blackMap / alpha;
645 TInt i = (parameters.blackMap * iLut[alpha]) >> 8;
647 iFadeColor.SetInternal(i << 16 | i << 8 | i | alpha << 24);
650 void CDirectGdiGcWrapper::DrawTextCursor(const TTextCursorInfo& aTextCursorInfo)
653 * This function is written with the following assumption:
654 * The UI Toolkit uses text entry windows with a white background
655 * and black text, but always requests a white text cursor.
657 * We therefore ignore the KRgbWhite text cursor cursor supplied
658 * and use a Black overprinting strategy instead.
661 aTextCursorInfo.iTextCursorType == TTextCursor::ETypeRectangle ||
662 aTextCursorInfo.iTextCursorType == TTextCursor::ETypeHollowRectangle,
663 EPluginPanicInvalidCursorType
666 TRegionFix<1> fullWindowRegion;
667 const TRegion* clippingRegion = &aTextCursorInfo.iRegion;
668 if (aTextCursorInfo.iRegion.CheckError())
670 fullWindowRegion.AddRect(aTextCursorInfo.iWindow->AbsRect());
671 clippingRegion = &fullWindowRegion;
674 if (clippingRegion->IsEmpty())
679 iContext->SetDrawMode(DirectGdi::EDrawModePEN);
680 switch (aTextCursorInfo.iTextCursorType)
682 case TTextCursor::ETypeRectangle:
684 iContext->SetBrushStyle(DirectGdi::ESolidBrush);
685 iContext->SetPenStyle(DirectGdi::ENullPen);
686 iContext->SetBrushColor(KRgbBlack);
689 case TTextCursor::ETypeHollowRectangle:
691 iContext->SetBrushStyle(DirectGdi::ENullBrush);
692 iContext->SetPenStyle(DirectGdi::ESolidPen);
693 iContext->SetPenColor(KRgbBlack);
697 iContext->SetClippingRegion(*clippingRegion);
699 * During Sprite drawing, the GC gets reset. Possibly other code could
700 * have done this also. So make sure we setup the origin so that window-relative
701 * co-ordinates work as expected; iCursorRect is in window co-ordinates.
703 iContext->SetOrigin(aTextCursorInfo.iWindow->Origin());
704 iContext->DrawRect(aTextCursorInfo.iCursorRect);