Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / vcl / generic / print / genpspgraphics.cxx
blob3365fbb569e0b30a3d2c54ee0592914c308c91e7
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 #ifdef ENABLE_GRAPHITE
50 #include <graphite_layout.hxx>
51 #include <graphite_serverfont.hxx>
52 #endif
54 #include <comphelper/string.hxx>
55 #include <i18npool/mslangid.hxx>
57 using namespace psp;
59 using ::rtl::OUString;
60 using ::rtl::OString;
62 // ----- Implementation of PrinterBmp by means of SalBitmap/BitmapBuffer ---------------
64 class SalPrinterBmp : public psp::PrinterBmp
66 private:
67 BitmapBuffer* mpBmpBuffer;
69 FncGetPixel mpFncGetPixel;
70 Scanline mpScanAccess;
71 sal_PtrDiff mnScanOffset;
73 sal_uInt32 ColorOf (BitmapColor& rColor) const;
74 sal_uInt8 GrayOf (BitmapColor& rColor) const;
76 SalPrinterBmp ();
78 public:
80 SalPrinterBmp (BitmapBuffer* pBitmap);
81 virtual ~SalPrinterBmp ();
82 virtual sal_uInt32 GetPaletteColor (sal_uInt32 nIdx) const;
83 virtual sal_uInt32 GetPaletteEntryCount () const;
84 virtual sal_uInt32 GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const;
85 virtual sal_uInt8 GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const;
86 virtual sal_uInt8 GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const;
87 virtual sal_uInt32 GetWidth () const;
88 virtual sal_uInt32 GetHeight() const;
89 virtual sal_uInt32 GetDepth () const;
92 SalPrinterBmp::SalPrinterBmp (BitmapBuffer* pBuffer) :
93 mpBmpBuffer (pBuffer)
95 DBG_ASSERT (mpBmpBuffer, "SalPrinterBmp::SalPrinterBmp () can't acquire Bitmap");
97 // calibrate scanline buffer
98 if( BMP_SCANLINE_ADJUSTMENT( mpBmpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
100 mpScanAccess = mpBmpBuffer->mpBits;
101 mnScanOffset = mpBmpBuffer->mnScanlineSize;
103 else
105 mpScanAccess = mpBmpBuffer->mpBits
106 + (mpBmpBuffer->mnHeight - 1) * mpBmpBuffer->mnScanlineSize;
107 mnScanOffset = - mpBmpBuffer->mnScanlineSize;
110 // request read access to the pixels
111 switch( BMP_SCANLINE_FORMAT( mpBmpBuffer->mnFormat ) )
113 case BMP_FORMAT_1BIT_MSB_PAL:
114 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL; break;
115 case BMP_FORMAT_1BIT_LSB_PAL:
116 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_LSB_PAL; break;
117 case BMP_FORMAT_4BIT_MSN_PAL:
118 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_MSN_PAL; break;
119 case BMP_FORMAT_4BIT_LSN_PAL:
120 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_LSN_PAL; break;
121 case BMP_FORMAT_8BIT_PAL:
122 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_PAL; break;
123 case BMP_FORMAT_8BIT_TC_MASK:
124 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_TC_MASK; break;
125 case BMP_FORMAT_16BIT_TC_MSB_MASK:
126 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_MSB_MASK; break;
127 case BMP_FORMAT_16BIT_TC_LSB_MASK:
128 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_LSB_MASK; break;
129 case BMP_FORMAT_24BIT_TC_BGR:
130 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_BGR; break;
131 case BMP_FORMAT_24BIT_TC_RGB:
132 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_RGB; break;
133 case BMP_FORMAT_24BIT_TC_MASK:
134 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_MASK; break;
135 case BMP_FORMAT_32BIT_TC_ABGR:
136 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ABGR; break;
137 case BMP_FORMAT_32BIT_TC_ARGB:
138 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ARGB; break;
139 case BMP_FORMAT_32BIT_TC_BGRA:
140 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_BGRA; break;
141 case BMP_FORMAT_32BIT_TC_RGBA:
142 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_RGBA; break;
143 case BMP_FORMAT_32BIT_TC_MASK:
144 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_MASK; break;
146 default:
147 OSL_FAIL("Error: SalPrinterBmp::SalPrinterBmp() unknown bitmap format");
148 break;
152 SalPrinterBmp::~SalPrinterBmp ()
156 sal_uInt32
157 SalPrinterBmp::GetWidth () const
159 return mpBmpBuffer->mnWidth;
162 sal_uInt32
163 SalPrinterBmp::GetHeight () const
165 return mpBmpBuffer->mnHeight;
168 sal_uInt32
169 SalPrinterBmp::GetDepth () const
171 sal_uInt32 nDepth;
173 switch (mpBmpBuffer->mnBitCount)
175 case 1:
176 nDepth = 1;
177 break;
179 case 4:
180 case 8:
181 nDepth = 8;
182 break;
184 case 16:
185 case 24:
186 case 32:
187 nDepth = 24;
188 break;
190 default:
191 nDepth = 1;
192 OSL_FAIL("Error: unsupported bitmap depth in SalPrinterBmp::GetDepth()");
193 break;
196 return nDepth;
199 sal_uInt32
200 SalPrinterBmp::ColorOf (BitmapColor& rColor) const
202 if (rColor.IsIndex())
203 return ColorOf (mpBmpBuffer->maPalette[rColor.GetIndex()]);
204 else
205 return ((rColor.GetBlue()) & 0x000000ff)
206 | ((rColor.GetGreen() << 8) & 0x0000ff00)
207 | ((rColor.GetRed() << 16) & 0x00ff0000);
210 sal_uInt8
211 SalPrinterBmp::GrayOf (BitmapColor& rColor) const
213 if (rColor.IsIndex())
214 return GrayOf (mpBmpBuffer->maPalette[rColor.GetIndex()]);
215 else
216 return ( rColor.GetBlue() * 28UL
217 + rColor.GetGreen() * 151UL
218 + rColor.GetRed() * 77UL ) >> 8;
221 sal_uInt32
222 SalPrinterBmp::GetPaletteEntryCount () const
224 return mpBmpBuffer->maPalette.GetEntryCount ();
227 sal_uInt32
228 SalPrinterBmp::GetPaletteColor (sal_uInt32 nIdx) const
230 return ColorOf (mpBmpBuffer->maPalette[nIdx]);
233 sal_uInt32
234 SalPrinterBmp::GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const
236 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
237 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
239 return ColorOf (aColor);
242 sal_uInt8
243 SalPrinterBmp::GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const
245 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
246 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
248 return GrayOf (aColor);
251 sal_uInt8
252 SalPrinterBmp::GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const
254 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
255 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
257 if (aColor.IsIndex())
258 return aColor.GetIndex();
259 else
260 return 0;
263 /*******************************************************
264 * GenPspGraphics *
265 *******************************************************/
267 GenPspGraphics::GenPspGraphics()
268 : m_pJobData( NULL ),
269 m_pPrinterGfx( NULL ),
270 m_pPhoneNr( NULL ),
271 m_bSwallowFaxNo( false ),
272 m_bPhoneCollectionActive( false ),
273 m_bFontVertical( false ),
274 m_pInfoPrinter( NULL )
276 for( int i = 0; i < MAX_FALLBACK; i++ )
277 m_pServerFont[i] = NULL;
280 void GenPspGraphics::Init( psp::JobData* pJob, psp::PrinterGfx* pGfx,
281 rtl::OUString* pPhone, bool bSwallow,
282 SalInfoPrinter* pInfoPrinter )
284 m_pJobData = pJob;
285 m_pPrinterGfx = pGfx;
286 m_pPhoneNr = pPhone;
287 m_bSwallowFaxNo = bSwallow;
288 m_pInfoPrinter = pInfoPrinter;
289 SetLayout( 0 );
292 GenPspGraphics::~GenPspGraphics()
294 ReleaseFonts();
297 void GenPspGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY )
299 if (m_pJobData != NULL)
301 int x = m_pJobData->m_aContext.getRenderResolution();
303 rDPIX = x;
304 rDPIY = x;
308 sal_uInt16 GenPspGraphics::GetBitCount() const
310 return m_pPrinterGfx->GetBitCount();
313 long GenPspGraphics::GetGraphicsWidth() const
315 return 0;
318 void GenPspGraphics::ResetClipRegion()
320 m_pPrinterGfx->ResetClipRegion();
323 bool GenPspGraphics::setClipRegion( const Region& i_rClip )
325 // TODO: support polygonal clipregions here
326 m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
328 ImplRegionInfo aInfo;
329 long nX, nY, nW, nH;
330 bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
331 while( bRegionRect )
333 if ( nW && nH )
335 m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
337 bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
339 m_pPrinterGfx->EndSetClipRegion();
340 return true;
343 void GenPspGraphics::SetLineColor()
345 m_pPrinterGfx->SetLineColor ();
348 void GenPspGraphics::SetLineColor( SalColor nSalColor )
350 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
351 SALCOLOR_GREEN (nSalColor),
352 SALCOLOR_BLUE (nSalColor));
353 m_pPrinterGfx->SetLineColor (aColor);
356 void GenPspGraphics::SetFillColor()
358 m_pPrinterGfx->SetFillColor ();
361 void GenPspGraphics::SetFillColor( SalColor nSalColor )
363 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
364 SALCOLOR_GREEN (nSalColor),
365 SALCOLOR_BLUE (nSalColor));
366 m_pPrinterGfx->SetFillColor (aColor);
369 void GenPspGraphics::SetROPLineColor( SalROPColor )
371 DBG_ASSERT( 0, "Error: PrinterGfx::SetROPLineColor() not implemented" );
374 void GenPspGraphics::SetROPFillColor( SalROPColor )
376 DBG_ASSERT( 0, "Error: PrinterGfx::SetROPFillColor() not implemented" );
379 void GenPspGraphics::SetXORMode( bool bSet, bool )
381 (void)bSet;
382 DBG_ASSERT( !bSet, "Error: PrinterGfx::SetXORMode() not implemented" );
385 void GenPspGraphics::drawPixel( long nX, long nY )
387 m_pPrinterGfx->DrawPixel (Point(nX, nY));
390 void GenPspGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
392 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
393 SALCOLOR_GREEN (nSalColor),
394 SALCOLOR_BLUE (nSalColor));
395 m_pPrinterGfx->DrawPixel (Point(nX, nY), aColor);
398 void GenPspGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
400 m_pPrinterGfx->DrawLine (Point(nX1, nY1), Point(nX2, nY2));
403 void GenPspGraphics::drawRect( long nX, long nY, long nDX, long nDY )
405 m_pPrinterGfx->DrawRect (Rectangle(Point(nX, nY), Size(nDX, nDY)));
408 void GenPspGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint *pPtAry )
410 m_pPrinterGfx->DrawPolyLine (nPoints, (Point*)pPtAry);
413 void GenPspGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry )
415 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx
416 m_pPrinterGfx->DrawPolygon (nPoints, (Point*)pPtAry);
419 void GenPspGraphics::drawPolyPolygon( sal_uInt32 nPoly,
420 const sal_uInt32 *pPoints,
421 PCONSTSALPOINT *pPtAry )
423 m_pPrinterGfx->DrawPolyPolygon (nPoly, pPoints, (const Point**)pPtAry);
426 bool GenPspGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
428 // TODO: implement and advertise OutDevSupport_B2DDraw support
429 return false;
432 bool GenPspGraphics::drawPolyLine(
433 const basegfx::B2DPolygon&,
434 double /*fTranspareny*/,
435 const basegfx::B2DVector& /*rLineWidths*/,
436 basegfx::B2DLineJoin /*eJoin*/,
437 com::sun::star::drawing::LineCap /*eLineCap*/)
439 // TODO: a PS printer can draw B2DPolyLines almost directly
440 return false;
443 sal_Bool GenPspGraphics::drawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
445 m_pPrinterGfx->DrawPolyLineBezier (nPoints, (Point*)pPtAry, pFlgAry);
446 return sal_True;
449 sal_Bool GenPspGraphics::drawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
451 m_pPrinterGfx->DrawPolygonBezier (nPoints, (Point*)pPtAry, pFlgAry);
452 return sal_True;
455 sal_Bool GenPspGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly,
456 const sal_uInt32* pPoints,
457 const SalPoint* const* pPtAry,
458 const sal_uInt8* const* pFlgAry )
460 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx
461 m_pPrinterGfx->DrawPolyPolygonBezier (nPoly, pPoints, (Point**)pPtAry, (sal_uInt8**)pFlgAry);
462 return sal_True;
465 void GenPspGraphics::invert( sal_uLong,
466 const SalPoint*,
467 SalInvert )
469 DBG_ASSERT( 0, "Error: PrinterGfx::Invert() not implemented" );
471 sal_Bool GenPspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize )
473 return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize );
476 void GenPspGraphics::copyBits( const SalTwoRect*,
477 SalGraphics* )
479 OSL_FAIL( "Error: PrinterGfx::CopyBits() not implemented" );
482 void GenPspGraphics::copyArea ( long,long,long,long,long,long,sal_uInt16 )
484 OSL_FAIL( "Error: PrinterGfx::CopyArea() not implemented" );
487 void GenPspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap )
489 Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY),
490 Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight));
491 Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY),
492 Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight));
494 BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(sal_True);
496 SalPrinterBmp aBmp (pBuffer);
497 m_pPrinterGfx->DrawBitmap (aDst, aSrc, aBmp);
499 const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, sal_True);
502 void GenPspGraphics::drawBitmap( const SalTwoRect*,
503 const SalBitmap&,
504 const SalBitmap& )
506 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent bitmap");
509 void GenPspGraphics::drawBitmap( const SalTwoRect*,
510 const SalBitmap&,
511 SalColor )
513 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent color");
516 void GenPspGraphics::drawMask( const SalTwoRect*,
517 const SalBitmap &,
518 SalColor )
520 OSL_FAIL("Error: PrinterGfx::DrawMask() not implemented");
523 SalBitmap* GenPspGraphics::getBitmap( long, long, long, long )
525 DBG_WARNING ("Warning: PrinterGfx::GetBitmap() not implemented");
526 return NULL;
529 SalColor GenPspGraphics::getPixel( long, long )
531 OSL_FAIL("Warning: PrinterGfx::GetPixel() not implemented");
532 return 0;
535 void GenPspGraphics::invert(long,long,long,long,SalInvert)
537 OSL_FAIL("Warning: PrinterGfx::Invert() not implemented");
540 //==========================================================================
542 class ImplPspFontData : public PhysicalFontFace
544 private:
545 enum { PSPFD_MAGIC = 0xb5bf01f0 };
546 sal_IntPtr mnFontId;
548 public:
549 ImplPspFontData( const psp::FastPrintFontInfo& );
550 virtual sal_IntPtr GetFontId() const { return mnFontId; }
551 virtual PhysicalFontFace* Clone() const { return new ImplPspFontData( *this ); }
552 virtual ImplFontEntry* CreateFontInstance( FontSelectPattern& ) const;
553 static bool CheckFontData( const PhysicalFontFace& r ) { return r.CheckMagic( PSPFD_MAGIC ); }
556 //--------------------------------------------------------------------------
558 ImplPspFontData::ImplPspFontData( const psp::FastPrintFontInfo& rInfo )
559 : PhysicalFontFace( GenPspGraphics::Info2DevFontAttributes(rInfo), PSPFD_MAGIC ),
560 mnFontId( rInfo.m_nID )
563 //--------------------------------------------------------------------------
565 ImplFontEntry* ImplPspFontData::CreateFontInstance( FontSelectPattern& rFSD ) const
567 ImplServerFontEntry* pEntry = new ImplServerFontEntry( rFSD );
568 return pEntry;
571 //==========================================================================
573 class PspFontLayout : public GenericSalLayout
575 public:
576 PspFontLayout( ::psp::PrinterGfx& );
577 virtual bool LayoutText( ImplLayoutArgs& );
578 virtual void InitFont() const;
579 virtual void DrawText( SalGraphics& ) const;
580 private:
581 ::psp::PrinterGfx& mrPrinterGfx;
582 sal_IntPtr mnFontID;
583 int mnFontHeight;
584 int mnFontWidth;
585 bool mbVertical;
586 bool mbArtItalic;
587 bool mbArtBold;
590 //--------------------------------------------------------------------------
592 PspFontLayout::PspFontLayout( ::psp::PrinterGfx& rGfx )
593 : mrPrinterGfx( rGfx )
595 mnFontID = mrPrinterGfx.GetFontID();
596 mnFontHeight = mrPrinterGfx.GetFontHeight();
597 mnFontWidth = mrPrinterGfx.GetFontWidth();
598 mbVertical = mrPrinterGfx.GetFontVertical();
599 mbArtItalic = mrPrinterGfx.GetArtificialItalic();
600 mbArtBold = mrPrinterGfx.GetArtificialBold();
603 //--------------------------------------------------------------------------
605 bool PspFontLayout::LayoutText( ImplLayoutArgs& rArgs )
607 mbVertical = ((rArgs.mnFlags & SAL_LAYOUT_VERTICAL) != 0);
609 long nUnitsPerPixel = 1;
610 int nOldGlyphId = -1;
611 long nGlyphWidth = 0;
612 int nCharPos = -1;
613 Point aNewPos( 0, 0 );
614 GlyphItem aPrevItem;
615 rtl_TextEncoding aFontEnc = mrPrinterGfx.GetFontMgr().getFontEncoding( mnFontID );
617 Reserve(rArgs.mnLength);
619 for(;;)
621 bool bRightToLeft;
622 if( !rArgs.GetNextPos( &nCharPos, &bRightToLeft ) )
623 break;
625 sal_Unicode cChar = rArgs.mpStr[ nCharPos ];
626 if( bRightToLeft )
627 cChar = GetMirroredChar( cChar );
628 // symbol font aliasing: 0x0020-0x00ff -> 0xf020 -> 0xf0ff
629 if( aFontEnc == RTL_TEXTENCODING_SYMBOL )
630 if( cChar < 256 )
631 cChar += 0xf000;
632 int nGlyphIndex = cChar; // printer glyphs = unicode
634 // update fallback_runs if needed
635 psp::CharacterMetric aMetric;
636 mrPrinterGfx.GetFontMgr().getMetrics( mnFontID, cChar, cChar, &aMetric, mbVertical );
637 if( aMetric.width == -1 && aMetric.height == -1 )
638 rArgs.NeedFallback( nCharPos, bRightToLeft );
640 // apply pair kerning to prev glyph if requested
641 if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags )
643 if( nOldGlyphId > 0 )
645 const std::list< KernPair >& rKernPairs = mrPrinterGfx.getKernPairs(mbVertical);
646 for( std::list< KernPair >::const_iterator it = rKernPairs.begin();
647 it != rKernPairs.end(); ++it )
649 if( it->first == nOldGlyphId && it->second == nGlyphIndex )
651 int nTextScale = mrPrinterGfx.GetFontWidth();
652 if( ! nTextScale )
653 nTextScale = mrPrinterGfx.GetFontHeight();
654 int nKern = (mbVertical ? it->kern_y : it->kern_x) * nTextScale;
655 nGlyphWidth += nKern;
656 aPrevItem.mnNewWidth = nGlyphWidth;
657 break;
663 // finish previous glyph
664 if( nOldGlyphId >= 0 )
665 AppendGlyph( aPrevItem );
666 nOldGlyphId = nGlyphIndex;
667 aNewPos.X() += nGlyphWidth;
669 // prepare GlyphItem for appending it in next round
670 nUnitsPerPixel = mrPrinterGfx.GetCharWidth( cChar, cChar, &nGlyphWidth );
671 int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0;
672 nGlyphIndex |= GF_ISCHAR;
673 aPrevItem = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth );
676 // append last glyph item if any
677 if( nOldGlyphId >= 0 )
678 AppendGlyph( aPrevItem );
680 SetOrientation( mrPrinterGfx.GetFontAngle() );
681 SetUnitsPerPixel( nUnitsPerPixel );
682 return (nOldGlyphId >= 0);
685 class PspServerFontLayout : public ServerFontLayout
687 public:
688 PspServerFontLayout( psp::PrinterGfx&, ServerFont& rFont, const ImplLayoutArgs& rArgs );
690 virtual void InitFont() const;
691 const sal_Unicode* getTextPtr() const { return maText.getStr() - mnMinCharPos; }
692 int getMinCharPos() const { return mnMinCharPos; }
693 int getMaxCharPos() const { return mnMinCharPos+maText.getLength()-1; }
694 private:
695 ::psp::PrinterGfx& mrPrinterGfx;
696 sal_IntPtr mnFontID;
697 int mnFontHeight;
698 int mnFontWidth;
699 bool mbVertical;
700 bool mbArtItalic;
701 bool mbArtBold;
702 rtl::OUString maText;
703 int mnMinCharPos;
706 PspServerFontLayout::PspServerFontLayout( ::psp::PrinterGfx& rGfx, ServerFont& rFont, const ImplLayoutArgs& rArgs )
707 : ServerFontLayout( rFont ),
708 mrPrinterGfx( rGfx )
710 mnFontID = mrPrinterGfx.GetFontID();
711 mnFontHeight = mrPrinterGfx.GetFontHeight();
712 mnFontWidth = mrPrinterGfx.GetFontWidth();
713 mbVertical = mrPrinterGfx.GetFontVertical();
714 mbArtItalic = mrPrinterGfx.GetArtificialItalic();
715 mbArtBold = mrPrinterGfx.GetArtificialBold();
716 maText = OUString( rArgs.mpStr + rArgs.mnMinCharPos, rArgs.mnEndCharPos - rArgs.mnMinCharPos+1 );
717 mnMinCharPos = rArgs.mnMinCharPos;
720 void PspServerFontLayout::InitFont() const
722 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth,
723 mnOrientation, mbVertical, mbArtItalic, mbArtBold );
726 //--------------------------------------------------------------------------
728 static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx, bool bIsPspServerFontLayout )
730 const int nMaxGlyphs = 200;
731 sal_uInt32 aGlyphAry[ nMaxGlyphs ]; // TODO: use sal_GlyphId
732 sal_Int32 aWidthAry[ nMaxGlyphs ];
733 sal_Int32 aIdxAry [ nMaxGlyphs ];
734 sal_Unicode aUnicodes[ nMaxGlyphs ];
735 int aCharPosAry [ nMaxGlyphs ];
737 Point aPos;
738 long nUnitsPerPixel = rLayout.GetUnitsPerPixel();
739 const sal_Unicode* pText = NULL;
740 int nMinCharPos = 0;
741 int nMaxCharPos = 0;
742 if (bIsPspServerFontLayout)
744 const PspServerFontLayout * pPspLayout = dynamic_cast<const PspServerFontLayout*>(&rLayout);
745 #ifdef ENABLE_GRAPHITE
746 const GraphiteServerFontLayout * pGrLayout = dynamic_cast<const GraphiteServerFontLayout*>(&rLayout);
747 #endif
748 if (pPspLayout)
750 pText = pPspLayout->getTextPtr();
751 nMinCharPos = pPspLayout->getMinCharPos();
752 nMaxCharPos = pPspLayout->getMaxCharPos();
754 #ifdef ENABLE_GRAPHITE
755 else if (pGrLayout)
758 #endif
760 for( int nStart = 0;; )
762 int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, pText ? aCharPosAry : NULL );
763 if( !nGlyphCount )
764 break;
766 sal_Int32 nXOffset = 0;
767 for( int i = 0; i < nGlyphCount; ++i )
769 nXOffset += aWidthAry[ i ];
770 aIdxAry[ i ] = nXOffset / nUnitsPerPixel;
771 sal_Int32 nGlyphIdx = aGlyphAry[i] & (GF_IDXMASK | GF_ROTMASK);
772 if( pText )
773 aUnicodes[i] = (aCharPosAry[i] >= nMinCharPos && aCharPosAry[i] <= nMaxCharPos) ? pText[ aCharPosAry[i] ] : 0;
774 else
775 aUnicodes[i] = (aGlyphAry[i] & GF_ISCHAR) ? nGlyphIdx : 0;
776 aGlyphAry[i] = nGlyphIdx;
779 rGfx.DrawGlyphs( aPos, (sal_uInt32 *)aGlyphAry, aUnicodes, nGlyphCount, aIdxAry );
783 //--------------------------------------------------------------------------
785 void PspFontLayout::InitFont() const
787 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth,
788 mnOrientation, mbVertical, mbArtItalic, mbArtBold );
791 //--------------------------------------------------------------------------
793 void PspFontLayout::DrawText( SalGraphics& ) const
795 DrawPrinterLayout( *this, mrPrinterGfx, false );
798 void GenPspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
800 // print complex text
801 DrawPrinterLayout( rLayout, *m_pPrinterGfx, true );
804 const ImplFontCharMap* GenPspGraphics::GetImplFontCharMap() const
806 if( !m_pServerFont[0] )
807 return NULL;
809 const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
810 return pIFCMap;
813 bool GenPspGraphics::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
815 if (!m_pServerFont[0])
816 return false;
817 return m_pServerFont[0]->GetFontCapabilities(rFontCapabilities);
820 sal_uInt16 GenPspGraphics::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
822 // release all fonts that are to be overridden
823 for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
825 if( m_pServerFont[i] != NULL )
827 // old server side font is no longer referenced
828 GlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] );
829 m_pServerFont[i] = NULL;
833 // return early if there is no new font
834 if( !pEntry )
835 return 0;
837 sal_IntPtr nID = pEntry->mpFontData ? pEntry->mpFontData->GetFontId() : 0;
839 // determine which font attributes need to be emulated
840 bool bArtItalic = false;
841 bool bArtBold = false;
842 if( pEntry->meItalic == ITALIC_OBLIQUE || pEntry->meItalic == ITALIC_NORMAL )
844 FontItalic eItalic = m_pPrinterGfx->GetFontMgr().getFontItalic( nID );
845 if( eItalic != ITALIC_NORMAL && eItalic != ITALIC_OBLIQUE )
846 bArtItalic = true;
848 int nWeight = (int)pEntry->meWeight;
849 int nRealWeight = (int)m_pPrinterGfx->GetFontMgr().getFontWeight( nID );
850 if( nRealWeight <= (int)WEIGHT_MEDIUM && nWeight > (int)WEIGHT_MEDIUM )
852 bArtBold = true;
855 // also set the serverside font for layouting
856 m_bFontVertical = pEntry->mbVertical;
857 if( pEntry->mpFontData )
859 // requesting a font provided by builtin rasterizer
860 ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
861 if( pServerFont != NULL )
863 if( pServerFont->TestFont() )
864 m_pServerFont[ nFallbackLevel ] = pServerFont;
865 else
866 GlyphCache::GetInstance().UncacheFont( *pServerFont );
870 // set the printer font
871 return m_pPrinterGfx->SetFont( nID,
872 pEntry->mnHeight,
873 pEntry->mnWidth,
874 pEntry->mnOrientation,
875 pEntry->mbVertical,
876 bArtItalic,
877 bArtBold
881 void GenPspGraphics::SetTextColor( SalColor nSalColor )
883 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
884 SALCOLOR_GREEN (nSalColor),
885 SALCOLOR_BLUE (nSalColor));
886 m_pPrinterGfx->SetTextColor (aColor);
889 bool GenPspGraphics::AddTempDevFont( ImplDevFontList*, const rtl::OUString&,const rtl::OUString& )
891 return false;
894 void GenPspGraphics::GetDevFontList( ImplDevFontList *pList )
896 ::std::list< psp::fontID > aList;
897 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
898 rMgr.getFontList( aList, m_pJobData->m_pParser, m_pInfoPrinter->m_bCompatMetrics );
900 ::std::list< psp::fontID >::iterator it;
901 psp::FastPrintFontInfo aInfo;
902 for (it = aList.begin(); it != aList.end(); ++it)
903 if (rMgr.getFontFastInfo (*it, aInfo))
904 AnnounceFonts( pList, aInfo );
906 // register platform specific font substitutions if available
907 SalGenericInstance::RegisterFontSubstitutors( pList );
910 void GenPspGraphics::ClearDevFontCache()
912 GlyphCache::GetInstance().ClearFontCache();
915 void GenPspGraphics::GetDevFontSubstList( OutputDevice* pOutDev )
917 const psp::PrinterInfo& rInfo = psp::PrinterInfoManager::get().getPrinterInfo( m_pJobData->m_aPrinterName );
918 if( rInfo.m_bPerformFontSubstitution )
920 for( boost::unordered_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator it = rInfo.m_aFontSubstitutes.begin(); it != rInfo.m_aFontSubstitutes.end(); ++it )
921 pOutDev->ImplAddDevFontSubstitute( it->first, it->second, FONT_SUBSTITUTE_ALWAYS );
925 void GenPspGraphics::GetFontMetric( ImplFontMetricData *pMetric, int )
927 const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
928 psp::PrintFontInfo aInfo;
930 if (rMgr.getFontInfo (m_pPrinterGfx->GetFontID(), aInfo))
932 ImplDevFontAttributes aDFA = Info2DevFontAttributes( aInfo );
933 static_cast<ImplFontAttributes&>(*pMetric) = aDFA;
934 pMetric->mbDevice = aDFA.mbDevice;
935 pMetric->mbScalableFont = true;
937 pMetric->mnOrientation = m_pPrinterGfx->GetFontAngle();
938 pMetric->mnSlant = 0;
940 sal_Int32 nTextHeight = m_pPrinterGfx->GetFontHeight();
941 sal_Int32 nTextWidth = m_pPrinterGfx->GetFontWidth();
942 if( ! nTextWidth )
943 nTextWidth = nTextHeight;
945 pMetric->mnWidth = nTextWidth;
946 pMetric->mnAscent = ( aInfo.m_nAscend * nTextHeight + 500 ) / 1000;
947 pMetric->mnDescent = ( aInfo.m_nDescend * nTextHeight + 500 ) / 1000;
948 pMetric->mnIntLeading = ( aInfo.m_nLeading * nTextHeight + 500 ) / 1000;
949 pMetric->mnExtLeading = 0;
953 sal_uLong GenPspGraphics::GetKernPairs( sal_uLong nPairs, ImplKernPairData *pKernPairs )
955 const ::std::list< ::psp::KernPair >& rPairs( m_pPrinterGfx->getKernPairs() );
956 sal_uLong nHavePairs = rPairs.size();
957 if( pKernPairs && nPairs )
959 ::std::list< ::psp::KernPair >::const_iterator it;
960 unsigned int i;
961 int nTextScale = m_pPrinterGfx->GetFontWidth();
962 if( ! nTextScale )
963 nTextScale = m_pPrinterGfx->GetFontHeight();
964 for( i = 0, it = rPairs.begin(); i < nPairs && i < nHavePairs; i++, ++it )
966 pKernPairs[i].mnChar1 = it->first;
967 pKernPairs[i].mnChar2 = it->second;
968 pKernPairs[i].mnKern = it->kern_x * nTextScale / 1000;
972 return nHavePairs;
975 sal_Bool GenPspGraphics::GetGlyphBoundRect( sal_GlyphId nGlyphIndex, Rectangle& rRect )
977 int nLevel = nGlyphIndex >> GF_FONTSHIFT;
978 if( nLevel >= MAX_FALLBACK )
979 return sal_False;
981 ServerFont* pSF = m_pServerFont[ nLevel ];
982 if( !pSF )
983 return sal_False;
985 nGlyphIndex &= GF_IDXMASK;
986 const GlyphMetric& rGM = pSF->GetGlyphMetric( nGlyphIndex );
987 rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() );
988 return sal_True;
991 sal_Bool GenPspGraphics::GetGlyphOutline( sal_GlyphId nGlyphIndex,
992 ::basegfx::B2DPolyPolygon& rB2DPolyPoly )
994 int nLevel = nGlyphIndex >> GF_FONTSHIFT;
995 if( nLevel >= MAX_FALLBACK )
996 return sal_False;
998 ServerFont* pSF = m_pServerFont[ nLevel ];
999 if( !pSF )
1000 return sal_False;
1002 nGlyphIndex &= GF_IDXMASK;
1003 if( pSF->GetGlyphOutline( nGlyphIndex, rB2DPolyPoly ) )
1004 return sal_True;
1006 return sal_False;
1009 SalLayout* GenPspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
1011 // workaround for printers not handling glyph indexing for non-TT fonts
1012 int nFontId = m_pPrinterGfx->GetFontID();
1013 if( psp::fonttype::TrueType != psp::PrintFontManager::get().getFontType( nFontId ) )
1014 rArgs.mnFlags |= SAL_LAYOUT_DISABLE_GLYPH_PROCESSING;
1015 else if( nFallbackLevel > 0 )
1016 rArgs.mnFlags &= ~SAL_LAYOUT_DISABLE_GLYPH_PROCESSING;
1018 GenericSalLayout* pLayout = NULL;
1020 if( m_pServerFont[ nFallbackLevel ]
1021 && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) )
1023 #ifdef ENABLE_GRAPHITE
1024 // Is this a Graphite font?
1025 if (GraphiteServerFontLayout::IsGraphiteEnabledFont(*m_pServerFont[nFallbackLevel]))
1027 pLayout = new GraphiteServerFontLayout(*m_pServerFont[nFallbackLevel]);
1029 else
1030 #endif
1031 pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pServerFont[nFallbackLevel], rArgs );
1033 else
1034 pLayout = new PspFontLayout( *m_pPrinterGfx );
1036 return pLayout;
1039 //--------------------------------------------------------------------------
1041 sal_Bool GenPspGraphics::CreateFontSubset(
1042 const rtl::OUString& rToFile,
1043 const PhysicalFontFace* pFont,
1044 sal_Int32* pGlyphIDs,
1045 sal_uInt8* pEncoding,
1046 sal_Int32* pWidths,
1047 int nGlyphCount,
1048 FontSubsetInfo& rInfo
1051 // in this context the pFont->GetFontId() is a valid PSP
1052 // font since they are the only ones left after the PDF
1053 // export has filtered its list of subsettable fonts (for
1054 // which this method was created). The correct way would
1055 // be to have the GlyphCache search for the PhysicalFontFace pFont
1056 psp::fontID aFont = pFont->GetFontId();
1058 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1059 bool bSuccess = rMgr.createFontSubset( rInfo,
1060 aFont,
1061 rToFile,
1062 pGlyphIDs,
1063 pEncoding,
1064 pWidths,
1065 nGlyphCount );
1066 return bSuccess;
1069 //--------------------------------------------------------------------------
1071 const Ucs2SIntMap* GenPspGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
1073 // in this context the pFont->GetFontId() is a valid PSP
1074 // font since they are the only ones left after the PDF
1075 // export has filtered its list of subsettable fonts (for
1076 // which this method was created). The correct way would
1077 // be to have the GlyphCache search for the PhysicalFontFace pFont
1078 psp::fontID aFont = pFont->GetFontId();
1079 return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
1082 //--------------------------------------------------------------------------
1084 void GenPspGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
1085 bool bVertical,
1086 Int32Vector& rWidths,
1087 Ucs2UIntMap& rUnicodeEnc )
1089 // in this context the pFont->GetFontId() is a valid PSP
1090 // font since they are the only ones left after the PDF
1091 // export has filtered its list of subsettable fonts (for
1092 // which this method was created). The correct way would
1093 // be to have the GlyphCache search for the PhysicalFontFace pFont
1094 psp::fontID aFont = pFont->GetFontId();
1095 GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
1098 const Ucs2SIntMap* GenPspGraphics::DoGetFontEncodingVector( fontID aFont, const Ucs2OStrMap** pNonEncoded )
1100 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1102 psp::PrintFontInfo aFontInfo;
1103 if( ! rMgr.getFontInfo( aFont, aFontInfo ) )
1105 if( pNonEncoded )
1106 *pNonEncoded = NULL;
1107 return NULL;
1110 return rMgr.getEncodingMap( aFont, pNonEncoded );
1113 void GenPspGraphics::DoGetGlyphWidths( psp::fontID aFont,
1114 bool bVertical,
1115 Int32Vector& rWidths,
1116 Ucs2UIntMap& rUnicodeEnc )
1118 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1119 rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
1121 // ----------------------------------------------------------------------------
1123 ImplDevFontAttributes GenPspGraphics::Info2DevFontAttributes( const psp::FastPrintFontInfo& rInfo )
1125 ImplDevFontAttributes aDFA;
1126 aDFA.maName = rInfo.m_aFamilyName;
1127 aDFA.maStyleName = rInfo.m_aStyleName;
1128 aDFA.meFamily = rInfo.m_eFamilyStyle;
1129 aDFA.meWeight = rInfo.m_eWeight;
1130 aDFA.meItalic = rInfo.m_eItalic;
1131 aDFA.meWidthType = rInfo.m_eWidth;
1132 aDFA.mePitch = rInfo.m_ePitch;
1133 aDFA.mbSymbolFlag = (rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL);
1134 aDFA.mbSubsettable = rInfo.m_bSubsettable;
1135 aDFA.mbEmbeddable = rInfo.m_bEmbeddable;
1137 switch( rInfo.m_eType )
1139 case psp::fonttype::Builtin:
1140 aDFA.mnQuality = 1024;
1141 aDFA.mbDevice = true;
1142 break;
1143 case psp::fonttype::TrueType:
1144 aDFA.mnQuality = 512;
1145 aDFA.mbDevice = false;
1146 break;
1147 case psp::fonttype::Type1:
1148 aDFA.mnQuality = 0;
1149 aDFA.mbDevice = false;
1150 break;
1151 default:
1152 aDFA.mnQuality = 0;
1153 aDFA.mbDevice = false;
1154 break;
1157 aDFA.mbOrientation = true;
1159 // add font family name aliases
1160 ::std::list< OUString >::const_iterator it = rInfo.m_aAliases.begin();
1161 bool bHasMapNames = false;
1162 for(; it != rInfo.m_aAliases.end(); ++it )
1164 if( bHasMapNames )
1165 aDFA.maMapNames.Append( ';' );
1166 aDFA.maMapNames.Append( (*it).getStr() );
1167 bHasMapNames = true;
1170 #if OSL_DEBUG_LEVEL > 2
1171 if( bHasMapNames )
1173 rtl::OString aOrigName(rtl::OUStringToOString(aDFA.maName, osl_getThreadTextEncoding()));
1174 rtl::OString aAliasNames(rtl::OUStringToOString(aDFA.maMapNames, osl_getThreadTextEncoding()));
1175 fprintf( stderr, "using alias names \"%s\" for font family \"%s\"\n",
1176 aAliasNames.getStr(), aOrigName.getStr() );
1178 #endif
1180 return aDFA;
1183 namespace vcl
1185 const char* getLangBoost()
1187 const char* pLangBoost;
1188 const LanguageType eLang = Application::GetSettings().GetUILanguageTag().getLanguageType();
1189 if (eLang == LANGUAGE_JAPANESE)
1190 pLangBoost = "jan";
1191 else if (MsLangId::isKorean(eLang))
1192 pLangBoost = "kor";
1193 else if (MsLangId::isSimplifiedChinese(eLang))
1194 pLangBoost = "zhs";
1195 else if (MsLangId::isTraditionalChinese(eLang))
1196 pLangBoost = "zht";
1197 else
1198 pLangBoost = NULL;
1199 return pLangBoost;
1203 // -----------------------------------------------------------------------
1205 void GenPspGraphics::AnnounceFonts( ImplDevFontList* pFontList, const psp::FastPrintFontInfo& aInfo )
1207 int nQuality = 0;
1209 if( aInfo.m_eType == psp::fonttype::TrueType )
1211 // asian type 1 fonts are not known
1212 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1213 OString aFileName( rMgr.getFontFileSysPath( aInfo.m_nID ) );
1214 int nPos = aFileName.lastIndexOf( '_' );
1215 if( nPos == -1 || aFileName[nPos+1] == '.' )
1216 nQuality += 5;
1217 else
1219 static const char* pLangBoost = NULL;
1220 static bool bOnce = true;
1221 if( bOnce )
1223 bOnce = false;
1224 pLangBoost = vcl::getLangBoost();
1227 if( pLangBoost )
1228 if( aFileName.copy( nPos+1, 3 ).equalsIgnoreAsciiCase( pLangBoost ) )
1229 nQuality += 10;
1233 ImplPspFontData* pFD = new ImplPspFontData( aInfo );
1234 pFD->mnQuality += nQuality;
1235 pFontList->Add( pFD );
1238 bool GenPspGraphics::filterText( const rtl::OUString& rOrig, rtl::OUString& rNewText, xub_StrLen nIndex, xub_StrLen& rLen, xub_StrLen& rCutStart, xub_StrLen& rCutStop )
1240 if( ! m_pPhoneNr )
1241 return false;
1243 rCutStop = rCutStart = STRING_NOTFOUND;
1245 #define FAX_PHONE_TOKEN "@@#"
1246 #define FAX_PHONE_TOKEN_LENGTH 3
1247 #define FAX_END_TOKEN "@@"
1248 #define FAX_END_TOKEN_LENGTH 2
1250 bool bRet = false;
1251 bool bStarted = false;
1252 bool bStopped = false;
1253 sal_Int32 nPos;
1254 sal_Int32 nStart = 0;
1255 sal_Int32 nStop = rLen;
1256 rtl::OUString aPhone = rOrig.copy( nIndex, rLen );
1258 if( ! m_bPhoneCollectionActive )
1260 if( ( nPos = aPhone.indexOfAsciiL( FAX_PHONE_TOKEN, FAX_PHONE_TOKEN_LENGTH ) ) != -1 )
1262 nStart = nPos;
1263 m_bPhoneCollectionActive = true;
1264 m_aPhoneCollection = rtl::OUString();
1265 bRet = true;
1266 bStarted = true;
1269 if( m_bPhoneCollectionActive )
1271 bRet = true;
1272 nPos = bStarted ? nStart + FAX_PHONE_TOKEN_LENGTH : 0;
1273 if( ( nPos = aPhone.indexOfAsciiL( FAX_END_TOKEN, FAX_END_TOKEN_LENGTH, nPos ) ) != -1 )
1275 m_bPhoneCollectionActive = false;
1276 nStop = nPos + FAX_END_TOKEN_LENGTH;
1277 bStopped = true;
1279 int nTokenStart = nStart + (bStarted ? FAX_PHONE_TOKEN_LENGTH : 0);
1280 int nTokenStop = nStop - (bStopped ? FAX_END_TOKEN_LENGTH : 0);
1281 m_aPhoneCollection += aPhone.copy( nTokenStart, nTokenStop - nTokenStart );
1282 if( ! m_bPhoneCollectionActive )
1284 rtl::OUStringBuffer aPhoneNr;
1285 aPhoneNr.appendAscii( RTL_CONSTASCII_STRINGPARAM( "<Fax#>" ) );
1286 aPhoneNr.append( m_aPhoneCollection );
1287 aPhoneNr.appendAscii( RTL_CONSTASCII_STRINGPARAM( "</Fax#>" ) );
1288 *m_pPhoneNr = aPhoneNr.makeStringAndClear();
1289 m_aPhoneCollection = rtl::OUString();
1292 if( m_aPhoneCollection.getLength() > 1024 )
1294 m_bPhoneCollectionActive = false;
1295 m_aPhoneCollection = rtl::OUString();
1296 bRet = false;
1299 if( bRet && m_bSwallowFaxNo )
1301 rLen -= nStop - nStart;
1302 rCutStart = nStart+nIndex;
1303 rCutStop = nStop+nIndex;
1304 rNewText = ( rCutStart ? rOrig.copy( 0, rCutStart ) : rtl::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 rtl::OUString aURL;
1393 if( !osl::File::getFileURLFromSystemPath( rtl::OStringToOUString( aSysPath, osl_getThreadTextEncoding() ), aURL ) )
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: */