1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/printingservices/printerdriversupport/src/FBSDRV.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,526 @@
1.4 +// Copyright (c) 1997-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "PDRSTD.H"
1.20 +#include <fbs.h>
1.21 +#include <bitdev.h>
1.22 +#include <banddev.h>
1.23 +#include <pdrstore.h>
1.24 +#include "pdrtext.h"
1.25 +
1.26 +EXPORT_C CFbsDrvDevice::CFbsDrvDevice()
1.27 + {
1.28 + __DECLARE_NAME(_S("CFbsDrvDevice"));
1.29 + }
1.30 +
1.31 +EXPORT_C CFbsDrvDevice::~CFbsDrvDevice()
1.32 + {
1.33 + delete iFbsTypefaceStore;
1.34 + delete iGenTypefaceFontsList;
1.35 + delete iGenTypefaceFontsType;
1.36 + }
1.37 +
1.38 +/** Creates a font from those available in the printer device's
1.39 +typeface store that most closely matches a font specification.
1.40 +
1.41 +When the font is no longer needed, call ReleaseFont().
1.42 +
1.43 +This function is replaced by GetNearestFontToDesignHeightInTwips()
1.44 +
1.45 +@param aFont On return, points to the font which most closely matches the
1.46 +specified font.
1.47 +@param aFontSpec An absolute font specification. Its iHeight member is
1.48 +interpreted as being in twips.
1.49 +@return KErrNone if successful; otherwise, another one of the system-wide error
1.50 +codes.
1.51 +@deprecated */
1.52 +EXPORT_C TInt CFbsDrvDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
1.53 + {
1.54 + return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
1.55 + }
1.56 +
1.57 +/** Creates a font from those available in the printer device's
1.58 +typeface store that most closely matches a font specification.
1.59 +
1.60 +When the font is no longer needed, call ReleaseFont().
1.61 +
1.62 +This function replaces GetNearestFontInTwips()
1.63 +
1.64 +@param aFont On return, points to the font which most closely matches the
1.65 +specified font.
1.66 +@param aFontSpec An absolute font specification. Its iHeight member is
1.67 +interpreted as being in twips.
1.68 +@return KErrNone if successful; otherwise, another one of the system-wide error
1.69 +codes. */
1.70 +EXPORT_C TInt CFbsDrvDevice::GetNearestFontToDesignHeightInTwips(CFont *&aFont, const TFontSpec &aFontSpec)
1.71 + {
1.72 + TRAPD(errCode, LoadTypeFaceListL());
1.73 + if(errCode != KErrNone)
1.74 + {
1.75 + return errCode;
1.76 + }
1.77 + TInt count = iGenTypefaceFontsList->Count();
1.78 + TInt count_fbs = 0;
1.79 + TTypefaceSupport support ; // holds typeface from iGenTypefaceFontsList
1.80 + TTypeface typeface = aFontSpec.iTypeface; // holds typeface from aFontSpec
1.81 + TBuf<KMaxTypefaceNameLength> support_name;
1.82 + TBuf<KMaxTypefaceNameLength> typeface_name;
1.83 + TBuf<KMaxTypefaceNameLength> aname;
1.84 + typeface_name.Copy(typeface.iName);
1.85 + TInt loop;
1.86 + TInt found = 0;
1.87 + TInt listindex = 0;
1.88 + TTypefaceSupport lsupport;
1.89 + // Try to match specified font name with name from typeface font list
1.90 + for (loop = 0; (loop < count) && (typeface.iName.CompareF(support.iTypeface.iName)); loop++)
1.91 + {
1.92 + TInt index = iGenTypefaceFontsList->At(loop);
1.93 + TInt type = iGenTypefaceFontsType->At(loop);
1.94 + if (type == 0)
1.95 + {
1.96 + iTypefaceStore->TypefaceSupport(support,index);
1.97 + support_name.Copy(support.iTypeface.iName);
1.98 + }
1.99 + else if(type == 1)
1.100 + {
1.101 + iFbsTypefaceStore->TypefaceSupport(support,index);
1.102 + if(support.iIsScalable)
1.103 + {
1.104 + count_fbs++;
1.105 + support_name.Copy(support.iTypeface.iName);
1.106 + }
1.107 + }
1.108 + if (!typeface.iName.CompareF(support.iTypeface.iName))
1.109 + {
1.110 + typeface_name.Copy(support.iTypeface.iName);
1.111 + found = 1;
1.112 + }
1.113 + }
1.114 +
1.115 + if (found)
1.116 + {
1.117 + if (loop <= iFbsTypefaceCount)
1.118 + {
1.119 + TFontSpec fontspec(aFontSpec);
1.120 + fontspec.iTypeface=support.iTypeface;
1.121 + return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
1.122 + }
1.123 + else if (loop <= count)
1.124 + {
1.125 + TFontSpec fontspec(aFontSpec);
1.126 + fontspec.iTypeface=support.iTypeface;
1.127 + return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
1.128 + }
1.129 + }
1.130 + else
1.131 + {
1.132 + if (!typeface.IsSymbol())
1.133 + { // To match first non-symbol, serif, proportional
1.134 + TypefaceSupport(lsupport, 0);
1.135 + while ((listindex < count) && ((lsupport.iTypeface.IsSymbol() ||
1.136 + (typeface.IsProportional() != lsupport.iTypeface.IsProportional()) ||
1.137 + (typeface.IsSerif() != lsupport.iTypeface.IsSerif()))))
1.138 + {
1.139 + TypefaceSupport(lsupport, listindex);
1.140 + aname.Copy(lsupport.iTypeface.iName);
1.141 + listindex++;
1.142 + }
1.143 + if (listindex == count)
1.144 + { // try to match first non-symbol.proportional
1.145 + listindex = 0;
1.146 + do
1.147 + {
1.148 + TypefaceSupport(lsupport, listindex);
1.149 + aname.Copy(lsupport.iTypeface.iName);
1.150 + listindex++;
1.151 + }
1.152 + while ((listindex < count) && (lsupport.iTypeface.IsSymbol() ||
1.153 + (typeface.IsProportional() != lsupport.iTypeface.IsProportional())));
1.154 + }
1.155 + if (listindex == count)
1.156 + { // try to match first non-symbol
1.157 + listindex = 0;
1.158 + do
1.159 + {
1.160 + TypefaceSupport(lsupport, listindex);
1.161 + aname.Copy(lsupport.iTypeface.iName);
1.162 + listindex++;
1.163 + }
1.164 + while ((listindex < count) && lsupport.iTypeface.IsSymbol());
1.165 + }
1.166 + }
1.167 + else
1.168 + { // try to match first symbol typeface
1.169 + listindex = 0;
1.170 + TypefaceSupport(lsupport, 0);
1.171 +
1.172 + while ((listindex < count) && !lsupport.iTypeface.IsSymbol())
1.173 + {
1.174 + TypefaceSupport(lsupport, listindex);
1.175 + aname.Copy(lsupport.iTypeface.iName);
1.176 + listindex++;
1.177 + }
1.178 + }
1.179 + if (listindex == count)
1.180 + {
1.181 + listindex = 0;
1.182 + TypefaceSupport(lsupport, listindex);
1.183 + }
1.184 + }
1.185 +
1.186 + if (listindex <= iFbsTypefaceCount)
1.187 + {
1.188 + TFontSpec fontspec(aFontSpec);
1.189 + fontspec.iTypeface = lsupport.iTypeface;
1.190 + TBuf<KMaxTypefaceNameLength> fontspec_name;
1.191 + fontspec_name.Copy(fontspec.iTypeface.iName);
1.192 + return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
1.193 + }
1.194 + else
1.195 + {
1.196 + TFontSpec fontspec(aFontSpec);
1.197 + fontspec.iTypeface = lsupport.iTypeface;
1.198 + TBuf<KMaxTypefaceNameLength> fontspec_name;
1.199 + fontspec_name.Copy(fontspec.iTypeface.iName);
1.200 + return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec);
1.201 + }
1.202 + }
1.203 +
1.204 +EXPORT_C void CFbsDrvDevice::ReleaseFont(CFont* aFont)
1.205 + {
1.206 + if (aFont)
1.207 + {
1.208 + if (aFont->TypeUid() != KCFbsFontUid)
1.209 + {
1.210 + iTypefaceStore->ReleaseFont(aFont);
1.211 + }
1.212 + else
1.213 + {
1.214 + iFbsTypefaceStore->ReleaseFont(aFont);
1.215 + }
1.216 + }
1.217 + }
1.218 +
1.219 +EXPORT_C TInt CFbsDrvDevice::NumTypefaces() const
1.220 + {
1.221 + return iGenTypefaceFontsList->Count();
1.222 + }
1.223 +
1.224 +/**
1.225 +@deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
1.226 +@see CFbsDrvDevice::LoadTypeFaceListL
1.227 +*/
1.228 +
1.229 +EXPORT_C void CFbsDrvDevice::LoadTypeFaceList()
1.230 + {
1.231 + // Trap and Ignore the ERROR code as its a non-leaving method.
1.232 + TRAP_IGNORE(LoadTypeFaceListL());
1.233 + }
1.234 +
1.235 +/**
1.236 +New Updated LoadTypeFaceList() method
1.237 +@publishedAll
1.238 +@released
1.239 +*/
1.240 +EXPORT_C void CFbsDrvDevice::LoadTypeFaceListL()
1.241 + {
1.242 + iFbsTypefaceCount = 0;
1.243 + iPdrTypefaceCount = 0;
1.244 + if (iGenTypefaceFontsList)
1.245 + iGenTypefaceFontsList->Reset();
1.246 + else
1.247 + iGenTypefaceFontsList = new (ELeave) CArrayFixFlat<TInt>(1);
1.248 +
1.249 + if (iGenTypefaceFontsType)
1.250 + iGenTypefaceFontsType->Reset();
1.251 + else
1.252 + iGenTypefaceFontsType = new (ELeave) CArrayFixFlat<TInt>(1);
1.253 +
1.254 + TInt loop;
1.255 + for(loop = 0; loop < iFbsTypefaceStore->NumTypefaces(); loop++)
1.256 + {
1.257 + TTypefaceSupport support;
1.258 + iFbsTypefaceStore->TypefaceSupport(support, loop);
1.259 + {
1.260 + if (support.iIsScalable)
1.261 + {
1.262 + iGenTypefaceFontsList->AppendL(loop);
1.263 + iGenTypefaceFontsType->AppendL(1);
1.264 + iFbsTypefaceCount++;
1.265 + }
1.266 + }
1.267 + }
1.268 +
1.269 + for (loop = 0; loop < iTypefaceStore->NumTypefaces(); loop++)
1.270 + {
1.271 + TTypefaceSupport support;
1.272 + iTypefaceStore->TypefaceSupport(support, loop);
1.273 +
1.274 + TBuf<KMaxTypefaceNameLength> name;
1.275 + name.Copy(support.iTypeface.iName);
1.276 +
1.277 + iGenTypefaceFontsList->AppendL(loop);
1.278 + iGenTypefaceFontsType->AppendL(0);
1.279 + iPdrTypefaceCount++;
1.280 + }
1.281 + }
1.282 +
1.283 +EXPORT_C void CFbsDrvDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport, TInt aTypefaceIndex) const
1.284 + {
1.285 + TInt index = iGenTypefaceFontsList->At(aTypefaceIndex);
1.286 + TInt type = iGenTypefaceFontsType->At(aTypefaceIndex);
1.287 +
1.288 + if (type == 0)
1.289 + iTypefaceStore->TypefaceSupport(aTypefaceSupport, index);
1.290 + else
1.291 + iFbsTypefaceStore->TypefaceSupport(aTypefaceSupport, index);
1.292 + }
1.293 +
1.294 +EXPORT_C TInt CFbsDrvDevice::FontHeightInTwips(TInt aTypefaceIndex, TInt aHeightIndex) const
1.295 + {
1.296 + TInt index = iGenTypefaceFontsList->At(aTypefaceIndex);
1.297 + TInt type = iGenTypefaceFontsType->At(aTypefaceIndex);
1.298 +
1.299 + if (type == 0)
1.300 + return iTypefaceStore->FontHeightInTwips(index, aHeightIndex);
1.301 + else
1.302 + return iFbsTypefaceStore->FontHeightInTwips(index, aHeightIndex);
1.303 + }
1.304 +
1.305 +EXPORT_C TInt CFbsDrvDevice::CreateContext(CGraphicsContext*& aGc)
1.306 + {
1.307 + __ASSERT_DEBUG(iControl, Panic(EPdrControlDoesNotExist));
1.308 + CPdrControl* control = (CPdrControl*)iControl;
1.309 + return control->CreateContext(aGc);
1.310 + }
1.311 +
1.312 +EXPORT_C void CFbsDrvDevice::CreateControlL(CPrinterPort* aPrinterPort)
1.313 + {
1.314 + __ASSERT_ALWAYS(aPrinterPort, Panic(EPdrRequiresPrinterPort));
1.315 + __ASSERT_ALWAYS(!iControl, Panic(EPdrControlAlreadyExists));
1.316 + __ASSERT_DEBUG(iCurrentPageSpecInTwips.iPortraitPageSize.iWidth && iCurrentPageSpecInTwips.iPortraitPageSize.iHeight, Panic(EPdrPageSpecNotSet));
1.317 + iControl = CFbsDrvControl::NewL(this, aPrinterPort, *iStore, iModelInfo->iResourcesStreamId);
1.318 + }
1.319 +
1.320 +/**
1.321 +@deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only.
1.322 +@see CFbsDrvDevice::SetModelL
1.323 +*/
1.324 +EXPORT_C TInt CFbsDrvDevice::SetModel(const TPrinterModelHeader& aModel, CStreamStore& aStore)
1.325 + {
1.326 + TInt ret = 0;
1.327 + TRAPD(errCode, ret=SetModelL(aModel, aStore));
1.328 + if(errCode != KErrNone)
1.329 + {
1.330 + return errCode;
1.331 + }
1.332 + return ret;
1.333 + }
1.334 +
1.335 +EXPORT_C TInt CFbsDrvDevice::SetModelL(const TPrinterModelHeader& aModel, CStreamStore& aStore)
1.336 + {
1.337 + TInt ret = CPdrDevice::SetModel(aModel, aStore);
1.338 + if (ret == KErrNone)
1.339 + {
1.340 + iFbsTypefaceStore = CFbsTypefaceStore::NewL(this);
1.341 + LoadTypeFaceListL();
1.342 + }
1.343 + return ret;
1.344 + }
1.345 +
1.346 +EXPORT_C TSize CFbsDrvDevice::KPixelSizeInTwips() const
1.347 + {
1.348 + return TSize(iModelInfo->iKPixelWidthInTwips, iModelInfo->iKPixelHeightInTwips);
1.349 + }
1.350 +
1.351 +EXPORT_C void CFbsDrvDevice::Reserved_1()
1.352 + {
1.353 + }
1.354 +
1.355 +EXPORT_C CFbsDrvControl* CFbsDrvControl::NewL(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort, CStreamStore& aStore, TStreamId aResourcesStreamId)
1.356 + {
1.357 + CFbsDrvControl* control = new(ELeave) CFbsDrvControl(aPdrDevice, aPrinterPort);
1.358 + CleanupStack::PushL(control);
1.359 + control->ConstructL(aStore, aResourcesStreamId);
1.360 + CleanupStack::Pop();
1.361 + return control;
1.362 + }
1.363 +
1.364 +EXPORT_C CFbsDrvControl::~CFbsDrvControl()
1.365 + {
1.366 + delete iScanLine;
1.367 + delete iCompressedScanLine;
1.368 + }
1.369 +
1.370 +EXPORT_C CFbsDrvControl::CFbsDrvControl(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort):
1.371 + CPdrControl(aPdrDevice, aPrinterPort),
1.372 + iScanLine(NULL),
1.373 + iCompressedScanLine(NULL)
1.374 + {
1.375 + __DECLARE_NAME(_S("CFbsDrvControl"));
1.376 + }
1.377 +
1.378 +EXPORT_C void CFbsDrvControl::ConstructL(CStreamStore& aStore, TStreamId aResourcesStreamId)
1.379 + {
1.380 + CPdrControl::ConstructL(aStore, aResourcesStreamId);
1.381 + }
1.382 +
1.383 +EXPORT_C void CFbsDrvControl::SetPageSizeL()
1.384 + {
1.385 + TCommandString des;
1.386 + des.Format(iResources->ResourceString(EPdrSetPageSize), iPdrDevice->CurrentPageSpecInTwips().iPortraitPageSize.iHeight / KTwipsPerInch);
1.387 + iPageBuffer->AddBytesL(des);
1.388 + }
1.389 +
1.390 +/**
1.391 + @return ETrue if there are non-blank bytes in scanline.
1.392 + */
1.393 +EXPORT_C TBool CFbsDrvControl::TransformBuffer()
1.394 + {
1.395 + TInt i;
1.396 + for (i = iScanLine->Length() - 1; (i >= 0) && (iScanLine->Des()[i] == 0xFF); i--)
1.397 + {
1.398 + }
1.399 + TInt length = i + 1;
1.400 + iScanLine->Des().SetLength(length);
1.401 + TUint8* p = (TUint8*)iScanLine->Des().Ptr();
1.402 + TUint8* pEnd = p + length;
1.403 + for (; p < pEnd; p++)
1.404 + {
1.405 + TInt byte1 = *p;
1.406 + TInt byte2 = 0;
1.407 + for (TInt j = 0; j < 8; j++)
1.408 + {
1.409 + byte2 = byte2 << 1;
1.410 + byte2 |= (byte1 & 1);
1.411 + byte1 = byte1 >> 1;
1.412 + }
1.413 + *p = (TUint8)~byte2;
1.414 + }
1.415 + return (length > 0); // returns ETrue if there are non-blank bytes in scanline
1.416 + }
1.417 +
1.418 +/**
1.419 + @return ETrue if the scanline is compressed successfully.
1.420 + */
1.421 +EXPORT_C TBool CFbsDrvControl::CompressBuffer()
1.422 + {
1.423 + TInt length1 = iScanLine->Des().Length();
1.424 + TInt length2 = 0;
1.425 + TUint8* p1 = (TUint8*)iScanLine->Des().Ptr();
1.426 + TUint8* p2 = (TUint8*)iCompressedScanLine->Des().Ptr();
1.427 + TUint8 repeat;
1.428 + for (TInt i = 0; (i < length1) && (length2 < length1); i += repeat + 1)
1.429 + {
1.430 + TUint8 byte = *(p1++);
1.431 + for (repeat = 0; ((i + repeat + 1) < length1) && (byte == *p1) && (repeat < 255);)
1.432 + {
1.433 + repeat++;
1.434 + p1++;
1.435 + }
1.436 + length2++;
1.437 + if (length2 < length1)
1.438 + {
1.439 + *(p2++) = repeat;
1.440 + length2++;
1.441 + if (length2 < length1)
1.442 + *(p2++) = byte;
1.443 + }
1.444 + }
1.445 + iCompressedScanLine->Des().SetLength(length2);
1.446 + return (length2 < length1); // returns ETrue if the scanline is compressed successfully
1.447 + }
1.448 +
1.449 +/**
1.450 + This function is intentionally a dummy. It has to be implemented because
1.451 + of an inherited pure virtual but it should always be overload by any class
1.452 + that derives from it.
1.453 +*/
1.454 +EXPORT_C void CFbsDrvControl::OutputBandL()
1.455 + {
1.456 + // I should probably put an assert in here.
1.457 + if (IsGraphicsBand())
1.458 + {
1.459 + TRect bandrect = iBandedDevice->BandRect();
1.460 + TSize size = bandrect.Size();
1.461 + TCommandString des;
1.462 + TBool datainband = EFalse;
1.463 + TInt numscanlines = size.iHeight;
1.464 + if (iBandedDevice->BandingDirection() == EBandingRightToLeft)
1.465 + numscanlines = size.iWidth;
1.466 + for (TInt i = 0; i < numscanlines; i++)
1.467 + {
1.468 + TInt x = bandrect.iTl.iX;
1.469 + TInt y = bandrect.iTl.iY + i;
1.470 + TPtr8 ptr = iScanLine->Des();
1.471 + if (iBandedDevice->BandingDirection() == EBandingTopToBottom)
1.472 + iBandedDevice->BandBitmap()->GetScanLine(ptr, TPoint(0, i), size.iWidth, iPdrDevice->DisplayMode());
1.473 + else
1.474 + {
1.475 + iBandedDevice->BandBitmap()->GetVerticalScanLine(ptr, numscanlines - (i + 1), iPdrDevice->DisplayMode());
1.476 + x = bandrect.iBr.iX - i;
1.477 + y = bandrect.iTl.iY;
1.478 + }
1.479 + if (TransformBuffer() && !datainband)
1.480 + {
1.481 + MoveToL(TPoint(x, y));
1.482 + if (iBandedDevice->BandingDirection() == EBandingLeftToRight)
1.483 + des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsPhysicalPageOrientation);
1.484 + else
1.485 + des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsLogicalPageOrientation);
1.486 + iPageBuffer->AddBytesL(des);
1.487 + datainband = ETrue;
1.488 + }
1.489 + if (datainband)
1.490 + {
1.491 + TCommandString buf = iResources->ResourceString(EPdrScanLine);
1.492 + if (CompressBuffer())
1.493 + {
1.494 + des.Format(buf, EFbsRunLength, iCompressedScanLine->Des().Length());
1.495 + iPageBuffer->AddBytesL(des);
1.496 + iPageBuffer->AddBytesL(iCompressedScanLine->Des());
1.497 + }
1.498 + else
1.499 + {
1.500 + des.Format(buf, EFbsNone, iScanLine->Des().Length());
1.501 + iPageBuffer->AddBytesL(des);
1.502 + iPageBuffer->AddBytesL(iScanLine->Des());
1.503 + }
1.504 + }
1.505 + }
1.506 + iPageBuffer->AddBytesL(iResources->ResourceString(EPdrBitmapEnd));
1.507 +
1.508 + iPosition.iX = iPdrDevice->OffsetInPixels().iX;
1.509 + TInt numentries = iPageText->NumEntries();
1.510 + if(numentries)
1.511 + {
1.512 + CPageTextEntry* entry;
1.513 + for(TInt y = bandrect.iTl.iY; y <= bandrect.iBr.iY; y++)
1.514 + {
1.515 + for(TInt index = 0; (index < numentries); index++)
1.516 + {
1.517 + entry = (*iPageText)[index];
1.518 + TPoint drawPos = entry->iDrawPos;
1.519 + if(drawPos.iY == y)
1.520 + OutputTextL(drawPos, entry->iTextWidthInPixels, *(entry->iTextFormat), *(entry->iText)); //!!
1.521 + }
1.522 + }
1.523 + }
1.524 + }
1.525 + }
1.526 +
1.527 +EXPORT_C void CFbsDrvControl::Reserved_1()
1.528 + {
1.529 + }