os/graphics/printingservices/printerdriversupport/src/PDRDEV.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1997-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 <banddev.h>
    17 #include <pdrstore.h>
    18 #include <bitdev.h>
    19 #include <bitstd.h>
    20 #include "PDRBODY.H"
    21 #include "PDRSTD.H"
    22 #include "pdrtext.h"
    23 
    24 EXPORT_C CPdrDevice::CPdrDevice():
    25 	CPrinterDevice(),
    26 	iStore(NULL),
    27 	iModel(),
    28 	iModelInfo(NULL),
    29 	iTypefaceStore(NULL)
    30 	{
    31 	__DECLARE_NAME(_S("CPdrDevice"));
    32 	}
    33 
    34 EXPORT_C CPdrDevice::~CPdrDevice()
    35 	{
    36 	DeleteControl();
    37 	delete iModelInfo;
    38 	delete iTypefaceStore;
    39 	}
    40 
    41 EXPORT_C void CPdrDevice::SelectPageSpecInTwips(const TPageSpec& aPageSpec)
    42 	{
    43 	CPrinterDevice::SelectPageSpecInTwips(aPageSpec);
    44 	iTypefaceStore->SetPageOrientation(aPageSpec.iOrientation);
    45 	}
    46 
    47 EXPORT_C TDisplayMode CPdrDevice::DisplayMode() const
    48 	{
    49 	return iModelInfo->iDisplayMode;
    50 	}
    51 
    52 EXPORT_C TSize CPdrDevice::SizeInPixels() const
    53 	{
    54 	TSize size;
    55 	size.iWidth = HorizontalTwipsToPixels(SizeInTwips().iWidth);
    56 	size.iHeight = VerticalTwipsToPixels(SizeInTwips().iHeight);
    57 	return size;
    58 	}
    59 
    60 EXPORT_C TSize CPdrDevice::SizeInTwips() const
    61 	{
    62 	TSize size;
    63 	if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::EPortrait)
    64 		{
    65 		size = iCurrentPageSpecInTwips.iPortraitPageSize;
    66 		}
    67 	else if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::ELandscape)
    68 		{
    69 		size.iWidth = iCurrentPageSpecInTwips.iPortraitPageSize.iHeight;
    70 		size.iHeight = iCurrentPageSpecInTwips.iPortraitPageSize.iWidth;
    71 		}
    72 	return size;
    73 	}
    74 
    75 EXPORT_C TRect CPdrDevice::PrintablePageInPixels() const
    76 	{
    77 	TRect rect;
    78 	if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::EPortrait)
    79 		{
    80 		rect.iTl.iX = iModelInfo->iPortraitOffsetInPixels.iX;
    81 		rect.iTl.iY = iModelInfo->iMinMarginsInPixels.iTop;
    82 		rect.iBr.iX = SizeInPixels().iWidth-iModelInfo->iPortraitOffsetInPixels.iX;
    83 		rect.iBr.iY = SizeInPixels().iHeight-iModelInfo->iMinMarginsInPixels.iBottom;
    84 		}
    85 	else if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::ELandscape)
    86 		{
    87 		rect.iTl.iX = iModelInfo->iLandscapeOffsetInPixels.iX;
    88 		rect.iTl.iY = iModelInfo->iMinMarginsInPixels.iLeft;
    89 		rect.iBr.iX = SizeInPixels().iWidth-iModelInfo->iLandscapeOffsetInPixels.iX;
    90 		rect.iBr.iY = SizeInPixels().iHeight-iModelInfo->iMinMarginsInPixels.iRight;
    91 		}
    92 	return rect;
    93 	}
    94 
    95 EXPORT_C TInt CPdrDevice::HorizontalTwipsToPixels(TInt aTwips) const
    96 	{
    97 	return ((1000 * aTwips) + (KPixelSizeInTwips().iWidth / 2)) / KPixelSizeInTwips().iWidth;
    98 	}
    99 
   100 EXPORT_C TInt CPdrDevice::VerticalTwipsToPixels(TInt aTwips) const
   101 	{
   102 	return ((1000 * aTwips) + (KPixelSizeInTwips().iHeight / 2)) / KPixelSizeInTwips().iHeight;
   103 	}
   104 
   105 EXPORT_C TInt CPdrDevice::HorizontalPixelsToTwips(TInt aPixels) const
   106 	{
   107 	return ((aPixels * KPixelSizeInTwips().iWidth) + 500) / 1000;
   108 	}
   109 
   110 EXPORT_C TInt CPdrDevice::VerticalPixelsToTwips(TInt aPixels) const
   111 	{
   112 	return ((aPixels * KPixelSizeInTwips().iHeight) + 500) / 1000;
   113 	}
   114 
   115 /** Creates a font from those available in the printer device's 
   116 typeface store that most closely matches a font specification. 
   117 
   118 When the font is no longer needed, call ReleaseFont().
   119 
   120 This function is replaced by GetNearestFontToDesignHeightInTwips()
   121 
   122 @param aFont On return, points to the font which most closely matches the 
   123 specified font.
   124 @param aFontSpec An absolute font specification. Its iHeight member is 
   125 interpreted as being in twips.
   126 @return KErrNone if successful; otherwise, another one of the system-wide error 
   127 codes.
   128 @deprecated */
   129 EXPORT_C TInt CPdrDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
   130 	{
   131 	return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
   132 	}
   133 
   134 /** Creates a font from those available in the printer device's 
   135 typeface store that most closely matches a font specification. 
   136 
   137 When the font is no longer needed, call ReleaseFont().
   138 
   139 This function replaces GetNearestFontInTwips()
   140 
   141 @param aFont On return, points to the font which most closely matches the 
   142 specified font.
   143 @param aFontSpec An absolute font specification. Its iHeight member is 
   144 interpreted as being in twips.
   145 @return KErrNone if successful; otherwise, another one of the system-wide error 
   146 codes. */
   147 EXPORT_C TInt CPdrDevice::GetNearestFontToDesignHeightInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
   148 	{
   149 	return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
   150 	}
   151 
   152 /** This call is defined because it had to be - it appeared as an abstract virtual in
   153 the base class. But it should never actually get called for this class. */
   154 EXPORT_C TInt CPdrDevice::GetNearestFontToMaxHeightInTwips(CFont*& /*aFont*/, const TFontSpec& /*aFontSpec*/, TInt /*aMaxHeight*/)
   155 	{
   156 	return KErrNotSupported;
   157 	}
   158 
   159 EXPORT_C TInt CPdrDevice::NumTypefaces() const
   160 	{
   161 	return iTypefaceStore->NumTypefaces();
   162 	}
   163 
   164 EXPORT_C void CPdrDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport, TInt aTypefaceIndex) const
   165 	{
   166 	iTypefaceStore->TypefaceSupport(aTypefaceSupport, aTypefaceIndex);
   167 	}
   168 
   169 EXPORT_C TInt CPdrDevice::FontHeightInTwips(TInt aTypefaceIndex, TInt aHeightIndex) const
   170 	{
   171 	return iTypefaceStore->FontHeightInTwips(aTypefaceIndex, aHeightIndex);
   172 	}
   173 
   174 EXPORT_C void CPdrDevice::PaletteAttributes(TBool& aModifiable, TInt& aNumEntries) const
   175 	{
   176 	aModifiable = EFalse;
   177 	aNumEntries = 0;
   178 	}
   179 
   180 EXPORT_C void CPdrDevice::SetPalette(CPalette* /*aPalette*/)
   181 	{
   182 	}
   183 	
   184 EXPORT_C TInt CPdrDevice::GetPalette(CPalette*& /*aPalette*/) const
   185 	{
   186 	return KErrNotSupported;
   187 	}
   188 
   189 EXPORT_C TPrinterModelEntry CPdrDevice::Model() const
   190 	{
   191 	return iModel.iEntry;
   192 	}
   193 
   194 EXPORT_C TInt CPdrDevice::Flags() const
   195 	{
   196 	return iModelInfo->iFlags;
   197 	}
   198 
   199 EXPORT_C TInt CPdrDevice::SetModel(const TPrinterModelHeader& aModel, CStreamStore& aStore)
   200 	{
   201 	iModel = aModel;
   202 	iStore = &aStore;
   203 	TRAPD(ret, DoSetModelL());
   204 	return ret;
   205 	}
   206 
   207 EXPORT_C void CPdrDevice::ReleaseFont(CFont* aFont)
   208 	{
   209 	iTypefaceStore->ReleaseFont(aFont);
   210 	}
   211 
   212 EXPORT_C TPoint CPdrDevice::OffsetInPixels()
   213 	{
   214 	TPoint offset;
   215 	if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::EPortrait)
   216 		offset = iModelInfo->iPortraitOffsetInPixels;
   217 	else if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::ELandscape)
   218 		offset = iModelInfo->iLandscapeOffsetInPixels;
   219 	return offset;
   220 	}
   221 
   222 EXPORT_C TSize CPdrDevice::KPixelSizeInTwips() const
   223 	{
   224 	TSize size; 
   225 	if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::EPortrait)
   226 		size = TSize(iModelInfo->iKPixelWidthInTwips, iModelInfo->iKPixelHeightInTwips);
   227 	else if (iCurrentPageSpecInTwips.iOrientation == TPageSpec::ELandscape)
   228 		size = TSize(iModelInfo->iKPixelHeightInTwips, iModelInfo->iKPixelWidthInTwips);
   229 	return size;
   230 	}
   231 
   232 void CPdrDevice::DoSetModelL()
   233 	{
   234 	RStoreReadStream stream;
   235 	stream.OpenLC(*iStore, iModel.iModelDataStreamId);
   236 	iModelInfo = new(ELeave) CPdrModelInfo();
   237 	iModelInfo->InternalizeL(stream);
   238 	CleanupStack::PopAndDestroy();
   239 	iTypefaceStore = CPdrTypefaceStore::NewL(*iStore, iModelInfo->iNumTypefaceFonts, iModelInfo->iTypefaceFontsEntryList, iCurrentPageSpecInTwips.iOrientation, iModelInfo->iKPixelHeightInTwips, this);
   240 	}
   241 
   242 EXPORT_C CPdrControl::CPdrControl(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort):
   243 	CPrinterControl(aPrinterPort),
   244 	iPdrDevice(aPdrDevice),
   245 	iPageBuffer(NULL),
   246 	iResources(NULL),
   247 	iBandedDevice(NULL),
   248 	iPageText(NULL),
   249 	iBandIndex(0),
   250 	iEntryIndex(0),
   251 	iPosition(iPdrDevice->OffsetInPixels()),
   252 	iTextFormat()
   253 	{
   254 	__DECLARE_NAME(_S("CPdrControl"));
   255 	}
   256 
   257 EXPORT_C CPdrControl::~CPdrControl()
   258 	{
   259 	delete iPageBuffer;
   260 	delete iResources;
   261 	delete iBandedDevice;
   262 	delete iPageText;
   263 	}
   264 
   265 EXPORT_C TInt CPdrControl::CreateContext(CGraphicsContext*& aGC)
   266 	{
   267 	__ASSERT_DEBUG(iState == EPrinting, Panic(EPdrNotPrinting));
   268 	TRAPD(ret, aGC = CPdrGc::NewL(iPdrDevice));
   269 	return ret;
   270 	}
   271 
   272 EXPORT_C TInt CPdrControl::BandsPerPage()
   273 	{
   274 	TInt numbands = {iBandedDevice ? iBandedDevice->NumBands() + 1 : 1};
   275 	return numbands;
   276 	}
   277 
   278 /**
   279  @return EMoreOnPage if more to print on the current page,
   280  otherwise ENoMoreOnPage.
   281 */
   282 EXPORT_C CPrinterControl::TMoreOnPage CPdrControl::QueueGetBand(TRequestStatus& aStatus, TBandAttributes& aBand)
   283 	{
   284 	TMoreOnPage moreonpage = ENoMoreOnPage;
   285 
   286 	TRAPD(ret, DoQueueGetBandL());
   287 	if (ret != KErrNone)
   288 		{
   289 		TRequestStatus* status = &aStatus;
   290 		User::RequestComplete(status, ret);
   291 		}
   292 	else
   293 		{
   294 		if (IsGraphicsBand())
   295 			{
   296 			aBand.iRect = iBandedDevice->BandRect();
   297 			aBand.iTextIsIgnored = ETrue;
   298 			aBand.iGraphicsIsIgnored = EFalse;
   299 			aBand.iFirstBandOnPage = EFalse;
   300 			}
   301 		else
   302 			{
   303 			aBand.iRect = iPdrDevice->PrintablePageInPixels();
   304 			aBand.iTextIsIgnored = EFalse;
   305 			aBand.iGraphicsIsIgnored = ETrue;
   306 			aBand.iFirstBandOnPage = ETrue;
   307 			}
   308 		if (iBandIndex == (BandsPerPage() - 1))
   309 			moreonpage = ENoMoreOnPage;
   310 		else
   311 			moreonpage = EMoreOnPage;
   312 		iPageBuffer->StartFlush(aStatus);
   313 		}
   314 	return moreonpage;
   315 	}
   316 
   317 EXPORT_C void CPdrControl::QueueEndPrint(TRequestStatus& aStatus)
   318 	{
   319 	TRAPD(ret, DoQueueEndPrintL());
   320 	iState = ENotPrinting;
   321 	if (ret != KErrNone)
   322 		{
   323 		TRequestStatus* status = &aStatus;
   324 		User::RequestComplete(status, ret);
   325 		}
   326 	else
   327 		iPageBuffer->StartFlush(aStatus);
   328 	}
   329 
   330 /**
   331  Tidy up synchronously in a short time.
   332 */
   333 EXPORT_C void CPdrControl::AbortPrint() // tidy up synchronously in a short time, return success code
   334 	{
   335 	iPageBuffer->Cancel(); // dont call DoCancel()
   336 	iState = ENotPrinting;
   337 	}
   338 
   339 EXPORT_C void CPdrControl::DrawTextL(const TPoint& aPoint, const TFontUnderline aUnderlineStyle, const TFontStrikethrough aStrikethroughStyle, const TRgb& aColor, const CInfoFont* aFont, const TDesC& aString)
   340 	{
   341 	__ASSERT_DEBUG(iState == EPrinting,Panic(EPdrNotPrinting));
   342 	if (iPageText)
   343 		iPageText->AddEntryL(aPoint, aUnderlineStyle, aStrikethroughStyle, aColor, aFont, aString);
   344 	else
   345 		{
   346 		HBufC8* string = aFont->TranslateStringL(aString);
   347 		CleanupStack::PushL(string);
   348 		TTextFormat textformat(aUnderlineStyle, aStrikethroughStyle, aColor, aFont->CommandString(), aFont->FontSpecInTwips().iFontStyle);
   349 		OutputTextL(aPoint + TPoint(0, aFont->BaselineOffsetInPixels()), aFont->MeasureText(aString), textformat,string->Des());
   350 		CleanupStack::PopAndDestroy();
   351 		}
   352 	}
   353 
   354 EXPORT_C TBool CPdrControl::IsGraphicsBand() const
   355 	{
   356 	return iBandIndex;
   357 	}
   358 
   359 EXPORT_C void CPdrControl::MoveToL(const TPoint& aPoint) 
   360 	{
   361 	// PCL, at least, treats move command strings with an explicit
   362 	// sign as being relative, so if the offset is negative then
   363 	// set the absolute position to zero first.
   364 
   365 	TPoint offset = iPdrDevice->OffsetInPixels();
   366 	TCommandString des;
   367 	if (aPoint.iX - iPosition.iX)
   368 		{
   369 		if (aPoint.iX - iPosition.iX < 0)
   370 			{
   371 			des.Format(iResources->ResourceString(EPdrSetXPos), 0);
   372 			iPageBuffer->AddBytesL(des);
   373 			}
   374 
   375 		des.Format(iResources->ResourceString(EPdrSetXPos), aPoint.iX - offset.iX);
   376 		iPageBuffer->AddBytesL(des);
   377 		}
   378 	if (aPoint.iY - iPosition.iY)
   379 		{
   380 		if (aPoint.iY - iPosition.iY < 0)
   381 			{
   382 			des.Format(iResources->ResourceString(EPdrSetYPos), 0);
   383 			iPageBuffer->AddBytesL(des);
   384 			}
   385 
   386 		des.Format(iResources->ResourceString(EPdrSetYPos), aPoint.iY - offset.iY);
   387 		iPageBuffer->AddBytesL(des);
   388 		}
   389 	iPosition = aPoint;
   390 	}
   391 
   392 EXPORT_C void CPdrControl::MoveByL(const TPoint& aVector) 
   393 	{
   394 	TCommandString resource;
   395 	TCommandString des;
   396 	TPoint vector = aVector;
   397 	if (vector.iX)
   398 		{
   399 		if (aVector.iX < 0)
   400 			{
   401 			CommandL(EPdrCarriageReturn);
   402 			vector.iX += iPosition.iX - iPdrDevice->OffsetInPixels().iX;
   403 			}
   404 		resource.Copy(iResources->ResourceString(EPdrIncrementXPos));
   405 		__ASSERT_DEBUG(resource.Length() >= 2, Panic(EPdrBadResourceString));
   406 		if (resource[0] == '*')
   407 			{
   408 			for (; vector.iX > 0; vector.iX--)
   409 				iPageBuffer->AddBytesL(resource.Mid(1));
   410 			}
   411 		else
   412 			{
   413 			des.Format(resource, vector.iX);
   414 			iPageBuffer->AddBytesL(des);
   415 			}
   416 		}
   417 	resource.Copy(iResources->ResourceString(EPdrIncrementYPos));
   418 	if (vector.iY)
   419 		{
   420 		__ASSERT_DEBUG(resource.Length() >= 2, Panic(EPdrBadResourceString));
   421 		if (resource[0] == '*')
   422 			{
   423 			for (; vector.iY > 0; vector.iY--)
   424 				iPageBuffer->AddBytesL(resource.Mid(1));
   425 			}
   426 		else
   427 			{
   428 			des.Format(resource, vector.iY);
   429 			iPageBuffer->AddBytesL(des);
   430 			}
   431 		}
   432 	iPosition += aVector;
   433 	}
   434 
   435 EXPORT_C void CPdrControl::OutputTextL(const TPoint& aPoint, TInt aWidthInPixels, const TTextFormat& aTextFormat, const TDesC8& aString)
   436 	{
   437 	__ASSERT_DEBUG(iState == EPrinting,Panic(EPdrNotPrinting));
   438 
   439 	if (iTextFormat.iFontString.Compare(aTextFormat.iFontString))
   440 		iPageBuffer->AddBytesL(aTextFormat.iFontString);
   441 
   442 	if (iTextFormat.iFontStyle.Posture() != aTextFormat.iFontStyle.Posture())
   443 		SetFontPostureL(aTextFormat.iFontStyle.Posture());
   444 
   445 	if (iTextFormat.iFontStyle.StrokeWeight() != aTextFormat.iFontStyle.StrokeWeight())
   446 		SetFontStrokeWeightL(aTextFormat.iFontStyle.StrokeWeight());
   447 
   448 	if (iTextFormat.iColor != aTextFormat.iColor)
   449 		SetTextColorL(aTextFormat.iColor);
   450 
   451 	iTextFormat = aTextFormat;
   452 
   453 	MoveToL(aPoint);
   454 
   455 	if (aTextFormat.iUnderlineStyle == EUnderlineOn)
   456 		CommandL(EPdrUnderlineOn);
   457 
   458 	if (aTextFormat.iStrikethroughStyle == EStrikethroughOn)
   459 		CommandL(EPdrStrikethroughOn);
   460 
   461 	iPageBuffer->AddBytesL(aString);
   462 
   463 	iPosition.iX += aWidthInPixels;
   464 
   465 	if (aTextFormat.iUnderlineStyle == EUnderlineOn)
   466 		CommandL(EPdrUnderlineOff);
   467 
   468 	if (aTextFormat.iStrikethroughStyle == EStrikethroughOn)
   469 		CommandL(EPdrStrikethroughOff);
   470 	}
   471 
   472 EXPORT_C void CPdrControl::DoQueueGetBandL()
   473 	{
   474 	if (iState == ENotPrinting)
   475 		{
   476 		iState = EPrinting;
   477 		iBandIndex = 0;
   478 		if (iBandedDevice)
   479 			iBandedDevice->Reset();
   480 		CommandL(EPdrReset);
   481 		SetPageSizeL();
   482 		CommandL(EPdrPreAmble);
   483 		SetPageOrientationL();
   484 		SetTextColorL(KRgbBlack);	
   485 		}
   486  	else 
   487 		{
   488 		OutputBandL();
   489 		if (iBandIndex == (BandsPerPage() - 1))
   490 			{
   491 			iBandIndex = 0;
   492 			iEntryIndex = 0;
   493 			if (iPageText)
   494 				iPageText->Reset(); 
   495 			CommandL(EPdrNewPage);
   496 			iPosition = iPdrDevice->OffsetInPixels();
   497 			}
   498 		else
   499 			iBandIndex = iBandedDevice->NextBand() + 1;
   500 		}
   501 	}
   502 
   503 EXPORT_C void CPdrControl::DoQueueEndPrintL()
   504 	{
   505 	OutputBandL();
   506 	CommandL(EPdrPostAmble);
   507 	}
   508 
   509 EXPORT_C void CPdrControl::ConstructL(CStreamStore& aStore, TStreamId aStreamId)
   510 	{
   511 	__ASSERT_ALWAYS(iPrinterPort, Panic(EPdrRequiresPrinterPort));
   512 	iPageBuffer = CPageBuffer::NewL(iPrinterPort);
   513 	iResources = new(ELeave) CPdrResources();
   514 	iResources->RestoreL(aStore, aStreamId);
   515 	}
   516 
   517 EXPORT_C void CPdrControl::SetPageSizeL()
   518 	{
   519 	}
   520 	 
   521 EXPORT_C void CPdrControl::SetPageOrientationL()
   522 	{
   523 	TPageSpec::TPageOrientation orientation = iPdrDevice->CurrentPageSpecInTwips().iOrientation;
   524 	if (orientation == TPageSpec::EPortrait)
   525 		CommandL(EPdrPortrait);
   526 	else
   527 		CommandL(EPdrLandscape);
   528 	}
   529 
   530 EXPORT_C void CPdrControl::SetFontStrokeWeightL(const TFontStrokeWeight aStrokeWeight)
   531 	{
   532 	if (aStrokeWeight == EStrokeWeightNormal)
   533 		CommandL(EPdrBoldOff);
   534 	else 
   535 		CommandL(EPdrBoldOn);
   536 	}
   537 
   538 EXPORT_C void CPdrControl::SetFontPostureL(const TFontPosture aPosture)
   539 	{
   540 	if (aPosture == EPostureUpright)
   541 		CommandL(EPdrItalicOff);
   542 	else 
   543 		CommandL(EPdrItalicOn);
   544 	}
   545 
   546 EXPORT_C void CPdrControl::SetTextColorL(const TRgb& /*aColor*/) 
   547 	{
   548 	}
   549 
   550 EXPORT_C void CPdrControl::CommandL(const TInt anId) 
   551 	{
   552 	iPageBuffer->AddBytesL(iResources->ResourceString(anId));
   553 	}
   554 
   555 void CPdrGc::ConstructL()
   556 	{
   557 	if (PdrControl()->BandedDevice())
   558 		{
   559 		User::LeaveIfError(PdrControl()->BandedDevice()->CreateContext((CGraphicsContext*&)iBandedGc));
   560 		TFontSpec spec;
   561 		User::LeaveIfError(PdrControl()->BandedDevice()->GetNearestFontToDesignHeightInTwips((CFont*&)iFbsFont, spec));
   562 		iBandedGc->UseFont(iFbsFont);
   563 		}
   564 	}
   565 
   566 CPdrGc::CPdrGc(CPdrDevice* aDevice):
   567 	iPdrDevice(aDevice),
   568 	iBandedGc(NULL),
   569 	iFbsFont(NULL),
   570 	iBandedFont(NULL),
   571 	iFont(NULL),
   572 	iOrigin(0, 0),
   573 	iPosition(0, 0),
   574 	iUnderlineStyle(EUnderlineOff),
   575 	iStrikethroughStyle(EStrikethroughOff),
   576 	iClippingRect(iPdrDevice->PrintablePageInPixels()),
   577 	iWordExcessWidthInPixels(0),
   578 	iNumGaps(0),
   579 	iCharExcessWidthInPixels(0),
   580 	iNumChars(0),
   581 	iPenColor(KRgbBlack)
   582 	{
   583 	}
   584 
   585 CPdrGc* CPdrGc::NewL(CPdrDevice* aDevice)
   586 	{
   587 	CPdrGc* gc = new(ELeave) CPdrGc(aDevice);
   588 	CleanupStack::PushL(gc);
   589 	gc->ConstructL();
   590 	CleanupStack::Pop();
   591 	return gc;
   592 	}
   593 
   594 EXPORT_C CPdrGc::~CPdrGc()
   595 	{
   596 	if (iBandedGc)
   597 		{
   598 		if (iBandedGc->IsFontUsed())
   599 			{
   600 			iBandedGc->DiscardFont();
   601 			iBandedFont = NULL;
   602 			}
   603 		delete iBandedGc;
   604 		PdrControl()->BandedDevice()->ReleaseFont(iFbsFont);
   605 		}
   606 	}
   607 
   608 EXPORT_C CGraphicsDevice* CPdrGc::Device() const
   609 	{
   610 	return iPdrDevice;
   611 	}
   612 
   613 EXPORT_C void CPdrGc::SetOrigin(const TPoint& aPos)
   614 	{
   615 	if (!PdrControl()->IsGraphicsBand())
   616 		iOrigin = aPos;
   617 	TPoint pos = PdrControl()->BandedDevice()->FullOriginToBandOrigin(aPos);
   618 	iBandedGc->SetOrigin(pos);
   619 	}
   620 
   621 EXPORT_C void CPdrGc::SetDrawMode(TDrawMode aDrawingMode)
   622 	{
   623 	iBandedGc->SetDrawMode(aDrawingMode);
   624 	}
   625 
   626 EXPORT_C void CPdrGc::SetClippingRect(const TRect& aRect)
   627 	{
   628 	if (!PdrControl()->IsGraphicsBand())
   629 		{
   630 		iClippingRect = aRect;
   631 		iClippingRect.Move(TPoint(0, 0) + iOrigin);	//  Recorded in original coordinates
   632 		}
   633 	iBandedGc->SetClippingRect(aRect);
   634 	}
   635 
   636 EXPORT_C void CPdrGc::CancelClippingRect()
   637 	{
   638 	if (!PdrControl()->IsGraphicsBand())
   639 		iClippingRect = iPdrDevice->PrintablePageInPixels();
   640 	iBandedGc->CancelClippingRect();
   641 	}
   642 
   643 EXPORT_C void CPdrGc::Reset()
   644 	{
   645 	if (iBandedGc->IsFontUsed())
   646 		{
   647 		iBandedGc->DiscardFont();
   648 		iBandedFont = NULL;
   649 		}
   650 	iBandedGc->Reset();
   651 	iBandedGc->UseFont(iFbsFont);
   652 	SetOrigin(TPoint(0, 0));
   653 	CancelClippingRect();
   654 	}
   655 
   656 EXPORT_C void CPdrGc::UseFont(const CFont* aFont)
   657 	{
   658 	if (aFont->TypeUid() == TUid::Uid(KCInfoFontUidVal))
   659 		{
   660 		iFont = (CInfoFont*)aFont;
   661 		iPrintTextUsingBitmaps = EFalse;
   662 		// We may have to use bitmaps - so set the font up in the bitmap gc as well
   663 		if (iBandedGc->IsFontUsed())
   664 			iBandedGc->DiscardFont();
   665 		iBandedFont = iFont->RealFont();
   666 		iBandedGc->UseFont(iBandedFont);
   667 		}
   668 	else 
   669 		{
   670 		if (iBandedGc->IsFontUsed())
   671 			{
   672 			iBandedGc->DiscardFont();
   673 			iBandedFont = NULL;
   674 			}
   675 		iBandedGc->UseFont(aFont);
   676 		iPrintTextUsingBitmaps = ETrue;
   677 		}
   678 	}
   679 
   680 EXPORT_C void CPdrGc::DiscardFont()
   681 	{
   682 	iFont = NULL;
   683 	if (iBandedFont)
   684 		{
   685 		iBandedGc->DiscardFont();
   686 		iBandedFont = NULL;
   687 		iBandedGc->UseFont(iFbsFont);
   688 		}
   689 	}
   690 
   691 EXPORT_C void CPdrGc::SetPenColor(const TRgb& aColor)
   692 	{
   693 	if (!PdrControl()->IsGraphicsBand())
   694 		iPenColor = aColor;
   695 	iBandedGc->SetPenColor(aColor);
   696 	}
   697 
   698 EXPORT_C void CPdrGc::SetPenStyle(TPenStyle aPenStyle)
   699 	{
   700 	iBandedGc->SetPenStyle(aPenStyle);
   701 	}
   702 
   703 EXPORT_C void CPdrGc::SetPenSize(const TSize& aSize)
   704 	{
   705 	iBandedGc->SetPenSize(aSize);
   706 	}
   707 
   708 EXPORT_C void CPdrGc::SetBrushColor(const TRgb& aColor)
   709 	{
   710 	if (PdrControl()->IsGraphicsBand())
   711 		iBandedGc->SetBrushColor(aColor);
   712 	}
   713 
   714 EXPORT_C void CPdrGc::SetBrushStyle(TBrushStyle aBrushStyle)
   715 	{
   716 	if (PdrControl()->IsGraphicsBand())
   717 		iBandedGc->SetBrushStyle(aBrushStyle);
   718 	}
   719 
   720 EXPORT_C void CPdrGc::SetBrushOrigin(const TPoint& aOrigin)
   721 	{
   722 	if (PdrControl()->IsGraphicsBand())
   723 		iBandedGc->SetBrushOrigin(aOrigin);
   724 	}
   725 
   726 EXPORT_C void CPdrGc::UseBrushPattern(const CFbsBitmap* aBitmap)
   727 	{
   728 	if (PdrControl()->IsGraphicsBand())
   729 		iBandedGc->UseBrushPattern(aBitmap);
   730 	}
   731 
   732 EXPORT_C void CPdrGc::DiscardBrushPattern()
   733 	{
   734 	if (PdrControl()->IsGraphicsBand())
   735 		iBandedGc->DiscardBrushPattern();
   736 	}
   737 
   738 EXPORT_C void CPdrGc::SetUnderlineStyle(TFontUnderline aUnderlineStyle)
   739 	{
   740 	if (!PdrControl()->IsGraphicsBand())
   741 		iUnderlineStyle = aUnderlineStyle;
   742 	iBandedGc->SetUnderlineStyle(aUnderlineStyle);
   743 	}
   744 
   745 EXPORT_C void CPdrGc::SetStrikethroughStyle(TFontStrikethrough aStrikethroughStyle)
   746 	{
   747 	if (!PdrControl()->IsGraphicsBand())
   748 		iStrikethroughStyle = aStrikethroughStyle;
   749 	iBandedGc->SetStrikethroughStyle(aStrikethroughStyle);
   750 	}
   751 
   752 EXPORT_C void CPdrGc::SetWordJustification(TInt aExcessWidth,TInt aNumGaps)
   753 	{
   754 	if (!PdrControl()->IsGraphicsBand())
   755 		{
   756 		iWordExcessWidthInPixels = aExcessWidth;
   757 		iNumGaps = aNumGaps;
   758 		}
   759 	iBandedGc->SetWordJustification(aExcessWidth, aNumGaps);
   760 	}
   761 
   762 EXPORT_C void CPdrGc::SetCharJustification(TInt aExcessWidth,TInt aNumChars)
   763 	{
   764 	if (!PdrControl()->IsGraphicsBand())
   765 		{
   766 		iCharExcessWidthInPixels = aExcessWidth;
   767 		iNumChars = aNumChars;
   768 		}
   769 	iBandedGc->SetCharJustification(aExcessWidth, aNumChars);
   770 	}
   771 
   772 EXPORT_C void CPdrGc::MoveTo(const TPoint& aPoint)
   773 	{
   774 	if (!PdrControl()->IsGraphicsBand())
   775 		iPosition = aPoint;
   776 	iBandedGc->MoveTo(aPoint);
   777 	}
   778 
   779 EXPORT_C void CPdrGc::MoveBy(const TPoint& aVector)
   780 	{
   781 	if (!PdrControl()->IsGraphicsBand())
   782 		iPosition += aVector;
   783 	iBandedGc->MoveBy(aVector);
   784 	}
   785 
   786 EXPORT_C void CPdrGc::Plot(const TPoint& aPoint)
   787 	{
   788 	if (PdrControl()->IsGraphicsBand())
   789 		iBandedGc->Plot(aPoint);
   790 	}
   791 
   792 EXPORT_C void CPdrGc::DrawArc(const TRect& aRect,const TPoint& aStart,const TPoint& aEnd)
   793 	{
   794 	if (PdrControl()->IsGraphicsBand())
   795 		iBandedGc->DrawArc(aRect, aStart, aEnd);
   796 	}
   797 
   798 EXPORT_C void CPdrGc::DrawLine(const TPoint& aPoint1,const TPoint& aPoint2)
   799 	{
   800 	if (PdrControl()->IsGraphicsBand())
   801 		iBandedGc->DrawLine(aPoint1, aPoint2);
   802 	}
   803 
   804 EXPORT_C void CPdrGc::DrawLineTo(const TPoint& aPoint)
   805 	{
   806 	if (PdrControl()->IsGraphicsBand())
   807 		iBandedGc->DrawLineTo(aPoint);
   808 	}
   809 
   810 EXPORT_C void CPdrGc::DrawLineBy(const TPoint& aVector)
   811 	{
   812 	if (PdrControl()->IsGraphicsBand())
   813 		iBandedGc->DrawLineBy(aVector);
   814 	}
   815 
   816 EXPORT_C void CPdrGc::DrawPolyLine(const CArrayFix<TPoint>* aPointList)
   817 	{
   818 	if (PdrControl()->IsGraphicsBand())
   819 		iBandedGc->DrawPolyLine(aPointList);
   820 	}
   821 
   822 EXPORT_C void CPdrGc::DrawPolyLine(const TPoint* aPointList,TInt aNumPoints)
   823 	{
   824 	if (PdrControl()->IsGraphicsBand())
   825 		iBandedGc->DrawPolyLine(aPointList, aNumPoints);
   826 	}
   827 
   828 EXPORT_C void CPdrGc::DrawPie(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
   829 	{
   830 	if (PdrControl()->IsGraphicsBand())
   831 		iBandedGc->DrawPie(aRect, aStart, aEnd);
   832 	}
   833 
   834 EXPORT_C void CPdrGc::DrawEllipse(const TRect& aRect)
   835 	{
   836 	if (PdrControl()->IsGraphicsBand())
   837 		iBandedGc->DrawEllipse(aRect);
   838 	}
   839 
   840 EXPORT_C void CPdrGc::DrawRect(const TRect& aRect)
   841 	{
   842 	if (PdrControl()->IsGraphicsBand())
   843 		iBandedGc->DrawRect(aRect);
   844 	}
   845 
   846 EXPORT_C void CPdrGc::DrawRoundRect(const TRect& aRect,const TSize& aCornerSize)
   847 	{
   848 	if (PdrControl()->IsGraphicsBand())
   849 		iBandedGc->DrawRoundRect(aRect, aCornerSize);
   850 	}
   851 
   852 EXPORT_C TInt CPdrGc::DrawPolygon(const CArrayFix<TPoint>* aPointList, TFillRule aFillRule)
   853 	{
   854 	TInt ret = KErrNone;
   855 	if (PdrControl()->IsGraphicsBand())
   856 		ret = iBandedGc->DrawPolygon(aPointList, aFillRule);
   857 	return ret;
   858 	}
   859 
   860 EXPORT_C TInt CPdrGc::DrawPolygon(const TPoint* aPointList,TInt aNumPoints,TFillRule aFillRule)
   861 	{
   862 	TInt ret = KErrNone;
   863 	if (PdrControl()->IsGraphicsBand())
   864 		ret = iBandedGc->DrawPolygon(aPointList, aNumPoints, aFillRule);
   865 	return ret;
   866 	}
   867 
   868 EXPORT_C void CPdrGc::DrawBitmap(const TPoint& aTopLeft, const CFbsBitmap* aSource)
   869 	{
   870 	if (PdrControl()->IsGraphicsBand())
   871 		iBandedGc->DrawBitmap(aTopLeft, aSource);
   872 	}
   873 
   874 EXPORT_C void CPdrGc::DrawBitmap(const TRect& aDestRect, const CFbsBitmap* aSource)
   875 	{
   876 	if (PdrControl()->IsGraphicsBand())
   877 		iBandedGc->DrawBitmap(aDestRect, aSource);
   878 	}
   879 
   880 EXPORT_C void CPdrGc::DrawBitmap(const TRect& aDestRect, const CFbsBitmap* aSource, const TRect& aSourceRect)
   881 	{
   882 	if (PdrControl()->IsGraphicsBand())
   883 		iBandedGc->DrawBitmap(aDestRect, aSource, aSourceRect);
   884 	}
   885 
   886 EXPORT_C void CPdrGc::DrawBitmapMasked(const TRect& /*aDestRect*/,const CFbsBitmap* /*aBitmap*/,const TRect& /*aSourceRect*/,const CFbsBitmap* /*aMaskBitmap*/,TBool /*aInvertMask*/)
   887 	{}
   888 
   889 EXPORT_C void CPdrGc::DrawBitmapMasked(const TRect& /*aDestRect*/,const CWsBitmap* /*aBitmap*/,const TRect& /*aSourceRect*/,const CWsBitmap* /*aMaskBitmap*/,TBool /*aInvertMask*/)
   890 	{}
   891 		
   892 EXPORT_C void CPdrGc::MapColors(const TRect& /*aRect*/,const TRgb* /*aColors*/,TInt /*aNumPairs*/,TBool /*aMapForwards*/)
   893 	{
   894 	}
   895 
   896 EXPORT_C TInt CPdrGc::SetClippingRegion(const TRegion &/*aRegion*/)
   897 	{	
   898 		return KErrNone;
   899 	}
   900 
   901 EXPORT_C void CPdrGc::CancelClippingRegion()
   902 	{}
   903 
   904 EXPORT_C void CPdrGc::DrawTextVertical(const TDesC& /*aText*/,const TPoint& /*aPos*/,TBool /*aUp*/)
   905 	{}
   906 	
   907 EXPORT_C void CPdrGc::DrawTextVertical(const TDesC& /*aText*/,const TRect& /*aBox*/,TInt /*aBaselineOffset*/,TBool /*aUp*/,TTextAlign /*aVert*/,TInt /*aMargin*/)
   908 	{}
   909 
   910 EXPORT_C TInt CPdrGc::AlphaBlendBitmaps(const TPoint& /*aDestPt*/, const CFbsBitmap* /*aSrcBmp*/, const TRect& /*aSrcRect*/, const CFbsBitmap* /*aAlphaBmp*/, const TPoint& /*aAlphaPt*/) 
   911 	{
   912 		return KErrNone;
   913 	}
   914 	
   915 EXPORT_C TInt CPdrGc::AlphaBlendBitmaps(const TPoint& /*aDestPt*/, const CWsBitmap* /*aSrcBmp*/,  const TRect& /*aSrcRect*/, const CWsBitmap*  /*aAlphaBmp*/, const TPoint& /*aAlphaPt*/)
   916 	{
   917 		return KErrNone;
   918 	}
   919 
   920 CPdrControl* CPdrGc::PdrControl() const 
   921 {
   922 	return ((CPdrControl*) iPdrDevice->iControl);
   923 }
   924 
   925 /**
   926 @deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
   927 @see CPdrGc::DrawTextL
   928 */
   929 
   930 EXPORT_C void CPdrGc::DrawText(const TDesC& aString, const TPoint& aPosition)
   931 	{
   932 	TRAP_IGNORE(DrawTextL(aString, aPosition));
   933 	}
   934 
   935 EXPORT_C void CPdrGc::DrawTextL(const TDesC& aString, const TPoint& aPosition)
   936 	{
   937 	if (!iPrintTextUsingBitmaps)
   938 		{
   939 		TInt firstCharNot = 0;
   940 		TInt length = 0;
   941 		__ASSERT_DEBUG(iFont, Panic(EPdrNoFontInUse));
   942 		if (iFont->AllCharsInFontRepertoire(aString, firstCharNot, length))
   943 			{
   944 			iPosition = aPosition;
   945 			TInt start = 0;
   946 			TPtrC ptr;  // Checks to see iWordExcessWidthInPixels > 0 to avoid panic in JustificationInPixels()
   947 			for (TInt i = 0; (i < aString.Length()) && iNumGaps && iWordExcessWidthInPixels; i++)
   948 				{
   949 				if (aString[i] == ' ')
   950 					{
   951 					ptr.Set(aString.Mid(start, i - start + 1));
   952 					if (!PdrControl()->IsGraphicsBand())
   953 						{
   954 						PdrControl()->DrawTextL(iPosition + iOrigin, iUnderlineStyle, iStrikethroughStyle, iPenColor, iFont, ptr);
   955 						}
   956 					iPosition += TPoint(iFont->MeasureText(ptr) + JustificationInPixels(iWordExcessWidthInPixels, iNumGaps), 0);
   957 					start = i + 1;
   958 					}
   959 				}
   960 			if (start < aString.Length())
   961 				{
   962 				ptr.Set(aString.Mid(start));
   963 				if (!PdrControl()->IsGraphicsBand())
   964 					{
   965 					PdrControl()->DrawTextL(iPosition + iOrigin, iUnderlineStyle, iStrikethroughStyle, iPenColor, iFont, ptr);
   966 					}
   967 				iPosition += TPoint(iFont->MeasureText(ptr), 0);
   968 				}
   969 			}
   970 		else
   971 			{
   972 			if (firstCharNot > 0)
   973 				{	// Take text substring and draw it
   974 				TPtrC ptr;
   975 				ptr.Set(aString.Mid(0, firstCharNot));
   976 				DrawText(ptr, aPosition);
   977 				// Whole string wasn't text so there must be some (bitmap) string left
   978 				// Update drawing position
   979 				TPoint position = iPosition;
   980 				// Take rest of string and try again
   981 				ptr.Set(aString.Mid(firstCharNot));
   982 				DrawText(ptr, position);
   983 				}
   984 			else
   985 				{	// Take bitmap substring and draw it
   986 				TPtrC ptr;
   987 				ptr.Set(aString.Mid(0, length));
   988 				if (PdrControl()->IsGraphicsBand())
   989 					{
   990 					iPrintTextUsingBitmaps = ETrue;
   991 					DrawText(ptr, aPosition);
   992 					iPrintTextUsingBitmaps = EFalse;
   993 					}
   994 				if (length < aString.Length())
   995 					{
   996 					// There must be some (text) string left
   997 					// Update drawing position
   998 					iPosition = aPosition;
   999 					TPtrC ptr2;
  1000 					TInt start = 0;
  1001 					// Checks to see iWordExcessWidthInPixels > 0 to avoid panic in JustificationInPixels()
  1002 					for (TInt i = 0; (i < ptr.Length()) && iNumGaps && iWordExcessWidthInPixels; i++)
  1003 						{
  1004 						if (ptr[i] == ' ')
  1005 							{
  1006 							ptr2.Set(ptr.Mid(start, i - start + 1));
  1007 							iPosition += TPoint(iFont->MeasureText(ptr2) + JustificationInPixels(iWordExcessWidthInPixels, iNumGaps), 0);
  1008 							start = i + 1;
  1009 							}
  1010 						}
  1011 					if (start < ptr.Length())
  1012 						{
  1013 						ptr2.Set(ptr.Mid(start));
  1014 						iPosition += TPoint(iFont->MeasureText(ptr2), 0);
  1015 						}
  1016 					TPoint position = iPosition;
  1017 					// Take rest of string and try again
  1018 					ptr.Set(aString.Mid(length));
  1019 					DrawText(ptr, position);
  1020 					}
  1021 				}
  1022 			}
  1023 		}
  1024 	else
  1025 		{
  1026 		if (PdrControl()->IsGraphicsBand())
  1027 			iBandedGc->DrawText(aString, aPosition);
  1028 		}
  1029 	}
  1030 
  1031 EXPORT_C void CPdrGc::DrawText(const TDesC& aString, const TRect& aBox, TInt aBaselineOffset, TTextAlign aHoriz, TInt aLeftMrg)
  1032 	{
  1033 	if (!iPrintTextUsingBitmaps)
  1034 		{
  1035 		__ASSERT_DEBUG(iFont, Panic(EPdrNoFontInUse));
  1036 		if (!PdrControl()->IsGraphicsBand())
  1037 			{
  1038 			TInt width = iFont->MeasureText(aString);
  1039 			TPoint pos;
  1040 			pos.iY = aBox.iTl.iY + aBaselineOffset;
  1041 			if (aHoriz == ELeft)
  1042 				pos.iX = aBox.iTl.iX + aLeftMrg;
  1043 			else if (aHoriz == ERight)
  1044 				pos.iX = aBox.iBr.iX - aLeftMrg - width;
  1045 			else if (aHoriz == ECenter)
  1046 				pos.iX = (aBox.iTl.iX + aBox.iBr.iX - width) / 2;
  1047 			DrawText(aString, pos);
  1048 			}
  1049 		else
  1050 			iBandedGc->DrawText(KNullDesC, aBox, aBaselineOffset, aHoriz, aLeftMrg);
  1051 		}
  1052 	else
  1053 		{
  1054 		if (PdrControl()->IsGraphicsBand())
  1055 			iBandedGc->DrawText(aString, aBox, aBaselineOffset, aHoriz, aLeftMrg);
  1056 		}
  1057 	}