sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "CANONSTD.H" sl@0: sl@0: #include sl@0: #include sl@0: #include "CANON.H" sl@0: #include "pdrtext.h" sl@0: sl@0: sl@0: EXPORT_C CPrinterDevice* NewPrinterDeviceL() sl@0: { sl@0: CCanonDevice* device = new(ELeave) CCanonDevice; sl@0: return device; sl@0: } sl@0: sl@0: CCanonDevice::CCanonDevice(): sl@0: CFbsDrvDevice() sl@0: { sl@0: __DECLARE_NAME(_S("CCanonDevice")); sl@0: } sl@0: sl@0: CCanonDevice::~CCanonDevice() sl@0: { sl@0: } sl@0: sl@0: TInt CCanonDevice::CreateContext(CGraphicsContext*& aGC) sl@0: { sl@0: __ASSERT_DEBUG(iControl, Panic(ECanonControlDoesNotExist)); sl@0: CPdrControl* control = (CPdrControl*)iControl; sl@0: return control->CreateContext(aGC); sl@0: } sl@0: sl@0: void CCanonDevice::CreateControlL(CPrinterPort* aPrinterPort) sl@0: { sl@0: __ASSERT_ALWAYS(aPrinterPort, Panic(ECanonRequiresPrinterPort)); sl@0: __ASSERT_ALWAYS(!iControl, Panic(ECanonControlAlreadyExists)); sl@0: __ASSERT_DEBUG(iCurrentPageSpecInTwips.iPortraitPageSize.iWidth && iCurrentPageSpecInTwips.iPortraitPageSize.iHeight, Panic(ECanonPageSpecNotSet)); sl@0: iControl = CCanonControl::NewL(this, aPrinterPort, *iStore, iModelInfo->iResourcesStreamId); sl@0: } sl@0: sl@0: CCanonControl* CCanonControl::NewL(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort, CStreamStore& aStore, TStreamId aResourcesStreamId) sl@0: { sl@0: CCanonControl* control = new(ELeave) CCanonControl(aPdrDevice, aPrinterPort); sl@0: CleanupStack::PushL(control); sl@0: control->ConstructL(aStore, aResourcesStreamId); sl@0: CleanupStack::Pop(); sl@0: return control; sl@0: } sl@0: sl@0: CCanonControl::~CCanonControl() sl@0: { sl@0: } sl@0: sl@0: void CCanonControl::ConstructL(CStreamStore& aStore, TStreamId aResourcesStreamId) sl@0: { sl@0: if((iPdrDevice->CurrentPageSpecInTwips().iOrientation == TPageSpec::ELandscape) sl@0: && (iPdrDevice->Flags() & ECanonLandscapeNotAvailable)) sl@0: User::Leave(KErrNotSupported); sl@0: CFbsDrvControl::ConstructL(aStore, aResourcesStreamId); sl@0: sl@0: TRect rect = iPdrDevice->PrintablePageInPixels(); sl@0: TSize size; sl@0: size.iWidth = iPdrDevice->HorizontalPixelsToTwips(1000); sl@0: size.iHeight = iPdrDevice->VerticalPixelsToTwips(1000); sl@0: iBandedDevice = CBandedDevice::NewL(rect, size, iPdrDevice->DisplayMode(), EBandingTopToBottom, KCanonNumScanLinesPerBand); sl@0: TInt len = CFbsBitmap::ScanLineLength(iBandedDevice->BandBitmap()->SizeInPixels().iWidth, iPdrDevice->DisplayMode()); sl@0: CFbsDrvControl::iScanLine = HBufC8::NewL(len); sl@0: CFbsDrvControl::iCompressedScanLine = HBufC8::NewL(len); sl@0: iPageText = CPageText::NewL(); sl@0: } sl@0: sl@0: void CCanonControl::OutputBandL() sl@0: { sl@0: if(IsGraphicsBand()) sl@0: { sl@0: TRect bandrect = iBandedDevice->BandRect(); sl@0: TSize size = bandrect.Size(); sl@0: TCommandString des; sl@0: TBool datainband = EFalse; sl@0: for(TInt i = 0; i < size.iWidth; i++) sl@0: { sl@0: iBandedDevice->BandBitmap()->GetVerticalScanLine(iScanLine, i, iPdrDevice->DisplayMode()); sl@0: if(TransformBuffer() && !datainband) sl@0: { sl@0: MoveToL(bandrect.iTl + TPoint(i, 0)); sl@0: des.Format(iResources->ResourceString(EPdrBitmapStart), KCanonBytesPerDotColumn * (size.iWidth - i)); sl@0: iPageBuffer->AddBytesL(des); sl@0: datainband = ETrue; sl@0: } sl@0: if(datainband) sl@0: iPageBuffer->AddBytesL(iScanLine); sl@0: } sl@0: iPageBuffer->AddBytesL(iResources->ResourceString(EPdrBitmapEnd)); sl@0: sl@0: iPosition.iX = iPdrDevice->OffsetInPixels().iX; sl@0: TInt numentries = iPageText->NumEntries(); sl@0: if(numentries) sl@0: { sl@0: CPageTextEntry* entry; sl@0: for(TInt y = bandrect.iTl.iY; y <= bandrect.iBr.iY; y++) sl@0: { sl@0: for(TInt index = 0; (index < numentries); index++) sl@0: { sl@0: entry = (*iPageText)[index]; sl@0: TPoint drawPos = entry->iDrawPos - TPoint(0, 16); // bodge to align pdr fonts with true types sl@0: if(drawPos.iY == y) sl@0: OutputTextL(drawPos, entry->iTextWidthInPixels, *(entry->iTextFormat), *(entry->iText)); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CCanonControl::MoveToL(const TPoint& aPoint) sl@0: { sl@0: TPoint vector = aPoint - iPosition; sl@0: TInt maxNoOfYIncrements = 256 * 5 / 6; // Ensures no more than 256 sl@0: for(; vector.iY >= maxNoOfYIncrements; ) sl@0: { sl@0: MoveByL(TPoint(0, maxNoOfYIncrements)); sl@0: vector = aPoint - iPosition; sl@0: } sl@0: MoveByL(vector); sl@0: iPosition = aPoint; sl@0: } sl@0: sl@0: void CCanonControl::MoveByL(const TPoint& aPoint) sl@0: { sl@0: TPoint vector = aPoint; sl@0: if(vector.iX < 0) sl@0: { sl@0: CommandL(EPdrCarriageReturn); sl@0: vector.iX += iPosition.iX - iPdrDevice->OffsetInPixels().iX; sl@0: } sl@0: vector.iX = vector.iX * 2 / 3; // X increments are in 120ths of an inch sl@0: vector.iY = vector.iY * 6 / 5; // Y increments are in 216ths of an inch sl@0: TPoint oldPosition = iPosition; sl@0: CFbsDrvControl::MoveByL(vector); sl@0: iPosition = oldPosition + aPoint; // Correct the position sl@0: } sl@0: sl@0: TBool CCanonControl::TransformBuffer() sl@0: { sl@0: TUint8* pStart = (TUint8*)iScanLine.Ptr(); sl@0: TUint8* pEnd = pStart + (KCanonNumScanLinesPerBand >> 3); sl@0: TUint8* p; sl@0: for(p = pStart; (p < pEnd) && (*p == 0xFF); p++) sl@0: { sl@0: } sl@0: TBool datainscanline = (p < pEnd); sl@0: for(p = pStart; p < pEnd; p++) sl@0: { sl@0: TInt byte1 = *p; sl@0: TInt byte2 = 0; sl@0: for(TInt j = 0; j < 8; j++) sl@0: { sl@0: byte2 = byte2 << 1; sl@0: byte2 = byte2 | (byte1 & 1); sl@0: byte1 = byte1 >> 1; sl@0: } sl@0: *p = (TUint8)~byte2; sl@0: } sl@0: return datainscanline; // returns ETrue if there are non-blank bytes in scanline sl@0: } sl@0: sl@0: CCanonControl::CCanonControl(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort): sl@0: CFbsDrvControl(aPdrDevice, aPrinterPort) sl@0: { sl@0: __DECLARE_NAME(_S("CCanonControl")); sl@0: } sl@0: