1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
25 # include <sys/mman.h>
26 # include <sys/stat.h>
27 # include <sys/types.h>
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"
42 #include "impfont.hxx"
43 #include "outfont.hxx"
44 #include "fontsubset.hxx"
47 #include "langboost.hxx"
49 #include <config_graphite.h>
51 #include <graphite_layout.hxx>
52 #include <graphite_serverfont.hxx>
55 #include <comphelper/string.hxx>
56 #include <i18nlangtag/mslangid.hxx>
61 // ----- Implementation of PrinterBmp by means of SalBitmap/BitmapBuffer ---------------
63 class SalPrinterBmp
: public psp::PrinterBmp
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;
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
) :
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
;
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;
146 OSL_FAIL("Error: SalPrinterBmp::SalPrinterBmp() unknown bitmap format");
151 SalPrinterBmp::~SalPrinterBmp ()
156 SalPrinterBmp::GetWidth () const
158 return mpBmpBuffer
->mnWidth
;
162 SalPrinterBmp::GetHeight () const
164 return mpBmpBuffer
->mnHeight
;
168 SalPrinterBmp::GetDepth () const
172 switch (mpBmpBuffer
->mnBitCount
)
191 OSL_FAIL("Error: unsupported bitmap depth in SalPrinterBmp::GetDepth()");
199 SalPrinterBmp::ColorOf (BitmapColor
& rColor
) const
201 if (rColor
.IsIndex())
202 return ColorOf (mpBmpBuffer
->maPalette
[rColor
.GetIndex()]);
204 return ((rColor
.GetBlue()) & 0x000000ff)
205 | ((rColor
.GetGreen() << 8) & 0x0000ff00)
206 | ((rColor
.GetRed() << 16) & 0x00ff0000);
210 SalPrinterBmp::GrayOf (BitmapColor
& rColor
) const
212 if (rColor
.IsIndex())
213 return GrayOf (mpBmpBuffer
->maPalette
[rColor
.GetIndex()]);
215 return ( rColor
.GetBlue() * 28UL
216 + rColor
.GetGreen() * 151UL
217 + rColor
.GetRed() * 77UL ) >> 8;
221 SalPrinterBmp::GetPaletteEntryCount () const
223 return mpBmpBuffer
->maPalette
.GetEntryCount ();
227 SalPrinterBmp::GetPaletteColor (sal_uInt32 nIdx
) const
229 return ColorOf (mpBmpBuffer
->maPalette
[nIdx
]);
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
);
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
);
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();
262 /*******************************************************
264 *******************************************************/
266 GenPspGraphics::GenPspGraphics()
267 : m_pJobData( NULL
),
268 m_pPrinterGfx( 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
)
284 m_pPrinterGfx
= pGfx
;
286 m_bSwallowFaxNo
= bSwallow
;
287 m_pInfoPrinter
= pInfoPrinter
;
291 GenPspGraphics::~GenPspGraphics()
296 void GenPspGraphics::GetResolution( sal_Int32
&rDPIX
, sal_Int32
&rDPIY
)
298 if (m_pJobData
!= NULL
)
300 int x
= m_pJobData
->m_aContext
.getRenderResolution();
307 sal_uInt16
GenPspGraphics::GetBitCount() const
309 return m_pPrinterGfx
->GetBitCount();
312 long GenPspGraphics::GetGraphicsWidth() const
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
;
329 bool bRegionRect
= i_rClip
.ImplGetFirstRect(aInfo
, nX
, nY
, nW
, nH
);
334 m_pPrinterGfx
->UnionClipRegion( nX
, nY
, nW
, nH
);
336 bRegionRect
= i_rClip
.ImplGetNextRect( aInfo
, nX
, nY
, nW
, nH
);
338 m_pPrinterGfx
->EndSetClipRegion();
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 )
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
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
442 sal_Bool
GenPspGraphics::drawPolyLineBezier( sal_uLong nPoints
, const SalPoint
* pPtAry
, const sal_uInt8
* pFlgAry
)
444 m_pPrinterGfx
->DrawPolyLineBezier (nPoints
, (Point
*)pPtAry
, pFlgAry
);
448 sal_Bool
GenPspGraphics::drawPolygonBezier( sal_uLong nPoints
, const SalPoint
* pPtAry
, const sal_uInt8
* pFlgAry
)
450 m_pPrinterGfx
->DrawPolygonBezier (nPoints
, (Point
*)pPtAry
, pFlgAry
);
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
);
464 void GenPspGraphics::invert( sal_uLong
,
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
*,
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
*,
505 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent bitmap");
508 void GenPspGraphics::drawBitmap( const SalTwoRect
*,
512 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent color");
515 void GenPspGraphics::drawMask( const SalTwoRect
*,
519 OSL_FAIL("Error: PrinterGfx::DrawMask() not implemented");
522 SalBitmap
* GenPspGraphics::getBitmap( long, long, long, long )
524 DBG_WARNING ("Warning: PrinterGfx::GetBitmap() not implemented");
528 SalColor
GenPspGraphics::getPixel( long, long )
530 OSL_FAIL("Warning: PrinterGfx::GetPixel() not implemented");
534 void GenPspGraphics::invert(long,long,long,long,SalInvert
)
536 OSL_FAIL("Warning: PrinterGfx::Invert() not implemented");
539 //==========================================================================
541 class ImplPspFontData
: public PhysicalFontFace
544 enum { PSPFD_MAGIC
= 0xb5bf01f0 };
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
);
570 //==========================================================================
572 class PspFontLayout
: public GenericSalLayout
575 PspFontLayout( ::psp::PrinterGfx
& );
576 virtual bool LayoutText( ImplLayoutArgs
& );
577 virtual void InitFont() const;
578 virtual void DrawText( SalGraphics
& ) const;
580 ::psp::PrinterGfx
& mrPrinterGfx
;
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;
612 Point
aNewPos( 0, 0 );
614 rtl_TextEncoding aFontEnc
= mrPrinterGfx
.GetFontMgr().getFontEncoding( mnFontID
);
616 Reserve(rArgs
.mnLength
);
621 if( !rArgs
.GetNextPos( &nCharPos
, &bRightToLeft
) )
624 sal_Unicode cChar
= rArgs
.mpStr
[ nCharPos
];
626 cChar
= GetMirroredChar( cChar
);
627 // symbol font aliasing: 0x0020-0x00ff -> 0xf020 -> 0xf0ff
628 if( aFontEnc
== RTL_TEXTENCODING_SYMBOL
)
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();
652 nTextScale
= mrPrinterGfx
.GetFontHeight();
653 int nKern
= (mbVertical
? it
->kern_y
: it
->kern_x
) * nTextScale
;
654 nGlyphWidth
+= nKern
;
655 aPrevItem
.mnNewWidth
= nGlyphWidth
;
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
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; }
694 ::psp::PrinterGfx
& mrPrinterGfx
;
705 PspServerFontLayout::PspServerFontLayout( ::psp::PrinterGfx
& rGfx
, ServerFont
& rFont
, const ImplLayoutArgs
& rArgs
)
706 : ServerFontLayout( rFont
),
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
];
737 long nUnitsPerPixel
= rLayout
.GetUnitsPerPixel();
738 const sal_Unicode
* pText
= NULL
;
741 if (bIsPspServerFontLayout
)
743 const PspServerFontLayout
* pPspLayout
= dynamic_cast<const PspServerFontLayout
*>(&rLayout
);
745 const GraphiteServerFontLayout
* pGrLayout
= dynamic_cast<const GraphiteServerFontLayout
*>(&rLayout
);
749 pText
= pPspLayout
->getTextPtr();
750 nMinCharPos
= pPspLayout
->getMinCharPos();
751 nMaxCharPos
= pPspLayout
->getMaxCharPos();
759 for( int nStart
= 0;; )
761 int nGlyphCount
= rLayout
.GetNextGlyphs( nMaxGlyphs
, aGlyphAry
, aPos
, nStart
, aWidthAry
, pText
? aCharPosAry
: NULL
);
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
);
772 aUnicodes
[i
] = (aCharPosAry
[i
] >= nMinCharPos
&& aCharPosAry
[i
] <= nMaxCharPos
) ? pText
[ aCharPosAry
[i
] ] : 0;
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] )
808 const ImplFontCharMap
* pIFCMap
= m_pServerFont
[0]->GetImplFontCharMap();
812 bool GenPspGraphics::GetImplFontCapabilities(vcl::FontCapabilities
&rFontCapabilities
) const
814 if (!m_pServerFont
[0])
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
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
)
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
)
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
;
865 GlyphCache::GetInstance().UncacheFont( *pServerFont
);
869 // set the printer font
870 return m_pPrinterGfx
->SetFont( nID
,
873 pEntry
->mnOrientation
,
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
& )
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();
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
;
960 int nTextScale
= m_pPrinterGfx
->GetFontWidth();
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;
974 sal_Bool
GenPspGraphics::GetGlyphBoundRect( sal_GlyphId nGlyphIndex
, Rectangle
& rRect
)
976 int nLevel
= nGlyphIndex
>> GF_FONTSHIFT
;
977 if( nLevel
>= MAX_FALLBACK
)
980 ServerFont
* pSF
= m_pServerFont
[ nLevel
];
984 nGlyphIndex
&= GF_IDXMASK
;
985 const GlyphMetric
& rGM
= pSF
->GetGlyphMetric( nGlyphIndex
);
986 rRect
= Rectangle( rGM
.GetOffset(), rGM
.GetSize() );
990 sal_Bool
GenPspGraphics::GetGlyphOutline( sal_GlyphId nGlyphIndex
,
991 ::basegfx::B2DPolyPolygon
& rB2DPolyPoly
)
993 int nLevel
= nGlyphIndex
>> GF_FONTSHIFT
;
994 if( nLevel
>= MAX_FALLBACK
)
997 ServerFont
* pSF
= m_pServerFont
[ nLevel
];
1001 nGlyphIndex
&= GF_IDXMASK
;
1002 if( pSF
->GetGlyphOutline( nGlyphIndex
, rB2DPolyPoly
) )
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
) )
1023 // Is this a Graphite font?
1024 if (GraphiteServerFontLayout::IsGraphiteEnabledFont(*m_pServerFont
[nFallbackLevel
]))
1026 pLayout
= new GraphiteServerFontLayout(*m_pServerFont
[nFallbackLevel
]);
1030 pLayout
= new PspServerFontLayout( *m_pPrinterGfx
, *m_pServerFont
[nFallbackLevel
], rArgs
);
1033 pLayout
= new PspFontLayout( *m_pPrinterGfx
);
1038 //--------------------------------------------------------------------------
1040 sal_Bool
GenPspGraphics::CreateFontSubset(
1041 const OUString
& rToFile
,
1042 const PhysicalFontFace
* pFont
,
1043 sal_Int32
* pGlyphIDs
,
1044 sal_uInt8
* pEncoding
,
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
,
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
,
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
) )
1105 *pNonEncoded
= NULL
;
1109 return rMgr
.getEncodingMap( aFont
, pNonEncoded
);
1112 void GenPspGraphics::DoGetGlyphWidths( psp::fontID aFont
,
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;
1142 case psp::fonttype::TrueType
:
1143 aDFA
.mnQuality
= 512;
1144 aDFA
.mbDevice
= false;
1146 case psp::fonttype::Type1
:
1148 aDFA
.mbDevice
= false;
1152 aDFA
.mbDevice
= false;
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
)
1164 aDFA
.maMapNames
.Append( ';' );
1165 aDFA
.maMapNames
.Append( (*it
).getStr() );
1166 bHasMapNames
= true;
1169 #if OSL_DEBUG_LEVEL > 2
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() );
1183 const char* getLangBoost()
1185 const char* pLangBoost
;
1186 const LanguageType eLang
= Application::GetSettings().GetUILanguageTag().getLanguageType();
1187 if (eLang
== LANGUAGE_JAPANESE
)
1189 else if (MsLangId::isKorean(eLang
))
1191 else if (MsLangId::isSimplifiedChinese(eLang
))
1193 else if (MsLangId::isTraditionalChinese(eLang
))
1201 // -----------------------------------------------------------------------
1203 void GenPspGraphics::AnnounceFonts( ImplDevFontList
* pFontList
, const psp::FastPrintFontInfo
& aInfo
)
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] == '.' )
1217 static const char* pLangBoost
= NULL
;
1218 static bool bOnce
= true;
1222 pLangBoost
= vcl::getLangBoost();
1226 if( aFileName
.copy( nPos
+1, 3 ).equalsIgnoreAsciiCase( pLangBoost
) )
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
)
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
1250 bool bStarted
= false;
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 )
1261 m_bPhoneCollectionActive
= true;
1262 m_aPhoneCollection
= "";
1267 if( m_bPhoneCollectionActive
)
1269 bool bStopped
= false;
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
;
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
= "";
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
&,
1317 bool GenPspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8
)
1322 SystemGraphicsData
GenPspGraphics::GetGraphicsData() const
1324 return SystemGraphicsData();
1327 SystemFontData
GenPspGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
1329 return SystemFontData();
1332 bool GenPspGraphics::supportsOperation( OutDevSupportType
) const
1337 void GenPspGraphics::DoFreeEmbedFontData( const void* pData
, long nLen
)
1341 munmap( (char*)pData
, nLen
);
1344 rtl_freeMemory( (void *)pData
);
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
) )
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
) )
1376 OString aSysPath
= rMgr
.getFontFileSysPath( aFont
);
1380 if( stat( aSysPath
.getStr(), &aStat
) )
1382 int fd
= open( aSysPath
.getStr(), O_RDONLY
);
1385 void* pFile
= mmap( NULL
, aStat
.st_size
, PROT_READ
, MAP_SHARED
, fd
, 0 );
1387 if( pFile
== MAP_FAILED
)
1389 *pDataLen
= aStat
.st_size
;
1391 // FIXME: test me ! ...
1393 if( osl::File::getFileURLFromSystemPath( OStringToOUString( aSysPath
, osl_getThreadTextEncoding() ), aURL
) != osl::File::E_None
)
1395 osl::File
aFile( aURL
);
1396 if( aFile
.open( osl_File_OpenFlag_Read
| osl_File_OpenFlag_NoLock
) != osl::File::E_None
)
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
;
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
;
1421 case psp::fonttype::Type1
: {
1422 const bool bPFA
= ((*(unsigned char*)pFile
) < 0x80);
1423 rInfo
.m_nFontType
= bPFA
? FontSubsetInfo::TYPE1_PFA
: FontSubsetInfo::TYPE1_PFB
;
1427 DoFreeEmbedFontData( pFile
, *pDataLen
);
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: */