printingservices/printerdriversupport/src/FBSDRV.CPP
changeset 0 5d03bc08d59c
child 69 3365349494cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/printingservices/printerdriversupport/src/FBSDRV.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,526 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "PDRSTD.H"
+#include <fbs.h>
+#include <bitdev.h>
+#include <banddev.h>
+#include <pdrstore.h>
+#include "pdrtext.h"
+
+EXPORT_C CFbsDrvDevice::CFbsDrvDevice()
+	{
+	__DECLARE_NAME(_S("CFbsDrvDevice"));
+	}
+
+EXPORT_C CFbsDrvDevice::~CFbsDrvDevice()
+	{
+	delete iFbsTypefaceStore;
+	delete iGenTypefaceFontsList;
+	delete iGenTypefaceFontsType;
+	}
+
+/** Creates a font from those available in the printer device's 
+typeface store that most closely matches a font specification. 
+
+When the font is no longer needed, call ReleaseFont().
+
+This function is replaced by GetNearestFontToDesignHeightInTwips()
+
+@param aFont On return, points to the font which most closely matches the 
+specified font.
+@param aFontSpec An absolute font specification. Its iHeight member is 
+interpreted as being in twips.
+@return KErrNone if successful; otherwise, another one of the system-wide error 
+codes.
+@deprecated */
+EXPORT_C TInt CFbsDrvDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
+	{
+	return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
+	}
+
+/** Creates a font from those available in the printer device's 
+typeface store that most closely matches a font specification. 
+
+When the font is no longer needed, call ReleaseFont().
+
+This function replaces GetNearestFontInTwips()
+
+@param aFont On return, points to the font which most closely matches the 
+specified font.
+@param aFontSpec An absolute font specification. Its iHeight member is 
+interpreted as being in twips.
+@return KErrNone if successful; otherwise, another one of the system-wide error 
+codes. */
+EXPORT_C TInt CFbsDrvDevice::GetNearestFontToDesignHeightInTwips(CFont *&aFont, const TFontSpec &aFontSpec)
+	{
+    TRAPD(errCode, LoadTypeFaceListL());
+	if(errCode != KErrNone)
+		{
+		return errCode;
+		}
+	TInt count = iGenTypefaceFontsList->Count();
+	TInt count_fbs = 0;
+	TTypefaceSupport support ;				// holds typeface from iGenTypefaceFontsList
+	TTypeface typeface = aFontSpec.iTypeface;	// holds typeface from aFontSpec
+	TBuf<KMaxTypefaceNameLength> support_name;
+	TBuf<KMaxTypefaceNameLength> typeface_name;
+	TBuf<KMaxTypefaceNameLength> aname;
+	typeface_name.Copy(typeface.iName);
+	TInt loop;
+	TInt found = 0;
+	TInt listindex = 0;
+	TTypefaceSupport lsupport;
+	// Try to match specified font name with name from typeface font list
+	for (loop = 0; (loop < count) && (typeface.iName.CompareF(support.iTypeface.iName)); loop++)
+		{
+		TInt index = iGenTypefaceFontsList->At(loop);
+		TInt type = iGenTypefaceFontsType->At(loop);
+		if (type == 0)
+			{
+			iTypefaceStore->TypefaceSupport(support,index);
+			support_name.Copy(support.iTypeface.iName);
+			}
+		else if(type == 1)
+			{
+			iFbsTypefaceStore->TypefaceSupport(support,index);
+			if(support.iIsScalable)
+				{
+				count_fbs++;
+				support_name.Copy(support.iTypeface.iName);
+				}
+			}
+		if (!typeface.iName.CompareF(support.iTypeface.iName))
+			{
+			typeface_name.Copy(support.iTypeface.iName);
+			found = 1;
+			}
+		}
+
+	if (found)
+		{
+		if (loop <= iFbsTypefaceCount)
+			{
+			TFontSpec fontspec(aFontSpec);
+			fontspec.iTypeface=support.iTypeface;
+			return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
+			}
+		else if (loop <= count)
+			{
+			TFontSpec fontspec(aFontSpec);
+			fontspec.iTypeface=support.iTypeface;
+			return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
+			}
+		}
+	else 
+		{
+		if (!typeface.IsSymbol())
+			{	// To match first non-symbol, serif, proportional
+			TypefaceSupport(lsupport, 0);
+			while ((listindex < count) && ((lsupport.iTypeface.IsSymbol() ||
+				(typeface.IsProportional() != lsupport.iTypeface.IsProportional()) ||
+				(typeface.IsSerif() != lsupport.iTypeface.IsSerif()))))
+				{
+				TypefaceSupport(lsupport, listindex);
+				aname.Copy(lsupport.iTypeface.iName);
+				listindex++;
+				}
+			if (listindex == count)
+				{	// try to match first non-symbol.proportional
+				listindex = 0;
+				do
+					{
+					TypefaceSupport(lsupport, listindex);
+					aname.Copy(lsupport.iTypeface.iName);
+					listindex++;
+					}
+				while ((listindex < count) && (lsupport.iTypeface.IsSymbol() ||
+					(typeface.IsProportional() != lsupport.iTypeface.IsProportional())));
+				}
+			if (listindex == count)
+				{	// try to match first non-symbol
+				listindex = 0;
+				do
+					{
+					TypefaceSupport(lsupport, listindex);
+					aname.Copy(lsupport.iTypeface.iName);
+					listindex++;
+					}
+				while ((listindex < count) && lsupport.iTypeface.IsSymbol());
+				}
+			}
+		else
+			{	// try to match first symbol typeface
+			listindex = 0;
+			TypefaceSupport(lsupport, 0);
+
+			while ((listindex < count) && !lsupport.iTypeface.IsSymbol())
+				{
+				TypefaceSupport(lsupport, listindex);
+				aname.Copy(lsupport.iTypeface.iName);
+				listindex++;
+				}
+			}
+		if (listindex == count)
+			{
+			listindex = 0;
+			TypefaceSupport(lsupport, listindex);
+			}
+		}
+		
+	if (listindex <= iFbsTypefaceCount)
+		{
+		TFontSpec fontspec(aFontSpec);
+		fontspec.iTypeface = lsupport.iTypeface;
+		TBuf<KMaxTypefaceNameLength> fontspec_name;
+		fontspec_name.Copy(fontspec.iTypeface.iName);
+		return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
+		}
+	else
+		{
+		TFontSpec fontspec(aFontSpec);
+		fontspec.iTypeface = lsupport.iTypeface;
+		TBuf<KMaxTypefaceNameLength> fontspec_name;
+		fontspec_name.Copy(fontspec.iTypeface.iName);
+		return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
+		}
+	}
+
+EXPORT_C void CFbsDrvDevice::ReleaseFont(CFont* aFont)
+	{
+	if (aFont)
+		{
+		if (aFont->TypeUid() != KCFbsFontUid)
+			{
+			iTypefaceStore->ReleaseFont(aFont);
+			}
+		else
+			{
+			iFbsTypefaceStore->ReleaseFont(aFont);
+			}
+		}
+	}
+
+EXPORT_C TInt CFbsDrvDevice::NumTypefaces() const
+	{
+	return iGenTypefaceFontsList->Count();
+	}
+
+/**
+@deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
+@see CFbsDrvDevice::LoadTypeFaceListL
+*/
+
+EXPORT_C void CFbsDrvDevice::LoadTypeFaceList()
+	{
+	// Trap and Ignore the ERROR code as its a non-leaving method.
+	TRAP_IGNORE(LoadTypeFaceListL());
+	}
+
+/**
+New Updated LoadTypeFaceList() method
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsDrvDevice::LoadTypeFaceListL()
+	{
+	iFbsTypefaceCount = 0;
+	iPdrTypefaceCount = 0;
+	if (iGenTypefaceFontsList)
+		iGenTypefaceFontsList->Reset();
+	else
+		iGenTypefaceFontsList = new (ELeave) CArrayFixFlat<TInt>(1);
+
+	if (iGenTypefaceFontsType)
+		iGenTypefaceFontsType->Reset();
+	else
+		iGenTypefaceFontsType = new (ELeave) CArrayFixFlat<TInt>(1);
+		
+	TInt loop;
+	for(loop = 0; loop < iFbsTypefaceStore->NumTypefaces(); loop++)
+		{
+		TTypefaceSupport support;
+		iFbsTypefaceStore->TypefaceSupport(support, loop);
+			{
+			if (support.iIsScalable)
+				{
+				iGenTypefaceFontsList->AppendL(loop);
+				iGenTypefaceFontsType->AppendL(1);
+				iFbsTypefaceCount++;
+				}
+			}
+		}
+
+	for (loop = 0; loop < iTypefaceStore->NumTypefaces(); loop++)
+		{
+		TTypefaceSupport support;
+		iTypefaceStore->TypefaceSupport(support, loop);
+
+		TBuf<KMaxTypefaceNameLength> name;
+		name.Copy(support.iTypeface.iName);
+
+		iGenTypefaceFontsList->AppendL(loop);
+		iGenTypefaceFontsType->AppendL(0);
+		iPdrTypefaceCount++;
+		}
+	}
+
+EXPORT_C void CFbsDrvDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport, TInt aTypefaceIndex) const
+	{
+	TInt index = iGenTypefaceFontsList->At(aTypefaceIndex);
+	TInt type = iGenTypefaceFontsType->At(aTypefaceIndex);
+
+	if (type == 0)
+		iTypefaceStore->TypefaceSupport(aTypefaceSupport, index);
+	else
+		iFbsTypefaceStore->TypefaceSupport(aTypefaceSupport, index);
+	}
+
+EXPORT_C TInt CFbsDrvDevice::FontHeightInTwips(TInt aTypefaceIndex, TInt aHeightIndex) const
+	{
+	TInt index = iGenTypefaceFontsList->At(aTypefaceIndex);
+	TInt type = iGenTypefaceFontsType->At(aTypefaceIndex);
+
+	if (type == 0)
+		return iTypefaceStore->FontHeightInTwips(index, aHeightIndex);
+	else
+		return iFbsTypefaceStore->FontHeightInTwips(index, aHeightIndex);
+	}
+
+EXPORT_C TInt CFbsDrvDevice::CreateContext(CGraphicsContext*& aGc)
+	{
+	__ASSERT_DEBUG(iControl, Panic(EPdrControlDoesNotExist));
+	CPdrControl* control = (CPdrControl*)iControl;
+	return control->CreateContext(aGc);
+	}
+
+EXPORT_C void CFbsDrvDevice::CreateControlL(CPrinterPort* aPrinterPort)
+	{
+	__ASSERT_ALWAYS(aPrinterPort, Panic(EPdrRequiresPrinterPort));
+	__ASSERT_ALWAYS(!iControl, Panic(EPdrControlAlreadyExists));
+	__ASSERT_DEBUG(iCurrentPageSpecInTwips.iPortraitPageSize.iWidth && iCurrentPageSpecInTwips.iPortraitPageSize.iHeight, Panic(EPdrPageSpecNotSet));
+	iControl = CFbsDrvControl::NewL(this, aPrinterPort, *iStore, iModelInfo->iResourcesStreamId);
+	}
+
+/**
+@deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
+@see CFbsDrvDevice::SetModelL
+*/
+EXPORT_C TInt CFbsDrvDevice::SetModel(const TPrinterModelHeader& aModel, CStreamStore& aStore)
+	{
+	TInt ret = 0;
+	TRAPD(errCode, ret=SetModelL(aModel, aStore));
+	if(errCode != KErrNone)
+		{
+		return errCode;
+		}
+	return ret;
+	}
+
+EXPORT_C TInt CFbsDrvDevice::SetModelL(const TPrinterModelHeader& aModel, CStreamStore& aStore)
+	{
+	TInt ret = CPdrDevice::SetModel(aModel, aStore);
+	if (ret == KErrNone)
+		{
+		iFbsTypefaceStore = CFbsTypefaceStore::NewL(this);
+		LoadTypeFaceListL();
+		}
+	return ret;
+	}
+
+EXPORT_C TSize CFbsDrvDevice::KPixelSizeInTwips() const
+	{
+	return TSize(iModelInfo->iKPixelWidthInTwips, iModelInfo->iKPixelHeightInTwips);
+	}
+
+EXPORT_C void CFbsDrvDevice::Reserved_1()
+	{
+	}
+
+EXPORT_C CFbsDrvControl* CFbsDrvControl::NewL(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort, CStreamStore& aStore, TStreamId aResourcesStreamId)
+	{
+	CFbsDrvControl* control = new(ELeave) CFbsDrvControl(aPdrDevice, aPrinterPort);
+	CleanupStack::PushL(control);
+	control->ConstructL(aStore, aResourcesStreamId);
+	CleanupStack::Pop();
+	return control;
+	}
+
+EXPORT_C CFbsDrvControl::~CFbsDrvControl()
+	{
+	delete iScanLine;
+	delete iCompressedScanLine;
+	}
+
+EXPORT_C CFbsDrvControl::CFbsDrvControl(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort):
+	CPdrControl(aPdrDevice, aPrinterPort),
+	iScanLine(NULL),
+	iCompressedScanLine(NULL)
+	{
+	__DECLARE_NAME(_S("CFbsDrvControl"));
+	}
+
+EXPORT_C void CFbsDrvControl::ConstructL(CStreamStore& aStore, TStreamId aResourcesStreamId)
+	{
+	CPdrControl::ConstructL(aStore, aResourcesStreamId);
+	}
+
+EXPORT_C void CFbsDrvControl::SetPageSizeL()
+	{
+	TCommandString des;
+	des.Format(iResources->ResourceString(EPdrSetPageSize), iPdrDevice->CurrentPageSpecInTwips().iPortraitPageSize.iHeight / KTwipsPerInch);
+	iPageBuffer->AddBytesL(des);
+	}
+
+/**
+ @return ETrue if there are non-blank bytes in scanline. 
+ */
+EXPORT_C TBool CFbsDrvControl::TransformBuffer()
+	{	
+	TInt i;
+	for (i = iScanLine->Des().Length() - 1; (i >= 0) && (iScanLine->Des()[i] == 0xFF); i--)
+		{
+		}
+	TInt length = i + 1;
+	iScanLine->Des().SetLength(length);
+	TUint8* p = (TUint8*)iScanLine->Des().Ptr();
+	TUint8* pEnd = p + length;
+	for (; p < pEnd; p++)
+		{
+		TInt byte1 = *p;
+		TInt byte2 = 0;
+		for (TInt j = 0; j < 8; j++)
+			{
+			byte2 = byte2 << 1;
+			byte2 |= (byte1 & 1);
+			byte1 = byte1 >> 1;
+			}
+		*p = (TUint8)~byte2; 
+		}
+	return (length > 0);	// returns ETrue if there are non-blank bytes in scanline
+	}
+
+/**
+ @return ETrue if the scanline is compressed successfully. 
+ */
+EXPORT_C TBool CFbsDrvControl::CompressBuffer()
+	{
+	TInt length1 = iScanLine->Des().Length();
+	TInt length2 = 0;
+	TUint8* p1 = (TUint8*)iScanLine->Des().Ptr();
+	TUint8* p2 = (TUint8*)iCompressedScanLine->Des().Ptr();
+	TUint8 repeat;
+	for (TInt i = 0; (i < length1) && (length2 < length1); i += repeat + 1)
+		{
+		TUint8 byte = *(p1++);
+		for (repeat = 0; ((i + repeat + 1) < length1) && (byte == *p1) && (repeat < 255);)
+			{
+			repeat++;
+			p1++;
+			}
+		length2++;
+		if (length2 < length1)
+			{
+			*(p2++) = repeat;
+			length2++;
+			if (length2 < length1)
+				*(p2++) = byte;
+			}
+		}
+	iCompressedScanLine->Des().SetLength(length2);
+	return (length2 < length1);   // returns ETrue if the scanline is compressed successfully
+	}
+
+/**
+ This function is intentionally a dummy. It has to be implemented because
+ of an inherited pure virtual but it should always be overload by any class
+ that derives from it.
+*/
+EXPORT_C void CFbsDrvControl::OutputBandL()
+	{
+	// I should probably put an assert in here.
+	if (IsGraphicsBand())
+		{
+		TRect bandrect = iBandedDevice->BandRect();
+		TSize size = bandrect.Size();
+		TCommandString des;
+		TBool datainband = EFalse;
+		TInt numscanlines = size.iHeight;
+		if (iBandedDevice->BandingDirection() == EBandingRightToLeft)
+			numscanlines = size.iWidth;
+		for (TInt i = 0; i < numscanlines; i++)
+			{
+			TInt x = bandrect.iTl.iX;
+			TInt y = bandrect.iTl.iY + i;
+			TPtr8 ptr = iScanLine->Des();
+			if (iBandedDevice->BandingDirection() == EBandingTopToBottom)
+				iBandedDevice->BandBitmap()->GetScanLine(ptr, TPoint(0, i), size.iWidth, iPdrDevice->DisplayMode());
+			else
+				{
+				iBandedDevice->BandBitmap()->GetVerticalScanLine(ptr, numscanlines - (i + 1), iPdrDevice->DisplayMode());
+				x = bandrect.iBr.iX - i;
+				y = bandrect.iTl.iY;
+				}
+			if (TransformBuffer() && !datainband)
+				{
+				MoveToL(TPoint(x, y));
+				if (iBandedDevice->BandingDirection() == EBandingLeftToRight)
+					des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsPhysicalPageOrientation);
+				else
+					des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsLogicalPageOrientation);
+				iPageBuffer->AddBytesL(des);
+				datainband = ETrue;
+				}
+			if (datainband)
+				{
+				TCommandString buf = iResources->ResourceString(EPdrScanLine);
+				if (CompressBuffer())
+					{
+					des.Format(buf, EFbsRunLength, iCompressedScanLine->Des().Length());
+					iPageBuffer->AddBytesL(des);
+					iPageBuffer->AddBytesL(iCompressedScanLine->Des());
+					}
+				else
+					{
+					des.Format(buf, EFbsNone, iScanLine->Des().Length());
+					iPageBuffer->AddBytesL(des);
+					iPageBuffer->AddBytesL(iScanLine->Des());
+					}
+				}
+			}
+		iPageBuffer->AddBytesL(iResources->ResourceString(EPdrBitmapEnd));
+
+		iPosition.iX = iPdrDevice->OffsetInPixels().iX;
+		TInt numentries = iPageText->NumEntries();
+		if(numentries)
+			{
+			CPageTextEntry* entry;
+			for(TInt y = bandrect.iTl.iY; y <= bandrect.iBr.iY; y++)
+				{
+				for(TInt index = 0; (index < numentries); index++)
+					{
+					entry = (*iPageText)[index];
+					TPoint drawPos = entry->iDrawPos;
+					if(drawPos.iY == y)
+						OutputTextL(drawPos, entry->iTextWidthInPixels, *(entry->iTextFormat), *(entry->iText));										 //!!
+					}
+				}
+			}
+		}
+	}
+
+EXPORT_C void CFbsDrvControl::Reserved_1()
+	{
+	}