sl@0: // Copyright (c) 1997-2010 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 "PDRSTD.H" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "pdrtext.h" sl@0: sl@0: EXPORT_C CFbsDrvDevice::CFbsDrvDevice() sl@0: { sl@0: __DECLARE_NAME(_S("CFbsDrvDevice")); sl@0: } sl@0: sl@0: EXPORT_C CFbsDrvDevice::~CFbsDrvDevice() sl@0: { sl@0: delete iFbsTypefaceStore; sl@0: delete iGenTypefaceFontsList; sl@0: delete iGenTypefaceFontsType; sl@0: } sl@0: sl@0: /** Creates a font from those available in the printer device's sl@0: typeface store that most closely matches a font specification. sl@0: sl@0: When the font is no longer needed, call ReleaseFont(). sl@0: sl@0: This function is replaced by GetNearestFontToDesignHeightInTwips() sl@0: sl@0: @param aFont On return, points to the font which most closely matches the sl@0: specified font. sl@0: @param aFontSpec An absolute font specification. Its iHeight member is sl@0: interpreted as being in twips. sl@0: @return KErrNone if successful; otherwise, another one of the system-wide error sl@0: codes. sl@0: @deprecated */ sl@0: EXPORT_C TInt CFbsDrvDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec) sl@0: { sl@0: return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec); sl@0: } sl@0: sl@0: /** Creates a font from those available in the printer device's sl@0: typeface store that most closely matches a font specification. sl@0: sl@0: When the font is no longer needed, call ReleaseFont(). sl@0: sl@0: This function replaces GetNearestFontInTwips() sl@0: sl@0: @param aFont On return, points to the font which most closely matches the sl@0: specified font. sl@0: @param aFontSpec An absolute font specification. Its iHeight member is sl@0: interpreted as being in twips. sl@0: @return KErrNone if successful; otherwise, another one of the system-wide error sl@0: codes. */ sl@0: EXPORT_C TInt CFbsDrvDevice::GetNearestFontToDesignHeightInTwips(CFont *&aFont, const TFontSpec &aFontSpec) sl@0: { sl@0: TRAPD(errCode, LoadTypeFaceListL()); sl@0: if(errCode != KErrNone) sl@0: { sl@0: return errCode; sl@0: } sl@0: TInt count = iGenTypefaceFontsList->Count(); sl@0: TInt count_fbs = 0; sl@0: TTypefaceSupport support ; // holds typeface from iGenTypefaceFontsList sl@0: TTypeface typeface = aFontSpec.iTypeface; // holds typeface from aFontSpec sl@0: TBuf support_name; sl@0: TBuf typeface_name; sl@0: TBuf aname; sl@0: typeface_name.Copy(typeface.iName); sl@0: TInt loop; sl@0: TInt found = 0; sl@0: TInt listindex = 0; sl@0: TTypefaceSupport lsupport; sl@0: // Try to match specified font name with name from typeface font list sl@0: for (loop = 0; (loop < count) && (typeface.iName.CompareF(support.iTypeface.iName)); loop++) sl@0: { sl@0: TInt index = iGenTypefaceFontsList->At(loop); sl@0: TInt type = iGenTypefaceFontsType->At(loop); sl@0: if (type == 0) sl@0: { sl@0: iTypefaceStore->TypefaceSupport(support,index); sl@0: support_name.Copy(support.iTypeface.iName); sl@0: } sl@0: else if(type == 1) sl@0: { sl@0: iFbsTypefaceStore->TypefaceSupport(support,index); sl@0: if(support.iIsScalable) sl@0: { sl@0: count_fbs++; sl@0: support_name.Copy(support.iTypeface.iName); sl@0: } sl@0: } sl@0: if (!typeface.iName.CompareF(support.iTypeface.iName)) sl@0: { sl@0: typeface_name.Copy(support.iTypeface.iName); sl@0: found = 1; sl@0: } sl@0: } sl@0: sl@0: if (found) sl@0: { sl@0: if (loop <= iFbsTypefaceCount) sl@0: { sl@0: TFontSpec fontspec(aFontSpec); sl@0: fontspec.iTypeface=support.iTypeface; sl@0: return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec); sl@0: } sl@0: else if (loop <= count) sl@0: { sl@0: TFontSpec fontspec(aFontSpec); sl@0: fontspec.iTypeface=support.iTypeface; sl@0: return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (!typeface.IsSymbol()) sl@0: { // To match first non-symbol, serif, proportional sl@0: TypefaceSupport(lsupport, 0); sl@0: while ((listindex < count) && ((lsupport.iTypeface.IsSymbol() || sl@0: (typeface.IsProportional() != lsupport.iTypeface.IsProportional()) || sl@0: (typeface.IsSerif() != lsupport.iTypeface.IsSerif())))) sl@0: { sl@0: TypefaceSupport(lsupport, listindex); sl@0: aname.Copy(lsupport.iTypeface.iName); sl@0: listindex++; sl@0: } sl@0: if (listindex == count) sl@0: { // try to match first non-symbol.proportional sl@0: listindex = 0; sl@0: do sl@0: { sl@0: TypefaceSupport(lsupport, listindex); sl@0: aname.Copy(lsupport.iTypeface.iName); sl@0: listindex++; sl@0: } sl@0: while ((listindex < count) && (lsupport.iTypeface.IsSymbol() || sl@0: (typeface.IsProportional() != lsupport.iTypeface.IsProportional()))); sl@0: } sl@0: if (listindex == count) sl@0: { // try to match first non-symbol sl@0: listindex = 0; sl@0: do sl@0: { sl@0: TypefaceSupport(lsupport, listindex); sl@0: aname.Copy(lsupport.iTypeface.iName); sl@0: listindex++; sl@0: } sl@0: while ((listindex < count) && lsupport.iTypeface.IsSymbol()); sl@0: } sl@0: } sl@0: else sl@0: { // try to match first symbol typeface sl@0: listindex = 0; sl@0: TypefaceSupport(lsupport, 0); sl@0: sl@0: while ((listindex < count) && !lsupport.iTypeface.IsSymbol()) sl@0: { sl@0: TypefaceSupport(lsupport, listindex); sl@0: aname.Copy(lsupport.iTypeface.iName); sl@0: listindex++; sl@0: } sl@0: } sl@0: if (listindex == count) sl@0: { sl@0: listindex = 0; sl@0: TypefaceSupport(lsupport, listindex); sl@0: } sl@0: } sl@0: sl@0: if (listindex <= iFbsTypefaceCount) sl@0: { sl@0: TFontSpec fontspec(aFontSpec); sl@0: fontspec.iTypeface = lsupport.iTypeface; sl@0: TBuf fontspec_name; sl@0: fontspec_name.Copy(fontspec.iTypeface.iName); sl@0: return iFbsTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec); sl@0: } sl@0: else sl@0: { sl@0: TFontSpec fontspec(aFontSpec); sl@0: fontspec.iTypeface = lsupport.iTypeface; sl@0: TBuf fontspec_name; sl@0: fontspec_name.Copy(fontspec.iTypeface.iName); sl@0: return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, fontspec); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CFbsDrvDevice::ReleaseFont(CFont* aFont) sl@0: { sl@0: if (aFont) sl@0: { sl@0: if (aFont->TypeUid() != KCFbsFontUid) sl@0: { sl@0: iTypefaceStore->ReleaseFont(aFont); sl@0: } sl@0: else sl@0: { sl@0: iFbsTypefaceStore->ReleaseFont(aFont); sl@0: } sl@0: } sl@0: } sl@0: sl@0: EXPORT_C TInt CFbsDrvDevice::NumTypefaces() const sl@0: { sl@0: return iGenTypefaceFontsList->Count(); sl@0: } sl@0: sl@0: /** sl@0: @deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only. sl@0: @see CFbsDrvDevice::LoadTypeFaceListL sl@0: */ sl@0: sl@0: EXPORT_C void CFbsDrvDevice::LoadTypeFaceList() sl@0: { sl@0: // Trap and Ignore the ERROR code as its a non-leaving method. sl@0: TRAP_IGNORE(LoadTypeFaceListL()); sl@0: } sl@0: sl@0: /** sl@0: New Updated LoadTypeFaceList() method sl@0: @publishedAll sl@0: @released sl@0: */ sl@0: EXPORT_C void CFbsDrvDevice::LoadTypeFaceListL() sl@0: { sl@0: iFbsTypefaceCount = 0; sl@0: iPdrTypefaceCount = 0; sl@0: if (iGenTypefaceFontsList) sl@0: iGenTypefaceFontsList->Reset(); sl@0: else sl@0: iGenTypefaceFontsList = new (ELeave) CArrayFixFlat(1); sl@0: sl@0: if (iGenTypefaceFontsType) sl@0: iGenTypefaceFontsType->Reset(); sl@0: else sl@0: iGenTypefaceFontsType = new (ELeave) CArrayFixFlat(1); sl@0: sl@0: TInt loop; sl@0: for(loop = 0; loop < iFbsTypefaceStore->NumTypefaces(); loop++) sl@0: { sl@0: TTypefaceSupport support; sl@0: iFbsTypefaceStore->TypefaceSupport(support, loop); sl@0: { sl@0: if (support.iIsScalable) sl@0: { sl@0: iGenTypefaceFontsList->AppendL(loop); sl@0: iGenTypefaceFontsType->AppendL(1); sl@0: iFbsTypefaceCount++; sl@0: } sl@0: } sl@0: } sl@0: sl@0: for (loop = 0; loop < iTypefaceStore->NumTypefaces(); loop++) sl@0: { sl@0: TTypefaceSupport support; sl@0: iTypefaceStore->TypefaceSupport(support, loop); sl@0: sl@0: TBuf name; sl@0: name.Copy(support.iTypeface.iName); sl@0: sl@0: iGenTypefaceFontsList->AppendL(loop); sl@0: iGenTypefaceFontsType->AppendL(0); sl@0: iPdrTypefaceCount++; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CFbsDrvDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport, TInt aTypefaceIndex) const sl@0: { sl@0: TInt index = iGenTypefaceFontsList->At(aTypefaceIndex); sl@0: TInt type = iGenTypefaceFontsType->At(aTypefaceIndex); sl@0: sl@0: if (type == 0) sl@0: iTypefaceStore->TypefaceSupport(aTypefaceSupport, index); sl@0: else sl@0: iFbsTypefaceStore->TypefaceSupport(aTypefaceSupport, index); sl@0: } sl@0: sl@0: EXPORT_C TInt CFbsDrvDevice::FontHeightInTwips(TInt aTypefaceIndex, TInt aHeightIndex) const sl@0: { sl@0: TInt index = iGenTypefaceFontsList->At(aTypefaceIndex); sl@0: TInt type = iGenTypefaceFontsType->At(aTypefaceIndex); sl@0: sl@0: if (type == 0) sl@0: return iTypefaceStore->FontHeightInTwips(index, aHeightIndex); sl@0: else sl@0: return iFbsTypefaceStore->FontHeightInTwips(index, aHeightIndex); sl@0: } sl@0: sl@0: EXPORT_C TInt CFbsDrvDevice::CreateContext(CGraphicsContext*& aGc) sl@0: { sl@0: __ASSERT_DEBUG(iControl, Panic(EPdrControlDoesNotExist)); sl@0: CPdrControl* control = (CPdrControl*)iControl; sl@0: return control->CreateContext(aGc); sl@0: } sl@0: sl@0: EXPORT_C void CFbsDrvDevice::CreateControlL(CPrinterPort* aPrinterPort) sl@0: { sl@0: __ASSERT_ALWAYS(aPrinterPort, Panic(EPdrRequiresPrinterPort)); sl@0: __ASSERT_ALWAYS(!iControl, Panic(EPdrControlAlreadyExists)); sl@0: __ASSERT_DEBUG(iCurrentPageSpecInTwips.iPortraitPageSize.iWidth && iCurrentPageSpecInTwips.iPortraitPageSize.iHeight, Panic(EPdrPageSpecNotSet)); sl@0: iControl = CFbsDrvControl::NewL(this, aPrinterPort, *iStore, iModelInfo->iResourcesStreamId); sl@0: } sl@0: sl@0: /** sl@0: @deprecated Interface is deprecated because it is unsafe as it may leave. It is available for backward compatibility reasons only. sl@0: @see CFbsDrvDevice::SetModelL sl@0: */ sl@0: EXPORT_C TInt CFbsDrvDevice::SetModel(const TPrinterModelHeader& aModel, CStreamStore& aStore) sl@0: { sl@0: TInt ret = 0; sl@0: TRAPD(errCode, ret=SetModelL(aModel, aStore)); sl@0: if(errCode != KErrNone) sl@0: { sl@0: return errCode; sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: EXPORT_C TInt CFbsDrvDevice::SetModelL(const TPrinterModelHeader& aModel, CStreamStore& aStore) sl@0: { sl@0: TInt ret = CPdrDevice::SetModel(aModel, aStore); sl@0: if (ret == KErrNone) sl@0: { sl@0: iFbsTypefaceStore = CFbsTypefaceStore::NewL(this); sl@0: LoadTypeFaceListL(); sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: EXPORT_C TSize CFbsDrvDevice::KPixelSizeInTwips() const sl@0: { sl@0: return TSize(iModelInfo->iKPixelWidthInTwips, iModelInfo->iKPixelHeightInTwips); sl@0: } sl@0: sl@0: EXPORT_C void CFbsDrvDevice::Reserved_1() sl@0: { sl@0: } sl@0: sl@0: EXPORT_C CFbsDrvControl* CFbsDrvControl::NewL(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort, CStreamStore& aStore, TStreamId aResourcesStreamId) sl@0: { sl@0: CFbsDrvControl* control = new(ELeave) CFbsDrvControl(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: EXPORT_C CFbsDrvControl::~CFbsDrvControl() sl@0: { sl@0: delete iScanLine; sl@0: delete iCompressedScanLine; sl@0: } sl@0: sl@0: EXPORT_C CFbsDrvControl::CFbsDrvControl(CPdrDevice* aPdrDevice, CPrinterPort* aPrinterPort): sl@0: CPdrControl(aPdrDevice, aPrinterPort), sl@0: iScanLine(NULL), sl@0: iCompressedScanLine(NULL) sl@0: { sl@0: __DECLARE_NAME(_S("CFbsDrvControl")); sl@0: } sl@0: sl@0: EXPORT_C void CFbsDrvControl::ConstructL(CStreamStore& aStore, TStreamId aResourcesStreamId) sl@0: { sl@0: CPdrControl::ConstructL(aStore, aResourcesStreamId); sl@0: } sl@0: sl@0: EXPORT_C void CFbsDrvControl::SetPageSizeL() sl@0: { sl@0: TCommandString des; sl@0: des.Format(iResources->ResourceString(EPdrSetPageSize), iPdrDevice->CurrentPageSpecInTwips().iPortraitPageSize.iHeight / KTwipsPerInch); sl@0: iPageBuffer->AddBytesL(des); sl@0: } sl@0: sl@0: /** sl@0: @return ETrue if there are non-blank bytes in scanline. sl@0: */ sl@0: EXPORT_C TBool CFbsDrvControl::TransformBuffer() sl@0: { sl@0: TInt i; sl@0: for (i = iScanLine->Length() - 1; (i >= 0) && (iScanLine->Des()[i] == 0xFF); i--) sl@0: { sl@0: } sl@0: TInt length = i + 1; sl@0: iScanLine->Des().SetLength(length); sl@0: TUint8* p = (TUint8*)iScanLine->Des().Ptr(); sl@0: TUint8* pEnd = p + length; sl@0: for (; 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 |= (byte1 & 1); sl@0: byte1 = byte1 >> 1; sl@0: } sl@0: *p = (TUint8)~byte2; sl@0: } sl@0: return (length > 0); // returns ETrue if there are non-blank bytes in scanline sl@0: } sl@0: sl@0: /** sl@0: @return ETrue if the scanline is compressed successfully. sl@0: */ sl@0: EXPORT_C TBool CFbsDrvControl::CompressBuffer() sl@0: { sl@0: TInt length1 = iScanLine->Des().Length(); sl@0: TInt length2 = 0; sl@0: TUint8* p1 = (TUint8*)iScanLine->Des().Ptr(); sl@0: TUint8* p2 = (TUint8*)iCompressedScanLine->Des().Ptr(); sl@0: TUint8 repeat; sl@0: for (TInt i = 0; (i < length1) && (length2 < length1); i += repeat + 1) sl@0: { sl@0: TUint8 byte = *(p1++); sl@0: for (repeat = 0; ((i + repeat + 1) < length1) && (byte == *p1) && (repeat < 255);) sl@0: { sl@0: repeat++; sl@0: p1++; sl@0: } sl@0: length2++; sl@0: if (length2 < length1) sl@0: { sl@0: *(p2++) = repeat; sl@0: length2++; sl@0: if (length2 < length1) sl@0: *(p2++) = byte; sl@0: } sl@0: } sl@0: iCompressedScanLine->Des().SetLength(length2); sl@0: return (length2 < length1); // returns ETrue if the scanline is compressed successfully sl@0: } sl@0: sl@0: /** sl@0: This function is intentionally a dummy. It has to be implemented because sl@0: of an inherited pure virtual but it should always be overload by any class sl@0: that derives from it. sl@0: */ sl@0: EXPORT_C void CFbsDrvControl::OutputBandL() sl@0: { sl@0: // I should probably put an assert in here. 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: TInt numscanlines = size.iHeight; sl@0: if (iBandedDevice->BandingDirection() == EBandingRightToLeft) sl@0: numscanlines = size.iWidth; sl@0: for (TInt i = 0; i < numscanlines; i++) sl@0: { sl@0: TInt x = bandrect.iTl.iX; sl@0: TInt y = bandrect.iTl.iY + i; sl@0: TPtr8 ptr = iScanLine->Des(); sl@0: if (iBandedDevice->BandingDirection() == EBandingTopToBottom) sl@0: iBandedDevice->BandBitmap()->GetScanLine(ptr, TPoint(0, i), size.iWidth, iPdrDevice->DisplayMode()); sl@0: else sl@0: { sl@0: iBandedDevice->BandBitmap()->GetVerticalScanLine(ptr, numscanlines - (i + 1), iPdrDevice->DisplayMode()); sl@0: x = bandrect.iBr.iX - i; sl@0: y = bandrect.iTl.iY; sl@0: } sl@0: if (TransformBuffer() && !datainband) sl@0: { sl@0: MoveToL(TPoint(x, y)); sl@0: if (iBandedDevice->BandingDirection() == EBandingLeftToRight) sl@0: des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsPhysicalPageOrientation); sl@0: else sl@0: des.Format(iResources->ResourceString(EPdrBitmapStart), EFbsLogicalPageOrientation); sl@0: iPageBuffer->AddBytesL(des); sl@0: datainband = ETrue; sl@0: } sl@0: if (datainband) sl@0: { sl@0: TCommandString buf = iResources->ResourceString(EPdrScanLine); sl@0: if (CompressBuffer()) sl@0: { sl@0: des.Format(buf, EFbsRunLength, iCompressedScanLine->Des().Length()); sl@0: iPageBuffer->AddBytesL(des); sl@0: iPageBuffer->AddBytesL(iCompressedScanLine->Des()); sl@0: } sl@0: else sl@0: { sl@0: des.Format(buf, EFbsNone, iScanLine->Des().Length()); sl@0: iPageBuffer->AddBytesL(des); sl@0: iPageBuffer->AddBytesL(iScanLine->Des()); sl@0: } sl@0: } 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; 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: EXPORT_C void CFbsDrvControl::Reserved_1() sl@0: { sl@0: }