Bump version to 4.1-6
[LibreOffice.git] / vcl / generic / print / genpspgraphics.cxx
blob993d8d554ad42cb9237dddeaba6b43560b3e3c4c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 // for mmap etc.
21 #if defined( UNX )
22 # include <stdlib.h>
23 # include <unistd.h>
24 # include <fcntl.h>
25 # include <sys/mman.h>
26 # include <sys/stat.h>
27 # include <sys/types.h>
28 #endif
30 #include "generic/geninst.h"
31 #include "generic/genpspgraphics.h"
32 #include "generic/glyphcache.hxx"
34 #include "vcl/jobdata.hxx"
35 #include "vcl/printerinfomanager.hxx"
36 #include "vcl/bmpacc.hxx"
37 #include "vcl/svapp.hxx"
38 #include "vcl/sysdata.hxx"
40 #include "generic/printergfx.hxx"
41 #include "salbmp.hxx"
42 #include "impfont.hxx"
43 #include "outfont.hxx"
44 #include "fontsubset.hxx"
45 #include "salprn.hxx"
46 #include "region.h"
47 #include "langboost.hxx"
49 #include <config_graphite.h>
50 #if ENABLE_GRAPHITE
51 #include <graphite_layout.hxx>
52 #include <graphite_serverfont.hxx>
53 #endif
55 #include <comphelper/string.hxx>
56 #include <i18nlangtag/mslangid.hxx>
58 using namespace psp;
61 // ----- Implementation of PrinterBmp by means of SalBitmap/BitmapBuffer ---------------
63 class SalPrinterBmp : public psp::PrinterBmp
65 private:
66 BitmapBuffer* mpBmpBuffer;
68 FncGetPixel mpFncGetPixel;
69 Scanline mpScanAccess;
70 sal_PtrDiff mnScanOffset;
72 sal_uInt32 ColorOf (BitmapColor& rColor) const;
73 sal_uInt8 GrayOf (BitmapColor& rColor) const;
75 SalPrinterBmp ();
77 public:
79 SalPrinterBmp (BitmapBuffer* pBitmap);
80 virtual ~SalPrinterBmp ();
81 virtual sal_uInt32 GetPaletteColor (sal_uInt32 nIdx) const;
82 virtual sal_uInt32 GetPaletteEntryCount () const;
83 virtual sal_uInt32 GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const;
84 virtual sal_uInt8 GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const;
85 virtual sal_uInt8 GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const;
86 virtual sal_uInt32 GetWidth () const;
87 virtual sal_uInt32 GetHeight() const;
88 virtual sal_uInt32 GetDepth () const;
91 SalPrinterBmp::SalPrinterBmp (BitmapBuffer* pBuffer) :
92 mpBmpBuffer (pBuffer)
94 DBG_ASSERT (mpBmpBuffer, "SalPrinterBmp::SalPrinterBmp () can't acquire Bitmap");
96 // calibrate scanline buffer
97 if( BMP_SCANLINE_ADJUSTMENT( mpBmpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
99 mpScanAccess = mpBmpBuffer->mpBits;
100 mnScanOffset = mpBmpBuffer->mnScanlineSize;
102 else
104 mpScanAccess = mpBmpBuffer->mpBits
105 + (mpBmpBuffer->mnHeight - 1) * mpBmpBuffer->mnScanlineSize;
106 mnScanOffset = - mpBmpBuffer->mnScanlineSize;
109 // request read access to the pixels
110 switch( BMP_SCANLINE_FORMAT( mpBmpBuffer->mnFormat ) )
112 case BMP_FORMAT_1BIT_MSB_PAL:
113 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL; break;
114 case BMP_FORMAT_1BIT_LSB_PAL:
115 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_LSB_PAL; break;
116 case BMP_FORMAT_4BIT_MSN_PAL:
117 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_MSN_PAL; break;
118 case BMP_FORMAT_4BIT_LSN_PAL:
119 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_LSN_PAL; break;
120 case BMP_FORMAT_8BIT_PAL:
121 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_PAL; break;
122 case BMP_FORMAT_8BIT_TC_MASK:
123 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_TC_MASK; break;
124 case BMP_FORMAT_16BIT_TC_MSB_MASK:
125 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_MSB_MASK; break;
126 case BMP_FORMAT_16BIT_TC_LSB_MASK:
127 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_LSB_MASK; break;
128 case BMP_FORMAT_24BIT_TC_BGR:
129 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_BGR; break;
130 case BMP_FORMAT_24BIT_TC_RGB:
131 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_RGB; break;
132 case BMP_FORMAT_24BIT_TC_MASK:
133 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_MASK; break;
134 case BMP_FORMAT_32BIT_TC_ABGR:
135 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ABGR; break;
136 case BMP_FORMAT_32BIT_TC_ARGB:
137 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ARGB; break;
138 case BMP_FORMAT_32BIT_TC_BGRA:
139 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_BGRA; break;
140 case BMP_FORMAT_32BIT_TC_RGBA:
141 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_RGBA; break;
142 case BMP_FORMAT_32BIT_TC_MASK:
143 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_MASK; break;
145 default:
146 OSL_FAIL("Error: SalPrinterBmp::SalPrinterBmp() unknown bitmap format");
147 break;
151 SalPrinterBmp::~SalPrinterBmp ()
155 sal_uInt32
156 SalPrinterBmp::GetWidth () const
158 return mpBmpBuffer->mnWidth;
161 sal_uInt32
162 SalPrinterBmp::GetHeight () const
164 return mpBmpBuffer->mnHeight;
167 sal_uInt32
168 SalPrinterBmp::GetDepth () const
170 sal_uInt32 nDepth;
172 switch (mpBmpBuffer->mnBitCount)
174 case 1:
175 nDepth = 1;
176 break;
178 case 4:
179 case 8:
180 nDepth = 8;
181 break;
183 case 16:
184 case 24:
185 case 32:
186 nDepth = 24;
187 break;
189 default:
190 nDepth = 1;
191 OSL_FAIL("Error: unsupported bitmap depth in SalPrinterBmp::GetDepth()");
192 break;
195 return nDepth;
198 sal_uInt32
199 SalPrinterBmp::ColorOf (BitmapColor& rColor) const
201 if (rColor.IsIndex())
202 return ColorOf (mpBmpBuffer->maPalette[rColor.GetIndex()]);
203 else
204 return ((rColor.GetBlue()) & 0x000000ff)
205 | ((rColor.GetGreen() << 8) & 0x0000ff00)
206 | ((rColor.GetRed() << 16) & 0x00ff0000);
209 sal_uInt8
210 SalPrinterBmp::GrayOf (BitmapColor& rColor) const
212 if (rColor.IsIndex())
213 return GrayOf (mpBmpBuffer->maPalette[rColor.GetIndex()]);
214 else
215 return ( rColor.GetBlue() * 28UL
216 + rColor.GetGreen() * 151UL
217 + rColor.GetRed() * 77UL ) >> 8;
220 sal_uInt32
221 SalPrinterBmp::GetPaletteEntryCount () const
223 return mpBmpBuffer->maPalette.GetEntryCount ();
226 sal_uInt32
227 SalPrinterBmp::GetPaletteColor (sal_uInt32 nIdx) const
229 return ColorOf (mpBmpBuffer->maPalette[nIdx]);
232 sal_uInt32
233 SalPrinterBmp::GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const
235 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
236 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
238 return ColorOf (aColor);
241 sal_uInt8
242 SalPrinterBmp::GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const
244 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
245 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
247 return GrayOf (aColor);
250 sal_uInt8
251 SalPrinterBmp::GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const
253 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
254 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
256 if (aColor.IsIndex())
257 return aColor.GetIndex();
258 else
259 return 0;
262 /*******************************************************
263 * GenPspGraphics *
264 *******************************************************/
266 GenPspGraphics::GenPspGraphics()
267 : m_pJobData( NULL ),
268 m_pPrinterGfx( NULL ),
269 m_pPhoneNr( NULL ),
270 m_bSwallowFaxNo( false ),
271 m_bPhoneCollectionActive( false ),
272 m_bFontVertical( false ),
273 m_pInfoPrinter( NULL )
275 for( int i = 0; i < MAX_FALLBACK; i++ )
276 m_pServerFont[i] = NULL;
279 void GenPspGraphics::Init( psp::JobData* pJob, psp::PrinterGfx* pGfx,
280 OUString* pPhone, bool bSwallow,
281 SalInfoPrinter* pInfoPrinter )
283 m_pJobData = pJob;
284 m_pPrinterGfx = pGfx;
285 m_pPhoneNr = pPhone;
286 m_bSwallowFaxNo = bSwallow;
287 m_pInfoPrinter = pInfoPrinter;
288 SetLayout( 0 );
291 GenPspGraphics::~GenPspGraphics()
293 ReleaseFonts();
296 void GenPspGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY )
298 if (m_pJobData != NULL)
300 int x = m_pJobData->m_aContext.getRenderResolution();
302 rDPIX = x;
303 rDPIY = x;
307 sal_uInt16 GenPspGraphics::GetBitCount() const
309 return m_pPrinterGfx->GetBitCount();
312 long GenPspGraphics::GetGraphicsWidth() const
314 return 0;
317 void GenPspGraphics::ResetClipRegion()
319 m_pPrinterGfx->ResetClipRegion();
322 bool GenPspGraphics::setClipRegion( const Region& i_rClip )
324 // TODO: support polygonal clipregions here
325 m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
327 ImplRegionInfo aInfo;
328 long nX, nY, nW, nH;
329 bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
330 while( bRegionRect )
332 if ( nW && nH )
334 m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
336 bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
338 m_pPrinterGfx->EndSetClipRegion();
339 return true;
342 void GenPspGraphics::SetLineColor()
344 m_pPrinterGfx->SetLineColor ();
347 void GenPspGraphics::SetLineColor( SalColor nSalColor )
349 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
350 SALCOLOR_GREEN (nSalColor),
351 SALCOLOR_BLUE (nSalColor));
352 m_pPrinterGfx->SetLineColor (aColor);
355 void GenPspGraphics::SetFillColor()
357 m_pPrinterGfx->SetFillColor ();
360 void GenPspGraphics::SetFillColor( SalColor nSalColor )
362 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
363 SALCOLOR_GREEN (nSalColor),
364 SALCOLOR_BLUE (nSalColor));
365 m_pPrinterGfx->SetFillColor (aColor);
368 void GenPspGraphics::SetROPLineColor( SalROPColor )
370 DBG_ASSERT( 0, "Error: PrinterGfx::SetROPLineColor() not implemented" );
373 void GenPspGraphics::SetROPFillColor( SalROPColor )
375 DBG_ASSERT( 0, "Error: PrinterGfx::SetROPFillColor() not implemented" );
378 void GenPspGraphics::SetXORMode( bool bSet, bool )
380 (void)bSet;
381 DBG_ASSERT( !bSet, "Error: PrinterGfx::SetXORMode() not implemented" );
384 void GenPspGraphics::drawPixel( long nX, long nY )
386 m_pPrinterGfx->DrawPixel (Point(nX, nY));
389 void GenPspGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
391 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
392 SALCOLOR_GREEN (nSalColor),
393 SALCOLOR_BLUE (nSalColor));
394 m_pPrinterGfx->DrawPixel (Point(nX, nY), aColor);
397 void GenPspGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
399 m_pPrinterGfx->DrawLine (Point(nX1, nY1), Point(nX2, nY2));
402 void GenPspGraphics::drawRect( long nX, long nY, long nDX, long nDY )
404 m_pPrinterGfx->DrawRect (Rectangle(Point(nX, nY), Size(nDX, nDY)));
407 void GenPspGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint *pPtAry )
409 m_pPrinterGfx->DrawPolyLine (nPoints, (Point*)pPtAry);
412 void GenPspGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry )
414 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx
415 m_pPrinterGfx->DrawPolygon (nPoints, (Point*)pPtAry);
418 void GenPspGraphics::drawPolyPolygon( sal_uInt32 nPoly,
419 const sal_uInt32 *pPoints,
420 PCONSTSALPOINT *pPtAry )
422 m_pPrinterGfx->DrawPolyPolygon (nPoly, pPoints, (const Point**)pPtAry);
425 bool GenPspGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
427 // TODO: implement and advertise OutDevSupport_B2DDraw support
428 return false;
431 bool GenPspGraphics::drawPolyLine(
432 const basegfx::B2DPolygon&,
433 double /*fTranspareny*/,
434 const basegfx::B2DVector& /*rLineWidths*/,
435 basegfx::B2DLineJoin /*eJoin*/,
436 com::sun::star::drawing::LineCap /*eLineCap*/)
438 // TODO: a PS printer can draw B2DPolyLines almost directly
439 return false;
442 sal_Bool GenPspGraphics::drawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
444 m_pPrinterGfx->DrawPolyLineBezier (nPoints, (Point*)pPtAry, pFlgAry);
445 return sal_True;
448 sal_Bool GenPspGraphics::drawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
450 m_pPrinterGfx->DrawPolygonBezier (nPoints, (Point*)pPtAry, pFlgAry);
451 return sal_True;
454 sal_Bool GenPspGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly,
455 const sal_uInt32* pPoints,
456 const SalPoint* const* pPtAry,
457 const sal_uInt8* const* pFlgAry )
459 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx
460 m_pPrinterGfx->DrawPolyPolygonBezier (nPoly, pPoints, (Point**)pPtAry, (sal_uInt8**)pFlgAry);
461 return sal_True;
464 void GenPspGraphics::invert( sal_uLong,
465 const SalPoint*,
466 SalInvert )
468 DBG_ASSERT( 0, "Error: PrinterGfx::Invert() not implemented" );
470 sal_Bool GenPspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize )
472 return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize );
475 void GenPspGraphics::copyBits( const SalTwoRect*,
476 SalGraphics* )
478 OSL_FAIL( "Error: PrinterGfx::CopyBits() not implemented" );
481 void GenPspGraphics::copyArea ( long,long,long,long,long,long,sal_uInt16 )
483 OSL_FAIL( "Error: PrinterGfx::CopyArea() not implemented" );
486 void GenPspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap )
488 Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY),
489 Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight));
490 Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY),
491 Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight));
493 BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(sal_True);
495 SalPrinterBmp aBmp (pBuffer);
496 m_pPrinterGfx->DrawBitmap (aDst, aSrc, aBmp);
498 const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, sal_True);
501 void GenPspGraphics::drawBitmap( const SalTwoRect*,
502 const SalBitmap&,
503 const SalBitmap& )
505 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent bitmap");
508 void GenPspGraphics::drawBitmap( const SalTwoRect*,
509 const SalBitmap&,
510 SalColor )
512 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent color");
515 void GenPspGraphics::drawMask( const SalTwoRect*,
516 const SalBitmap &,
517 SalColor )
519 OSL_FAIL("Error: PrinterGfx::DrawMask() not implemented");
522 SalBitmap* GenPspGraphics::getBitmap( long, long, long, long )
524 DBG_WARNING ("Warning: PrinterGfx::GetBitmap() not implemented");
525 return NULL;
528 SalColor GenPspGraphics::getPixel( long, long )
530 OSL_FAIL("Warning: PrinterGfx::GetPixel() not implemented");
531 return 0;
534 void GenPspGraphics::invert(long,long,long,long,SalInvert)
536 OSL_FAIL("Warning: PrinterGfx::Invert() not implemented");
539 //==========================================================================
541 class ImplPspFontData : public PhysicalFontFace
543 private:
544 enum { PSPFD_MAGIC = 0xb5bf01f0 };
545 sal_IntPtr mnFontId;
547 public:
548 ImplPspFontData( const psp::FastPrintFontInfo& );
549 virtual sal_IntPtr GetFontId() const { return mnFontId; }
550 virtual PhysicalFontFace* Clone() const { return new ImplPspFontData( *this ); }
551 virtual ImplFontEntry* CreateFontInstance( FontSelectPattern& ) const;
552 static bool CheckFontData( const PhysicalFontFace& r ) { return r.CheckMagic( PSPFD_MAGIC ); }
555 //--------------------------------------------------------------------------
557 ImplPspFontData::ImplPspFontData( const psp::FastPrintFontInfo& rInfo )
558 : PhysicalFontFace( GenPspGraphics::Info2DevFontAttributes(rInfo), PSPFD_MAGIC ),
559 mnFontId( rInfo.m_nID )
562 //--------------------------------------------------------------------------
564 ImplFontEntry* ImplPspFontData::CreateFontInstance( FontSelectPattern& rFSD ) const
566 ImplServerFontEntry* pEntry = new ImplServerFontEntry( rFSD );
567 return pEntry;
570 //==========================================================================
572 class PspFontLayout : public GenericSalLayout
574 public:
575 PspFontLayout( ::psp::PrinterGfx& );
576 virtual bool LayoutText( ImplLayoutArgs& );
577 virtual void InitFont() const;
578 virtual void DrawText( SalGraphics& ) const;
579 private:
580 ::psp::PrinterGfx& mrPrinterGfx;
581 sal_IntPtr mnFontID;
582 int mnFontHeight;
583 int mnFontWidth;
584 bool mbVertical;
585 bool mbArtItalic;
586 bool mbArtBold;
589 //--------------------------------------------------------------------------
591 PspFontLayout::PspFontLayout( ::psp::PrinterGfx& rGfx )
592 : mrPrinterGfx( rGfx )
594 mnFontID = mrPrinterGfx.GetFontID();
595 mnFontHeight = mrPrinterGfx.GetFontHeight();
596 mnFontWidth = mrPrinterGfx.GetFontWidth();
597 mbVertical = mrPrinterGfx.GetFontVertical();
598 mbArtItalic = mrPrinterGfx.GetArtificialItalic();
599 mbArtBold = mrPrinterGfx.GetArtificialBold();
602 //--------------------------------------------------------------------------
604 bool PspFontLayout::LayoutText( ImplLayoutArgs& rArgs )
606 mbVertical = ((rArgs.mnFlags & SAL_LAYOUT_VERTICAL) != 0);
608 long nUnitsPerPixel = 1;
609 int nOldGlyphId = -1;
610 long nGlyphWidth = 0;
611 int nCharPos = -1;
612 Point aNewPos( 0, 0 );
613 GlyphItem aPrevItem;
614 rtl_TextEncoding aFontEnc = mrPrinterGfx.GetFontMgr().getFontEncoding( mnFontID );
616 Reserve(rArgs.mnLength);
618 for(;;)
620 bool bRightToLeft;
621 if( !rArgs.GetNextPos( &nCharPos, &bRightToLeft ) )
622 break;
624 sal_Unicode cChar = rArgs.mpStr[ nCharPos ];
625 if( bRightToLeft )
626 cChar = GetMirroredChar( cChar );
627 // symbol font aliasing: 0x0020-0x00ff -> 0xf020 -> 0xf0ff
628 if( aFontEnc == RTL_TEXTENCODING_SYMBOL )
629 if( cChar < 256 )
630 cChar += 0xf000;
631 int nGlyphIndex = cChar; // printer glyphs = unicode
633 // update fallback_runs if needed
634 psp::CharacterMetric aMetric;
635 mrPrinterGfx.GetFontMgr().getMetrics( mnFontID, cChar, cChar, &aMetric, mbVertical );
636 if( aMetric.width == -1 && aMetric.height == -1 )
637 rArgs.NeedFallback( nCharPos, bRightToLeft );
639 // apply pair kerning to prev glyph if requested
640 if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags )
642 if( nOldGlyphId > 0 )
644 const std::list< KernPair >& rKernPairs = mrPrinterGfx.getKernPairs(mbVertical);
645 for( std::list< KernPair >::const_iterator it = rKernPairs.begin();
646 it != rKernPairs.end(); ++it )
648 if( it->first == nOldGlyphId && it->second == nGlyphIndex )
650 int nTextScale = mrPrinterGfx.GetFontWidth();
651 if( ! nTextScale )
652 nTextScale = mrPrinterGfx.GetFontHeight();
653 int nKern = (mbVertical ? it->kern_y : it->kern_x) * nTextScale;
654 nGlyphWidth += nKern;
655 aPrevItem.mnNewWidth = nGlyphWidth;
656 break;
662 // finish previous glyph
663 if( nOldGlyphId >= 0 )
664 AppendGlyph( aPrevItem );
665 nOldGlyphId = nGlyphIndex;
666 aNewPos.X() += nGlyphWidth;
668 // prepare GlyphItem for appending it in next round
669 nUnitsPerPixel = mrPrinterGfx.GetCharWidth( cChar, cChar, &nGlyphWidth );
670 int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0;
671 nGlyphIndex |= GF_ISCHAR;
672 aPrevItem = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth );
675 // append last glyph item if any
676 if( nOldGlyphId >= 0 )
677 AppendGlyph( aPrevItem );
679 SetOrientation( mrPrinterGfx.GetFontAngle() );
680 SetUnitsPerPixel( nUnitsPerPixel );
681 return (nOldGlyphId >= 0);
684 class PspServerFontLayout : public ServerFontLayout
686 public:
687 PspServerFontLayout( psp::PrinterGfx&, ServerFont& rFont, const ImplLayoutArgs& rArgs );
689 virtual void InitFont() const;
690 const sal_Unicode* getTextPtr() const { return maText.getStr() - mnMinCharPos; }
691 int getMinCharPos() const { return mnMinCharPos; }
692 int getMaxCharPos() const { return mnMinCharPos+maText.getLength()-1; }
693 private:
694 ::psp::PrinterGfx& mrPrinterGfx;
695 sal_IntPtr mnFontID;
696 int mnFontHeight;
697 int mnFontWidth;
698 bool mbVertical;
699 bool mbArtItalic;
700 bool mbArtBold;
701 OUString maText;
702 int mnMinCharPos;
705 PspServerFontLayout::PspServerFontLayout( ::psp::PrinterGfx& rGfx, ServerFont& rFont, const ImplLayoutArgs& rArgs )
706 : ServerFontLayout( rFont ),
707 mrPrinterGfx( rGfx )
709 mnFontID = mrPrinterGfx.GetFontID();
710 mnFontHeight = mrPrinterGfx.GetFontHeight();
711 mnFontWidth = mrPrinterGfx.GetFontWidth();
712 mbVertical = mrPrinterGfx.GetFontVertical();
713 mbArtItalic = mrPrinterGfx.GetArtificialItalic();
714 mbArtBold = mrPrinterGfx.GetArtificialBold();
715 maText = OUString( rArgs.mpStr + rArgs.mnMinCharPos, rArgs.mnEndCharPos - rArgs.mnMinCharPos+1 );
716 mnMinCharPos = rArgs.mnMinCharPos;
719 void PspServerFontLayout::InitFont() const
721 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth,
722 mnOrientation, mbVertical, mbArtItalic, mbArtBold );
725 //--------------------------------------------------------------------------
727 static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx, bool bIsPspServerFontLayout )
729 const int nMaxGlyphs = 200;
730 sal_uInt32 aGlyphAry[ nMaxGlyphs ]; // TODO: use sal_GlyphId
731 sal_Int32 aWidthAry[ nMaxGlyphs ];
732 sal_Int32 aIdxAry [ nMaxGlyphs ];
733 sal_Unicode aUnicodes[ nMaxGlyphs ];
734 int aCharPosAry [ nMaxGlyphs ];
736 Point aPos;
737 long nUnitsPerPixel = rLayout.GetUnitsPerPixel();
738 const sal_Unicode* pText = NULL;
739 int nMinCharPos = 0;
740 int nMaxCharPos = 0;
741 if (bIsPspServerFontLayout)
743 const PspServerFontLayout * pPspLayout = dynamic_cast<const PspServerFontLayout*>(&rLayout);
744 #if ENABLE_GRAPHITE
745 const GraphiteServerFontLayout * pGrLayout = dynamic_cast<const GraphiteServerFontLayout*>(&rLayout);
746 #endif
747 if (pPspLayout)
749 pText = pPspLayout->getTextPtr();
750 nMinCharPos = pPspLayout->getMinCharPos();
751 nMaxCharPos = pPspLayout->getMaxCharPos();
753 #if ENABLE_GRAPHITE
754 else if (pGrLayout)
757 #endif
759 for( int nStart = 0;; )
761 int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, pText ? aCharPosAry : NULL );
762 if( !nGlyphCount )
763 break;
765 sal_Int32 nXOffset = 0;
766 for( int i = 0; i < nGlyphCount; ++i )
768 nXOffset += aWidthAry[ i ];
769 aIdxAry[ i ] = nXOffset / nUnitsPerPixel;
770 sal_Int32 nGlyphIdx = aGlyphAry[i] & (GF_IDXMASK | GF_ROTMASK);
771 if( pText )
772 aUnicodes[i] = (aCharPosAry[i] >= nMinCharPos && aCharPosAry[i] <= nMaxCharPos) ? pText[ aCharPosAry[i] ] : 0;
773 else
774 aUnicodes[i] = (aGlyphAry[i] & GF_ISCHAR) ? nGlyphIdx : 0;
775 aGlyphAry[i] = nGlyphIdx;
778 rGfx.DrawGlyphs( aPos, (sal_uInt32 *)aGlyphAry, aUnicodes, nGlyphCount, aIdxAry );
782 //--------------------------------------------------------------------------
784 void PspFontLayout::InitFont() const
786 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth,
787 mnOrientation, mbVertical, mbArtItalic, mbArtBold );
790 //--------------------------------------------------------------------------
792 void PspFontLayout::DrawText( SalGraphics& ) const
794 DrawPrinterLayout( *this, mrPrinterGfx, false );
797 void GenPspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
799 // print complex text
800 DrawPrinterLayout( rLayout, *m_pPrinterGfx, true );
803 const ImplFontCharMap* GenPspGraphics::GetImplFontCharMap() const
805 if( !m_pServerFont[0] )
806 return NULL;
808 const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
809 return pIFCMap;
812 bool GenPspGraphics::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
814 if (!m_pServerFont[0])
815 return false;
816 return m_pServerFont[0]->GetFontCapabilities(rFontCapabilities);
819 sal_uInt16 GenPspGraphics::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
821 // release all fonts that are to be overridden
822 for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
824 if( m_pServerFont[i] != NULL )
826 // old server side font is no longer referenced
827 GlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] );
828 m_pServerFont[i] = NULL;
832 // return early if there is no new font
833 if( !pEntry )
834 return 0;
836 sal_IntPtr nID = pEntry->mpFontData ? pEntry->mpFontData->GetFontId() : 0;
838 // determine which font attributes need to be emulated
839 bool bArtItalic = false;
840 bool bArtBold = false;
841 if( pEntry->GetSlant() == ITALIC_OBLIQUE || pEntry->GetSlant() == ITALIC_NORMAL )
843 FontItalic eItalic = m_pPrinterGfx->GetFontMgr().getFontItalic( nID );
844 if( eItalic != ITALIC_NORMAL && eItalic != ITALIC_OBLIQUE )
845 bArtItalic = true;
847 int nWeight = (int)pEntry->GetWeight();
848 int nRealWeight = (int)m_pPrinterGfx->GetFontMgr().getFontWeight( nID );
849 if( nRealWeight <= (int)WEIGHT_MEDIUM && nWeight > (int)WEIGHT_MEDIUM )
851 bArtBold = true;
854 // also set the serverside font for layouting
855 m_bFontVertical = pEntry->mbVertical;
856 if( pEntry->mpFontData )
858 // requesting a font provided by builtin rasterizer
859 ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
860 if( pServerFont != NULL )
862 if( pServerFont->TestFont() )
863 m_pServerFont[ nFallbackLevel ] = pServerFont;
864 else
865 GlyphCache::GetInstance().UncacheFont( *pServerFont );
869 // set the printer font
870 return m_pPrinterGfx->SetFont( nID,
871 pEntry->mnHeight,
872 pEntry->mnWidth,
873 pEntry->mnOrientation,
874 pEntry->mbVertical,
875 bArtItalic,
876 bArtBold
880 void GenPspGraphics::SetTextColor( SalColor nSalColor )
882 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
883 SALCOLOR_GREEN (nSalColor),
884 SALCOLOR_BLUE (nSalColor));
885 m_pPrinterGfx->SetTextColor (aColor);
888 bool GenPspGraphics::AddTempDevFont( ImplDevFontList*, const OUString&,const OUString& )
890 return false;
893 void GenPspGraphics::GetDevFontList( ImplDevFontList *pList )
895 ::std::list< psp::fontID > aList;
896 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
897 rMgr.getFontList( aList, m_pJobData->m_pParser );
899 ::std::list< psp::fontID >::iterator it;
900 psp::FastPrintFontInfo aInfo;
901 for (it = aList.begin(); it != aList.end(); ++it)
902 if (rMgr.getFontFastInfo (*it, aInfo))
903 AnnounceFonts( pList, aInfo );
905 // register platform specific font substitutions if available
906 SalGenericInstance::RegisterFontSubstitutors( pList );
909 void GenPspGraphics::ClearDevFontCache()
911 GlyphCache::GetInstance().ClearFontCache();
914 void GenPspGraphics::GetDevFontSubstList( OutputDevice* pOutDev )
916 const psp::PrinterInfo& rInfo = psp::PrinterInfoManager::get().getPrinterInfo( m_pJobData->m_aPrinterName );
917 if( rInfo.m_bPerformFontSubstitution )
919 for( boost::unordered_map< OUString, OUString, OUStringHash >::const_iterator it = rInfo.m_aFontSubstitutes.begin(); it != rInfo.m_aFontSubstitutes.end(); ++it )
920 pOutDev->ImplAddDevFontSubstitute( it->first, it->second, FONT_SUBSTITUTE_ALWAYS );
924 void GenPspGraphics::GetFontMetric( ImplFontMetricData *pMetric, int )
926 const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
927 psp::PrintFontInfo aInfo;
929 if (rMgr.getFontInfo (m_pPrinterGfx->GetFontID(), aInfo))
931 ImplDevFontAttributes aDFA = Info2DevFontAttributes( aInfo );
932 static_cast<ImplFontAttributes&>(*pMetric) = aDFA;
933 pMetric->mbDevice = aDFA.mbDevice;
934 pMetric->mbScalableFont = true;
936 pMetric->mnOrientation = m_pPrinterGfx->GetFontAngle();
937 pMetric->mnSlant = 0;
939 sal_Int32 nTextHeight = m_pPrinterGfx->GetFontHeight();
940 sal_Int32 nTextWidth = m_pPrinterGfx->GetFontWidth();
941 if( ! nTextWidth )
942 nTextWidth = nTextHeight;
944 pMetric->mnWidth = nTextWidth;
945 pMetric->mnAscent = ( aInfo.m_nAscend * nTextHeight + 500 ) / 1000;
946 pMetric->mnDescent = ( aInfo.m_nDescend * nTextHeight + 500 ) / 1000;
947 pMetric->mnIntLeading = ( aInfo.m_nLeading * nTextHeight + 500 ) / 1000;
948 pMetric->mnExtLeading = 0;
952 sal_uLong GenPspGraphics::GetKernPairs( sal_uLong nPairs, ImplKernPairData *pKernPairs )
954 const ::std::list< ::psp::KernPair >& rPairs( m_pPrinterGfx->getKernPairs() );
955 sal_uLong nHavePairs = rPairs.size();
956 if( pKernPairs && nPairs )
958 ::std::list< ::psp::KernPair >::const_iterator it;
959 unsigned int i;
960 int nTextScale = m_pPrinterGfx->GetFontWidth();
961 if( ! nTextScale )
962 nTextScale = m_pPrinterGfx->GetFontHeight();
963 for( i = 0, it = rPairs.begin(); i < nPairs && i < nHavePairs; i++, ++it )
965 pKernPairs[i].mnChar1 = it->first;
966 pKernPairs[i].mnChar2 = it->second;
967 pKernPairs[i].mnKern = it->kern_x * nTextScale / 1000;
971 return nHavePairs;
974 sal_Bool GenPspGraphics::GetGlyphBoundRect( sal_GlyphId nGlyphIndex, Rectangle& rRect )
976 int nLevel = nGlyphIndex >> GF_FONTSHIFT;
977 if( nLevel >= MAX_FALLBACK )
978 return sal_False;
980 ServerFont* pSF = m_pServerFont[ nLevel ];
981 if( !pSF )
982 return sal_False;
984 nGlyphIndex &= GF_IDXMASK;
985 const GlyphMetric& rGM = pSF->GetGlyphMetric( nGlyphIndex );
986 rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() );
987 return sal_True;
990 sal_Bool GenPspGraphics::GetGlyphOutline( sal_GlyphId nGlyphIndex,
991 ::basegfx::B2DPolyPolygon& rB2DPolyPoly )
993 int nLevel = nGlyphIndex >> GF_FONTSHIFT;
994 if( nLevel >= MAX_FALLBACK )
995 return sal_False;
997 ServerFont* pSF = m_pServerFont[ nLevel ];
998 if( !pSF )
999 return sal_False;
1001 nGlyphIndex &= GF_IDXMASK;
1002 if( pSF->GetGlyphOutline( nGlyphIndex, rB2DPolyPoly ) )
1003 return sal_True;
1005 return sal_False;
1008 SalLayout* GenPspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
1010 // workaround for printers not handling glyph indexing for non-TT fonts
1011 int nFontId = m_pPrinterGfx->GetFontID();
1012 if( psp::fonttype::TrueType != psp::PrintFontManager::get().getFontType( nFontId ) )
1013 rArgs.mnFlags |= SAL_LAYOUT_DISABLE_GLYPH_PROCESSING;
1014 else if( nFallbackLevel > 0 )
1015 rArgs.mnFlags &= ~SAL_LAYOUT_DISABLE_GLYPH_PROCESSING;
1017 GenericSalLayout* pLayout = NULL;
1019 if( m_pServerFont[ nFallbackLevel ]
1020 && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) )
1022 #if ENABLE_GRAPHITE
1023 // Is this a Graphite font?
1024 if (GraphiteServerFontLayout::IsGraphiteEnabledFont(*m_pServerFont[nFallbackLevel]))
1026 pLayout = new GraphiteServerFontLayout(*m_pServerFont[nFallbackLevel]);
1028 else
1029 #endif
1030 pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pServerFont[nFallbackLevel], rArgs );
1032 else
1033 pLayout = new PspFontLayout( *m_pPrinterGfx );
1035 return pLayout;
1038 //--------------------------------------------------------------------------
1040 sal_Bool GenPspGraphics::CreateFontSubset(
1041 const OUString& rToFile,
1042 const PhysicalFontFace* pFont,
1043 sal_Int32* pGlyphIDs,
1044 sal_uInt8* pEncoding,
1045 sal_Int32* pWidths,
1046 int nGlyphCount,
1047 FontSubsetInfo& rInfo
1050 // in this context the pFont->GetFontId() is a valid PSP
1051 // font since they are the only ones left after the PDF
1052 // export has filtered its list of subsettable fonts (for
1053 // which this method was created). The correct way would
1054 // be to have the GlyphCache search for the PhysicalFontFace pFont
1055 psp::fontID aFont = pFont->GetFontId();
1057 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1058 bool bSuccess = rMgr.createFontSubset( rInfo,
1059 aFont,
1060 rToFile,
1061 pGlyphIDs,
1062 pEncoding,
1063 pWidths,
1064 nGlyphCount );
1065 return bSuccess;
1068 //--------------------------------------------------------------------------
1070 const Ucs2SIntMap* GenPspGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
1072 // in this context the pFont->GetFontId() is a valid PSP
1073 // font since they are the only ones left after the PDF
1074 // export has filtered its list of subsettable fonts (for
1075 // which this method was created). The correct way would
1076 // be to have the GlyphCache search for the PhysicalFontFace pFont
1077 psp::fontID aFont = pFont->GetFontId();
1078 return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
1081 //--------------------------------------------------------------------------
1083 void GenPspGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
1084 bool bVertical,
1085 Int32Vector& rWidths,
1086 Ucs2UIntMap& rUnicodeEnc )
1088 // in this context the pFont->GetFontId() is a valid PSP
1089 // font since they are the only ones left after the PDF
1090 // export has filtered its list of subsettable fonts (for
1091 // which this method was created). The correct way would
1092 // be to have the GlyphCache search for the PhysicalFontFace pFont
1093 psp::fontID aFont = pFont->GetFontId();
1094 GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
1097 const Ucs2SIntMap* GenPspGraphics::DoGetFontEncodingVector( fontID aFont, const Ucs2OStrMap** pNonEncoded )
1099 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1101 psp::PrintFontInfo aFontInfo;
1102 if( ! rMgr.getFontInfo( aFont, aFontInfo ) )
1104 if( pNonEncoded )
1105 *pNonEncoded = NULL;
1106 return NULL;
1109 return rMgr.getEncodingMap( aFont, pNonEncoded );
1112 void GenPspGraphics::DoGetGlyphWidths( psp::fontID aFont,
1113 bool bVertical,
1114 Int32Vector& rWidths,
1115 Ucs2UIntMap& rUnicodeEnc )
1117 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1118 rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
1120 // ----------------------------------------------------------------------------
1122 ImplDevFontAttributes GenPspGraphics::Info2DevFontAttributes( const psp::FastPrintFontInfo& rInfo )
1124 ImplDevFontAttributes aDFA;
1125 aDFA.SetFamilyName( rInfo.m_aFamilyName );
1126 aDFA.SetStyleName( rInfo.m_aStyleName );
1127 aDFA.SetFamilyType( rInfo.m_eFamilyStyle );
1128 aDFA.SetWeight( rInfo.m_eWeight );
1129 aDFA.SetItalic( rInfo.m_eItalic );
1130 aDFA.SetWidthType( rInfo.m_eWidth );
1131 aDFA.SetPitch( rInfo.m_ePitch );
1132 aDFA.SetSymbolFlag( (rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL) );
1133 aDFA.mbSubsettable = rInfo.m_bSubsettable;
1134 aDFA.mbEmbeddable = rInfo.m_bEmbeddable;
1136 switch( rInfo.m_eType )
1138 case psp::fonttype::Builtin:
1139 aDFA.mnQuality = 1024;
1140 aDFA.mbDevice = true;
1141 break;
1142 case psp::fonttype::TrueType:
1143 aDFA.mnQuality = 512;
1144 aDFA.mbDevice = false;
1145 break;
1146 case psp::fonttype::Type1:
1147 aDFA.mnQuality = 0;
1148 aDFA.mbDevice = false;
1149 break;
1150 default:
1151 aDFA.mnQuality = 0;
1152 aDFA.mbDevice = false;
1153 break;
1156 aDFA.mbOrientation = true;
1158 // add font family name aliases
1159 ::std::list< OUString >::const_iterator it = rInfo.m_aAliases.begin();
1160 bool bHasMapNames = false;
1161 for(; it != rInfo.m_aAliases.end(); ++it )
1163 if( bHasMapNames )
1164 aDFA.maMapNames.Append( ';' );
1165 aDFA.maMapNames.Append( (*it).getStr() );
1166 bHasMapNames = true;
1169 #if OSL_DEBUG_LEVEL > 2
1170 if( bHasMapNames )
1172 OString aOrigName(OUStringToOString(aDFA.GetFamilyName(), osl_getThreadTextEncoding()));
1173 OString aAliasNames(OUStringToOString(aDFA.GetAliasNames(), osl_getThreadTextEncoding()));
1174 SAL_INFO( "vcl.fonts", "using alias names " << aAliasNames.getStr() << " for font family " << aOrigName.getStr() );
1176 #endif
1178 return aDFA;
1181 namespace vcl
1183 const char* getLangBoost()
1185 const char* pLangBoost;
1186 const LanguageType eLang = Application::GetSettings().GetUILanguageTag().getLanguageType();
1187 if (eLang == LANGUAGE_JAPANESE)
1188 pLangBoost = "jan";
1189 else if (MsLangId::isKorean(eLang))
1190 pLangBoost = "kor";
1191 else if (MsLangId::isSimplifiedChinese(eLang))
1192 pLangBoost = "zhs";
1193 else if (MsLangId::isTraditionalChinese(eLang))
1194 pLangBoost = "zht";
1195 else
1196 pLangBoost = NULL;
1197 return pLangBoost;
1201 // -----------------------------------------------------------------------
1203 void GenPspGraphics::AnnounceFonts( ImplDevFontList* pFontList, const psp::FastPrintFontInfo& aInfo )
1205 int nQuality = 0;
1207 if( aInfo.m_eType == psp::fonttype::TrueType )
1209 // asian type 1 fonts are not known
1210 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1211 OString aFileName( rMgr.getFontFileSysPath( aInfo.m_nID ) );
1212 int nPos = aFileName.lastIndexOf( '_' );
1213 if( nPos == -1 || aFileName[nPos+1] == '.' )
1214 nQuality += 5;
1215 else
1217 static const char* pLangBoost = NULL;
1218 static bool bOnce = true;
1219 if( bOnce )
1221 bOnce = false;
1222 pLangBoost = vcl::getLangBoost();
1225 if( pLangBoost )
1226 if( aFileName.copy( nPos+1, 3 ).equalsIgnoreAsciiCase( pLangBoost ) )
1227 nQuality += 10;
1231 ImplPspFontData* pFD = new ImplPspFontData( aInfo );
1232 pFD->mnQuality += nQuality;
1233 pFontList->Add( pFD );
1236 bool GenPspGraphics::filterText( const OUString& rOrig, OUString& rNewText, sal_Int32 nIndex, sal_Int32& rLen, sal_Int32& rCutStart, sal_Int32& rCutStop )
1238 if( ! m_pPhoneNr )
1239 return false;
1241 rNewText = rOrig;
1242 rCutStop = rCutStart = -1;
1244 #define FAX_PHONE_TOKEN "@@#"
1245 #define FAX_PHONE_TOKEN_LENGTH 3
1246 #define FAX_END_TOKEN "@@"
1247 #define FAX_END_TOKEN_LENGTH 2
1249 bool bRet = false;
1250 bool bStarted = false;
1251 sal_Int32 nPos;
1252 sal_Int32 nStart = 0;
1253 sal_Int32 nStop = rLen;
1254 OUString aPhone = rOrig.copy( nIndex, rLen );
1256 if( ! m_bPhoneCollectionActive )
1258 if( ( nPos = aPhone.indexOfAsciiL( FAX_PHONE_TOKEN, FAX_PHONE_TOKEN_LENGTH ) ) != -1 )
1260 nStart = nPos;
1261 m_bPhoneCollectionActive = true;
1262 m_aPhoneCollection = "";
1263 bRet = true;
1264 bStarted = true;
1267 if( m_bPhoneCollectionActive )
1269 bool bStopped = false;
1270 bRet = true;
1271 nPos = bStarted ? nStart + FAX_PHONE_TOKEN_LENGTH : 0;
1272 if( ( nPos = aPhone.indexOfAsciiL( FAX_END_TOKEN, FAX_END_TOKEN_LENGTH, nPos ) ) != -1 )
1274 m_bPhoneCollectionActive = false;
1275 nStop = nPos + FAX_END_TOKEN_LENGTH;
1276 bStopped = true;
1278 int nTokenStart = nStart + (bStarted ? FAX_PHONE_TOKEN_LENGTH : 0);
1279 int nTokenStop = nStop - (bStopped ? FAX_END_TOKEN_LENGTH : 0);
1280 m_aPhoneCollection += aPhone.copy( nTokenStart, nTokenStop - nTokenStart );
1281 if( ! m_bPhoneCollectionActive )
1283 OUStringBuffer aPhoneNr;
1284 aPhoneNr.append( "<Fax#>" );
1285 aPhoneNr.append( m_aPhoneCollection );
1286 aPhoneNr.append( "</Fax#>" );
1287 *m_pPhoneNr = aPhoneNr.makeStringAndClear();
1288 m_aPhoneCollection = "";
1291 if( m_aPhoneCollection.getLength() > 1024 )
1293 m_bPhoneCollectionActive = false;
1294 m_aPhoneCollection = "";
1295 bRet = false;
1298 if( bRet && m_bSwallowFaxNo )
1300 rLen -= nStop - nStart;
1301 rCutStart = nStart+nIndex;
1302 rCutStop = nStop+nIndex;
1303 if (rCutStart != rCutStop)
1304 rNewText = ( rCutStart ? rOrig.copy( 0, rCutStart ) : OUString() ) + rOrig.copy( rCutStop );
1307 return bRet && m_bSwallowFaxNo;
1310 bool GenPspGraphics::drawAlphaBitmap( const SalTwoRect&,
1311 const SalBitmap&,
1312 const SalBitmap& )
1314 return false;
1317 bool GenPspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8 )
1319 return false;
1322 SystemGraphicsData GenPspGraphics::GetGraphicsData() const
1324 return SystemGraphicsData();
1327 SystemFontData GenPspGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
1329 return SystemFontData();
1332 bool GenPspGraphics::supportsOperation( OutDevSupportType ) const
1334 return false;
1337 void GenPspGraphics::DoFreeEmbedFontData( const void* pData, long nLen )
1339 #if defined( UNX )
1340 if( pData )
1341 munmap( (char*)pData, nLen );
1342 #else
1343 (void)nLen;
1344 rtl_freeMemory( (void *)pData );
1345 #endif
1348 const void* GenPspGraphics::DoGetEmbedFontData( psp::fontID aFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen )
1351 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1353 psp::PrintFontInfo aFontInfo;
1354 if( ! rMgr.getFontInfo( aFont, aFontInfo ) )
1355 return NULL;
1357 // fill in font info
1358 rInfo.m_nAscent = aFontInfo.m_nAscend;
1359 rInfo.m_nDescent = aFontInfo.m_nDescend;
1360 rInfo.m_aPSName = rMgr.getPSName( aFont );
1362 int xMin, yMin, xMax, yMax;
1363 rMgr.getFontBoundingBox( aFont, xMin, yMin, xMax, yMax );
1365 psp::CharacterMetric aMetrics[256];
1366 sal_Ucs aUnicodes[256];
1367 if( aFontInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL && aFontInfo.m_eType == psp::fonttype::Type1 )
1369 for( int i = 0; i < 256; i++ )
1370 aUnicodes[i] = pUnicodes[i] < 0x0100 ? pUnicodes[i] + 0xf000 : pUnicodes[i];
1371 pUnicodes = aUnicodes;
1373 if( ! rMgr.getMetrics( aFont, pUnicodes, 256, aMetrics ) )
1374 return NULL;
1376 OString aSysPath = rMgr.getFontFileSysPath( aFont );
1378 #if defined( UNX )
1379 struct stat aStat;
1380 if( stat( aSysPath.getStr(), &aStat ) )
1381 return NULL;
1382 int fd = open( aSysPath.getStr(), O_RDONLY );
1383 if( fd < 0 )
1384 return NULL;
1385 void* pFile = mmap( NULL, aStat.st_size, PROT_READ, MAP_SHARED, fd, 0 );
1386 close( fd );
1387 if( pFile == MAP_FAILED )
1388 return NULL;
1389 *pDataLen = aStat.st_size;
1390 #else
1391 // FIXME: test me ! ...
1392 OUString aURL;
1393 if( osl::File::getFileURLFromSystemPath( OStringToOUString( aSysPath, osl_getThreadTextEncoding() ), aURL ) != osl::File::E_None )
1394 return NULL;
1395 osl::File aFile( aURL );
1396 if( aFile.open( osl_File_OpenFlag_Read | osl_File_OpenFlag_NoLock ) != osl::File::E_None )
1397 return NULL;
1399 osl::DirectoryItem aItem;
1400 osl::DirectoryItem::get( aURL, aItem );
1401 osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileSize );
1402 aItem.getFileStatus( aFileStatus );
1404 void *pFile = rtl_allocateMemory( aFileStatus.getFileSize() );
1405 sal_uInt64 nRead = 0;
1406 aFile.read( pFile, aFileStatus.getFileSize(), nRead );
1407 *pDataLen = (long) nRead;
1408 #endif
1410 rInfo.m_aFontBBox = Rectangle( Point( xMin, yMin ), Size( xMax-xMin, yMax-yMin ) );
1411 rInfo.m_nCapHeight = yMax; // Well ...
1413 for( int i = 0; i < 256; i++ )
1414 pWidths[i] = (aMetrics[i].width > 0 ? aMetrics[i].width : 0);
1416 switch( aFontInfo.m_eType )
1418 case psp::fonttype::TrueType:
1419 rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF;
1420 break;
1421 case psp::fonttype::Type1: {
1422 const bool bPFA = ((*(unsigned char*)pFile) < 0x80);
1423 rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB;
1425 break;
1426 default:
1427 DoFreeEmbedFontData( pFile, *pDataLen );
1428 return NULL;
1431 return pFile;
1434 void GenPspGraphics::FreeEmbedFontData( const void* pData, long nLen )
1436 DoFreeEmbedFontData( pData, nLen );
1439 const void* GenPspGraphics::GetEmbedFontData( const PhysicalFontFace* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen )
1441 // in this context the pFont->GetFontId() is a valid PSP
1442 // font since they are the only ones left after the PDF
1443 // export has filtered its list of subsettable fonts (for
1444 // which this method was created). The correct way would
1445 // be to have the GlyphCache search for the PhysicalFontFace pFont
1446 psp::fontID aFont = pFont->GetFontId();
1447 return DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen );
1450 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */