mmplugins/imagingplugins/codecs/WMFCodec/WMFCodec.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 1999-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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <fbs.h>
       
    17 #include <hal.h>
       
    18 #include "WMFCodec.h"
       
    19 
       
    20 /*
       
    21 Not supported:
       
    22 0) Misc
       
    23 	// 0x0105 - SETRELABS
       
    24 	// 0x0231 - SETMAPPERFLAGS
       
    25 	// 0x0419 - FLOODFILL
       
    26 	// 0x0548 - EXTFLOODFILL
       
    27 	// 0x0626 - ESCAPE
       
    28 	// 0x0830 - CHORD
       
    29 1) Blitting
       
    30 	// 0x0107 - SETSTRETCHBLTMODE
       
    31 	// 0x0922 - BITBLT
       
    32 	// 0x0940 - DIBBITBLT
       
    33 	// 0x0b23 - STRETCHBLT
       
    34 	// 0x0d33 - SETDIBTODEV
       
    35 2) Clipping
       
    36 	// 0x0220 - OFFSETCLIPRGN
       
    37 	// 0x0415 - EXCLUDECLIPRECT
       
    38 3) Palettes
       
    39 	// 0x0035 - REALIZEPALETTE
       
    40 	// 0x0037 - SETPALENTRIES
       
    41 	// 0x00f7 - CREATEPALETTE
       
    42 	// 0x0139 - RESIZEPALETTE
       
    43 	// 0x0234 - SELECTPALETTE
       
    44 	// 0x0436 - ANIMATEPALETTE
       
    45 */
       
    46 
       
    47 const TInt KFontNormalWeightLimit = 550;	// Halfway between FW_NORMAL and FW_BOLD
       
    48 const TInt KFontFixedPitch = 1;				// FIXED_PITCH
       
    49 const TInt KFontFamilyRoman = 1;			// FF_ROMAN
       
    50 const TInt KFontFamilySwiss = 2;			// FF_SWISS
       
    51 const TInt KFontFamilyMono = 3;				// FF_MODERN
       
    52 const TInt KFontFamilyScript = 4;			// FF_SCRIPT
       
    53 const TInt KFontFamilyDecorative = 5;		// FF_DECORATIVE
       
    54 
       
    55 const TInt KExtTextOutFlagClipped = 4;		// ETO_CLIPPED
       
    56 
       
    57 //const TInt KTextAlignFlagNoUpdateCP = 0;	// EABI warning removal
       
    58 //const TInt KTextAlignFlagUpdateCP = 1; // Not supported		// EABI warning removal
       
    59 //const TInt KTextAlignFlagLeft = 0;		// EABI warning removal
       
    60 const TInt KTextAlignFlagRight = 2;
       
    61 const TInt KTextAlignFlagCenter = 6;
       
    62 //const TInt KTextAlignFlagTop = 0;			// EABI warning removal
       
    63 const TInt KTextAlignFlagBottom = 8;
       
    64 const TInt KTextAlignFlagBaseline = 24;
       
    65 
       
    66 const TInt KTextAlignMaskHorz = 6;
       
    67 const TInt KTextAlignMaskVert = 24;
       
    68 
       
    69 const TUint KMaxProcessTime = 175000; //limit DoProcessL() to 175ms for liveliness
       
    70 
       
    71 // Wrapper class for drawing to the bitmap.
       
    72 // All drawing operations go through this class.
       
    73 CFbsBitGcWrapper* CFbsBitGcWrapper::NewL(CFbsDevice& aDevice, CFbsBitGcWrapper* aGc)
       
    74 	{
       
    75 	CFbsBitGcWrapper* self = new(ELeave) CFbsBitGcWrapper;
       
    76 
       
    77 	CleanupStack::PushL(self);
       
    78 	self->ConstructL(aDevice, aGc);
       
    79 	CleanupStack::Pop(self);
       
    80 	return self;
       
    81 	}
       
    82 
       
    83 CFbsBitGcWrapper::CFbsBitGcWrapper():
       
    84 	iBrushColor(KRgbWhite),
       
    85 	iBrushStyle(CGraphicsContext::ENullBrush),
       
    86 	iPenColor(KRgbBlack),
       
    87 	iPenStyle(CGraphicsContext::ESolidPen),
       
    88 	iPenSize(1,1),
       
    89 	iTextColor(KRgbBlack),
       
    90 	iBackgroundColor(KRgbWhite)
       
    91 	{}
       
    92 
       
    93 void CFbsBitGcWrapper::ConstructL(CFbsDevice& aDevice, CFbsBitGcWrapper* aGc)
       
    94 	{
       
    95 	User::LeaveIfError(aDevice.CreateContext(iGc));
       
    96 	User::LeaveIfError(aDevice.CreateContext(iPolygonGc));
       
    97 	if (aGc)
       
    98 		{
       
    99 		iGc->CopySettings(*(aGc->iGc));
       
   100 		iGc->CancelClippingRegion();
       
   101 
       
   102 		iPolygonGc->CopySettings(*(aGc->iGc));
       
   103 		iPolygonGc->CancelClippingRegion();
       
   104 
       
   105 		iBrushColor = aGc->iBrushColor;
       
   106 		iBrushStyle = aGc->iBrushStyle;
       
   107 		iPenColor = aGc->iPenColor;
       
   108 		iPenStyle = aGc->iPenStyle;
       
   109 		iPenSize = aGc->iPenSize;
       
   110 
       
   111 		iTextColor = aGc->iTextColor;
       
   112 		iBackgroundColor = aGc->iBackgroundColor;
       
   113 		iPatternBrush = aGc->iPatternBrush;
       
   114 		}
       
   115 	}
       
   116 
       
   117 CFbsBitGcWrapper::~CFbsBitGcWrapper()
       
   118 	{
       
   119 	delete iGc;
       
   120 	delete iPolygonGc;
       
   121 	}
       
   122 
       
   123 void CFbsBitGcWrapper::SetPen(const CPen& aPen)
       
   124 	{
       
   125 	iPenStyle = aPen.iStyle;
       
   126 	iPenSize = aPen.iSize;
       
   127 	iPenColor = aPen.iColor;
       
   128 
       
   129 	iGc->SetPenStyle(iPenStyle);
       
   130 	iGc->SetPenSize(iPenSize);
       
   131 	iGc->SetPenColor(iPenColor);
       
   132 	}
       
   133 
       
   134 void CFbsBitGcWrapper::SetBrush(CBrush& aBrush)
       
   135 	{
       
   136 	iBrushColor = aBrush.iColor;
       
   137 	iBrushStyle = aBrush.iStyle;
       
   138 	iPatternBrush = (iBrushStyle == CGraphicsContext::EPatternedBrush) ? static_cast<CPatternBrush*> (&aBrush) : NULL;
       
   139 
       
   140 	iGc->SetBrushStyle(iBrushStyle);
       
   141 	iGc->SetBrushColor(iBrushColor);
       
   142 	}
       
   143 
       
   144 void CFbsBitGcWrapper::RestorePenAndBrush()
       
   145 	{
       
   146 	iGc->SetPenStyle(iPenStyle);
       
   147 	iGc->SetPenSize(iPenSize);
       
   148 	iGc->SetPenColor(iPenColor);
       
   149 
       
   150 	iGc->SetBrushStyle(iBrushStyle);
       
   151 	iGc->SetBrushColor(iBrushColor);
       
   152 	}
       
   153 
       
   154 void CFbsBitGcWrapper::DrawPolygonL(const TPoint* aPointList,TInt aNumPoints,CGraphicsContext::TFillRule aFillRule)
       
   155 	{
       
   156 	RealizeBrush();
       
   157 	if (iPenStyle == CGraphicsContext::ENullPen || iPenSize.iWidth == 0)
       
   158 		{
       
   159 		if (iBrushStyle != CGraphicsContext::ENullBrush)
       
   160 			{
       
   161 			iPolygonGc->CopySettings(*iGc);
       
   162 			iPolygonGc->CancelClippingRegion();
       
   163 
       
   164 			iPolygonGc->SetPenStyle(CGraphicsContext::ESolidPen);
       
   165 			iPolygonGc->SetPenSize(TSize(1,1));
       
   166 			iPolygonGc->SetPenColor(iBrushColor);
       
   167 
       
   168 			User::LeaveIfError(iPolygonGc->DrawPolygon(aPointList,aNumPoints,aFillRule));
       
   169 			}
       
   170 		}
       
   171 	else
       
   172 		User::LeaveIfError(iGc->DrawPolygon(aPointList,aNumPoints,aFillRule));
       
   173 	}
       
   174 
       
   175 const CFbsFont* CFbsBitGcWrapper::CurrentFont()
       
   176 	{
       
   177 	return iCurrentFont;
       
   178 	}
       
   179 
       
   180 void CFbsBitGcWrapper::Clear()
       
   181 	{
       
   182 	iGc->Clear();
       
   183 	}
       
   184 
       
   185 void CFbsBitGcWrapper::SetUnderlineStyle(TFontUnderline aUnderlineStyle)
       
   186 	{
       
   187 	iGc->SetUnderlineStyle(aUnderlineStyle);
       
   188 	}
       
   189 
       
   190 void CFbsBitGcWrapper::SetStrikethroughStyle(TFontStrikethrough aStrikethroughStyle)
       
   191 	{
       
   192 	iGc->SetStrikethroughStyle(aStrikethroughStyle);
       
   193 	}
       
   194 
       
   195 void CFbsBitGcWrapper::UseFont(const CFbsFont* aFont)
       
   196 	{
       
   197 	iGc->UseFont(aFont);
       
   198 	iCurrentFont = aFont;
       
   199 	}
       
   200 
       
   201 void CFbsBitGcWrapper::SetClippingRegion(const TRegion* aRegion)
       
   202 	{
       
   203 	iGc->SetClippingRegion(aRegion);
       
   204 	}
       
   205 
       
   206 void CFbsBitGcWrapper::SetCharJustification(TInt aExcessWidth, TInt aNumGaps)
       
   207 	{
       
   208 	iGc->SetCharJustification(aExcessWidth, aNumGaps);
       
   209 	}
       
   210 
       
   211 void CFbsBitGcWrapper::SetWordJustification(TInt aExcessWidth, TInt aNumChars)
       
   212 	{
       
   213 	iGc->SetWordJustification(aExcessWidth, aNumChars);
       
   214 	}
       
   215 
       
   216 void CFbsBitGcWrapper::DrawLineTo(const TPoint& aPoint)
       
   217 	{
       
   218 	iGc->DrawLineTo(aPoint);
       
   219 	}
       
   220 
       
   221 void CFbsBitGcWrapper::MoveTo(const TPoint& aPoint)
       
   222 	{
       
   223 	iGc->MoveTo(aPoint);
       
   224 	}
       
   225 
       
   226 void CFbsBitGcWrapper::DrawPolyLine(const TPoint* aPointList, TInt aNumPoints)
       
   227 	{
       
   228 	iGc->DrawPolyLine(aPointList, aNumPoints);
       
   229 	}
       
   230 
       
   231 void CFbsBitGcWrapper::DrawEllipse(const TRect& aRect)
       
   232 	{
       
   233 	RealizeBrush();
       
   234 	iGc->DrawEllipse(aRect);
       
   235 	}
       
   236 
       
   237 void CFbsBitGcWrapper::DrawRect(const TRect& aRect)
       
   238 	{
       
   239 	RealizeBrush();
       
   240 	iGc->DrawRect(aRect);
       
   241 	}
       
   242 
       
   243 void CFbsBitGcWrapper::DrawRoundRect(const TRect& aRect, const TSize& aEllipse)
       
   244 	{
       
   245 	RealizeBrush();
       
   246 	iGc->DrawRoundRect(aRect, aEllipse);
       
   247 	}
       
   248 
       
   249 void CFbsBitGcWrapper::SetPenStyle(CGraphicsContext::TPenStyle aPenStyle)
       
   250 	{
       
   251 	iGc->SetPenStyle(aPenStyle);
       
   252 	}
       
   253 
       
   254 void CFbsBitGcWrapper::SetBrushStyle(CGraphicsContext::TBrushStyle aBrushStyle)
       
   255 	{
       
   256 	iGc->SetBrushStyle(aBrushStyle);
       
   257 	}
       
   258 
       
   259 void CFbsBitGcWrapper::SetBrushColor(const TRgb& aColor)
       
   260 	{
       
   261 	iGc->SetBrushColor(aColor);
       
   262 	}
       
   263 
       
   264 void CFbsBitGcWrapper::SetDrawMode(CGraphicsContext::TDrawMode aDrawMode)
       
   265 	{
       
   266 	iGc->SetDrawMode(aDrawMode);
       
   267 	}
       
   268 
       
   269 void CFbsBitGcWrapper::SetPenColor(const TRgb& aColor)
       
   270 	{
       
   271 	iGc->SetPenColor(aColor);
       
   272 	}
       
   273 
       
   274 void CFbsBitGcWrapper::SetTextPenColor()
       
   275 	{
       
   276 	iGc->SetPenColor(iTextColor);
       
   277 	}
       
   278 
       
   279 void CFbsBitGcWrapper::Plot(const TPoint& aPoint)
       
   280 	{
       
   281 	iGc->Plot(aPoint);
       
   282 	}
       
   283 
       
   284 void CFbsBitGcWrapper::SetPenSize(const TSize& aSize)
       
   285 	{
       
   286 	iGc->SetPenSize(aSize);
       
   287 	}
       
   288 
       
   289 
       
   290 void CFbsBitGcWrapper::DrawArc(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
       
   291 	{
       
   292 	iGc->DrawArc(aRect, aStart, aEnd);
       
   293 	}
       
   294 
       
   295 void CFbsBitGcWrapper::DrawPie(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
       
   296 	{
       
   297 	RealizeBrush();
       
   298 	iGc->DrawPie(aRect, aStart, aEnd);
       
   299 	}
       
   300 
       
   301 void CFbsBitGcWrapper::DrawBitmap(const TRect& aDestRect, const CFbsBitmap* aSource, const TRect& aSourceRect)
       
   302 	{
       
   303 	iGc->DrawBitmap(aDestRect, aSource, aSourceRect);
       
   304 	}
       
   305 
       
   306 void CFbsBitGcWrapper::DrawText(const TDesC& aText,const TPoint& aPosition)
       
   307 	{
       
   308 	iGc->DrawText(aText, aPosition);
       
   309 	}
       
   310 
       
   311 void CFbsBitGcWrapper::UseBrushPattern(const CFbsBitmap* aPatternBitmap)
       
   312 	{
       
   313 	iGc->UseBrushPattern(aPatternBitmap);
       
   314 	}
       
   315 
       
   316 void CFbsBitGcWrapper::SetBackgroundColor(TRgb aBackgroundColor)
       
   317 	{
       
   318 	iBackgroundColor = aBackgroundColor;
       
   319 	}
       
   320 
       
   321 void CFbsBitGcWrapper::SetTextColor(TRgb aTextColor)
       
   322 	{
       
   323 	iTextColor = aTextColor;
       
   324 	}
       
   325 
       
   326 void CFbsBitGcWrapper::RealizeBrush()
       
   327 	{
       
   328 	if (iPatternBrush)
       
   329 		iPatternBrush->RealizeBrush(iTextColor, iBackgroundColor);
       
   330 	}
       
   331 
       
   332 // Wrapper class for drawing to the bitmap and mask.
       
   333 // All drawing operations are performed through this class when mask generation is requested.
       
   334 CFbsBitGcMaskWrapper* CFbsBitGcMaskWrapper::NewL(CFbsDevice& aDevice, CFbsDevice& aMaskDevice, CFbsBitGcMaskWrapper* aGc)
       
   335 	{
       
   336 	CFbsBitGcMaskWrapper* self = new(ELeave) CFbsBitGcMaskWrapper;
       
   337 
       
   338 	CleanupStack::PushL(self);
       
   339 	self->ConstructL(aDevice, aMaskDevice, aGc);
       
   340 	CleanupStack::Pop(self);
       
   341 	return self;
       
   342 	}
       
   343 
       
   344 CFbsBitGcMaskWrapper::CFbsBitGcMaskWrapper()
       
   345 	{
       
   346 	}
       
   347 
       
   348 void CFbsBitGcMaskWrapper::ConstructL(CFbsDevice& aDevice, CFbsDevice& aMaskDevice, CFbsBitGcMaskWrapper* aGc)
       
   349 	{
       
   350 	CFbsBitGcWrapper::ConstructL(aDevice, aGc);
       
   351 	User::LeaveIfError(aMaskDevice.CreateContext(iMaskGc));
       
   352 	User::LeaveIfError(aMaskDevice.CreateContext(iPolygonMaskGc));
       
   353 	if (aGc)
       
   354 		{
       
   355 		iMaskGc->CopySettings(*(aGc->iMaskGc));
       
   356 		iMaskGc->CancelClippingRegion();
       
   357 
       
   358 		iPolygonMaskGc->CopySettings(*(aGc->iMaskGc));
       
   359 		iPolygonMaskGc->CancelClippingRegion();
       
   360 		}
       
   361 
       
   362 	// Set the pen color to white.
       
   363 	// (Ensures that all drawing operations will set pixels on the mask)
       
   364 	iMaskGc->SetPenColor(KRgbWhite);
       
   365 	iPolygonMaskGc->SetPenColor(KRgbWhite);
       
   366 	}
       
   367 
       
   368 CFbsBitGcMaskWrapper::~CFbsBitGcMaskWrapper()
       
   369 	{
       
   370 	delete iMaskGc;
       
   371 	delete iPolygonMaskGc;
       
   372 	}
       
   373 
       
   374 void CFbsBitGcMaskWrapper::SetPen(const CPen& aPen)
       
   375 	{
       
   376 	CFbsBitGcWrapper::SetPen(aPen);
       
   377 
       
   378 	iMaskGc->SetPenStyle(iPenStyle);
       
   379 	iMaskGc->SetPenSize(iPenSize);
       
   380 	}
       
   381 
       
   382 void CFbsBitGcMaskWrapper::SetBrush(CBrush& aBrush)
       
   383 	{
       
   384 	CFbsBitGcWrapper::SetBrush(aBrush);
       
   385 
       
   386 	if (!iPatternBrush)
       
   387 		iMaskGc->SetBrushStyle(iBrushStyle);
       
   388 	else
       
   389 		iMaskGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   390 	}
       
   391 
       
   392 void CFbsBitGcMaskWrapper::DrawPolygonL(const TPoint* aPointList,TInt aNumPoints,CGraphicsContext::TFillRule aFillRule)
       
   393 	{
       
   394 	CFbsBitGcWrapper::DrawPolygonL(aPointList, aNumPoints, aFillRule);
       
   395 	if (iPenStyle == CGraphicsContext::ENullPen || iPenSize.iWidth == 0)
       
   396 		{
       
   397 		if (iBrushStyle != CGraphicsContext::ENullBrush)
       
   398 			{
       
   399 			iPolygonMaskGc->CopySettings(*iMaskGc);
       
   400 			iPolygonMaskGc->CancelClippingRegion();
       
   401 
       
   402 			iPolygonMaskGc->SetPenStyle(CGraphicsContext::ESolidPen);
       
   403 			iPolygonMaskGc->SetPenSize(TSize(1,1));
       
   404 
       
   405 			User::LeaveIfError(iPolygonMaskGc->DrawPolygon(aPointList,aNumPoints,aFillRule));
       
   406 			}
       
   407 		}
       
   408 	else
       
   409 		User::LeaveIfError(iMaskGc->DrawPolygon(aPointList,aNumPoints,aFillRule));
       
   410 	}
       
   411 
       
   412 void CFbsBitGcMaskWrapper::Clear()
       
   413 	{
       
   414 	CFbsBitGcWrapper::Clear();
       
   415 
       
   416 	// Clear the mask to black.
       
   417 	iMaskGc->SetBrushColor(KRgbBlack);
       
   418 	iMaskGc->Clear();
       
   419 
       
   420 	// Reset the brush color to white.
       
   421 	iMaskGc->SetBrushColor(KRgbWhite);
       
   422 	}
       
   423 
       
   424 void CFbsBitGcMaskWrapper::SetUnderlineStyle(TFontUnderline aUnderlineStyle)
       
   425 	{
       
   426 	CFbsBitGcWrapper::SetUnderlineStyle(aUnderlineStyle);
       
   427 	iMaskGc->SetUnderlineStyle(aUnderlineStyle);
       
   428 	}
       
   429 
       
   430 void CFbsBitGcMaskWrapper::SetStrikethroughStyle(TFontStrikethrough aStrikethroughStyle)
       
   431 	{
       
   432 	CFbsBitGcWrapper::SetStrikethroughStyle(aStrikethroughStyle);
       
   433 	iMaskGc->SetStrikethroughStyle(aStrikethroughStyle);
       
   434 	}
       
   435 
       
   436 void CFbsBitGcMaskWrapper::UseFont(const CFbsFont* aFont)
       
   437 	{
       
   438 	CFbsBitGcWrapper::UseFont(aFont);
       
   439 	iMaskGc->UseFont(aFont);
       
   440 	}
       
   441 
       
   442 void CFbsBitGcMaskWrapper::SetClippingRegion(const TRegion* aRegion)
       
   443 	{
       
   444 	CFbsBitGcWrapper::SetClippingRegion(aRegion);
       
   445 	iMaskGc->SetClippingRegion(aRegion);
       
   446 	}
       
   447 
       
   448 void CFbsBitGcMaskWrapper::SetCharJustification(TInt aExcessWidth, TInt aNumGaps)
       
   449 	{
       
   450 	CFbsBitGcWrapper::SetCharJustification(aExcessWidth, aNumGaps);
       
   451 	iMaskGc->SetCharJustification(aExcessWidth, aNumGaps);
       
   452 	}
       
   453 
       
   454 void CFbsBitGcMaskWrapper::SetWordJustification(TInt aExcessWidth, TInt aNumChars)
       
   455 	{
       
   456 	CFbsBitGcWrapper::SetWordJustification(aExcessWidth, aNumChars);
       
   457 	iMaskGc->SetWordJustification(aExcessWidth, aNumChars);
       
   458 	}
       
   459 
       
   460 void CFbsBitGcMaskWrapper::DrawLineTo(const TPoint& aPoint)
       
   461 	{
       
   462 	CFbsBitGcWrapper::DrawLineTo(aPoint);
       
   463 	iMaskGc->DrawLineTo(aPoint);
       
   464 	}
       
   465 
       
   466 void CFbsBitGcMaskWrapper::MoveTo(const TPoint& aPoint)
       
   467 	{
       
   468 	CFbsBitGcWrapper::MoveTo(aPoint);
       
   469 	iMaskGc->MoveTo(aPoint);
       
   470 	}
       
   471 
       
   472 void CFbsBitGcMaskWrapper::DrawPolyLine(const TPoint* aPointList, TInt aNumPoints)
       
   473 	{
       
   474 	CFbsBitGcWrapper::DrawPolyLine(aPointList, aNumPoints);
       
   475 	iMaskGc->DrawPolyLine(aPointList, aNumPoints);
       
   476 	}
       
   477 
       
   478 void CFbsBitGcMaskWrapper::DrawEllipse(const TRect& aRect)
       
   479 	{
       
   480 	CFbsBitGcWrapper::DrawEllipse(aRect);
       
   481 	iMaskGc->DrawEllipse(aRect);
       
   482 	}
       
   483 
       
   484 void CFbsBitGcMaskWrapper::DrawRect(const TRect& aRect)
       
   485 	{
       
   486 	CFbsBitGcWrapper::DrawRect(aRect);
       
   487 	iMaskGc->DrawRect(aRect);
       
   488 	}
       
   489 
       
   490 void CFbsBitGcMaskWrapper::DrawRoundRect(const TRect& aRect, const TSize& aEllipse)
       
   491 	{
       
   492 	CFbsBitGcWrapper::DrawRoundRect(aRect, aEllipse);
       
   493 	iMaskGc->DrawRoundRect(aRect, aEllipse);
       
   494 	}
       
   495 
       
   496 void CFbsBitGcMaskWrapper::SetPenStyle(CGraphicsContext::TPenStyle aPenStyle)
       
   497 	{
       
   498 	CFbsBitGcWrapper::SetPenStyle(aPenStyle);
       
   499 	iMaskGc->SetPenStyle(aPenStyle);
       
   500 	}
       
   501 
       
   502 void CFbsBitGcMaskWrapper::SetBrushStyle(CGraphicsContext::TBrushStyle aBrushStyle)
       
   503 	{
       
   504 	CFbsBitGcWrapper::SetBrushStyle(aBrushStyle);
       
   505 	iMaskGc->SetBrushStyle(aBrushStyle);
       
   506 	}
       
   507 
       
   508 void CFbsBitGcMaskWrapper::SetDrawMode(CGraphicsContext::TDrawMode aDrawMode)
       
   509 	{
       
   510 	CFbsBitGcWrapper::SetDrawMode(aDrawMode);
       
   511 	}
       
   512 
       
   513 void CFbsBitGcMaskWrapper::Plot(const TPoint& aPoint)
       
   514 	{
       
   515 	CFbsBitGcWrapper::Plot(aPoint);
       
   516 	iMaskGc->Plot(aPoint);
       
   517 	}
       
   518 
       
   519 void CFbsBitGcMaskWrapper::SetPenSize(const TSize& aSize)
       
   520 	{
       
   521 	CFbsBitGcWrapper::SetPenSize(aSize);
       
   522 	iMaskGc->SetPenSize(aSize);
       
   523 	}
       
   524 
       
   525 void CFbsBitGcMaskWrapper::DrawArc(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
       
   526 	{
       
   527 	CFbsBitGcWrapper::DrawArc(aRect, aStart, aEnd);
       
   528 	iMaskGc->DrawArc(aRect, aStart, aEnd);
       
   529 	}
       
   530 
       
   531 void CFbsBitGcMaskWrapper::DrawPie(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
       
   532 	{
       
   533 	CFbsBitGcWrapper::DrawPie(aRect, aStart, aEnd);
       
   534 	iMaskGc->DrawPie(aRect, aStart, aEnd);
       
   535 	}
       
   536 
       
   537 void CFbsBitGcMaskWrapper::DrawBitmap(const TRect& aDestRect, const CFbsBitmap* aSource, const TRect& aSourceRect)
       
   538 	{
       
   539 	CFbsBitGcWrapper::DrawBitmap(aDestRect, aSource, aSourceRect);
       
   540 	iMaskGc->Clear(aDestRect);
       
   541 	}
       
   542 
       
   543 void CFbsBitGcMaskWrapper::DrawText(const TDesC& aText,const TPoint& aPosition)
       
   544 	{
       
   545 	CFbsBitGcWrapper::DrawText(aText, aPosition);
       
   546 	iMaskGc->DrawText(aText, aPosition);
       
   547 	}
       
   548 
       
   549 
       
   550 void CPen::Apply(CFbsBitGcWrapper* aGc)
       
   551 	{
       
   552 	aGc->SetPen(*this);
       
   553 	}
       
   554 
       
   555 TInt CPen::Type() const
       
   556 	{
       
   557 	return KWmfGraphicsObjectPen;
       
   558 	}
       
   559 
       
   560 void CDummyBrush::Apply(CFbsBitGcWrapper* /* aGc */)
       
   561 	{
       
   562 	}
       
   563 
       
   564 TInt CDummyBrush::Type() const
       
   565 	{
       
   566 	return KWmfGraphicsObjectDummyBrush;
       
   567 	}
       
   568 
       
   569 void CBrush::Apply(CFbsBitGcWrapper* aGc)
       
   570 	{
       
   571 	aGc->SetBrush(*this);
       
   572 	}
       
   573 
       
   574 TInt CBrush::Type() const
       
   575 	{
       
   576 	return KWmfGraphicsObjectBrush;
       
   577 	}
       
   578 
       
   579 CPatternBrush* CPatternBrush::NewL()
       
   580 	{
       
   581 	CPatternBrush* self = new(ELeave) CPatternBrush;
       
   582 
       
   583 	CleanupStack::PushL(self);
       
   584 	self->ConstructL();
       
   585 	CleanupStack::Pop(self);
       
   586 	return self;
       
   587 	}
       
   588 
       
   589 void CPatternBrush::ConstructL()
       
   590 	{
       
   591 	iBitmap = new(ELeave) CFbsBitmap;
       
   592 	}
       
   593 
       
   594 CPatternBrush::CPatternBrush()
       
   595 : iTextColor(KRgbWhite), iBackgroundColor(KRgbWhite)
       
   596 	{
       
   597 	iStyle = CGraphicsContext::EPatternedBrush;
       
   598 	}
       
   599 
       
   600 CPatternBrush::~CPatternBrush()
       
   601 	{
       
   602 	delete iBitmap;
       
   603 	delete[] iBitmapBits;
       
   604 	}
       
   605 
       
   606 void CPatternBrush::Apply(CFbsBitGcWrapper* aGc)
       
   607 	{
       
   608 	aGc->UseBrushPattern(iBitmap);
       
   609 	CBrush::Apply(aGc);
       
   610 	}
       
   611 
       
   612 TInt CPatternBrush::Type() const
       
   613 	{
       
   614 	return KWmfGraphicsObjectPatternBrush;
       
   615 	}
       
   616 
       
   617 void CPatternBrush::SetBitmapBits(TUint8* aBitmapBits)
       
   618 	{
       
   619 	iBitmapBits = aBitmapBits;
       
   620 	}
       
   621 
       
   622 void CPatternBrush::RealizeBrush(TRgb aTextColor, TRgb aBackgroundColor)
       
   623 	{
       
   624 	if (!iBitmapBits)
       
   625 		return;
       
   626 
       
   627 	if ((aTextColor == iTextColor) && (aBackgroundColor == iBackgroundColor))
       
   628 		return;
       
   629 
       
   630 	iTextColor = aTextColor;
       
   631 	iBackgroundColor = aBackgroundColor;
       
   632 
       
   633 	TInt width = iBitmap->SizeInPixels().iWidth;
       
   634 	TInt height = iBitmap->SizeInPixels().iHeight;
       
   635 	TInt padding = ((width + 31) & ~31) - width;
       
   636 	TUint pixelMask = 0x80;
       
   637 	TUint8* bytePtr = iBitmapBits;
       
   638 	TBitmapUtil util(iBitmap);
       
   639 	for (TInt y = height - 1; y >= 0; y--)
       
   640 		{
       
   641 		util.Begin(TPoint(0,y));
       
   642 
       
   643 		TInt x;
       
   644 		for (x = 0; x < width; x++)
       
   645 			{
       
   646 			TRgb color((bytePtr[0] & pixelMask) ? iBackgroundColor : iTextColor);
       
   647 			util.SetPixel(color.Color64K());
       
   648 			util.IncXPos();
       
   649 
       
   650 			pixelMask >>= 1;
       
   651 			if (pixelMask == 0)
       
   652 				{
       
   653 				pixelMask = 0x80;
       
   654 				bytePtr++;
       
   655 				}
       
   656 			}
       
   657 
       
   658 		for (x = 0 ; x<padding ; x++)
       
   659 			{
       
   660 			pixelMask >>= 1;
       
   661 			if (pixelMask == 0)
       
   662 				{
       
   663 				pixelMask = 0x80;
       
   664 				bytePtr++;
       
   665 				}
       
   666 			}
       
   667 
       
   668 		util.End();
       
   669 		}
       
   670 	}
       
   671 
       
   672 CFbsBitmap* CPatternBrush::Bitmap()
       
   673 	{
       
   674 	return iBitmap;
       
   675 	}
       
   676 
       
   677 
       
   678 CFontObject::CFontObject(CFbsDevice& aDevice,CFbsFont& aFont,TBool aUnderline,TBool aStrikeOut):
       
   679 	iDevice(aDevice),
       
   680 	iFont(aFont),
       
   681 	iUnderline(aUnderline ? EUnderlineOn : EUnderlineOff),
       
   682 	iStrikeOut(aStrikeOut ? EStrikethroughOn : EStrikethroughOff)
       
   683 	{}
       
   684 
       
   685 CFontObject::~CFontObject()
       
   686 	{
       
   687 	iDevice.ReleaseFont(&iFont);
       
   688 	}
       
   689 
       
   690 void CFontObject::Apply(CFbsBitGcWrapper* aGc)
       
   691 	{
       
   692 	aGc->SetUnderlineStyle(iUnderline);
       
   693 	aGc->SetStrikethroughStyle(iStrikeOut);
       
   694 	aGc->UseFont(&iFont);
       
   695 	}
       
   696 
       
   697 TInt CFontObject::Type() const
       
   698 	{
       
   699 	return KWmfGraphicsObjectFont;
       
   700 	}
       
   701 
       
   702 
       
   703 CRectRegion::CRectRegion(CFbsDevice& aDevice, TRegion& aClipRegion, TInt aLeft, TInt aTop, TInt aRight, TInt aBottom):
       
   704 	iRect(aLeft, aTop, aRight, aBottom), iDevice(aDevice), iClipRegion(aClipRegion)
       
   705 	{}
       
   706 
       
   707 void CRectRegion::Apply(CFbsBitGcWrapper* aGc)
       
   708 	{
       
   709 	iClipRegion.Clear();
       
   710 	TRect bitmapRect(iDevice.SizeInPixels());
       
   711 	iClipRegion.AddRect(bitmapRect);
       
   712 
       
   713 	TRegionFix<1> rectRegion;
       
   714 	rectRegion.AddRect(iRect);
       
   715 
       
   716 	iClipRegion.Intersect(rectRegion);
       
   717 	aGc->SetClippingRegion(&iClipRegion);
       
   718 	}
       
   719 
       
   720 TInt CRectRegion::Type() const
       
   721 	{
       
   722 	return KWmfGraphicsObjectRegion;
       
   723 	}
       
   724 
       
   725 
       
   726 void CPaletteObject::Apply(CFbsBitGcWrapper* /* aGc */)
       
   727 	{
       
   728 	}
       
   729 
       
   730 TInt CPaletteObject::Type() const
       
   731 	{
       
   732 	return KWmfGraphicsObjectPalette;
       
   733 	}
       
   734 
       
   735 
       
   736 //
       
   737 // CWmfReadCodec
       
   738 //
       
   739 
       
   740 CWmfReadCodec::CWmfReadCodec(TInt aWordsExpected)
       
   741 	: iWordsExpected(aWordsExpected)
       
   742 	{
       
   743 	}
       
   744 
       
   745 CWmfReadCodec::~CWmfReadCodec()
       
   746 	{
       
   747 	delete[] iPointArray;
       
   748 	iSavedGcStack.ResetAndDestroy();
       
   749 
       
   750 	for (TInt index = 0; index < KWmfMaxGraphicsObjectCount; index++)
       
   751 		delete iGraphicsObject[index];
       
   752 
       
   753 	delete iDefaultPen;
       
   754 	delete iDefaultBrush;
       
   755 	delete iGc;
       
   756 	delete iDevice;
       
   757 	delete iMaskDevice;
       
   758 	delete[] iAccumulator;
       
   759 	}
       
   760 
       
   761 CWmfReadCodec* CWmfReadCodec::NewL(TInt aWordsExpected)
       
   762 	{
       
   763 	CWmfReadCodec* self = new(ELeave) CWmfReadCodec(aWordsExpected);
       
   764 	CleanupStack::PushL(self);
       
   765 	self->ConstructL();
       
   766 	CleanupStack::Pop(self); 
       
   767 	return self;
       
   768 	}
       
   769 
       
   770 void CWmfReadCodec::ConstructL()
       
   771 	{
       
   772 	CImageReadCodec::ConstructL();
       
   773 
       
   774 	iDefaultPen = new(ELeave) CPen;
       
   775 	iDefaultBrush = new(ELeave) CBrush;
       
   776 	}
       
   777 
       
   778 void CWmfReadCodec::InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& /*aFrameImageData*/, TBool /*aDisableErrorDiffusion*/, CFbsBitmap& aBitmap, CFbsBitmap* aDestinationMask)
       
   779 	{
       
   780 	iWordsProcessed = 0;
       
   781 
       
   782 	for (TInt index = 0; index < KWmfMaxGraphicsObjectCount; index++)
       
   783 		{
       
   784 		delete iGraphicsObject[index];
       
   785 		iGraphicsObject[index] = NULL;
       
   786 		}
       
   787 
       
   788 	delete iGc; iGc = NULL;
       
   789 	delete iDevice;	iDevice = NULL;
       
   790 	delete iMaskDevice; iMaskDevice = NULL;
       
   791 	iDevice = CFbsBitmapDevice::NewL(&aBitmap);
       
   792 
       
   793 	if ((aFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) && aDestinationMask)
       
   794 		{
       
   795 		iMaskDevice = CFbsBitmapDevice::NewL(aDestinationMask);
       
   796 		iGc = CFbsBitGcMaskWrapper::NewL(*iDevice, *iMaskDevice);
       
   797 		}
       
   798 	else
       
   799 		{
       
   800 		iGc = CFbsBitGcWrapper::NewL(*iDevice);
       
   801 		}
       
   802 	
       
   803 	if ((aFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) && !aDestinationMask && aBitmap.DisplayMode() == EColor16MA)
       
   804 		{
       
   805 		// Special case of single 16MA destination bitmap.
       
   806 		const TRgb transparentBlack(0x000000, 0x00);
       
   807 		ClearBitmapL(aBitmap, transparentBlack);
       
   808 		}
       
   809 	else
       
   810 		{
       
   811 		iGc->Clear(); // Ensure bitmap is cleared. (Also clear the mask if we are generating one)	
       
   812 		}
       
   813 	
       
   814 	iBkModeOpaque = EFalse;
       
   815 	iMapMode = EMapModeTEXT;
       
   816 	iWindowOrg.SetXY(0,0);
       
   817 	iWindowExt = aBitmap.SizeInPixels();
       
   818 	iViewportOrg.SetXY(0,0);
       
   819 	iViewportExt = iWindowExt;
       
   820 
       
   821 	iClipRegion.Clear();
       
   822 	TRect bitmapRect(iDevice->SizeInPixels());
       
   823 	iClipRegion.AddRect(bitmapRect);
       
   824 		
       
   825 	iFillRule = CGraphicsContext::EAlternate;
       
   826 
       
   827 	delete[] iAccumulator; iAccumulator = NULL;
       
   828 	iAccumulatorPtr = NULL;
       
   829 	iAccumulatorSizeInWords = 0;
       
   830 	iLookingForRecord = ETrue;
       
   831 	iRecordSizeInWords = 0;
       
   832 	iFunction = 0;
       
   833 	iWordsToRead = 0;
       
   834 	iFinished = EFalse;
       
   835 	}
       
   836 
       
   837 TFrameState CWmfReadCodec::ProcessFrameL(TBufPtr8& aSrc)
       
   838 	{
       
   839 	TUint16* startDataPtr = REINTERPRET_CAST(TUint16*,&aSrc[0]);
       
   840 	TUint16* dataPtr = startDataPtr;
       
   841 	TUint16* dataPtrLimit = dataPtr + Min(TInt(aSrc.Length() / sizeof(TUint16)),iWordsExpected - iWordsProcessed);
       
   842 
       
   843 	DoProcessL(dataPtr,dataPtrLimit);
       
   844 
       
   845 	TInt wordsUsed = dataPtr - startDataPtr;
       
   846 	aSrc.Shift(wordsUsed * sizeof(TUint16));
       
   847 	iWordsProcessed += wordsUsed;
       
   848 
       
   849 	if (iWordsProcessed >= iWordsExpected || iFinished)
       
   850 		return EFrameComplete;
       
   851 
       
   852 	return EFrameIncomplete;
       
   853 	}
       
   854 
       
   855 void CWmfReadCodec::DoProcessL(TUint16*& aDataPtr,const TUint16* aDataPtrLimit)
       
   856 	{
       
   857 	const TUint16* safeDataPtrLimit = aDataPtrLimit - KWmfMinRecordSizeInWords;
       
   858 	
       
   859 	//Do not spend more than KMaxProcessTime here
       
   860 	TInt systemTickPeriod;
       
   861 	User::LeaveIfError(HAL::Get(HAL::ESystemTickPeriod,systemTickPeriod));
       
   862 
       
   863 	TUint currentTick = User::TickCount();
       
   864 	const TUint tickLimit = currentTick + (KMaxProcessTime / systemTickPeriod);
       
   865 
       
   866 	//Disable tick check if tickLimit overflow
       
   867 	TBool disableTickCheck = EFalse;
       
   868 	if(tickLimit<=currentTick)
       
   869 		disableTickCheck = ETrue;
       
   870 
       
   871 	while (aDataPtr <= aDataPtrLimit && (disableTickCheck || currentTick < tickLimit))
       
   872 		{
       
   873 		if (iLookingForRecord) // Find record
       
   874 			{
       
   875 			if (aDataPtr > safeDataPtrLimit) // Ensures that a record header can always be safely read
       
   876 				return;
       
   877 
       
   878 			iRecordSizeInWords = (aDataPtr[1] << 16) | aDataPtr[0];
       
   879 			if (iRecordSizeInWords < KWmfMinRecordSizeInWords || iRecordSizeInWords > iWordsExpected)
       
   880 				User::Leave(KErrCorrupt);
       
   881 
       
   882 			iFunction = aDataPtr[2];
       
   883 
       
   884 			iWordsToRead = iRecordSizeInWords - KWmfMinRecordSizeInWords;
       
   885 			if (iWordsToRead > aDataPtrLimit - aDataPtr - KWmfMinRecordSizeInWords) // Check to see if we need to accumulate data
       
   886 				{
       
   887 				if (iWordsToRead > iAccumulatorSizeInWords)
       
   888 					{
       
   889 					delete[] iAccumulator;
       
   890 					iAccumulator = NULL;
       
   891 					iAccumulatorSizeInWords = 0;
       
   892 
       
   893 					iAccumulator = new(ELeave) TUint16[iWordsToRead];
       
   894 					iAccumulatorSizeInWords = iWordsToRead;
       
   895 					}
       
   896 
       
   897 				iAccumulatorPtr = iAccumulator;
       
   898 				}
       
   899 			else
       
   900 				iAccumulatorPtr = NULL;
       
   901 
       
   902 			aDataPtr += KWmfMinRecordSizeInWords;
       
   903 			iLookingForRecord = EFalse;
       
   904 			}
       
   905 		else if (iFunction == KWmfTerminateFunction) // Finished
       
   906 			{
       
   907 			iFinished = ETrue;
       
   908 			return;
       
   909 			}
       
   910 		else if (iAccumulatorPtr && iWordsToRead > 0) // Accumulate data
       
   911 			{
       
   912 			const TInt wordsToAccumulate = Min(iWordsToRead,aDataPtrLimit - aDataPtr);
       
   913 			Mem::Copy(iAccumulatorPtr,aDataPtr,wordsToAccumulate * sizeof(TUint16));
       
   914 			aDataPtr += wordsToAccumulate;
       
   915 			iAccumulatorPtr += wordsToAccumulate;
       
   916 			iWordsToRead -= wordsToAccumulate;
       
   917 
       
   918 			if (iWordsToRead > 0)
       
   919 				return;
       
   920 			}
       
   921 		else // Process data
       
   922 			{
       
   923 			TUint16* dataPtr = iAccumulatorPtr ? iAccumulator : aDataPtr;
       
   924 
       
   925 			if (iFunction < 0x0230)
       
   926 				{
       
   927 				if (iFunction < 0x0130)
       
   928 					DoProcess00L(iFunction,dataPtr);
       
   929 				else
       
   930 					DoProcess01L(iFunction,dataPtr);
       
   931 				}
       
   932 			else
       
   933 				{
       
   934 				if (iFunction < 0x500)
       
   935 					DoProcess10L(iFunction,dataPtr);
       
   936 				else
       
   937 					DoProcess11L(iFunction,dataPtr);
       
   938 				}
       
   939 
       
   940 			if (iAccumulatorPtr)
       
   941 				{
       
   942 				if (iAccumulatorSizeInWords > 0x800)
       
   943 					{
       
   944 					delete[] iAccumulator;
       
   945 					iAccumulator = NULL;
       
   946 					iAccumulatorSizeInWords = 0;
       
   947 					}
       
   948 
       
   949 				iAccumulatorPtr = NULL;
       
   950 				}
       
   951 			else
       
   952 				aDataPtr += iWordsToRead;
       
   953 
       
   954 			iLookingForRecord = ETrue;
       
   955 			}
       
   956 		currentTick = User::TickCount();
       
   957 		}
       
   958 	}
       
   959 
       
   960 void CWmfReadCodec::DoProcess00L(TInt aFunction,TUint16* aArgPtr)
       
   961 	{
       
   962 	if (aFunction < 0x0107)
       
   963 		{
       
   964 		if (aFunction < 0x0103)
       
   965 			DoProcess0000L(aFunction,aArgPtr);
       
   966 		else
       
   967 			DoProcess0001L(aFunction,aArgPtr);
       
   968 		}
       
   969 	else
       
   970 		{
       
   971 		if (aFunction < 0x012b)
       
   972 			DoProcess0010L(aFunction,aArgPtr);
       
   973 		else
       
   974 			DoProcess0011L(aFunction,aArgPtr);
       
   975 		}
       
   976 	}
       
   977 
       
   978 void CWmfReadCodec::DoProcess01L(TInt aFunction,TUint16* aArgPtr)
       
   979 	{
       
   980 	if (aFunction < 0x020d)
       
   981 		{
       
   982 		if (aFunction < 0x0205)
       
   983 			DoProcess0100L(aFunction,aArgPtr);
       
   984 		else
       
   985 			DoProcess0101L(aFunction,aArgPtr);
       
   986 		}
       
   987 	else
       
   988 		{
       
   989 		if (aFunction < 0x0212)
       
   990 			DoProcess0110L(aFunction,aArgPtr);
       
   991 		else
       
   992 			DoProcess0111L(aFunction,aArgPtr);
       
   993 		}
       
   994 	}
       
   995 
       
   996 void CWmfReadCodec::DoProcess10L(TInt aFunction,TUint16* aArgPtr)
       
   997 	{
       
   998 	if (aFunction < 0x0413)
       
   999 		{
       
  1000 		if (aFunction < 0x0300)
       
  1001 			DoProcess1000L(aFunction,aArgPtr);
       
  1002 		else
       
  1003 			DoProcess1001L(aFunction,aArgPtr);
       
  1004 		}
       
  1005 	else
       
  1006 		{
       
  1007 		if (aFunction < 0x041a)
       
  1008 			DoProcess1010L(aFunction,aArgPtr);
       
  1009 		else
       
  1010 			DoProcess1011L(aFunction,aArgPtr);
       
  1011 		}
       
  1012 	}
       
  1013 
       
  1014 void CWmfReadCodec::DoProcess11L(TInt aFunction,TUint16* aArgPtr)
       
  1015 	{
       
  1016 	if (aFunction < 0x0820)
       
  1017 		{
       
  1018 		if (aFunction < 0x0620)
       
  1019 			DoProcess1100L(aFunction,aArgPtr);
       
  1020 		else
       
  1021 			DoProcess1101L(aFunction,aArgPtr);
       
  1022 		}
       
  1023 	else
       
  1024 		{
       
  1025 		if (aFunction < 0x0b00)
       
  1026 			DoProcess1110L(aFunction,aArgPtr);
       
  1027 		else
       
  1028 			DoProcess1111L(aFunction,aArgPtr);
       
  1029 		}
       
  1030 	}
       
  1031 
       
  1032 void CWmfReadCodec::DoProcess0000L(TInt aFunction,TUint16* aArgPtr)
       
  1033 	{
       
  1034 	// Not supported:
       
  1035 	// 0x0035 - REALIZEPALETTE
       
  1036 	// 0x0037 - SETPALENTRIES
       
  1037 	// 0x00f7 - CREATEPALETTE
       
  1038 
       
  1039 	switch (aFunction)
       
  1040 		{
       
  1041 	case 0x001e: // SAVEDC
       
  1042 		{
       
  1043 		CFbsBitGcWrapper* gcCopy = CloneGcL();
       
  1044 		CleanupStack::PushL(gcCopy);
       
  1045 
       
  1046 		User::LeaveIfError(iSavedGcStack.Append(gcCopy));
       
  1047 		CleanupStack::Pop(); // gcCopy
       
  1048 		}
       
  1049 		break;
       
  1050 	case 0x00f7: // CREATEPALETTE
       
  1051 		AddGraphicsObject(new(ELeave) CPaletteObject);
       
  1052 		// Create the object to maintain the handle list
       
  1053 		break;
       
  1054 	case 0x0102: // SETBKMODE
       
  1055 		// 1 = TRANSPARENT, 2 = OPAQUE
       
  1056 		iBkModeOpaque = (aArgPtr[0] == 2);
       
  1057 		break;
       
  1058 	default:
       
  1059 		break;
       
  1060 		}
       
  1061 	}
       
  1062 
       
  1063 void CWmfReadCodec::DoProcess0001L(TInt aFunction,TUint16* aArgPtr)
       
  1064 	{
       
  1065 	// Not supported:
       
  1066 	// 0x0105 - SETRELABS
       
  1067 
       
  1068 	switch (aFunction)
       
  1069 		{
       
  1070 	case 0x0103: // SETMAPMODE
       
  1071 		iMapMode = TMapMode(aArgPtr[0]);
       
  1072 		break;
       
  1073 	case 0x0104: // SETROP2
       
  1074 		SetROP(iGc,aArgPtr[0]);
       
  1075 		break;
       
  1076 	case 0x0106: // SETPOLYFILLMODE
       
  1077 		// 1 = ALTERNATE, 2 = WINDING
       
  1078 		iFillRule = (aArgPtr[0] == 2) ? CGraphicsContext::EWinding : CGraphicsContext::EAlternate;
       
  1079 	default:
       
  1080 		break;
       
  1081 		}
       
  1082 	}
       
  1083 
       
  1084 void CWmfReadCodec::DoProcess0010L(TInt aFunction,TUint16* aArgPtr)
       
  1085 	{
       
  1086 	// Not supported:
       
  1087 	// 0x0107 - SETSTRETCHBLTMODE
       
  1088 
       
  1089 	switch (aFunction)
       
  1090 		{
       
  1091 	case 0x0108: // SETTEXTCHAREXTRA
       
  1092 		{
       
  1093 		const TInt extraSpace = LogicalSizeToDeviceSize(aArgPtr[0],ETrue);
       
  1094 		if (extraSpace != 0)
       
  1095 			{
       
  1096 			const TInt numChars = KMaxTInt / extraSpace; // Choose a suitably high number of chars to keep the char spacing going
       
  1097 			iGc->SetCharJustification(extraSpace * numChars,numChars);
       
  1098 			}
       
  1099 		}
       
  1100 		break;
       
  1101 	case 0x0127: // RESTOREDC
       
  1102 		{
       
  1103 		const TInt savedGcCount = iSavedGcStack.Count();
       
  1104 		if (savedGcCount > 0)
       
  1105 			{
       
  1106 			delete iGc;
       
  1107 			iGc = iSavedGcStack[savedGcCount - 1];
       
  1108 			iSavedGcStack.Remove(savedGcCount - 1);
       
  1109 			ASSERT(iGc);
       
  1110 			}
       
  1111 		}
       
  1112 		break;
       
  1113 	case 0x012a: // INVERTREGION
       
  1114 		{
       
  1115 		CGraphicsObject* object = GraphicsObject(aArgPtr[0]);
       
  1116 		if (object && object->Type() == KWmfGraphicsObjectRegion)
       
  1117 			{
       
  1118 			CRectRegion* rectRgn = STATIC_CAST(CRectRegion*,object);
       
  1119 			CFbsBitGcWrapper* gc = CloneGcL();
       
  1120 
       
  1121 			gc->SetPenStyle(CGraphicsContext::ENullPen);
       
  1122 			gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1123 			gc->SetBrushColor(KRgbWhite);
       
  1124 			gc->SetDrawMode(CGraphicsContext::EDrawModeXOR);
       
  1125 			gc->DrawRect(rectRgn->iRect);
       
  1126 
       
  1127 			delete gc;
       
  1128 			}
       
  1129 		}
       
  1130 		break;
       
  1131 	default:
       
  1132 		break;
       
  1133 		}
       
  1134 	}
       
  1135 
       
  1136 void CWmfReadCodec::DoProcess0011L(TInt aFunction,TUint16* aArgPtr)
       
  1137 	{
       
  1138 	switch (aFunction)
       
  1139 		{
       
  1140 	case 0x012e: // SETTEXTALIGN
       
  1141 		iTextAlignFlags = aArgPtr[0];
       
  1142 		break;
       
  1143 	case 0x012b: // PAINTREGION
       
  1144 		{
       
  1145 		CGraphicsObject* object = GraphicsObject(aArgPtr[0]);
       
  1146 		if (object && object->Type() == KWmfGraphicsObjectRegion)
       
  1147 			{
       
  1148 			CRectRegion* rectRgn = STATIC_CAST(CRectRegion*,object);
       
  1149 			CFbsBitGcWrapper* gc = CloneGcL();
       
  1150 
       
  1151 			gc->SetPenStyle(CGraphicsContext::ENullPen);
       
  1152 			gc->DrawRect(rectRgn->iRect);
       
  1153 
       
  1154 			delete gc;
       
  1155 			}
       
  1156 		}
       
  1157 		break;
       
  1158 	case 0x012c: // SELECTCLIPREGION
       
  1159 	case 0x012d: // SELECTOBJECT
       
  1160 		{
       
  1161 		CGraphicsObject* object = GraphicsObject(aArgPtr[0]);
       
  1162 		if (object)
       
  1163 			object->Apply(iGc);
       
  1164 		}
       
  1165 		break;
       
  1166 	default:
       
  1167 		break;
       
  1168 		}
       
  1169 	}
       
  1170 
       
  1171 void CWmfReadCodec::DoProcess0100L(TInt aFunction,TUint16* aArgPtr)
       
  1172 	{
       
  1173 	// Not supported:
       
  1174 	// 0x0139 - RESIZEPALETTE
       
  1175 
       
  1176 	switch (aFunction)
       
  1177 		{
       
  1178 	case 0x01f9: // CREATEPATTERNBRUSH
       
  1179 	case 0x0142: // DIBCREATEPATTERNBRUSH
       
  1180 		{
       
  1181 		CPatternBrush* patternBrush = CPatternBrush::NewL();
       
  1182 
       
  1183 		TInt err = ExtractDib(aArgPtr + 2, patternBrush);
       
  1184 		if (err == KErrNone)
       
  1185 			AddGraphicsObject(patternBrush);
       
  1186 		else
       
  1187 			{
       
  1188 			// Coverity reports a leave_without_push error here because
       
  1189 			// CPatternBrush has a CFbsBitmap member which can panic
       
  1190 			// during its destructor. The panic has a trapped leave and
       
  1191 			// for some reason coverity does not recognise it.
       
  1192 			// Mark as false positive
       
  1193 			// coverity[leave_without_push : FALSE]
       
  1194 			delete patternBrush;
       
  1195 
       
  1196 			if (err == KErrNotSupported) // Ignore KErrNotSupported
       
  1197 				AddGraphicsObject(new(ELeave) CDummyBrush); // Create the object to maintain the handle list
       
  1198 			else
       
  1199 				User::Leave(err);
       
  1200 			}
       
  1201 		}
       
  1202 		break;
       
  1203 	case 0x01f0: // DELETEOBJECT
       
  1204 		RemoveGraphicsObject(aArgPtr[0]);
       
  1205 		break;
       
  1206 	case 0x0201: // SETBKCOLOR
       
  1207 		iGc->SetBackgroundColor(ExtractColor(aArgPtr));
       
  1208 		break;
       
  1209 	default:
       
  1210 		break;
       
  1211 		}
       
  1212 	}
       
  1213 
       
  1214 void CWmfReadCodec::DoProcess0101L(TInt aFunction,TUint16* aArgPtr)
       
  1215 	{
       
  1216 	switch (aFunction)
       
  1217 		{
       
  1218 	case 0x0209: // SETTEXTCOLOR
       
  1219 		iGc->SetTextColor(ExtractColor(aArgPtr));
       
  1220 		break;
       
  1221 	case 0x020a: // SETTEXTJUSTIFICATION
       
  1222 		iGc->SetWordJustification(LogicalSizeToDeviceSize(aArgPtr[1],ETrue),aArgPtr[0]);
       
  1223 		break;
       
  1224 	case 0x020b: // SETWINDOWORG
       
  1225 		iWindowOrg.SetXY(REINTERPRET_CAST(TInt16*,aArgPtr)[1],REINTERPRET_CAST(TInt16*,aArgPtr)[0]);
       
  1226 		break;
       
  1227 	case 0x020c: // SETWINDOWEXT
       
  1228 		iWindowExt.SetSize(REINTERPRET_CAST(TInt16*,aArgPtr)[1],REINTERPRET_CAST(TInt16*,aArgPtr)[0]);
       
  1229 		break;
       
  1230 	default:
       
  1231 		break;
       
  1232 		}
       
  1233 	}
       
  1234 
       
  1235 void CWmfReadCodec::DoProcess0110L(TInt aFunction,TUint16* aArgPtr)
       
  1236 	{
       
  1237 	switch (aFunction)
       
  1238 		{
       
  1239 	case 0x020d: // SETVIEWPORTORG
       
  1240 		if (iIgnoreViewportMetaData == EFalse)
       
  1241 			iViewportOrg.SetXY(REINTERPRET_CAST(TInt16*,aArgPtr)[1],REINTERPRET_CAST(TInt16*,aArgPtr)[0]);
       
  1242 		break;
       
  1243 	case 0x020e: // SETVIEWPORTEXT
       
  1244 		if (iIgnoreViewportMetaData == EFalse)
       
  1245 			iViewportExt.SetSize(REINTERPRET_CAST(TInt16*,aArgPtr)[1],REINTERPRET_CAST(TInt16*,aArgPtr)[0]);
       
  1246 		break;
       
  1247 	case 0x020f: // OFFSETWINDOWORG
       
  1248 		iWindowOrg += TPoint(REINTERPRET_CAST(TInt16*,aArgPtr)[1],REINTERPRET_CAST(TInt16*,aArgPtr)[0]);
       
  1249 		break;
       
  1250 	case 0x0211: // OFFSETVIEWPORTORG
       
  1251 		if (iIgnoreViewportMetaData == EFalse)
       
  1252 			iViewportOrg += TPoint(REINTERPRET_CAST(TInt16*,aArgPtr)[1],REINTERPRET_CAST(TInt16*,aArgPtr)[0]);
       
  1253 		break;
       
  1254 	default:
       
  1255 		break;
       
  1256 		}
       
  1257 	}
       
  1258 
       
  1259 void CWmfReadCodec::DoProcess0111L(TInt aFunction,TUint16* aArgPtr)
       
  1260 	{
       
  1261 	// Not supported:
       
  1262 	// 0x0220 - OFFSETCLIPRGN
       
  1263 
       
  1264 	switch (aFunction)
       
  1265 		{
       
  1266 	case 0x0213: // LINETO
       
  1267 		iGc->DrawLineTo(ExtractPoint(aArgPtr,EFalse));
       
  1268 		break;
       
  1269 	case 0x0214: // MOVETO
       
  1270 		iGc->MoveTo(ExtractPoint(aArgPtr,EFalse));
       
  1271 		break;
       
  1272 	case 0x0228: // FILLREGION
       
  1273 		{
       
  1274 		CGraphicsObject* regionObject = GraphicsObject(aArgPtr[0]);
       
  1275 		CGraphicsObject* brushObject = GraphicsObject(aArgPtr[1]);
       
  1276 		if (regionObject && (regionObject->Type() == KWmfGraphicsObjectRegion)
       
  1277 			&& brushObject && ((brushObject->Type() == KWmfGraphicsObjectBrush) || (brushObject->Type() == KWmfGraphicsObjectPatternBrush)))
       
  1278 			{
       
  1279 			CRectRegion* rectRgn = STATIC_CAST(CRectRegion*,regionObject);
       
  1280 			CFbsBitGcWrapper* gc = CloneGcL();
       
  1281 
       
  1282 			gc->SetPenStyle(CGraphicsContext::ENullPen);
       
  1283 			brushObject->Apply(iGc);
       
  1284 			gc->DrawRect(rectRgn->iRect);
       
  1285 
       
  1286 			delete gc;
       
  1287 			}
       
  1288 		}
       
  1289 		break;
       
  1290 	default:
       
  1291 		break;
       
  1292 		}
       
  1293 	}
       
  1294 
       
  1295 void CWmfReadCodec::DoProcess1000L(TInt aFunction,TUint16* aArgPtr)
       
  1296 	{
       
  1297 	// Not supported:
       
  1298 	// 0x0231 - SETMAPPERFLAGS
       
  1299 	// 0x0234 - SELECTPALETTE
       
  1300 
       
  1301 	switch (aFunction)
       
  1302 		{
       
  1303 	case 0x02fa: // CREATEPENINDIRECT
       
  1304 		{
       
  1305 		TInt style = aArgPtr[0];
       
  1306 
       
  1307 		CPen* pen = NULL;
       
  1308 
       
  1309 		if (iDefaultPen)
       
  1310 			{
       
  1311 			pen = iDefaultPen;
       
  1312 			iDefaultPen = NULL;
       
  1313 			}
       
  1314 		else
       
  1315 			pen = new(ELeave) CPen;
       
  1316 
       
  1317 		switch (style)
       
  1318 			{
       
  1319 		case 0: // PS_SOLID
       
  1320 			pen->iStyle = CGraphicsContext::ESolidPen;
       
  1321 			break;
       
  1322 		case 1: // PS_DASH
       
  1323 			pen->iStyle = CGraphicsContext::EDashedPen;
       
  1324 			break;
       
  1325 		case 2: // PS_DOT
       
  1326 			pen->iStyle = CGraphicsContext::EDottedPen;
       
  1327 			break;
       
  1328 		case 3: // PS_DASHDOT
       
  1329 			pen->iStyle = CGraphicsContext::EDotDashPen;
       
  1330 			break;
       
  1331 		case 4: // PS_DASHDOTDOT
       
  1332 			pen->iStyle = CGraphicsContext::EDotDotDashPen;
       
  1333 			break;
       
  1334 		case 5: // PS_NULL
       
  1335 			pen->iStyle = CGraphicsContext::ENullPen;
       
  1336 			break;
       
  1337 		case 6: // PS_INSIDEFRAME
       
  1338 		case 7: // PS_USERSTYLE
       
  1339 		case 8: // PS_ALTERNATE
       
  1340 		default:
       
  1341 			pen->iStyle = CGraphicsContext::ESolidPen;
       
  1342 			break;
       
  1343 			}
       
  1344 		pen->iSize.iWidth = Max(LogicalSizeToDeviceSize(aArgPtr[1],ETrue),1);
       
  1345 		pen->iSize.iHeight = Max(LogicalSizeToDeviceSize(aArgPtr[1],EFalse),1);
       
  1346 		pen->iColor = ExtractColor(aArgPtr + 3);
       
  1347 
       
  1348 		AddGraphicsObject(pen);
       
  1349 		}
       
  1350 		break;
       
  1351 	case 0x02fb: // CREATEFONTINDIRECT
       
  1352 		{
       
  1353 		const TInt height = Abs(TInt((TInt16)aArgPtr[0]));
       
  1354 		const TInt weight = Abs(TInt(aArgPtr[4]));
       
  1355 		const TInt italic = Abs(aArgPtr[5] & 0xff);
       
  1356 		const TInt underline = Abs(aArgPtr[5] >> 8);
       
  1357 		const TInt strikeOut = Abs(aArgPtr[6] & 0xff);
       
  1358 		const TInt pitchAndFamily = Abs(aArgPtr[8] >> 8);
       
  1359 
       
  1360 		TFontSpec fontSpec;
       
  1361 		fontSpec.iTypeface.SetIsProportional(((pitchAndFamily & 3) != KFontFixedPitch));
       
  1362 
       
  1363 		switch (pitchAndFamily >> 4)
       
  1364 			{
       
  1365 		case KFontFamilyRoman:
       
  1366 		case KFontFamilyScript:
       
  1367 		case KFontFamilyDecorative:
       
  1368 			fontSpec.iTypeface.SetIsProportional(ETrue);
       
  1369 			fontSpec.iTypeface.SetIsSerif(ETrue);
       
  1370 			break;
       
  1371 		case KFontFamilySwiss:
       
  1372 			fontSpec.iTypeface.SetIsProportional(ETrue);
       
  1373 			fontSpec.iTypeface.SetIsSerif(EFalse);
       
  1374 			break;
       
  1375 		case KFontFamilyMono:
       
  1376 			fontSpec.iTypeface.SetIsProportional(EFalse);
       
  1377 			fontSpec.iTypeface.SetIsSerif(ETrue);
       
  1378 			break;
       
  1379 		default:
       
  1380 			break;
       
  1381 			}
       
  1382 
       
  1383 		const TInt fontHeight = LogicalSizeToDeviceSize(height,EFalse);
       
  1384 		fontSpec.iHeight = Max(fontHeight,1);
       
  1385 
       
  1386 		if (weight > KFontNormalWeightLimit)
       
  1387 			fontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
  1388 		if (italic)
       
  1389 			fontSpec.iFontStyle.SetPosture(EPostureItalic);
       
  1390 
       
  1391 		CFbsFont* font = NULL;
       
  1392 		User::LeaveIfError(iDevice->GetNearestFontInPixels(font,fontSpec));
       
  1393 
       
  1394 		CFontObject* fontObject = new CFontObject(*iDevice,*font,underline,strikeOut);
       
  1395 
       
  1396 		if (!fontObject)
       
  1397 			{
       
  1398 			iDevice->ReleaseFont(font);
       
  1399 			User::Leave(KErrNoMemory);
       
  1400 			}
       
  1401 		else
       
  1402 			AddGraphicsObject(fontObject);
       
  1403 		}
       
  1404 		break;
       
  1405 	case 0x02fc: // CREATEBRUSHINDIRECT
       
  1406 		{
       
  1407 		TInt style = aArgPtr[0];
       
  1408 		TInt hatch = aArgPtr[3];
       
  1409 
       
  1410 		CBrush* brush = NULL;
       
  1411 
       
  1412 		if (iDefaultBrush)
       
  1413 			{
       
  1414 			brush = iDefaultBrush;
       
  1415 			iDefaultBrush = NULL;
       
  1416 			}
       
  1417 		else
       
  1418 			brush = new(ELeave) CBrush;
       
  1419 
       
  1420 		switch (style)
       
  1421 			{
       
  1422 		case 0: // BS_SOLID
       
  1423 			brush->iStyle = CGraphicsContext::ESolidBrush;
       
  1424 			break;
       
  1425 		case 1: // BS_NULL, BS_HOLLOW           
       
  1426 			brush->iStyle = CGraphicsContext::ENullBrush;
       
  1427 			break;
       
  1428 		case 2: // BS_HATCHED
       
  1429 			switch (hatch)
       
  1430 				{
       
  1431 			case 0: // HS_HORIZONTAL
       
  1432 				brush->iStyle = CGraphicsContext::EHorizontalHatchBrush;
       
  1433 				break;
       
  1434 			case 1: // HS_VERTICAL
       
  1435 				brush->iStyle = CGraphicsContext::EVerticalHatchBrush;
       
  1436 				break;
       
  1437 			case 2: // HS_FDIAGONAL
       
  1438 				brush->iStyle = CGraphicsContext::EForwardDiagonalHatchBrush;
       
  1439 				break;
       
  1440 			case 3: // HS_BDIAGONAL
       
  1441 				brush->iStyle = CGraphicsContext::ERearwardDiagonalHatchBrush;
       
  1442 				break;
       
  1443 			case 4: // HS_CROSS
       
  1444 				brush->iStyle = CGraphicsContext::ESquareCrossHatchBrush;
       
  1445 				break;
       
  1446 			case 5: // HS_DIAGCROSS
       
  1447 				brush->iStyle = CGraphicsContext::EDiamondCrossHatchBrush;
       
  1448 				break;
       
  1449 			default:
       
  1450 				brush->iStyle = CGraphicsContext::ESolidBrush;
       
  1451 				break;
       
  1452 				}
       
  1453 			break;
       
  1454 		case 3: // BS_PATTERN
       
  1455 		case 4: // BS_INDEXED
       
  1456 		case 5: // BS_DIBPATTERN
       
  1457 		case 6: // BS_DIBPATTERNPT
       
  1458 		case 7: // BS_PATTERN8X8
       
  1459 		case 8: // BS_DIBPATTERN8X8
       
  1460 		case 9: // BS_MONOPATTERN
       
  1461 		default:
       
  1462 			brush->iStyle = CGraphicsContext::ESolidBrush;
       
  1463 			break;
       
  1464 			}
       
  1465 		brush->iColor = ExtractColor(aArgPtr + 1);
       
  1466 
       
  1467 		AddGraphicsObject(brush);
       
  1468 		}
       
  1469 		break;
       
  1470 	default:
       
  1471 		break;
       
  1472 		}
       
  1473 	}
       
  1474 
       
  1475 void CWmfReadCodec::DoProcess1001L(TInt aFunction,TUint16* aArgPtr)
       
  1476 	{
       
  1477 	switch (aFunction)
       
  1478 		{
       
  1479 	case 0x0324: // POLYGON
       
  1480 	case 0x0325: // POLYLINE
       
  1481 		{
       
  1482 		//check if the record size sufficient for polygon/polyline record.
       
  1483 		if(iRecordSizeInWords < KWmfPolyRecordSizeInWords)
       
  1484 			{
       
  1485 			User::Leave(KErrCorrupt);
       
  1486 			}
       
  1487 
       
  1488 		const TInt numPoints = aArgPtr[0];
       
  1489 		if (numPoints <= 0)
       
  1490 			break;
       
  1491 
       
  1492 		//check if the entire data about polygon/polyline is within the record.Each point needs 2 words
       
  1493 		if(iRecordSizeInWords < (KWmfPolyRecordSizeInWords  + (numPoints * 2)))
       
  1494 			{
       
  1495 			User::Leave(KErrCorrupt);
       
  1496 			}
       
  1497 
       
  1498 		if (numPoints > iPointArrayEntries)
       
  1499 			{
       
  1500 			delete[] iPointArray;
       
  1501 			iPointArray = NULL;
       
  1502 			iPointArray = new(ELeave) TPoint[numPoints];
       
  1503 			iPointArrayEntries = numPoints;
       
  1504 			}
       
  1505 
       
  1506 		TUint16* pointPtr = aArgPtr + 1;
       
  1507 		TPoint* pointArrayPtr = iPointArray;
       
  1508 
       
  1509 		for (TInt count = 0; count < numPoints; count++)
       
  1510 			{
       
  1511 			*pointArrayPtr++ = ExtractPoint(pointPtr,ETrue);
       
  1512 			pointPtr += 2;
       
  1513 			}
       
  1514 
       
  1515 		if (aFunction == 0x0324) // POLYGON
       
  1516 			iGc->DrawPolygonL(iPointArray,numPoints,iFillRule);
       
  1517 		else // POLYLINE
       
  1518 			iGc->DrawPolyLine(iPointArray, numPoints);
       
  1519 		}
       
  1520 		break;
       
  1521 	case 0x0410: // SCALEWINDOWEXT
       
  1522 		{
       
  1523 		TInt xMult = aArgPtr[3];
       
  1524 		TInt xDiv = aArgPtr[2];
       
  1525 		TInt yMult = aArgPtr[1];
       
  1526 		TInt yDiv = aArgPtr[0];
       
  1527 
       
  1528 		if (xDiv != 0)
       
  1529 			iWindowExt.iWidth = (iWindowExt.iWidth * xMult) / xDiv;
       
  1530 		if (yDiv != 0)
       
  1531 			iWindowExt.iHeight = (iWindowExt.iHeight * yMult) / yDiv;
       
  1532 		}
       
  1533 		break;
       
  1534 	case 0x0412: // SCALEVIEWPORTEXT
       
  1535 		{
       
  1536 		if (iIgnoreViewportMetaData == EFalse)
       
  1537 			{
       
  1538 			TInt xMult = aArgPtr[3];
       
  1539 			TInt xDiv = aArgPtr[2];
       
  1540 			TInt yMult = aArgPtr[1];
       
  1541 			TInt yDiv = aArgPtr[0];
       
  1542 	
       
  1543 			if (xDiv != 0)
       
  1544 				iViewportExt.iWidth = (iViewportExt.iWidth * xMult) / xDiv;
       
  1545 			if (yDiv != 0)
       
  1546 				iViewportExt.iHeight = (iViewportExt.iHeight * yMult) / yDiv;
       
  1547 			}
       
  1548 		}
       
  1549 		break;
       
  1550 	default:
       
  1551 		break;
       
  1552 		}
       
  1553 	}
       
  1554 
       
  1555 void CWmfReadCodec::DoProcess1010L(TInt aFunction,TUint16* aArgPtr)
       
  1556 	{
       
  1557 	// Not supported:
       
  1558 	// 0x0415 - EXCLUDECLIPRECT
       
  1559 	// 0x0419 - FLOODFILL
       
  1560 
       
  1561 	switch (aFunction)
       
  1562 		{
       
  1563 	case 0x0416: // INTERSECTCLIPRECT
       
  1564 		{
       
  1565 		iIntersectRegion.Clear();
       
  1566 		iIntersectRegion.AddRect(ExtractRect(aArgPtr));
       
  1567 
       
  1568 		iIntersectRegion.Intersect(iClipRegion);
       
  1569 		iGc->SetClippingRegion(&iIntersectRegion);
       
  1570 		}
       
  1571 		break;
       
  1572 	case 0x0418: // ELLIPSE
       
  1573 		iGc->DrawEllipse(ExtractRect(aArgPtr));
       
  1574 		break;
       
  1575 	default:
       
  1576 		break;
       
  1577 		}
       
  1578 	}
       
  1579 
       
  1580 void CWmfReadCodec::DoProcess1011L(TInt aFunction,TUint16* aArgPtr)
       
  1581 	{
       
  1582 	// Not supported:
       
  1583 	// 0x0436 - ANIMATEPALETTE
       
  1584 
       
  1585 	switch (aFunction)
       
  1586 		{
       
  1587 	case 0x041b: // RECTANGLE
       
  1588 		iGc->DrawRect(ExtractRect(aArgPtr));
       
  1589 		break;
       
  1590 	case 0x041f: // SETPIXEL
       
  1591 		{
       
  1592 		CFbsBitGcWrapper* gc = CloneGcL();
       
  1593 
       
  1594 		gc->SetPenColor(ExtractColor(aArgPtr));
       
  1595 		gc->Plot(ExtractPoint(aArgPtr + 2,EFalse));
       
  1596 
       
  1597 		delete gc;
       
  1598 		}
       
  1599 		break;
       
  1600 	case 0x0429: // FRAMEREGION
       
  1601 		{
       
  1602 		CGraphicsObject* object1 = GraphicsObject(aArgPtr[0]);
       
  1603 		CGraphicsObject* object2 = GraphicsObject(aArgPtr[1]);
       
  1604 
       
  1605 		if (object1 && object1->Type() == KWmfGraphicsObjectRegion &&
       
  1606 			object2 && ((object2->Type() == KWmfGraphicsObjectBrush) || (object2->Type() == KWmfGraphicsObjectPatternBrush)))
       
  1607 			{
       
  1608 			CRectRegion* region = STATIC_CAST(CRectRegion*,object1);
       
  1609 			CBrush* brush = STATIC_CAST(CBrush*,object2);
       
  1610 
       
  1611 			if (brush->iStyle == CGraphicsContext::ESolidBrush)
       
  1612 				{
       
  1613 				CFbsBitGcWrapper* gc = CloneGcL();
       
  1614 
       
  1615 				gc->SetPenStyle(CGraphicsContext::ESolidPen);
       
  1616 				gc->SetPenColor(brush->iColor);
       
  1617 				gc->SetPenSize(TSize(aArgPtr[3],aArgPtr[2]));
       
  1618 				gc->SetBrushStyle(CGraphicsContext::ENullBrush);
       
  1619 
       
  1620 				gc->DrawRect(region->iRect);
       
  1621 
       
  1622 				delete gc;
       
  1623 				}
       
  1624 			}
       
  1625 		}
       
  1626 		break;
       
  1627 	default:
       
  1628 		break;
       
  1629 		}
       
  1630 	}
       
  1631 
       
  1632 void CWmfReadCodec::DoProcess1100L(TInt aFunction,TUint16* aArgPtr)
       
  1633 	{
       
  1634 	// Not supported:
       
  1635 	// 0x0548 - EXTFLOODFILL
       
  1636 
       
  1637 	switch (aFunction)
       
  1638 		{
       
  1639 	case 0x0521: // TEXTOUT
       
  1640 		{
       
  1641 		CFbsBitGcWrapper* gc = CloneGcL();
       
  1642 		CleanupStack::PushL(gc);
       
  1643 
       
  1644 		gc->SetPenStyle(CGraphicsContext::ESolidPen);
       
  1645 		gc->SetTextPenColor();
       
  1646 		if (iBkModeOpaque)
       
  1647 			gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1648 		else
       
  1649 			gc->SetBrushStyle(CGraphicsContext::ENullBrush);
       
  1650 		
       
  1651 		if(iRecordSizeInWords < KMinTextoutRecordSizeInWords)
       
  1652 			{
       
  1653 			// Invalid Textout record.
       
  1654 			User::Leave(KErrCorrupt);
       
  1655 			}
       
  1656 		//read the count of text-string bytes. The text is padded if necessary.
       
  1657 		//The count doesn't include the padded byte.
       
  1658 		const TInt count = *aArgPtr++;
       
  1659 		//convert into words
       
  1660 		TUint stringWords = (count+1) / 2;
       
  1661 		if ((KMinTextoutRecordSizeInWords + stringWords) > iRecordSizeInWords)
       
  1662 			{
       
  1663 			// Invalid Textout record.
       
  1664 			User::Leave(KErrCorrupt);
       
  1665 			}
       
  1666 		const TPtrC8 text((TUint8*)aArgPtr,count);
       
  1667 
       
  1668 		DrawTextL(text, ExtractPoint(aArgPtr + stringWords, EFalse), gc);
       
  1669 
       
  1670 		CleanupStack::PopAndDestroy(gc);
       
  1671 		}
       
  1672 		break;
       
  1673 	case 0x0538: // POLYPOLYGON
       
  1674 		{
       
  1675 		//check if the record size sufficient for polygon/polyline record.
       
  1676 		if(iRecordSizeInWords < KWmfPolyRecordSizeInWords)
       
  1677 			{
       
  1678 			User::Leave(KErrCorrupt);
       
  1679 			}
       
  1680 		const TInt numPolygons = *aArgPtr++;
       
  1681 		if (numPolygons <= 0)
       
  1682 			break;
       
  1683 		
       
  1684 		//check if the words that contain the number of points for each polygon are within the record
       
  1685 		if(iRecordSizeInWords < (KWmfPolyRecordSizeInWords  + numPolygons))
       
  1686 			{
       
  1687 			User::Leave(KErrCorrupt);
       
  1688 			}
       
  1689 		
       
  1690 		//index of word that has point for polygons
       
  1691 		TInt pointWord = KWmfPolyRecordSizeInWords  + numPolygons;
       
  1692 		TUint16* pointArgs = aArgPtr + numPolygons;
       
  1693 		for (TInt polygonIndex = 0; polygonIndex < numPolygons; polygonIndex++)
       
  1694 			{
       
  1695 			const TInt numPoints = aArgPtr[polygonIndex];
       
  1696 			if (numPoints <= 0)
       
  1697 				break;
       
  1698 
       
  1699 			//check if the point values are available within the record; each point needs 2 words
       
  1700 			pointWord += numPoints * 2;
       
  1701 			if(iRecordSizeInWords < pointWord )
       
  1702 				{
       
  1703 				User::Leave(KErrCorrupt);
       
  1704 				}
       
  1705 
       
  1706 			if (numPoints > iPointArrayEntries)
       
  1707 				{
       
  1708 				delete[] iPointArray;
       
  1709 				iPointArray = NULL;
       
  1710 				iPointArray = new(ELeave) TPoint[numPoints];
       
  1711 				iPointArrayEntries = numPoints;
       
  1712 				}
       
  1713 
       
  1714 			TPoint* pointArrayPtr = iPointArray;
       
  1715 			for (TInt pointIndex = 0; pointIndex < numPoints; pointIndex++)
       
  1716 				{
       
  1717 				*pointArrayPtr++ = ExtractPoint(pointArgs,ETrue);
       
  1718 				pointArgs += 2;
       
  1719 				}
       
  1720 
       
  1721 			iGc->DrawPolygonL(iPointArray,numPoints,iFillRule);
       
  1722 			}
       
  1723 		}
       
  1724 		break;
       
  1725 	case 0x061c: // ROUNDRECT
       
  1726 		iGc->DrawRoundRect(ExtractRect(aArgPtr + 2),ExtractPoint(aArgPtr,EFalse).AsSize());
       
  1727 		break;
       
  1728 	case 0x061d: // PATBLT
       
  1729 		{
       
  1730 		TInt left = LogicalCoordToDeviceCoord(aArgPtr[5],ETrue);
       
  1731 		TInt top = LogicalCoordToDeviceCoord(aArgPtr[4],EFalse);
       
  1732 		TInt width = LogicalSizeToDeviceSize(aArgPtr[3],ETrue);
       
  1733 		TInt height = LogicalSizeToDeviceSize(aArgPtr[2],EFalse);
       
  1734 
       
  1735 		CFbsBitGcWrapper* gc = CloneGcL();
       
  1736 
       
  1737 		gc->SetPenStyle(CGraphicsContext::ENullPen);
       
  1738 		SetROP3(gc, aArgPtr[0] | (aArgPtr[1] << 16));
       
  1739 		gc->DrawRect(TRect(TPoint(left,top),TSize(width,height)));
       
  1740 
       
  1741 		delete gc;
       
  1742 		}
       
  1743 		break;
       
  1744 	default:
       
  1745 		break;
       
  1746 		}
       
  1747 	}
       
  1748 
       
  1749 void CWmfReadCodec::DoProcess1101L(TInt aFunction,TUint16* aArgPtr)
       
  1750 	{
       
  1751 	// Not supported:
       
  1752 	// 0x0626 - ESCAPE
       
  1753 
       
  1754 	switch (aFunction)
       
  1755 		{
       
  1756 	case 0x06ff: // CREATEREGION
       
  1757 		{
       
  1758 		TInt left = LogicalCoordToDeviceCoord(aArgPtr[7],ETrue);
       
  1759 		TInt top = LogicalCoordToDeviceCoord(aArgPtr[8],EFalse);
       
  1760 		TInt right = LogicalCoordToDeviceCoord(aArgPtr[9],ETrue);
       
  1761 		TInt bottom = LogicalCoordToDeviceCoord(aArgPtr[10],EFalse);
       
  1762 
       
  1763 		AddGraphicsObject(new(ELeave) CRectRegion(*iDevice, iClipRegion, left, top, right, bottom));
       
  1764 		}
       
  1765 		break;
       
  1766 	case 0x0817: // ARC
       
  1767 		iGc->DrawArc(ExtractRect(aArgPtr + 4),ExtractPoint(aArgPtr + 2,EFalse),ExtractPoint(aArgPtr,EFalse));
       
  1768 		break;
       
  1769 	case 0x081a: // PIE
       
  1770 		iGc->DrawPie(ExtractRect(aArgPtr + 4),ExtractPoint(aArgPtr + 2,EFalse),ExtractPoint(aArgPtr,EFalse));
       
  1771 		break;
       
  1772 	default:
       
  1773 		break;
       
  1774 		}
       
  1775 	}
       
  1776 
       
  1777 void CWmfReadCodec::DoProcess1110L(TInt aFunction,TUint16* aArgPtr)
       
  1778 	{
       
  1779 	// Not supported:
       
  1780 	// 0x0830 - CHORD
       
  1781 	// 0x0922 - BITBLT
       
  1782 	// 0x0940 - DIBBITBLT
       
  1783 
       
  1784 	switch (aFunction)
       
  1785 		{
       
  1786 	case 0x0a32: // EXTTEXTOUT
       
  1787 		{
       
  1788 		CFbsBitGcWrapper* gc = CloneGcL();
       
  1789 		CleanupStack::PushL(gc);
       
  1790 
       
  1791 		gc->SetPenStyle(CGraphicsContext::ESolidPen);
       
  1792 		gc->SetTextPenColor();
       
  1793 		if (iBkModeOpaque)
       
  1794 			gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1795 		else
       
  1796 			gc->SetBrushStyle(CGraphicsContext::ENullBrush);
       
  1797 
       
  1798 		const TPoint pos(ExtractPoint(aArgPtr,EFalse));
       
  1799 		const TInt count = aArgPtr[2];
       
  1800 		const TInt flag = aArgPtr[3];
       
  1801 
       
  1802 		aArgPtr += (flag & KExtTextOutFlagClipped) ? 8 : 4;
       
  1803 
       
  1804 		const TPtrC8 text((TUint8*)aArgPtr,count);
       
  1805 
       
  1806 		DrawTextL(text,pos,gc);
       
  1807 
       
  1808 		CleanupStack::PopAndDestroy(gc);
       
  1809 		}
       
  1810 		break;
       
  1811 	default:
       
  1812 		break;
       
  1813 		}
       
  1814 	}
       
  1815 
       
  1816 void CWmfReadCodec::DoProcess1111L(TInt aFunction,TUint16* aArgPtr)
       
  1817 	{
       
  1818 	// Not supported:
       
  1819 	// 0x0b23 - STRETCHBLT
       
  1820 	// 0x0d33 - SETDIBTODEV
       
  1821 
       
  1822 	switch (aFunction)
       
  1823 		{
       
  1824 	case 0x0b41: // DIBSTRETCHBLT
       
  1825 		{
       
  1826 		const TInt16* argPtr = (TInt16*)aArgPtr;
       
  1827 		const TInt srcX = argPtr[5];
       
  1828 		const TInt srcY = argPtr[4];
       
  1829 		const TInt srcWidth = argPtr[3];
       
  1830 		const TInt srcHeight = argPtr[2];
       
  1831 		const TInt dstX = LogicalCoordToDeviceCoord(argPtr[9],ETrue);
       
  1832 		const TInt dstY = LogicalCoordToDeviceCoord(argPtr[8],EFalse);
       
  1833 		const TInt dstWidth = LogicalSizeToDeviceSize(argPtr[7],ETrue);
       
  1834 		const TInt dstHeight = LogicalSizeToDeviceSize(argPtr[6],EFalse);
       
  1835 
       
  1836 		CFbsBitmap* dib = new(ELeave) CFbsBitmap;
       
  1837 		TInt err = ExtractDib(aArgPtr + 10, dib);
       
  1838 
       
  1839 		CleanupStack::PushL(dib);
       
  1840 		if (err == KErrNone)
       
  1841 			{
       
  1842 			const TRect srcRect(TPoint(srcX,srcY),TSize(srcWidth,srcHeight));
       
  1843 			const TRect dstRect(TPoint(dstX,dstY),TSize(dstWidth,dstHeight));
       
  1844 
       
  1845 			iGc->DrawBitmap(dstRect,dib,srcRect);
       
  1846 			}
       
  1847 		else if (err != KErrNotSupported) // Ignore KErrNotSupported
       
  1848 			User::Leave(err);
       
  1849 
       
  1850 		CleanupStack::PopAndDestroy(dib);
       
  1851 		}
       
  1852 		break;
       
  1853 	case 0x0f43: // STRETCHDIB
       
  1854 		{
       
  1855 		const TInt16* argPtr = (TInt16*)aArgPtr;
       
  1856 		const TInt srcX = argPtr[6];
       
  1857 		const TInt srcY = argPtr[5];
       
  1858 		const TInt srcWidth = argPtr[4];
       
  1859 		const TInt srcHeight = argPtr[3];
       
  1860 		const TInt dstX = LogicalCoordToDeviceCoord(argPtr[10],ETrue);
       
  1861 		const TInt dstY = LogicalCoordToDeviceCoord(argPtr[9],EFalse);
       
  1862 		const TInt dstWidth = LogicalSizeToDeviceSize(argPtr[8],ETrue);
       
  1863 		const TInt dstHeight = LogicalSizeToDeviceSize(argPtr[7],EFalse);
       
  1864 
       
  1865 		CFbsBitmap* dib = new(ELeave) CFbsBitmap;
       
  1866 		TInt err = ExtractDib(aArgPtr + 11, dib);
       
  1867 
       
  1868 		CleanupStack::PushL(dib);
       
  1869 		if (err == KErrNone)
       
  1870 			{
       
  1871 			const TRect srcRect(TPoint(srcX,srcY),TSize(srcWidth,srcHeight));
       
  1872 			const TRect dstRect(TPoint(dstX,dstY),TSize(dstWidth,dstHeight));
       
  1873 
       
  1874 			iGc->DrawBitmap(dstRect,dib,srcRect);
       
  1875 			}
       
  1876 		else if (err != KErrNotSupported) // Ignore KErrNotSupported
       
  1877 			User::Leave(err);
       
  1878 
       
  1879 		CleanupStack::PopAndDestroy(dib);
       
  1880 		}
       
  1881 		break;
       
  1882 	default:
       
  1883 		break;
       
  1884 		}
       
  1885 	}
       
  1886 
       
  1887 void CWmfReadCodec::DrawTextL(const TDesC8& aText, const TPoint& aPos, CFbsBitGcWrapper* aGc)
       
  1888 	{
       
  1889 	if(aText.Length()==0)
       
  1890 		return;
       
  1891 
       
  1892 	HBufC* unicodeText = HBufC::NewMaxLC(aText.Length());
       
  1893 	TPtr16 text = unicodeText->Des();
       
  1894 	text.Copy(aText);
       
  1895 
       
  1896 	TPoint pos(aPos);
       
  1897 	const CFbsFont* font = iGc->CurrentFont();
       
  1898 
       
  1899 	if (font)
       
  1900 		{
       
  1901 		const TInt textAlignHorz = iTextAlignFlags & KTextAlignMaskHorz;
       
  1902 		const TInt textAlignVert = iTextAlignFlags & KTextAlignMaskVert;
       
  1903 
       
  1904 		switch (textAlignHorz)
       
  1905 			{
       
  1906 		case KTextAlignFlagRight:
       
  1907 			pos.iX -= font->TextWidthInPixels(text);
       
  1908 			break;
       
  1909 		case KTextAlignFlagCenter:
       
  1910 			pos.iX -= font->TextWidthInPixels(text) / 2;
       
  1911 			break;
       
  1912 		default: // KTextAlignFlagLeft
       
  1913 			break;
       
  1914 			}
       
  1915 
       
  1916 		// rather than use font->AscentInPixels(), font->DescentInPixels(),
       
  1917 		// which don't include the height of accents etc, 
       
  1918 		// use the maximum possible ascent/decent instead
       
  1919 		TInt ascent;
       
  1920 		TInt descent;
       
  1921 		TOpenFontMetrics fontMetrics;
       
  1922 		if (font->IsOpenFont() && font->GetFontMetrics(fontMetrics))
       
  1923 			{
       
  1924 			ascent = fontMetrics.MaxHeight();
       
  1925 			descent = fontMetrics.MaxDepth();
       
  1926 			}
       
  1927 		else
       
  1928 			{
       
  1929 			ascent = font->AscentInPixels();
       
  1930 			descent = font->DescentInPixels();
       
  1931 			}
       
  1932 
       
  1933 		switch (textAlignVert)
       
  1934 			{
       
  1935 		case KTextAlignFlagBottom:
       
  1936 			pos.iY -= descent;
       
  1937 			break;
       
  1938 		case KTextAlignFlagBaseline:
       
  1939 			break;
       
  1940 		default: // KTextAlignFlagTop
       
  1941 			pos.iY += ascent;
       
  1942 			break;
       
  1943 			}
       
  1944 		aGc->DrawText(*unicodeText,pos);
       
  1945 		}
       
  1946 
       
  1947 	CleanupStack::PopAndDestroy(unicodeText);
       
  1948 	}
       
  1949 
       
  1950 void CWmfReadCodec::AddGraphicsObject(CGraphicsObject* aObject)
       
  1951 	{
       
  1952 	for (TInt index = 0; index < KWmfMaxGraphicsObjectCount; index++)
       
  1953 		{
       
  1954 		if (iGraphicsObject[index] == NULL)
       
  1955 			{
       
  1956 			iGraphicsObject[index] = aObject;
       
  1957 			return;
       
  1958 			}
       
  1959 		}
       
  1960 
       
  1961 	delete aObject; // No more space so throw the object away
       
  1962 	}
       
  1963 
       
  1964 CGraphicsObject* CWmfReadCodec::GraphicsObject(TInt aHandle)
       
  1965 	{
       
  1966 	if (aHandle < KWmfMaxGraphicsObjectCount)
       
  1967 		return iGraphicsObject[aHandle];
       
  1968 
       
  1969 	return NULL;
       
  1970 	}
       
  1971 
       
  1972 void CWmfReadCodec::RemoveGraphicsObject(TInt aHandle)
       
  1973 	{
       
  1974 	if (aHandle < KWmfMaxGraphicsObjectCount)
       
  1975 		{
       
  1976 		CGraphicsObject* object = iGraphicsObject[aHandle];
       
  1977 
       
  1978 		if (object)
       
  1979 			{
       
  1980 			if (object->Type() == KWmfGraphicsObjectPen && !iDefaultPen)
       
  1981 				iDefaultPen = STATIC_CAST(CPen*,object);
       
  1982 			else if (object->Type() == KWmfGraphicsObjectBrush && !iDefaultBrush)
       
  1983 				iDefaultBrush = STATIC_CAST(CBrush*,object);
       
  1984 			else
       
  1985 				delete object;
       
  1986 
       
  1987 			iGraphicsObject[aHandle] = NULL;
       
  1988 			}
       
  1989 		}
       
  1990 	}
       
  1991 
       
  1992 CFbsBitGcWrapper* CWmfReadCodec::CloneGcL()
       
  1993 	{
       
  1994 	CFbsBitGcWrapper* gcCopy;
       
  1995 	if (iMaskDevice)
       
  1996 		gcCopy = CFbsBitGcMaskWrapper::NewL(*iDevice, *iMaskDevice, static_cast<CFbsBitGcMaskWrapper*> (iGc));
       
  1997 	else
       
  1998 		gcCopy = CFbsBitGcWrapper::NewL(*iDevice, iGc);
       
  1999 
       
  2000 	return gcCopy;
       
  2001 	}
       
  2002 
       
  2003 TInt CWmfReadCodec::LogicalCoordToDeviceCoord(TInt aLogicalCoord,TBool aHorizontal)
       
  2004 	{
       
  2005 	if (aHorizontal)
       
  2006 		{
       
  2007 		if (iWindowExt.iWidth != 0)
       
  2008 			return ((aLogicalCoord - iWindowOrg.iX) * iViewportExt.iWidth / iWindowExt.iWidth) + iViewportOrg.iX;
       
  2009 		}
       
  2010 	else
       
  2011 		{
       
  2012 		if (iWindowExt.iHeight != 0)
       
  2013 			return ((aLogicalCoord - iWindowOrg.iY) * iViewportExt.iHeight / iWindowExt.iHeight) + iViewportOrg.iY;
       
  2014 		}
       
  2015 
       
  2016 	return 0;
       
  2017 	}
       
  2018 
       
  2019 TInt CWmfReadCodec::LogicalSizeToDeviceSize(TInt aLogicalSize,TBool aHorizontal)
       
  2020 	{
       
  2021 	if (aHorizontal)
       
  2022 		{
       
  2023 		if (iWindowExt.iWidth != 0)
       
  2024 			return aLogicalSize * iViewportExt.iWidth / iWindowExt.iWidth;
       
  2025 		}
       
  2026 	else
       
  2027 		{
       
  2028 		if (iWindowExt.iHeight != 0)
       
  2029 			return aLogicalSize * iViewportExt.iHeight / iWindowExt.iHeight;
       
  2030 		}
       
  2031 
       
  2032 	return 0;
       
  2033 	}
       
  2034 
       
  2035 void CWmfReadCodec::SetROP(CFbsBitGcWrapper* aGc,TInt aROP)
       
  2036 	{
       
  2037 	CGraphicsContext::TDrawMode drawMode = CGraphicsContext::EDrawModePEN;
       
  2038 
       
  2039 	switch (aROP)
       
  2040 		{
       
  2041 	case 1: // R2_BLACK
       
  2042 		aGc->SetPenColor(KRgbBlack);
       
  2043 		aGc->SetBrushColor(KRgbBlack);
       
  2044 		aGc->SetDrawMode(drawMode);
       
  2045 		return;
       
  2046 
       
  2047 	case 11: // R2_NOP
       
  2048 		aGc->SetPenStyle(CGraphicsContext::ENullPen);
       
  2049 		aGc->SetBrushStyle(CGraphicsContext::ENullBrush);
       
  2050 		aGc->SetDrawMode(drawMode);
       
  2051 		return;
       
  2052 
       
  2053 	case 16: // R2_WHITE
       
  2054 		aGc->SetPenColor(KRgbWhite);
       
  2055 		aGc->SetBrushColor(KRgbWhite);
       
  2056 		aGc->SetDrawMode(drawMode);
       
  2057 		return;
       
  2058 
       
  2059 	default:
       
  2060 		break;
       
  2061 		}
       
  2062 
       
  2063 	switch (aROP)
       
  2064 		{
       
  2065 	case 2:		drawMode = CGraphicsContext::EDrawModeNOTANDNOT;	break; // R2_NOTMERGEPEN
       
  2066 	case 3:		drawMode = CGraphicsContext::EDrawModeANDNOT;		break; // R2_MASKNOTPEN
       
  2067 	case 4:		drawMode = CGraphicsContext::EDrawModeNOTPEN;		break; // R2_NOTCOPYPEN
       
  2068 	case 5:		drawMode = CGraphicsContext::EDrawModeNOTAND;		break; // R2_MASKPENNOT
       
  2069 	case 6:		drawMode = CGraphicsContext::EDrawModeNOTSCREEN;	break; // R2_NOT
       
  2070 	case 7:		drawMode = CGraphicsContext::EDrawModeXOR;			break; // R2_XORPEN
       
  2071 	case 8:		drawMode = CGraphicsContext::EDrawModeNOTORNOT;		break; // R2_NOTMASKPEN
       
  2072 	case 9:		drawMode = CGraphicsContext::EDrawModeAND;			break; // R2_MASKPEN
       
  2073 	case 10:	drawMode = CGraphicsContext::EDrawModeNOTXOR;		break; // R2_NOTXORPEN
       
  2074 
       
  2075 	case 12:	break; // R2_MERGENOTPEN (not supported)
       
  2076 	case 13:	break; // R2_COPYPEN
       
  2077 	case 14:	drawMode = CGraphicsContext::EDrawModeNOTOR;		break; // R2_MERGEPENNOT
       
  2078 	case 15:	drawMode = CGraphicsContext::EDrawModeOR;			break; // R2_MERGEPEN
       
  2079 
       
  2080 	default:
       
  2081 		break;
       
  2082 		}
       
  2083 
       
  2084 	aGc->RestorePenAndBrush();
       
  2085 	aGc->SetDrawMode(drawMode);
       
  2086 	}
       
  2087 
       
  2088 void CWmfReadCodec::SetROP3(CFbsBitGcWrapper* aGc,TInt aROP)
       
  2089 	{
       
  2090 	CGraphicsContext::TDrawMode drawMode = CGraphicsContext::EDrawModePEN;
       
  2091 	switch (aROP)
       
  2092 		{
       
  2093 	case 0x005A0049: // PATINVERT
       
  2094 		drawMode = CGraphicsContext::EDrawModeXOR;
       
  2095 		break;
       
  2096 	case 0x00550009: // DSTINVERT
       
  2097 		drawMode = CGraphicsContext::EDrawModeNOTSCREEN;
       
  2098 		aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  2099 		break;
       
  2100 	case 0x00000042: // BLACKNESS
       
  2101 		aGc->SetBrushColor(KRgbBlack);
       
  2102 		aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  2103 		break;
       
  2104 	case 0x00FF0062: // WHITENESS
       
  2105 		aGc->SetBrushColor(KRgbWhite);
       
  2106 		aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  2107 		break;
       
  2108 
       
  2109 	case 0x00F00021: // PATCOPY
       
  2110 	default:
       
  2111 		break;
       
  2112 		}
       
  2113 
       
  2114 	aGc->SetDrawMode(drawMode);
       
  2115 	}
       
  2116 
       
  2117 TRgb CWmfReadCodec::ExtractColor(const TUint16* aArgPtr)
       
  2118 	{
       
  2119 	return TRgb(aArgPtr[0] & 0xff,aArgPtr[0] >> 8,aArgPtr[1] & 0xff);
       
  2120 	}
       
  2121 
       
  2122 TPoint CWmfReadCodec::ExtractPoint(const TUint16* aArgPtr,TBool aXYOrder)
       
  2123 	{
       
  2124 	TInt16* coordPtr = (TInt16*)aArgPtr;
       
  2125 
       
  2126 	TInt left = coordPtr[0];
       
  2127 	TInt top = coordPtr[1];
       
  2128 
       
  2129 	if (!aXYOrder)
       
  2130 		{
       
  2131 		TInt temp = left;
       
  2132 		left = top;
       
  2133 		top = temp;
       
  2134 		}
       
  2135 
       
  2136 	left = LogicalCoordToDeviceCoord(left,ETrue);
       
  2137 	top = LogicalCoordToDeviceCoord(top,EFalse);
       
  2138 
       
  2139 	return TPoint(left,top);
       
  2140 	}
       
  2141 
       
  2142 TRect CWmfReadCodec::ExtractRect(const TUint16* aArgPtr)
       
  2143 	{
       
  2144 	TInt16* coordPtr = (TInt16*)aArgPtr;
       
  2145 
       
  2146 	TInt left = LogicalCoordToDeviceCoord(coordPtr[3],ETrue);
       
  2147 	TInt top = LogicalCoordToDeviceCoord(coordPtr[2],EFalse);
       
  2148 	TInt right = LogicalCoordToDeviceCoord(coordPtr[1],ETrue);
       
  2149 	TInt bottom = LogicalCoordToDeviceCoord(coordPtr[0],EFalse);
       
  2150 
       
  2151 	return TRect(left,top,right,bottom);
       
  2152 	}
       
  2153 
       
  2154 TInt CWmfReadCodec::ExtractDib(const TUint16* aArgPtr, CPatternBrush* aPatternBrush)
       
  2155 	{
       
  2156 	TInt bitCount = aArgPtr[7];
       
  2157 	if (bitCount != 1)
       
  2158 		return ExtractDib(aArgPtr, aPatternBrush->Bitmap());
       
  2159 
       
  2160 	TInt structSize = aArgPtr[0] | (aArgPtr[1] << 16);
       
  2161 	TInt width = aArgPtr[2] | (aArgPtr[3] << 16);
       
  2162 	TInt height = aArgPtr[4] | (aArgPtr[5] << 16);
       
  2163 
       
  2164 	// Skip biPlanes half-word
       
  2165 	TInt compression = aArgPtr[8] | (aArgPtr[9] << 16);
       
  2166 	if (compression)
       
  2167 		return KErrNotSupported;
       
  2168 
       
  2169 	// Skip biSizeImage word
       
  2170 	TInt xPixelsPerMeter = aArgPtr[12] | (aArgPtr[13] << 16);
       
  2171 	TInt yPixelsPerMeter = aArgPtr[14] | (aArgPtr[15] << 16);
       
  2172 
       
  2173 	// Skip biClrUsed word
       
  2174 	// Skip biClrImportant word
       
  2175 
       
  2176 	TUint8* bytePtr = (TUint8*)aArgPtr;
       
  2177 	bytePtr += structSize;
       
  2178 
       
  2179 	CFbsBitmap* bitmap = aPatternBrush->Bitmap();
       
  2180 	TInt err = bitmap->Create(TSize(width,height), EColor64K);
       
  2181 	if (err != KErrNone)
       
  2182 		return err;
       
  2183 
       
  2184 	TSize twipsSize(0,0);
       
  2185 	if (xPixelsPerMeter > 0)
       
  2186 		twipsSize.iWidth = KTwipsPerCm * 100 * width / xPixelsPerMeter;
       
  2187 	if (yPixelsPerMeter > 0)
       
  2188 		twipsSize.iHeight = KTwipsPerCm * 100 * height / yPixelsPerMeter;
       
  2189 	bitmap->SetSizeInTwips(twipsSize);
       
  2190 
       
  2191 	// Skip the palette.
       
  2192 	bytePtr+= 8;
       
  2193 
       
  2194 	// Set the pattern bits.
       
  2195 	TInt padding = ((width + 31) & ~31) - width;
       
  2196 	TInt byteTotal = ((width+padding)*height)/8;
       
  2197 	TUint8* bitmapBits = new TUint8[byteTotal];
       
  2198 	if (!bitmapBits)
       
  2199 		return KErrNoMemory;
       
  2200 
       
  2201 	Mem::Copy(bitmapBits, bytePtr, byteTotal);
       
  2202 	aPatternBrush->SetBitmapBits(bitmapBits);
       
  2203 	return KErrNone;
       
  2204 	}
       
  2205 
       
  2206 TInt CWmfReadCodec::ExtractDib(const TUint16* aArgPtr, CFbsBitmap* aBitmap)
       
  2207 	{
       
  2208 	const TInt structSize = aArgPtr[0] | (aArgPtr[1] << 16);
       
  2209 	const TInt width = aArgPtr[2] | (aArgPtr[3] << 16);
       
  2210 	const TInt height = aArgPtr[4] | (aArgPtr[5] << 16);
       
  2211 
       
  2212 	// Skip biPlanes half-word
       
  2213 	const TInt bitCount = aArgPtr[7];
       
  2214 	const TInt compression = aArgPtr[8] | (aArgPtr[9] << 16);
       
  2215 	if (((bitCount != 24) && (bitCount != 8) && (bitCount != 1)) || compression)
       
  2216 		return KErrNotSupported;
       
  2217 
       
  2218 	// Skip biSizeImage word
       
  2219 	const TInt xPixelsPerMeter = aArgPtr[12] | (aArgPtr[13] << 16);
       
  2220 	const TInt yPixelsPerMeter = aArgPtr[14] | (aArgPtr[15] << 16);
       
  2221 
       
  2222 	// Skip biClrUsed word
       
  2223 	// Skip biClrImportant word
       
  2224 
       
  2225 	TUint8* bytePtr = (TUint8*)aArgPtr;
       
  2226 	bytePtr += structSize;
       
  2227 
       
  2228 	TInt err = aBitmap->Create(TSize(width,height), EColor64K);
       
  2229 	if (err != KErrNone)
       
  2230 		return err;
       
  2231 
       
  2232 	TSize twipsSize(0,0);
       
  2233 	if (xPixelsPerMeter > 0)
       
  2234 		twipsSize.iWidth = KTwipsPerCm * 100 * width / xPixelsPerMeter;
       
  2235 	if (yPixelsPerMeter > 0)
       
  2236 		twipsSize.iHeight = KTwipsPerCm * 100 * height / yPixelsPerMeter;
       
  2237 	aBitmap->SetSizeInTwips(twipsSize);
       
  2238 
       
  2239 	TBitmapUtil util(aBitmap);
       
  2240 	if (bitCount == 24)
       
  2241 		{
       
  2242 		TInt byteWidth = 3*width;
       
  2243 		TInt padding = ((byteWidth + 3) & ~3) - byteWidth;
       
  2244 		for (TInt y = height - 1; y >= 0; y--)
       
  2245 			{
       
  2246 			util.Begin(TPoint(0,y));
       
  2247 			for (TInt x = 0; x < width; x++)
       
  2248 				{
       
  2249 				TRgb color(bytePtr[2],bytePtr[1],bytePtr[0]);
       
  2250 				util.SetPixel(color.Color64K());
       
  2251 				util.IncXPos();
       
  2252 				bytePtr += 3;
       
  2253 				}
       
  2254 			bytePtr += padding;
       
  2255 			util.End();
       
  2256 			}
       
  2257 		}
       
  2258 	else if (bitCount == 8)
       
  2259 		{
       
  2260 		// Read the palette.
       
  2261 		TRgb* palette = new TRgb[256];
       
  2262 		if (!palette)
       
  2263 			return KErrNoMemory;
       
  2264 
       
  2265 		for (TInt count = 0; count < 256; count++)
       
  2266 			{
       
  2267 			TInt blue = bytePtr[0];
       
  2268 			TInt green = bytePtr[1];
       
  2269 			TInt red = bytePtr[2];
       
  2270 			
       
  2271 			bytePtr += 4; // Skip rgbReserved
       
  2272 			palette[count] = TRgb(red, green, blue);
       
  2273 			}
       
  2274 
       
  2275 		const TInt padding = ((width + 3) & ~3) - width;
       
  2276 		for (TInt y = height - 1; y >= 0; y--)
       
  2277 			{
       
  2278 			util.Begin(TPoint(0,y));
       
  2279 			for (TInt x = 0; x < width; x++)
       
  2280 				{
       
  2281 				TRgb color(palette[bytePtr[0]]);
       
  2282 				util.SetPixel(color.Color64K());
       
  2283 				util.IncXPos();
       
  2284 				bytePtr++;
       
  2285 				}
       
  2286 			bytePtr += padding;
       
  2287 			util.End();
       
  2288 			}
       
  2289 
       
  2290 		delete[] palette;
       
  2291 		}
       
  2292 	else // 1bpp
       
  2293 		{
       
  2294 		// Read the palette.
       
  2295 		TRgb palette[2];
       
  2296 		for (TInt count = 0; count < 2; count++)
       
  2297 			{
       
  2298 			TInt blue = bytePtr[0];
       
  2299 			TInt green = bytePtr[1];
       
  2300 			TInt red = bytePtr[2];
       
  2301 			
       
  2302 			bytePtr += 4; // Skip rgbReserved
       
  2303 			palette[count] = TRgb(red, green, blue);
       
  2304 			}
       
  2305 
       
  2306 		const TInt padding = ((width + 31) & ~31) - width;
       
  2307 		TUint pixelMask = 0x80;
       
  2308 		for (TInt y = height - 1; y >= 0; y--)
       
  2309 			{
       
  2310 			util.Begin(TPoint(0,y));
       
  2311 
       
  2312 			TInt x;
       
  2313 			for (x = 0; x < width; x++)
       
  2314 				{
       
  2315 				TRgb color(palette[(bytePtr[0] & pixelMask) ? 1 : 0]);
       
  2316 				util.SetPixel(color.Color64K());
       
  2317 				util.IncXPos();
       
  2318 
       
  2319 				pixelMask >>= 1;
       
  2320 				if (pixelMask == 0)
       
  2321 					{
       
  2322 					pixelMask = 0x80;
       
  2323 					bytePtr++;
       
  2324 					}
       
  2325 				}
       
  2326 
       
  2327 			for (x = 0 ; x<padding ; x++)
       
  2328 				{
       
  2329 				pixelMask >>= 1;
       
  2330 				if (pixelMask == 0)
       
  2331 					{
       
  2332 					pixelMask = 0x80;
       
  2333 					bytePtr++;
       
  2334 					}
       
  2335 				}
       
  2336 
       
  2337 			util.End();
       
  2338 			}
       
  2339 		}
       
  2340 
       
  2341 	return KErrNone;
       
  2342 	}
       
  2343 
       
  2344 TInt CWmfReadCodec::ReducedSize(const TSize& aOriginalSize,TInt aReductionFactor, TSize& aReducedSize) const
       
  2345 	{
       
  2346 	aReducedSize = aOriginalSize;
       
  2347    	if (aReductionFactor<0)
       
  2348    	   {
       
  2349    	   return KErrArgument;
       
  2350    	   }
       
  2351    	TInt roundup = aReductionFactor>0? 1<<(aReductionFactor-1): 0;
       
  2352    	aReducedSize.SetSize(((aOriginalSize.iWidth+roundup)>>aReductionFactor),
       
  2353                ((aOriginalSize.iHeight+roundup)>>aReductionFactor) );
       
  2354     return KErrNone;            
       
  2355 	}
       
  2356 
       
  2357 TInt CWmfReadCodec::ReductionFactor(const TSize& aOriginalSize, const TSize& aReducedSize) const
       
  2358 	{
       
  2359 	if( (aReducedSize.iWidth<=0) || (aReducedSize.iHeight<=0))
       
  2360       	{
       
  2361       	return 0;
       
  2362 		}
       
  2363    	TInt reductionFactor = 0;
       
  2364    	TInt roundup=0;
       
  2365 	while( ((aOriginalSize.iWidth+roundup)>>reductionFactor) > aReducedSize.iWidth || 
       
  2366          ((aOriginalSize.iHeight+roundup)>>reductionFactor) > aReducedSize.iHeight)
       
  2367     	{
       
  2368       	reductionFactor++;
       
  2369       	roundup=1<<(reductionFactor-1);
       
  2370     	}
       
  2371 	return reductionFactor;
       
  2372 	}
       
  2373 
       
  2374 void CWmfReadCodec::SetIgnoreViewportMetaData(TBool aIgnoreViewportMetaData)
       
  2375 	{
       
  2376 	iIgnoreViewportMetaData = aIgnoreViewportMetaData;
       
  2377 	}