os/graphics/printingservices/printerdriversupport/src/FBSDRV.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1997-2010 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 "PDRSTD.H"
    17 #include <fbs.h>
    18 #include <bitdev.h>
    19 #include <banddev.h>
    20 #include <pdrstore.h>
    21 #include "pdrtext.h"
    22 
    23 EXPORT_C CFbsDrvDevice::CFbsDrvDevice()
    24 	{
    25 	__DECLARE_NAME(_S("CFbsDrvDevice"));
    26 	}
    27 
    28 EXPORT_C CFbsDrvDevice::~CFbsDrvDevice()
    29 	{
    30 	delete iFbsTypefaceStore;
    31 	delete iGenTypefaceFontsList;
    32 	delete iGenTypefaceFontsType;
    33 	}
    34 
    35 /** Creates a font from those available in the printer device's 
    36 typeface store that most closely matches a font specification. 
    37 
    38 When the font is no longer needed, call ReleaseFont().
    39 
    40 This function is replaced by GetNearestFontToDesignHeightInTwips()
    41 
    42 @param aFont On return, points to the font which most closely matches the 
    43 specified font.
    44 @param aFontSpec An absolute font specification. Its iHeight member is 
    45 interpreted as being in twips.
    46 @return KErrNone if successful; otherwise, another one of the system-wide error 
    47 codes.
    48 @deprecated */
    49 EXPORT_C TInt CFbsDrvDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
    50 	{
    51 	return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
    52 	}
    53 
    54 /** Creates a font from those available in the printer device's 
    55 typeface store that most closely matches a font specification. 
    56 
    57 When the font is no longer needed, call ReleaseFont().
    58 
    59 This function replaces GetNearestFontInTwips()
    60 
    61 @param aFont On return, points to the font which most closely matches the 
    62 specified font.
    63 @param aFontSpec An absolute font specification. Its iHeight member is 
    64 interpreted as being in twips.
    65 @return KErrNone if successful; otherwise, another one of the system-wide error 
    66 codes. */
    67 EXPORT_C TInt CFbsDrvDevice::GetNearestFontToDesignHeightInTwips(CFont *&aFont, const TFontSpec &aFontSpec)
    68 	{
    69     TRAPD(errCode, LoadTypeFaceListL());
    70 	if(errCode != KErrNone)
    71 		{
    72 		return errCode;
    73 		}
    74 	TInt count = iGenTypefaceFontsList->Count();
    75 	TInt count_fbs = 0;
    76 	TTypefaceSupport support ;				// holds typeface from iGenTypefaceFontsList
    77 	TTypeface typeface = aFontSpec.iTypeface;	// holds typeface from aFontSpec
    78 	TBuf<KMaxTypefaceNameLength> support_name;
    79 	TBuf<KMaxTypefaceNameLength> typeface_name;
    80 	TBuf<KMaxTypefaceNameLength> aname;
    81 	typeface_name.Copy(typeface.iName);
    82 	TInt loop;
    83 	TInt found = 0;
    84 	TInt listindex = 0;
    85 	TTypefaceSupport lsupport;
    86 	// Try to match specified font name with name from typeface font list
    87 	for (loop = 0; (loop < count) && (typeface.iName.CompareF(support.iTypeface.iName)); loop++)
    88 		{
    89 		TInt index = iGenTypefaceFontsList->At(loop);
    90 		TInt type = iGenTypefaceFontsType->At(loop);
    91 		if (type == 0)
    92 			{
    93 			iTypefaceStore->TypefaceSupport(support,index);
    94 			support_name.Copy(support.iTypeface.iName);
    95 			}
    96 		else if(type == 1)
    97 			{
    98 			iFbsTypefaceStore->TypefaceSupport(support,index);
    99 			if(support.iIsScalable)
   100 				{
   101 				count_fbs++;
   102 				support_name.Copy(support.iTypeface.iName);
   103 				}
   104 			}
   105 		if (!typeface.iName.CompareF(support.iTypeface.iName))
   106 			{
   107 			typeface_name.Copy(support.iTypeface.iName);
   108 			found = 1;
   109 			}
   110 		}
   111 
   112 	if (found)
   113 		{
   114 		if (loop <= iFbsTypefaceCount)
   115 			{
   116 			TFontSpec fontspec(aFontSpec);
   117 			fontspec.iTypeface=support.iTypeface;
   118 			return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
   119 			}
   120 		else if (loop <= count)
   121 			{
   122 			TFontSpec fontspec(aFontSpec);
   123 			fontspec.iTypeface=support.iTypeface;
   124 			return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
   125 			}
   126 		}
   127 	else 
   128 		{
   129 		if (!typeface.IsSymbol())
   130 			{	// To match first non-symbol, serif, proportional
   131 			TypefaceSupport(lsupport, 0);
   132 			while ((listindex < count) && ((lsupport.iTypeface.IsSymbol() ||
   133 				(typeface.IsProportional() != lsupport.iTypeface.IsProportional()) ||
   134 				(typeface.IsSerif() != lsupport.iTypeface.IsSerif()))))
   135 				{
   136 				TypefaceSupport(lsupport, listindex);
   137 				aname.Copy(lsupport.iTypeface.iName);
   138 				listindex++;
   139 				}
   140 			if (listindex == count)
   141 				{	// try to match first non-symbol.proportional
   142 				listindex = 0;
   143 				do
   144 					{
   145 					TypefaceSupport(lsupport, listindex);
   146 					aname.Copy(lsupport.iTypeface.iName);
   147 					listindex++;
   148 					}
   149 				while ((listindex < count) && (lsupport.iTypeface.IsSymbol() ||
   150 					(typeface.IsProportional() != lsupport.iTypeface.IsProportional())));
   151 				}
   152 			if (listindex == count)
   153 				{	// try to match first non-symbol
   154 				listindex = 0;
   155 				do
   156 					{
   157 					TypefaceSupport(lsupport, listindex);
   158 					aname.Copy(lsupport.iTypeface.iName);
   159 					listindex++;
   160 					}
   161 				while ((listindex < count) && lsupport.iTypeface.IsSymbol());
   162 				}
   163 			}
   164 		else
   165 			{	// try to match first symbol typeface
   166 			listindex = 0;
   167 			TypefaceSupport(lsupport, 0);
   168 
   169 			while ((listindex < count) && !lsupport.iTypeface.IsSymbol())
   170 				{
   171 				TypefaceSupport(lsupport, listindex);
   172 				aname.Copy(lsupport.iTypeface.iName);
   173 				listindex++;
   174 				}
   175 			}
   176 		if (listindex == count)
   177 			{
   178 			listindex = 0;
   179 			TypefaceSupport(lsupport, listindex);
   180 			}
   181 		}
   182 		
   183 	if (listindex <= iFbsTypefaceCount)
   184 		{
   185 		TFontSpec fontspec(aFontSpec);
   186 		fontspec.iTypeface = lsupport.iTypeface;
   187 		TBuf<KMaxTypefaceNameLength> fontspec_name;
   188 		fontspec_name.Copy(fontspec.iTypeface.iName);
   189 		return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
   190 		}
   191 	else
   192 		{
   193 		TFontSpec fontspec(aFontSpec);
   194 		fontspec.iTypeface = lsupport.iTypeface;
   195 		TBuf<KMaxTypefaceNameLength> fontspec_name;
   196 		fontspec_name.Copy(fontspec.iTypeface.iName);
   197 		return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
   198 		}
   199 	}
   200 
   201 EXPORT_C void CFbsDrvDevice::ReleaseFont(CFont* aFont)
   202 	{
   203 	if (aFont)
   204 		{
   205 		if (aFont->TypeUid() != KCFbsFontUid)
   206 			{
   207 			iTypefaceStore->ReleaseFont(aFont);
   208 			}
   209 		else
   210 			{
   211 			iFbsTypefaceStore->ReleaseFont(aFont);
   212 			}
   213 		}
   214 	}
   215 
   216 EXPORT_C TInt CFbsDrvDevice::NumTypefaces() const
   217 	{
   218 	return iGenTypefaceFontsList->Count();
   219 	}
   220 
   221 /**
   222 @deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
   223 @see CFbsDrvDevice::LoadTypeFaceListL
   224 */
   225 
   226 EXPORT_C void CFbsDrvDevice::LoadTypeFaceList()
   227 	{
   228 	// Trap and Ignore the ERROR code as its a non-leaving method.
   229 	TRAP_IGNORE(LoadTypeFaceListL());
   230 	}
   231 
   232 /**
   233 New Updated LoadTypeFaceList() method
   234 @publishedAll
   235 @released
   236 */
   237 EXPORT_C void CFbsDrvDevice::LoadTypeFaceListL()
   238 	{
   239 	iFbsTypefaceCount = 0;
   240 	iPdrTypefaceCount = 0;
   241 	if (iGenTypefaceFontsList)
   242 		iGenTypefaceFontsList->Reset();
   243 	else
   244 		iGenTypefaceFontsList = new (ELeave) CArrayFixFlat<TInt>(1);
   245 
   246 	if (iGenTypefaceFontsType)
   247 		iGenTypefaceFontsType->Reset();
   248 	else
   249 		iGenTypefaceFontsType = new (ELeave) CArrayFixFlat<TInt>(1);
   250 		
   251 	TInt loop;
   252 	for(loop = 0; loop < iFbsTypefaceStore->NumTypefaces(); loop++)
   253 		{
   254 		TTypefaceSupport support;
   255 		iFbsTypefaceStore->TypefaceSupport(support, loop);
   256 			{
   257 			if (support.iIsScalable)
   258 				{
   259 				iGenTypefaceFontsList->AppendL(loop);
   260 				iGenTypefaceFontsType->AppendL(1);
   261 				iFbsTypefaceCount++;
   262 				}
   263 			}
   264 		}
   265 
   266 	for (loop = 0; loop < iTypefaceStore->NumTypefaces(); loop++)
   267 		{
   268 		TTypefaceSupport support;
   269 		iTypefaceStore->TypefaceSupport(support, loop);
   270 
   271 		TBuf<KMaxTypefaceNameLength> name;
   272 		name.Copy(support.iTypeface.iName);
   273 
   274 		iGenTypefaceFontsList->AppendL(loop);
   275 		iGenTypefaceFontsType->AppendL(0);
   276 		iPdrTypefaceCount++;
   277 		}
   278 	}
   279 
   280 EXPORT_C void CFbsDrvDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport, TInt aTypefaceIndex) const
   281 	{
   282 	TInt index = iGenTypefaceFontsList->At(aTypefaceIndex);
   283 	TInt type = iGenTypefaceFontsType->At(aTypefaceIndex);
   284 
   285 	if (type == 0)
   286 		iTypefaceStore->TypefaceSupport(aTypefaceSupport, index);
   287 	else
   288 		iFbsTypefaceStore->TypefaceSupport(aTypefaceSupport, index);
   289 	}
   290 
   291 EXPORT_C TInt CFbsDrvDevice::FontHeightInTwips(TInt aTypefaceIndex, TInt aHeightIndex) const
   292 	{
   293 	TInt index = iGenTypefaceFontsList->At(aTypefaceIndex);
   294 	TInt type = iGenTypefaceFontsType->At(aTypefaceIndex);
   295 
   296 	if (type == 0)
   297 		return iTypefaceStore->FontHeightInTwips(index, aHeightIndex);
   298 	else
   299 		return iFbsTypefaceStore->FontHeightInTwips(index, aHeightIndex);
   300 	}
   301 
   302 EXPORT_C TInt CFbsDrvDevice::CreateContext(CGraphicsContext*& aGc)
   303 	{
   304 	__ASSERT_DEBUG(iControl, Panic(EPdrControlDoesNotExist));
   305 	CPdrControl* control = (CPdrControl*)iControl;
   306 	return control->CreateContext(aGc);
   307 	}
   308 
   309 EXPORT_C void CFbsDrvDevice::CreateControlL(CPrinterPort* aPrinterPort)
   310 	{
   311 	__ASSERT_ALWAYS(aPrinterPort, Panic(EPdrRequiresPrinterPort));
   312 	__ASSERT_ALWAYS(!iControl, Panic(EPdrControlAlreadyExists));
   313 	__ASSERT_DEBUG(iCurrentPageSpecInTwips.iPortraitPageSize.iWidth && iCurrentPageSpecInTwips.iPortraitPageSize.iHeight, Panic(EPdrPageSpecNotSet));
   314 	iControl = CFbsDrvControl::NewL(this, aPrinterPort, *iStore, iModelInfo->iResourcesStreamId);
   315 	}
   316 
   317 /**
   318 @deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
   319 @see CFbsDrvDevice::SetModelL
   320 */
   321 EXPORT_C TInt CFbsDrvDevice::SetModel(const TPrinterModelHeader& aModel, CStreamStore& aStore)
   322 	{
   323 	TInt ret = 0;
   324 	TRAPD(errCode, ret=SetModelL(aModel, aStore));
   325 	if(errCode != KErrNone)
   326 		{
   327 		return errCode;
   328 		}
   329 	return ret;
   330 	}
   331 
   332 EXPORT_C TInt CFbsDrvDevice::SetModelL(const TPrinterModelHeader& aModel, CStreamStore& aStore)
   333 	{
   334 	TInt ret = CPdrDevice::SetModel(aModel, aStore);
   335 	if (ret == KErrNone)
   336 		{
   337 		iFbsTypefaceStore = CFbsTypefaceStore::NewL(this);
   338 		LoadTypeFaceListL();
   339 		}
   340 	return ret;
   341 	}
   342 
   343 EXPORT_C TSize CFbsDrvDevice::KPixelSizeInTwips() const
   344 	{
   345 	return TSize(iModelInfo->iKPixelWidthInTwips, iModelInfo->iKPixelHeightInTwips);
   346 	}
   347 
   348 EXPORT_C void CFbsDrvDevice::Reserved_1()
   349 	{
   350 	}
   351 
   352 EXPORT_C CFbsDrvControl* CFbsDrvControl::NewL(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort, CStreamStore& aStore, TStreamId aResourcesStreamId)
   353 	{
   354 	CFbsDrvControl* control = new(ELeave) CFbsDrvControl(aPdrDevice, aPrinterPort);
   355 	CleanupStack::PushL(control);
   356 	control->ConstructL(aStore, aResourcesStreamId);
   357 	CleanupStack::Pop();
   358 	return control;
   359 	}
   360 
   361 EXPORT_C CFbsDrvControl::~CFbsDrvControl()
   362 	{
   363 	delete iScanLine;
   364 	delete iCompressedScanLine;
   365 	}
   366 
   367 EXPORT_C CFbsDrvControl::CFbsDrvControl(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort):
   368 	CPdrControl(aPdrDevice, aPrinterPort),
   369 	iScanLine(NULL),
   370 	iCompressedScanLine(NULL)
   371 	{
   372 	__DECLARE_NAME(_S("CFbsDrvControl"));
   373 	}
   374 
   375 EXPORT_C void CFbsDrvControl::ConstructL(CStreamStore& aStore, TStreamId aResourcesStreamId)
   376 	{
   377 	CPdrControl::ConstructL(aStore, aResourcesStreamId);
   378 	}
   379 
   380 EXPORT_C void CFbsDrvControl::SetPageSizeL()
   381 	{
   382 	TCommandString des;
   383 	des.Format(iResources->ResourceString(EPdrSetPageSize), iPdrDevice->CurrentPageSpecInTwips().iPortraitPageSize.iHeight / KTwipsPerInch);
   384 	iPageBuffer->AddBytesL(des);
   385 	}
   386 
   387 /**
   388  @return ETrue if there are non-blank bytes in scanline. 
   389  */
   390 EXPORT_C TBool CFbsDrvControl::TransformBuffer()
   391 	{	
   392 	TInt i;
   393 	for (i = iScanLine->Length() - 1; (i >= 0) && (iScanLine->Des()[i] == 0xFF); i--)
   394 		{
   395 		}
   396 	TInt length = i + 1;
   397 	iScanLine->Des().SetLength(length);
   398 	TUint8* p = (TUint8*)iScanLine->Des().Ptr();
   399 	TUint8* pEnd = p + length;
   400 	for (; p < pEnd; p++)
   401 		{
   402 		TInt byte1 = *p;
   403 		TInt byte2 = 0;
   404 		for (TInt j = 0; j < 8; j++)
   405 			{
   406 			byte2 = byte2 << 1;
   407 			byte2 |= (byte1 & 1);
   408 			byte1 = byte1 >> 1;
   409 			}
   410 		*p = (TUint8)~byte2; 
   411 		}
   412 	return (length > 0);	// returns ETrue if there are non-blank bytes in scanline
   413 	}
   414 
   415 /**
   416  @return ETrue if the scanline is compressed successfully. 
   417  */
   418 EXPORT_C TBool CFbsDrvControl::CompressBuffer()
   419 	{
   420 	TInt length1 = iScanLine->Des().Length();
   421 	TInt length2 = 0;
   422 	TUint8* p1 = (TUint8*)iScanLine->Des().Ptr();
   423 	TUint8* p2 = (TUint8*)iCompressedScanLine->Des().Ptr();
   424 	TUint8 repeat;
   425 	for (TInt i = 0; (i < length1) && (length2 < length1); i += repeat + 1)
   426 		{
   427 		TUint8 byte = *(p1++);
   428 		for (repeat = 0; ((i + repeat + 1) < length1) && (byte == *p1) && (repeat < 255);)
   429 			{
   430 			repeat++;
   431 			p1++;
   432 			}
   433 		length2++;
   434 		if (length2 < length1)
   435 			{
   436 			*(p2++) = repeat;
   437 			length2++;
   438 			if (length2 < length1)
   439 				*(p2++) = byte;
   440 			}
   441 		}
   442 	iCompressedScanLine->Des().SetLength(length2);
   443 	return (length2 < length1);   // returns ETrue if the scanline is compressed successfully
   444 	}
   445 
   446 /**
   447  This function is intentionally a dummy. It has to be implemented because
   448  of an inherited pure virtual but it should always be overload by any class
   449  that derives from it.
   450 */
   451 EXPORT_C void CFbsDrvControl::OutputBandL()
   452 	{
   453 	// I should probably put an assert in here.
   454 	if (IsGraphicsBand())
   455 		{
   456 		TRect bandrect = iBandedDevice->BandRect();
   457 		TSize size = bandrect.Size();
   458 		TCommandString des;
   459 		TBool datainband = EFalse;
   460 		TInt numscanlines = size.iHeight;
   461 		if (iBandedDevice->BandingDirection() == EBandingRightToLeft)
   462 			numscanlines = size.iWidth;
   463 		for (TInt i = 0; i < numscanlines; i++)
   464 			{
   465 			TInt x = bandrect.iTl.iX;
   466 			TInt y = bandrect.iTl.iY + i;
   467 			TPtr8 ptr = iScanLine->Des();
   468 			if (iBandedDevice->BandingDirection() == EBandingTopToBottom)
   469 				iBandedDevice->BandBitmap()->GetScanLine(ptr, TPoint(0, i), size.iWidth, iPdrDevice->DisplayMode());
   470 			else
   471 				{
   472 				iBandedDevice->BandBitmap()->GetVerticalScanLine(ptr, numscanlines - (i + 1), iPdrDevice->DisplayMode());
   473 				x = bandrect.iBr.iX - i;
   474 				y = bandrect.iTl.iY;
   475 				}
   476 			if (TransformBuffer() && !datainband)
   477 				{
   478 				MoveToL(TPoint(x, y));
   479 				if (iBandedDevice->BandingDirection() == EBandingLeftToRight)
   480 					des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsPhysicalPageOrientation);
   481 				else
   482 					des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsLogicalPageOrientation);
   483 				iPageBuffer->AddBytesL(des);
   484 				datainband = ETrue;
   485 				}
   486 			if (datainband)
   487 				{
   488 				TCommandString buf = iResources->ResourceString(EPdrScanLine);
   489 				if (CompressBuffer())
   490 					{
   491 					des.Format(buf, EFbsRunLength, iCompressedScanLine->Des().Length());
   492 					iPageBuffer->AddBytesL(des);
   493 					iPageBuffer->AddBytesL(iCompressedScanLine->Des());
   494 					}
   495 				else
   496 					{
   497 					des.Format(buf, EFbsNone, iScanLine->Des().Length());
   498 					iPageBuffer->AddBytesL(des);
   499 					iPageBuffer->AddBytesL(iScanLine->Des());
   500 					}
   501 				}
   502 			}
   503 		iPageBuffer->AddBytesL(iResources->ResourceString(EPdrBitmapEnd));
   504 
   505 		iPosition.iX = iPdrDevice->OffsetInPixels().iX;
   506 		TInt numentries = iPageText->NumEntries();
   507 		if(numentries)
   508 			{
   509 			CPageTextEntry* entry;
   510 			for(TInt y = bandrect.iTl.iY; y <= bandrect.iBr.iY; y++)
   511 				{
   512 				for(TInt index = 0; (index < numentries); index++)
   513 					{
   514 					entry = (*iPageText)[index];
   515 					TPoint drawPos = entry->iDrawPos;
   516 					if(drawPos.iY == y)
   517 						OutputTextL(drawPos, entry->iTextWidthInPixels, *(entry->iTextFormat), *(entry->iText));										 //!!
   518 					}
   519 				}
   520 			}
   521 		}
   522 	}
   523 
   524 EXPORT_C void CFbsDrvControl::Reserved_1()
   525 	{
   526 	}