1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eps.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
35 #include <tools/stream.hxx>
36 #include <tools/bigint.hxx>
37 #include <tools/poly.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/metaact.hxx>
40 #include <vcl/graph.hxx>
41 #include <vcl/bmpacc.hxx>
42 #include <vcl/region.hxx>
43 #include <vcl/metric.hxx>
44 #include <vcl/font.hxx>
45 #include <vcl/virdev.hxx>
46 #include <vcl/msgbox.hxx>
47 #include <vcl/cvtgrf.hxx>
48 #include <vcl/gradient.hxx>
49 #include <svtools/solar.hrc>
50 #include <svtools/fltcall.hxx>
51 #include <svtools/FilterConfigItem.hxx>
52 #include <vcl/graphictools.hxx>
53 #include "strings.hrc"
59 #define POSTSCRIPT_BOUNDINGSEARCH 0x1000 // we only try to get the BoundingBox
60 // in the first 4096 bytes
62 #define EPS_PREVIEW_TIFF 1
63 #define EPS_PREVIEW_EPSI 2
65 #define PS_LINESIZE 70 // maximum number of characters a line in the output
67 #define PS_NONE 0 // formating mode: action which is inserted behind the output
72 // -----------------------------Feld-Typen-------------------------------
76 struct ChrSet
* pSucc
;
84 struct StackMember
* pSucc
;
99 SvtGraphicStroke::CapType eLineCap
;
100 SvtGraphicStroke::JoinType eJoinType
;
101 SvtGraphicStroke::DashArray aDashArray
;
104 struct PSLZWCTreeNode
107 PSLZWCTreeNode
* pBrother
; // naechster Knoten, der den selben Vater hat
108 PSLZWCTreeNode
* pFirstChild
; // erster Sohn
109 USHORT nCode
; // Der Code fuer den String von Pixelwerten, der sich ergibt, wenn
110 USHORT nValue
; // Der Pixelwert
117 ULONG mnLevelWarning
; // number of embedded eps files which was not exported
118 ULONG mnLastPercent
; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
119 UINT32 mnLatestPush
; // offset auf streamposition, an der zuletzt gepusht wurde
121 long mnLevel
; // dialog options
122 sal_Bool mbGrayScale
;
123 sal_Bool mbCompression
;
125 sal_Int32 mnTextMode
;
128 const GDIMetaFile
* pMTF
;
129 GDIMetaFile
* pAMTF
; // only created if Graphics is not a Metafile
132 double nBoundingX1
; // this represents the bounding box
137 StackMember
* pGDIStack
;
138 ULONG mnCursorPos
; // aktuelle Cursorposition im Output
139 Color aColor
; // aktuelle Farbe die fuer den Output benutzt wird
141 Color aLineColor
; // aktuelle GDIMetafile Farbeinstellungen
145 BOOL bTextFillColor
; //
146 Color aTextFillColor
; //
147 Color aBackgroundColor
; //
149 TextAlign eTextAlign
; //
153 SvtGraphicStroke::CapType eLineCap
;
154 SvtGraphicStroke::JoinType eJoinType
;
155 SvtGraphicStroke::DashArray aDashArray
;
160 ChrSet
* pChrSetList
; // Liste der Character-Sets
161 BYTE nNextChrSetId
; // die erste unbenutzte ChrSet-Id
163 PSLZWCTreeNode
* pTable
; // LZW compression data
164 PSLZWCTreeNode
* pPrefix
; // the compression is as same as the TIFF compression
173 com::sun::star::uno::Reference
< com::sun::star::task::XStatusIndicator
> xStatusIndicator
;
175 void ImplWriteProlog( const Graphic
* pPreviewEPSI
= NULL
);
176 void ImplWriteEpilog();
177 void ImplWriteActions( const GDIMetaFile
& rMtf
, VirtualDevice
& rVDev
);
179 // this method makes LF's, space inserting and word wrapping as used in all nMode
181 inline void ImplExecMode( ULONG nMode
);
183 // writes char[] + LF to stream
184 inline void ImplWriteLine( const char*, ULONG nMode
= PS_RET
);
186 // writes ( nNumb / 10^nCount ) in ASCII format to stream
187 void ImplWriteF( sal_Int32 nNumb
, ULONG nCount
= 3, ULONG nMode
= PS_SPACE
);
189 // writes a double in ASCII format to stream
190 void ImplWriteDouble( double, ULONG nMode
= PS_SPACE
);
192 // writes a long in ASCII format to stream
193 void ImplWriteLong( sal_Int32 nNumb
, ULONG nMode
= PS_SPACE
);
195 // writes a byte in ASCII format to stream
196 void ImplWriteByte( BYTE nNumb
, ULONG nMode
= PS_SPACE
);
198 // writes a byte in ASCII (hex) format to stream
199 void ImplWriteHexByte( BYTE nNumb
, ULONG nMode
= PS_WRAP
);
201 // writes nNumb as number from 0.000 till 1.000 in ASCII format to stream
202 void ImplWriteB1( BYTE nNumb
, ULONG nMode
= PS_SPACE
);
204 inline void ImplWritePoint( const Point
&, sal_uInt32 nMode
= PS_SPACE
);
205 void ImplMoveTo( const Point
&, sal_uInt32 nMode
= PS_SPACE
);
206 void ImplLineTo( const Point
&, sal_uInt32 nMode
= PS_SPACE
);
207 void ImplCurveTo( const Point
& rP1
, const Point
& rP2
, const Point
& rP3
, sal_uInt32 nMode
= PS_SPACE
);
208 void ImplTranslate( const double& fX
, const double& fY
, sal_uInt32 nMode
= PS_RET
);
209 void ImplScale( const double& fX
, const double& fY
, sal_uInt32 nMode
= PS_RET
);
211 void ImplWriteLine( const Polygon
& rPolygon
);
212 void ImplAddPath( const Polygon
& rPolygon
);
213 void ImplWriteLineInfo( double fLineWidth
, double fMiterLimit
, SvtGraphicStroke::CapType eLineCap
,
214 SvtGraphicStroke::JoinType eJoinType
, SvtGraphicStroke::DashArray
& rDashArray
);
215 void ImplWriteLineInfo( const LineInfo
& rLineInfo
);
216 void ImplRect( const Rectangle
& rRectangle
);
217 void ImplRectFill ( const Rectangle
& rRectangle
);
218 void ImplWriteGradient( const PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
, VirtualDevice
& rVDev
);
219 void ImplIntersect( const PolyPolygon
& rPolyPoly
);
220 void ImplPolyPoly( const PolyPolygon
& rPolyPolygon
, sal_Bool bTextOutline
= sal_False
);
221 void ImplPolyLine( const Polygon
& rPolygon
);
223 void ImplSetClipRegion( Region
& rRegion
);
224 void ImplBmp( Bitmap
*, Bitmap
*, const Point
&, double nWidth
, double nHeight
);
225 void ImplText( const String
& rUniString
, const Point
& rPos
, const INT32
* pDXArry
, sal_Int32 nWidth
, VirtualDevice
& rVDev
);
226 void ImplSetAttrForText( const Point
& rPoint
);
227 void ImplWriteCharacter( sal_Char
);
228 void ImplWriteString( const ByteString
&, VirtualDevice
& rVDev
, const INT32
* pDXArry
= NULL
, BOOL bStretch
= FALSE
);
229 void ImplDefineFont( const char*, const char* );
231 void ImplClosePathDraw( ULONG nMode
= PS_RET
);
234 inline void ImplWriteLineColor( ULONG nMode
= PS_RET
);
235 inline void ImplWriteFillColor( ULONG nMode
= PS_RET
);
236 inline void ImplWriteTextColor( ULONG nMode
= PS_RET
);
237 inline void ImplWriteTextFillColor( ULONG nMode
= PS_RET
);
238 void ImplWriteColor( ULONG nMode
);
240 double ImplGetScaling( const MapMode
& );
241 void ImplGetMapMode( const MapMode
& );
242 BOOL
ImplGetBoundingBox( double* nNumb
, BYTE
* pSource
, ULONG nSize
);
243 BYTE
* ImplSearchEntry( BYTE
* pSource
, BYTE
* pDest
, ULONG nComp
, ULONG nSize
);
245 void StartCompression();
246 void Compress( BYTE nSrc
);
247 void EndCompression();
248 inline void WriteBits( USHORT nCode
, USHORT nCodeLen
);
251 BOOL
WritePS( const Graphic
& rGraphic
, SvStream
& rTargetStream
, FilterConfigItem
* );
256 //========================== Methoden von PSWriter ==========================
258 //---------------------------------------------------------------------------------
266 PSWriter::~PSWriter()
271 //---------------------------------------------------------------------------------
273 BOOL
PSWriter::WritePS( const Graphic
& rGraphic
, SvStream
& rTargetStream
, FilterConfigItem
* pFilterConfigItem
)
275 UINT32 nStreamPosition
= 0, nPSPosition
= 0; // -Wall warning, unset, check
281 mnLatestPush
= 0xEFFFFFFE;
283 if ( pFilterConfigItem
)
285 xStatusIndicator
= pFilterConfigItem
->GetStatusIndicator();
286 if ( xStatusIndicator
.is() )
289 xStatusIndicator
->start( aMsg
, 100 );
293 mpPS
= &rTargetStream
;
294 mpPS
->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
296 // default values for the dialog options
299 #ifdef UNX // don't compress by default on unix as ghostscript is unable to read LZW compressed eps
300 mbCompression
= FALSE
;
302 mbCompression
= TRUE
;
304 mnTextMode
= 0; // default0 : export glyph outlines
306 // try to get the dialog selection
307 if ( pFilterConfigItem
)
309 ByteString
aResMgrName( "eps" );
312 pResMgr
= ResMgr::CreateResMgr( aResMgrName
.GetBuffer(), Application::GetSettings().GetUILocale() );
316 String
aPreviewStr( RTL_CONSTASCII_USTRINGPARAM( "Preview" ) );
317 String
aVersionStr( RTL_CONSTASCII_USTRINGPARAM( "Version" ) );
318 String
aColorStr( RTL_CONSTASCII_USTRINGPARAM( "ColorFormat" ) );
319 String
aComprStr( RTL_CONSTASCII_USTRINGPARAM( "CompressionMode" ) );
320 #ifdef UNX // don't put binary tiff preview ahead of postscript code by default on unix as ghostscript is unable to read it
321 mnPreview
= pFilterConfigItem
->ReadInt32( aPreviewStr
, 0 );
323 mnPreview
= pFilterConfigItem
->ReadInt32( aPreviewStr
, 1 );
325 mnLevel
= pFilterConfigItem
->ReadInt32( aVersionStr
, 2 );
328 mbGrayScale
= pFilterConfigItem
->ReadInt32( aColorStr
, 1 ) == 2;
329 #ifdef UNX // don't compress by default on unix as ghostscript is unable to read LZW compressed eps
330 mbCompression
= pFilterConfigItem
->ReadInt32( aComprStr
, 0 ) != 0;
332 mbCompression
= pFilterConfigItem
->ReadInt32( aComprStr
, 1 ) == 1;
334 String
sTextMode( RTL_CONSTASCII_USTRINGPARAM( "TextMode" ) );
335 mnTextMode
= pFilterConfigItem
->ReadInt32( sTextMode
, 0 );
336 if ( mnTextMode
> 2 )
342 // compression is not available for Level 1
346 mbCompression
= FALSE
;
349 if ( mnPreview
& EPS_PREVIEW_TIFF
)
351 rTargetStream
<< (UINT32
)0xC6D3D0C5;
352 nStreamPosition
= rTargetStream
.Tell();
353 rTargetStream
<< (UINT32
)0 << (UINT32
)0 << (UINT32
)0 << (UINT32
)0
354 << nStreamPosition
+ 26 << (UINT32
)0 << (UINT16
)0xffff;
359 BitmapEx
aTempBitmapEx( rGraphic
.GetBitmapEx() );
360 aTempBitmapEx
.Convert( BMP_CONVERSION_8BIT_GREYS
);
361 nErrCode
= GraphicConverter::Export( rTargetStream
, aTempBitmapEx
, CVT_TIF
) ;
364 nErrCode
= GraphicConverter::Export( rTargetStream
, rGraphic
, CVT_TIF
) ;
366 if ( nErrCode
== ERRCODE_NONE
)
368 rTargetStream
.Seek( STREAM_SEEK_TO_END
);
369 nPSPosition
= rTargetStream
.Tell();
370 rTargetStream
.Seek( nStreamPosition
+ 20 );
371 rTargetStream
<< nPSPosition
- 30; // size of tiff gfx
372 rTargetStream
.Seek( nPSPosition
);
376 mnPreview
&=~ EPS_PREVIEW_TIFF
;
377 rTargetStream
.Seek( nStreamPosition
- 4 );
381 // global default value setting
385 if ( rGraphic
.GetType() == GRAPHIC_GDIMETAFILE
)
386 pMTF
= &rGraphic
.GetGDIMetaFile();
388 pMTF
= pAMTF
= new GDIMetaFile( rGraphic
.GetGDIMetaFile() );
389 aVDev
.SetMapMode( pMTF
->GetPrefMapMode() );
390 nBoundingX1
= nBoundingY1
= 0;
391 nBoundingX2
= pMTF
->GetPrefSize().Width();
392 nBoundingY2
= pMTF
->GetPrefSize().Height();
395 aColor
= Color( COL_TRANSPARENT
);
397 aLineColor
= Color( COL_BLACK
);
399 aFillColor
= Color( COL_WHITE
);
400 bTextFillColor
= TRUE
;
401 aTextFillColor
= Color( COL_BLACK
);
404 eLineCap
= SvtGraphicStroke::capButt
;
405 eJoinType
= SvtGraphicStroke::joinMiter
;
406 aBackgroundColor
= Color( COL_WHITE
);
407 eTextAlign
= ALIGN_BASELINE
;
408 bRegionChanged
= FALSE
;
414 if( pMTF
->GetActionCount() )
416 ImplWriteProlog( ( mnPreview
& EPS_PREVIEW_EPSI
) ? &rGraphic
: NULL
);
418 ImplWriteActions( *pMTF
, aVDev
);
420 if ( mnPreview
& EPS_PREVIEW_TIFF
)
422 UINT32 nPosition
= rTargetStream
.Tell();
423 rTargetStream
.Seek( nStreamPosition
);
424 rTargetStream
<< nPSPosition
;
425 rTargetStream
<< nPosition
- nPSPosition
;
426 rTargetStream
.Seek( nPosition
);
431 pChrSetList
=pCS
->pSucc
;
437 pGDIStack
=pGS
->pSucc
;
444 if ( mbStatus
&& mnLevelWarning
&& pFilterConfigItem
)
446 ByteString
aResMgrName( "eps" );
448 pResMgr
= ResMgr::CreateResMgr( aResMgrName
.GetBuffer(), Application::GetSettings().GetUILocale() );
451 InfoBox
aInfoBox( NULL
, String( ResId( KEY_VERSION_CHECK
, *pResMgr
) ) );
457 if ( xStatusIndicator
.is() )
458 xStatusIndicator
->end();
463 //---------------------------------------------------------------------------------
465 void PSWriter::ImplWriteProlog( const Graphic
* pPreview
)
467 ImplWriteLine( "%!PS-Adobe-3.0 EPSF-3.0 " );
468 *mpPS
<< "%%BoundingBox: "; // BoundingBox
471 Size aSizePoint
= Application::GetDefaultDevice()->LogicToLogic( pMTF
->GetPrefSize(),
472 pMTF
->GetPrefMapMode(), MAP_POINT
);
473 ImplWriteLong( aSizePoint
.Width() );
474 ImplWriteLong( aSizePoint
.Height() ,PS_RET
);
475 ImplWriteLine( "%%Pages: 0" );
476 ImplWriteLine( "%%Creator: Sun Microsystems, Inc." );
477 ImplWriteLine( "%%Title: none" );
478 ImplWriteLine( "%%CreationDate: none" );
482 *mpPS
<< "%%LanguageLevel: "; // Language level
483 ImplWriteLong( mnLevel
, PS_RET
);
484 if ( !mbGrayScale
&& mnLevel
== 1 )
485 ImplWriteLine( "%%Extensions: CMYK" ); // CMYK extension is to set in color mode in level 1
486 ImplWriteLine( "%%EndComments" );
487 if ( pPreview
&& aSizePoint
.Width() && aSizePoint
.Height() )
489 Size
aSizeBitmap( ( aSizePoint
.Width() + 7 ) & ~7, aSizePoint
.Height() );
490 Bitmap
aTmpBitmap( pPreview
->GetBitmap() );
491 aTmpBitmap
.Scale( aSizeBitmap
, BMP_SCALE_INTERPOLATE
);
492 aTmpBitmap
.Convert( BMP_CONVERSION_1BIT_THRESHOLD
);
493 BitmapReadAccess
* pAcc
= aTmpBitmap
.AcquireReadAccess();
496 *mpPS
<< "%%BeginPreview: "; // BoundingBox
497 ImplWriteLong( aSizeBitmap
.Width() );
498 ImplWriteLong( aSizeBitmap
.Height() );
500 INT32 nLines
= aSizeBitmap
.Width() / 312;
501 if ( ( nLines
* 312 ) != aSizeBitmap
.Width() )
503 nLines
*= aSizeBitmap
.Height();
504 ImplWriteLong( nLines
);
506 INT32 nX
, nY
, nCount2
, nCount
= 4;
507 const BitmapColor
aBlack( pAcc
->GetBestMatchingColor( Color( COL_BLACK
) ) );
508 for ( nY
= 0; nY
< aSizeBitmap
.Height(); nY
++ )
512 for ( nX
= 0; nX
< aSizeBitmap
.Width(); nX
++ )
516 ImplExecMode( PS_RET
);
521 if ( pAcc
->GetPixel( nY
, nX
) == aBlack
)
523 if ( ! ( --nCount
) )
536 aTmpBitmap
.ReleaseAccess( pAcc
);
537 ImplExecMode( PS_RET
);
538 ImplWriteLine( "%%EndPreview" );
541 ImplWriteLine( "%%BeginProlog" );
542 ImplWriteLine( "%%BeginResource: procset SDRes-Prolog 1.0 0" );
545 ImplWriteLine( "/b4_inc_state save def\n/dict_count countdictstack def\n/op_count count 1 sub def\nuserdict begin" );
546 ImplWriteLine( "0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath" );
547 ImplWriteLine( "/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if" );
549 ImplWriteLine( "/bdef {bind def} bind def" ); // der neue operator bdef wird erzeugt
551 ImplWriteLine( "/c {setgray} bdef" );
553 ImplWriteLine( "/c {setrgbcolor} bdef" );
554 ImplWriteLine( "/l {neg lineto} bdef" );
555 ImplWriteLine( "/rl {neg rlineto} bdef" );
556 ImplWriteLine( "/lc {setlinecap} bdef" );
557 ImplWriteLine( "/lj {setlinejoin} bdef" );
558 ImplWriteLine( "/lw {setlinewidth} bdef" );
559 ImplWriteLine( "/ml {setmiterlimit} bdef" );
560 ImplWriteLine( "/ld {setdash} bdef" );
561 ImplWriteLine( "/m {neg moveto} bdef" );
562 ImplWriteLine( "/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef" );
563 ImplWriteLine( "/r {rotate} bdef" );
564 ImplWriteLine( "/t {neg translate} bdef" );
565 ImplWriteLine( "/s {scale} bdef" );
566 ImplWriteLine( "/sw {show} bdef" );
567 ImplWriteLine( "/gs {gsave} bdef" );
568 ImplWriteLine( "/gr {grestore} bdef" );
570 ImplWriteLine( "/f {findfont dup length dict begin" ); // Setfont
571 ImplWriteLine( "{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def" );
572 ImplWriteLine( "currentdict end /NFont exch definefont pop /NFont findfont} bdef" );
574 ImplWriteLine( "/p {closepath} bdef" );
575 ImplWriteLine( "/sf {scalefont setfont} bdef" );
577 ImplWriteLine( "/ef {eofill}bdef" ); // close path and fill
578 ImplWriteLine( "/pc {closepath stroke}bdef" ); // close path and draw
579 ImplWriteLine( "/ps {stroke}bdef" ); // draw current path
580 ImplWriteLine( "/pum {matrix currentmatrix}bdef" ); // pushes the current matrix
581 ImplWriteLine( "/pom {setmatrix}bdef" ); // pops the matrix
582 ImplWriteLine( "/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef" );
583 ImplWriteLine( "%%EndResource" );
584 ImplWriteLine( "%%EndProlog" );
585 ImplWriteLine( "%%BeginSetup" );
586 ImplWriteLine( "%%EndSetup" );
587 ImplWriteLine( "%%Page: 1 1" );
588 ImplWriteLine( "%%BeginPageSetup" );
589 ImplWriteLine( "%%EndPageSetup" );
590 ImplWriteLine( "pum" );
591 ImplScale( (double)aSizePoint
.Width() / (double)pMTF
->GetPrefSize().Width(), (double)aSizePoint
.Height() / (double)pMTF
->GetPrefSize().Height() );
592 ImplWriteDouble( 0 );
593 ImplWriteDouble( -pMTF
->GetPrefSize().Height() );
594 ImplWriteLine( "t" );
595 ImplWriteLine( "/tm matrix currentmatrix def" );
598 //---------------------------------------------------------------------------------
600 void PSWriter::ImplWriteEpilog()
602 ImplTranslate( 0, nBoundingY2
);
603 ImplWriteLine( "pom" );
604 ImplWriteLine( "count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore" );
606 ImplWriteLine( "%%PageTrailer" );
607 ImplWriteLine( "%%Trailer" );
609 ImplWriteLine( "%%EOF" );
612 //---------------------------------------------------------------------------------
613 //---------------------------------------------------------------------------------
614 //---------------------------------------------------------------------------------
616 void PSWriter::ImplWriteActions( const GDIMetaFile
& rMtf
, VirtualDevice
& rVDev
)
618 PolyPolygon aFillPath
;
620 for( ULONG nCurAction
= 0, nCount
= rMtf
.GetActionCount(); nCurAction
< nCount
; nCurAction
++ )
622 MetaAction
* pMA
= rMtf
.GetAction( nCurAction
);
624 switch( pMA
->GetType() )
626 case META_NULL_ACTION
:
629 case META_PIXEL_ACTION
:
631 Color
aOldLineColor( aLineColor
);
632 aLineColor
= ( (const MetaPixelAction
*) pMA
)->GetColor();
633 ImplWriteLineColor( PS_SPACE
);
634 ImplMoveTo( ( (const MetaPixelAction
*)pMA
)->GetPoint() );
635 ImplLineTo( ( (const MetaPixelAction
*)pMA
)->GetPoint() );
637 aLineColor
= aOldLineColor
;
641 case META_POINT_ACTION
:
643 ImplWriteLineColor( PS_SPACE
);
644 ImplMoveTo( ( (const MetaPointAction
*)pMA
)->GetPoint() );
645 ImplLineTo( ( (const MetaPointAction
*)pMA
)->GetPoint() );
650 case META_LINE_ACTION
:
652 const LineInfo
& rLineInfo
= ( ( const MetaLineAction
*)pMA
)->GetLineInfo();
653 ImplWriteLineInfo( rLineInfo
);
656 ImplWriteLineColor( PS_SPACE
);
657 ImplMoveTo( ( (const MetaLineAction
*) pMA
)->GetStartPoint() );
658 ImplLineTo( ( (const MetaLineAction
*) pMA
)->GetEndPoint() );
664 case META_RECT_ACTION
:
666 ImplRect( ( (const MetaRectAction
*) pMA
)->GetRect() );
670 case META_ROUNDRECT_ACTION
:
671 ImplRect( ( (const MetaRoundRectAction
*) pMA
)->GetRect() );
674 case META_ELLIPSE_ACTION
:
676 Rectangle aRect
= ( ( (const MetaEllipseAction
*) pMA
)->GetRect() );
677 Point aCenter
= aRect
.Center();
678 Polygon
aPoly( aCenter
, aRect
.GetWidth() / 2, aRect
.GetHeight() / 2 );
679 PolyPolygon
aPolyPoly( aPoly
);
680 ImplPolyPoly( aPolyPoly
);
684 case META_ARC_ACTION
:
686 Polygon
aPoly( ( (const MetaArcAction
*)pMA
)->GetRect(), ( (const MetaArcAction
*)pMA
)->GetStartPoint(),
687 ( (const MetaArcAction
*)pMA
)->GetEndPoint(), POLY_ARC
);
688 PolyPolygon
aPolyPoly( aPoly
);
689 ImplPolyPoly( aPolyPoly
);
693 case META_PIE_ACTION
:
695 Polygon
aPoly( ( (const MetaPieAction
*)pMA
)->GetRect(), ( (const MetaPieAction
*)pMA
)->GetStartPoint(),
696 ( (const MetaPieAction
*)pMA
)->GetEndPoint(), POLY_PIE
);
697 PolyPolygon
aPolyPoly( aPoly
);
698 ImplPolyPoly( aPolyPoly
);
702 case META_CHORD_ACTION
:
704 Polygon
aPoly( ( (const MetaChordAction
*)pMA
)->GetRect(), ( (const MetaChordAction
*)pMA
)->GetStartPoint(),
705 ( (const MetaChordAction
*)pMA
)->GetEndPoint(), POLY_CHORD
);
706 PolyPolygon
aPolyPoly( aPoly
);
707 ImplPolyPoly( aPolyPoly
);
711 case META_POLYLINE_ACTION
:
713 Polygon
aPoly( ( (const MetaPolyLineAction
*) pMA
)->GetPolygon() );
714 const LineInfo
& rLineInfo
= ( ( const MetaPolyLineAction
*)pMA
)->GetLineInfo();
715 ImplWriteLineInfo( rLineInfo
);
716 ImplPolyLine( aPoly
);
720 case META_POLYGON_ACTION
:
722 PolyPolygon
aPolyPoly( ( (const MetaPolygonAction
*) pMA
)->GetPolygon() );
723 ImplPolyPoly( aPolyPoly
);
727 case META_POLYPOLYGON_ACTION
:
729 ImplPolyPoly( ( (const MetaPolyPolygonAction
*) pMA
)->GetPolyPolygon() );
733 case META_TEXT_ACTION
:
735 const MetaTextAction
* pA
= (const MetaTextAction
*) pMA
;
737 String
aUniStr( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() );
738 Point
aPoint( pA
->GetPoint() );
740 ImplText( aUniStr
, aPoint
, NULL
, 0, rVDev
);
744 case META_TEXTRECT_ACTION
:
746 DBG_ERROR( "Unsupported action: TextRect...Action!" );
750 case META_STRETCHTEXT_ACTION
:
752 const MetaStretchTextAction
* pA
= (const MetaStretchTextAction
*)pMA
;
753 String
aUniStr( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() );
754 Point
aPoint( pA
->GetPoint() );
756 ImplText( aUniStr
, aPoint
, NULL
, pA
->GetWidth(), rVDev
);
760 case META_TEXTARRAY_ACTION
:
762 const MetaTextArrayAction
* pA
= (const MetaTextArrayAction
*)pMA
;
763 String
aUniStr( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() );
764 Point
aPoint( pA
->GetPoint() );
766 ImplText( aUniStr
, aPoint
, pA
->GetDXArray(), 0, rVDev
);
770 case META_BMP_ACTION
:
772 Bitmap aBitmap
= ( (const MetaBmpAction
*)pMA
)->GetBitmap();
774 aBitmap
.Convert( BMP_CONVERSION_8BIT_GREYS
);
775 Point aPoint
= ( (const MetaBmpAction
*) pMA
)->GetPoint();
776 Size aSize
= aBitmap
.GetSizePixel();
777 ImplBmp( &aBitmap
, NULL
, aPoint
, aSize
.Width(), aSize
.Height() );
781 case META_BMPSCALE_ACTION
:
783 Bitmap aBitmap
= ( (const MetaBmpScaleAction
*)pMA
)->GetBitmap();
785 aBitmap
.Convert( BMP_CONVERSION_8BIT_GREYS
);
786 Point aPoint
= ( (const MetaBmpScaleAction
*) pMA
)->GetPoint();
787 Size aSize
= ( (const MetaBmpScaleAction
*)pMA
)->GetSize();
788 ImplBmp( &aBitmap
, NULL
, aPoint
, aSize
.Width(), aSize
.Height() );
792 case META_BMPSCALEPART_ACTION
:
794 Bitmap
aBitmap( ( (const MetaBmpScalePartAction
*)pMA
)->GetBitmap() );
795 aBitmap
.Crop( Rectangle( ( (const MetaBmpScalePartAction
*)pMA
)->GetSrcPoint(),
796 ( (const MetaBmpScalePartAction
*)pMA
)->GetSrcSize() ) );
798 aBitmap
.Convert( BMP_CONVERSION_8BIT_GREYS
);
799 Point aPoint
= ( (const MetaBmpScalePartAction
*) pMA
)->GetDestPoint();
800 Size aSize
= ( (const MetaBmpScalePartAction
*)pMA
)->GetDestSize();
801 ImplBmp( &aBitmap
, NULL
, aPoint
, aSize
.Width(), aSize
.Height() );
805 case META_BMPEX_ACTION
:
807 BitmapEx
aBitmapEx( ( (MetaBmpExAction
*)pMA
)->GetBitmapEx() );
808 Bitmap
aBitmap( aBitmapEx
.GetBitmap() );
810 aBitmap
.Convert( BMP_CONVERSION_8BIT_GREYS
);
811 Bitmap
aMask( aBitmapEx
.GetMask() );
812 Point aPoint
= ( (const MetaBmpExAction
*) pMA
)->GetPoint();
813 Size aSize
= ( aBitmap
.GetSizePixel() );
814 ImplBmp( &aBitmap
, &aMask
, aPoint
, aSize
.Width(), aSize
.Height() );
818 case META_BMPEXSCALE_ACTION
:
820 BitmapEx
aBitmapEx( ( (MetaBmpExScaleAction
*)pMA
)->GetBitmapEx() );
821 Bitmap
aBitmap( aBitmapEx
.GetBitmap() );
823 aBitmap
.Convert( BMP_CONVERSION_8BIT_GREYS
);
824 Bitmap
aMask( aBitmapEx
.GetMask() );
825 Point aPoint
= ( (const MetaBmpExScaleAction
*) pMA
)->GetPoint();
826 Size
aSize( ( (const MetaBmpExScaleAction
*)pMA
)->GetSize() );
827 ImplBmp( &aBitmap
, &aMask
, aPoint
, aSize
.Width(), aSize
.Height() );
831 case META_BMPEXSCALEPART_ACTION
:
833 BitmapEx
aBitmapEx( ( (const MetaBmpExScalePartAction
*)pMA
)->GetBitmapEx() );
834 aBitmapEx
.Crop( Rectangle( ( (const MetaBmpExScalePartAction
*)pMA
)->GetSrcPoint(),
835 ( (const MetaBmpExScalePartAction
*)pMA
)->GetSrcSize() ) );
836 Bitmap
aBitmap( aBitmapEx
.GetBitmap() );
838 aBitmap
.Convert( BMP_CONVERSION_8BIT_GREYS
);
839 Bitmap
aMask( aBitmapEx
.GetMask() );
840 Point aPoint
= ( (const MetaBmpExScalePartAction
*) pMA
)->GetDestPoint();
841 Size aSize
= ( (const MetaBmpExScalePartAction
*)pMA
)->GetDestSize();
842 ImplBmp( &aBitmap
, &aMask
, aPoint
, aSize
.Width(), aSize
.Height() );
846 // Unsupported Actions
847 case META_MASK_ACTION
:
848 case META_MASKSCALE_ACTION
:
849 case META_MASKSCALEPART_ACTION
:
851 DBG_ERROR( "Unsupported action: MetaMask...Action!" );
855 case META_GRADIENT_ACTION
:
857 PolyPolygon
aPolyPoly( ( (const MetaGradientAction
*)pMA
)->GetRect() );
858 ImplWriteGradient( aPolyPoly
, ( (const MetaGradientAction
*) pMA
)->GetGradient(), rVDev
);
862 case META_GRADIENTEX_ACTION
:
864 PolyPolygon
aPolyPoly( ( (const MetaGradientExAction
*)pMA
)->GetPolyPolygon() );
865 ImplWriteGradient( aPolyPoly
, ( (const MetaGradientExAction
*) pMA
)->GetGradient(), rVDev
);
869 case META_HATCH_ACTION
:
871 VirtualDevice l_aVDev
;
874 l_aVDev
.SetMapMode( rVDev
.GetMapMode() );
875 l_aVDev
.AddHatchActions( ( (const MetaHatchAction
*)pMA
)->GetPolyPolygon(),
876 ( (const MetaHatchAction
*)pMA
)->GetHatch(), aTmpMtf
);
877 ImplWriteActions( aTmpMtf
, rVDev
);
881 case META_WALLPAPER_ACTION
:
883 const MetaWallpaperAction
* pA
= (const MetaWallpaperAction
*)pMA
;
884 Rectangle aRect
= pA
->GetRect();
885 Wallpaper aWallpaper
= pA
->GetWallpaper();
887 if ( aWallpaper
.IsBitmap() )
889 BitmapEx aBitmapEx
= aWallpaper
.GetBitmap();
890 Bitmap
aBitmap( aBitmapEx
.GetBitmap() );
891 if ( aBitmapEx
.IsTransparent() )
893 if ( aWallpaper
.IsGradient() )
899 Bitmap
aMask( aBitmapEx
.GetMask() );
900 ImplBmp( &aBitmap
, &aMask
, Point( aRect
.Left(), aRect
.Top() ), aRect
.GetWidth(), aRect
.GetHeight() );
903 ImplBmp( &aBitmap
, NULL
, Point( aRect
.Left(), aRect
.Top() ), aRect
.GetWidth(), aRect
.GetHeight() );
908 else if ( aWallpaper
.IsGradient() )
916 aColor
= aWallpaper
.GetColor();
917 ImplRectFill( aRect
);
922 case META_ISECTRECTCLIPREGION_ACTION
:
924 const MetaISectRectClipRegionAction
* pA
= (const MetaISectRectClipRegionAction
*) pMA
;
925 Region
aRegion( pA
->GetRect() );
926 ImplSetClipRegion( aRegion
);
930 case META_CLIPREGION_ACTION
:
932 const MetaClipRegionAction
* pA
= (const MetaClipRegionAction
*) pMA
;
933 Region
aRegion( pA
->GetRegion() );
934 ImplSetClipRegion( aRegion
);
938 case META_ISECTREGIONCLIPREGION_ACTION
:
940 const MetaISectRegionClipRegionAction
* pA
= (const MetaISectRegionClipRegionAction
*) pMA
;
941 Region
aRegion( pA
->GetRegion() );
942 ImplSetClipRegion( aRegion
);
946 case META_MOVECLIPREGION_ACTION
:
949 if ( !aClipRegion.IsEmpty() )
951 const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*) pMA;
952 aClipRegion.Move( pA->GetHorzMove(), pA->GetVertMove() );
959 case META_LINECOLOR_ACTION
:
961 if ( ( (const MetaLineColorAction
*) pMA
)->IsSetting() )
964 aLineColor
= ( (const MetaLineColorAction
*) pMA
)->GetColor();
971 case META_FILLCOLOR_ACTION
:
973 if ( ( (const MetaFillColorAction
*) pMA
)->IsSetting() )
976 aFillColor
= ( (const MetaFillColorAction
*) pMA
)->GetColor();
983 case META_TEXTCOLOR_ACTION
:
985 aTextColor
= ( (const MetaTextColorAction
*) pMA
)->GetColor();
989 case META_TEXTFILLCOLOR_ACTION
:
991 if ( ( (const MetaTextFillColorAction
*) pMA
)->IsSetting() )
993 bTextFillColor
= TRUE
;
994 aTextFillColor
= ( (const MetaTextFillColorAction
*) pMA
)->GetColor();
997 bTextFillColor
= FALSE
;
1001 case META_TEXTALIGN_ACTION
:
1003 eTextAlign
= ( (const MetaTextAlignAction
*) pMA
)->GetTextAlign();
1007 case META_MAPMODE_ACTION
:
1009 pMA
->Execute( &rVDev
);
1010 ImplGetMapMode( rVDev
.GetMapMode() );
1014 case META_FONT_ACTION
:
1016 maFont
= ((const MetaFontAction
*)pMA
)->GetFont();
1017 rVDev
.SetFont( maFont
);
1021 case META_PUSH_ACTION
:
1023 rVDev
.Push(((const MetaPushAction
*)pMA
)->GetFlags() );
1024 StackMember
* pGS
= new StackMember
;
1025 pGS
->pSucc
= pGDIStack
;
1027 pGS
->aDashArray
= aDashArray
;
1028 pGS
->eJoinType
= eJoinType
;
1029 pGS
->eLineCap
= eLineCap
;
1030 pGS
->fLineWidth
= fLineWidth
;
1031 pGS
->fMiterLimit
= fMiterLimit
;
1032 pGS
->eTextAlign
= eTextAlign
;
1033 pGS
->aGlobalCol
= aColor
;
1034 pGS
->bLineCol
= bLineColor
;
1035 pGS
->aLineCol
= aLineColor
;
1036 pGS
->bFillCol
= bFillColor
;
1037 pGS
->aFillCol
= aFillColor
;
1038 pGS
->aTextCol
= aTextColor
;
1039 pGS
->bTextFillCol
= bTextFillColor
;
1040 pGS
->aTextFillCol
= aTextFillColor
;
1041 pGS
->aBackgroundCol
= aBackgroundColor
;
1042 bRegionChanged
= FALSE
;
1043 pGS
->aFont
= maFont
;
1044 mnLatestPush
= mpPS
->Tell();
1045 ImplWriteLine( "gs" );
1049 case META_POP_ACTION
:
1056 pGDIStack
= pGS
->pSucc
;
1057 aDashArray
= pGS
->aDashArray
;
1058 eJoinType
= pGS
->eJoinType
;
1059 eLineCap
= pGS
->eLineCap
;
1060 fLineWidth
= pGS
->fLineWidth
;
1061 fMiterLimit
= pGS
->fMiterLimit
;
1062 eTextAlign
= pGS
->eTextAlign
;
1063 aColor
= pGS
->aGlobalCol
;
1064 bLineColor
= pGS
->bLineCol
;
1065 aLineColor
= pGS
->aLineCol
;
1066 bFillColor
= pGS
->bFillCol
;
1067 aFillColor
= pGS
->aFillCol
;
1068 aTextColor
= pGS
->aTextCol
;
1069 bTextFillColor
= pGS
->bTextFillCol
;
1070 aTextFillColor
= pGS
->aTextFillCol
;
1071 aBackgroundColor
= pGS
->aBackgroundCol
;
1072 maFont
= pGS
->aFont
;
1073 maLastFont
= Font(); // set maLastFont != maFont -> so that
1075 sal_uInt32 nCurrentPos
= mpPS
->Tell();
1076 if ( nCurrentPos
- 3 == mnLatestPush
)
1078 mpPS
->Seek( mnLatestPush
);
1079 ImplWriteLine( " " );
1080 mpPS
->Seek( mnLatestPush
);
1083 ImplWriteLine( "gr" );
1088 case META_EPS_ACTION
:
1090 GfxLink aGfxLink
= ( (const MetaEPSAction
*) pMA
)->GetLink();
1091 const GDIMetaFile
aSubstitute( ( ( const MetaEPSAction
*) pMA
)->GetSubstitute() );
1093 BOOL bLevelConflict
= FALSE
;
1094 BYTE
* pSource
= (BYTE
*) aGfxLink
.GetData();
1095 ULONG nSize
= aGfxLink
.GetDataSize();
1096 ULONG nParseThis
= POSTSCRIPT_BOUNDINGSEARCH
;
1097 if ( nSize
< 64 ) // assuming eps is larger than 64 bytes
1099 if ( nParseThis
> nSize
)
1102 if ( pSource
&& ( mnLevel
== 1 ) )
1104 BYTE
* pFound
= ImplSearchEntry( pSource
, (BYTE
*)"%%LanguageLevel:", nParseThis
- 10, 16 );
1112 if ( ( k
> '0' ) && ( k
<= '9' ) )
1116 bLevelConflict
= TRUE
;
1124 if ( !bLevelConflict
)
1126 double nBoundingBox
[4];
1127 if ( pSource
&& ImplGetBoundingBox( nBoundingBox
, pSource
, nParseThis
) )
1129 Point aPoint
= ( (const MetaEPSAction
*) pMA
)->GetPoint();
1130 Size aSize
= ( (const MetaEPSAction
*) pMA
)->GetSize();
1132 MapMode
aMapMode( aSubstitute
.GetPrefMapMode() );
1133 Size
aOutSize( rVDev
.LogicToLogic( aSize
, rVDev
.GetMapMode(), aMapMode
) );
1134 Point
aOrigin( rVDev
.LogicToLogic( aPoint
, rVDev
.GetMapMode(), aMapMode
) );
1135 aOrigin
.Y() += aOutSize
.Height();
1136 aMapMode
.SetOrigin( aOrigin
);
1137 aMapMode
.SetScaleX( aOutSize
.Width() / ( nBoundingBox
[ 2 ] - nBoundingBox
[ 0 ] ) );
1138 aMapMode
.SetScaleY( aOutSize
.Height() / ( nBoundingBox
[ 3 ] - nBoundingBox
[ 1 ] ) );
1139 ImplWriteLine( "gs" );
1140 ImplGetMapMode( aMapMode
);
1141 ImplWriteLine( "%%BeginDocument:" );
1142 mpPS
->Write( pSource
, aGfxLink
.GetDataSize() );
1143 ImplWriteLine( "%%EndDocument\ngr" );
1149 case META_TRANSPARENT_ACTION
:
1151 // ImplLine( ( (const MetaTransparentAction*) pMA )->GetPolyPolygon() );
1155 case META_RASTEROP_ACTION
:
1157 pMA
->Execute( &rVDev
);
1161 case META_FLOATTRANSPARENT_ACTION
:
1163 const MetaFloatTransparentAction
* pA
= (const MetaFloatTransparentAction
*) pMA
;
1165 GDIMetaFile
aTmpMtf( pA
->GetGDIMetaFile() );
1166 Point
aSrcPt( aTmpMtf
.GetPrefMapMode().GetOrigin() );
1167 const Size
aSrcSize( aTmpMtf
.GetPrefSize() );
1168 const Point
aDestPt( pA
->GetPoint() );
1169 const Size
aDestSize( pA
->GetSize() );
1170 const double fScaleX
= aSrcSize
.Width() ? (double) aDestSize
.Width() / aSrcSize
.Width() : 1.0;
1171 const double fScaleY
= aSrcSize
.Height() ? (double) aDestSize
.Height() / aSrcSize
.Height() : 1.0;
1172 long nMoveX
, nMoveY
;
1174 if( fScaleX
!= 1.0 || fScaleY
!= 1.0 )
1176 aTmpMtf
.Scale( fScaleX
, fScaleY
);
1177 aSrcPt
.X() = FRound( aSrcPt
.X() * fScaleX
), aSrcPt
.Y() = FRound( aSrcPt
.Y() * fScaleY
);
1180 nMoveX
= aDestPt
.X() - aSrcPt
.X(), nMoveY
= aDestPt
.Y() - aSrcPt
.Y();
1182 if( nMoveX
|| nMoveY
)
1183 aTmpMtf
.Move( nMoveX
, nMoveY
);
1185 ImplWriteActions( aTmpMtf
, rVDev
);
1189 case META_COMMENT_ACTION
:
1191 const MetaCommentAction
* pA
= (const MetaCommentAction
*) pMA
;
1192 if ( pA
->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL
)
1194 const MetaGradientExAction
* pGradAction
= NULL
;
1195 while( ++nCurAction
< nCount
)
1197 MetaAction
* pAction
= rMtf
.GetAction( nCurAction
);
1198 if( pAction
->GetType() == META_GRADIENTEX_ACTION
)
1199 pGradAction
= (const MetaGradientExAction
*) pAction
;
1200 else if( ( pAction
->GetType() == META_COMMENT_ACTION
) &&
1201 ( ( (const MetaCommentAction
*) pAction
)->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL
) )
1207 ImplWriteGradient( pGradAction
->GetPolyPolygon(), pGradAction
->GetGradient(), rVDev
);
1209 else if ( pA
->GetComment().Equals( "XPATHFILL_SEQ_END" ) )
1211 if ( aFillPath
.Count() )
1213 aFillPath
= PolyPolygon();
1214 ImplWriteLine( "gr" );
1219 const BYTE
* pData
= pA
->GetData();
1222 SvMemoryStream
aMemStm( (void*)pData
, pA
->GetDataSize(), STREAM_READ
);
1223 sal_Bool bSkipSequence
= sal_False
;
1226 if( pA
->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" ) )
1228 sSeqEnd
= ByteString( "XPATHSTROKE_SEQ_END" );
1229 SvtGraphicStroke aStroke
;
1233 aStroke
.getPath( aPath
);
1235 PolyPolygon aStartArrow
;
1236 PolyPolygon aEndArrow
;
1237 // double fTransparency( aStroke.getTransparency() );
1238 double fStrokeWidth( aStroke
.getStrokeWidth() );
1239 SvtGraphicStroke::JoinType
eJT( aStroke
.getJoinType() );
1240 SvtGraphicStroke::DashArray l_aDashArray
;
1242 aStroke
.getStartArrow( aStartArrow
);
1243 aStroke
.getEndArrow( aEndArrow
);
1244 aStroke
.getDashArray( l_aDashArray
);
1246 bSkipSequence
= sal_True
;
1247 if ( l_aDashArray
.size() > 11 ) // ps dasharray limit is 11
1248 bSkipSequence
= sal_False
;
1249 if ( aStartArrow
.Count() || aEndArrow
.Count() )
1250 bSkipSequence
= sal_False
;
1251 if ( (sal_uInt32
)eJT
> 2 )
1252 bSkipSequence
= sal_False
;
1253 if ( l_aDashArray
.size() && ( fStrokeWidth
!= 0.0 ) )
1254 bSkipSequence
= sal_False
;
1255 if ( bSkipSequence
)
1257 ImplWriteLineInfo( fStrokeWidth
, aStroke
.getMiterLimit(),
1258 aStroke
.getCapType(), eJT
, l_aDashArray
);
1259 ImplPolyLine( aPath
);
1262 else if( pA
->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) )
1264 sSeqEnd
= ByteString( "XPATHFILL_SEQ_END" );
1265 SvtGraphicFill aFill
;
1267 switch( aFill
.getFillType() )
1269 case SvtGraphicFill::fillSolid
:
1271 bSkipSequence
= sal_True
;
1272 PolyPolygon aPolyPoly
;
1273 aFill
.getPath( aPolyPoly
);
1274 sal_uInt16 i
, nPolyCount
= aPolyPoly
.Count();
1277 aFillColor
= aFill
.getFillColor();
1278 ImplWriteFillColor( PS_SPACE
);
1279 for ( i
= 0; i
< nPolyCount
; )
1281 ImplAddPath( aPolyPoly
.GetObject( i
) );
1282 if ( ++i
< nPolyCount
)
1286 ImplExecMode( PS_RET
);
1291 ImplExecMode( PS_RET
);
1296 case SvtGraphicFill::fillTexture
:
1298 aFill
.getPath( aFillPath
);
1300 /* normally an object filling is consisting of three MetaActions:
1301 MetaBitmapAction using RasterOp xor,
1302 MetaPolyPolygonAction using RasterOp rop_0
1303 MetaBitmapAction using RasterOp xor
1305 Because RasterOps cannot been used in Postscript, we have to
1306 replace these actions. The MetaComment "XPATHFILL_SEQ_BEGIN" is
1307 providing the clippath of the object. The following loop is
1308 trying to find the bitmap that is matching the clippath, so that
1309 only one bitmap is exported, otherwise if the bitmap is not
1310 locatable, all metaactions are played normally.
1312 sal_uInt32 nCommentStartAction
= nCurAction
;
1313 sal_uInt32 nBitmapCount
= 0;
1314 sal_uInt32 nBitmapAction
= 0;
1316 sal_Bool bOk
= sal_True
;
1317 while( bOk
&& ( ++nCurAction
< nCount
) )
1319 MetaAction
* pAction
= rMtf
.GetAction( nCurAction
);
1320 switch( pAction
->GetType() )
1322 case META_BMPSCALE_ACTION
:
1323 case META_BMPSCALEPART_ACTION
:
1324 case META_BMPEXSCALE_ACTION
:
1325 case META_BMPEXSCALEPART_ACTION
:
1328 nBitmapAction
= nCurAction
;
1331 case META_COMMENT_ACTION
:
1333 if (((const MetaCommentAction
*)pAction
)->GetComment().Equals( "XPATHFILL_SEQ_END" ))
1339 if( nBitmapCount
== 2 )
1341 ImplWriteLine( "gs" );
1342 ImplIntersect( aFillPath
);
1343 GDIMetaFile aTempMtf
;
1344 aTempMtf
.AddAction( rMtf
.GetAction( nBitmapAction
)->Clone() );
1345 ImplWriteActions( aTempMtf
, rVDev
);
1346 ImplWriteLine( "gr" );
1347 aFillPath
= PolyPolygon();
1350 nCurAction
= nCommentStartAction
+ 1;
1354 case SvtGraphicFill::fillGradient
:
1355 aFill
.getPath( aFillPath
);
1358 case SvtGraphicFill::fillHatch
:
1361 if ( aFillPath
.Count() )
1363 ImplWriteLine( "gs" );
1364 ImplIntersect( aFillPath
);
1367 if ( bSkipSequence
)
1369 while( ++nCurAction
< nCount
)
1371 pMA
= rMtf
.GetAction( nCurAction
);
1372 if ( pMA
->GetType() == META_COMMENT_ACTION
)
1374 ByteString
sComment( ((MetaCommentAction
*)pMA
)->GetComment() );
1375 if ( sComment
.Equals( sSeqEnd
) )
1390 //---------------------------------------------------------------------------------
1392 inline void PSWriter::ImplWritePoint( const Point
& rPoint
, sal_uInt32 nMode
)
1394 ImplWriteDouble( rPoint
.X() );
1395 ImplWriteDouble( rPoint
.Y(), nMode
);
1398 //---------------------------------------------------------------------------------
1400 void PSWriter::ImplMoveTo( const Point
& rPoint
, sal_uInt32 nMode
)
1402 ImplWritePoint( rPoint
);
1403 ImplWriteByte( 'm' );
1404 ImplExecMode( nMode
);
1407 //---------------------------------------------------------------------------------
1409 void PSWriter::ImplLineTo( const Point
& rPoint
, sal_uInt32 nMode
)
1411 ImplWritePoint( rPoint
);
1412 ImplWriteByte( 'l' );
1413 ImplExecMode( nMode
);
1416 //---------------------------------------------------------------------------------
1418 void PSWriter::ImplCurveTo( const Point
& rP1
, const Point
& rP2
, const Point
& rP3
, sal_uInt32 nMode
)
1420 ImplWritePoint( rP1
);
1421 ImplWritePoint( rP2
);
1422 ImplWritePoint( rP3
);
1424 ImplExecMode( nMode
);
1427 //---------------------------------------------------------------------------------
1429 void PSWriter::ImplTranslate( const double& fX
, const double& fY
, sal_uInt32 nMode
)
1431 ImplWriteDouble( fX
);
1432 ImplWriteDouble( fY
);
1433 ImplWriteByte( 't' );
1434 ImplExecMode( nMode
);
1437 //---------------------------------------------------------------------------------
1439 void PSWriter::ImplScale( const double& fX
, const double& fY
, sal_uInt32 nMode
)
1441 ImplWriteDouble( fX
);
1442 ImplWriteDouble( fY
);
1443 ImplWriteByte( 's' );
1444 ImplExecMode( nMode
);
1447 //---------------------------------------------------------------------------------
1449 void PSWriter::ImplRect( const Rectangle
& rRect
)
1452 ImplRectFill( rRect
);
1455 double nWidth
= rRect
.GetWidth();
1456 double nHeight
= rRect
.GetHeight();
1458 ImplWriteLineColor( PS_SPACE
);
1459 ImplMoveTo( rRect
.TopLeft() );
1460 ImplWriteDouble( nWidth
);
1462 ImplWriteDouble( nHeight
);
1464 ImplWriteDouble( nWidth
);
1465 *mpPS
<< "neg 0 rl ";
1466 ImplClosePathDraw();
1472 //---------------------------------------------------------------------------------
1474 void PSWriter::ImplRectFill( const Rectangle
& rRect
)
1476 double nWidth
= rRect
.GetWidth();
1477 double nHeight
= rRect
.GetHeight();
1479 ImplWriteFillColor( PS_SPACE
);
1480 ImplMoveTo( rRect
.TopLeft() );
1481 ImplWriteDouble( nWidth
);
1483 ImplWriteDouble( nHeight
);
1485 ImplWriteDouble( nWidth
);
1486 *mpPS
<< "neg 0 rl ef ";
1489 ImplExecMode( PS_RET
);
1492 //---------------------------------------------------------------------------------
1494 void PSWriter::ImplAddPath( const Polygon
& rPolygon
)
1497 USHORT nPointCount
= rPolygon
.GetSize();
1498 if ( nPointCount
> 1 )
1500 ImplMoveTo( rPolygon
.GetPoint( 0 ) );
1501 while ( i
< nPointCount
)
1503 if ( ( rPolygon
.GetFlags( i
) == POLY_CONTROL
)
1504 && ( ( i
+ 2 ) < nPointCount
)
1505 && ( rPolygon
.GetFlags( i
+ 1 ) == POLY_CONTROL
)
1506 && ( rPolygon
.GetFlags( i
+ 2 ) != POLY_CONTROL
) )
1508 ImplCurveTo( rPolygon
[ i
], rPolygon
[ i
+ 1 ], rPolygon
[ i
+ 2 ], PS_WRAP
);
1512 ImplLineTo( rPolygon
.GetPoint( i
++ ), PS_SPACE
| PS_WRAP
);
1517 //---------------------------------------------------------------------------------
1519 void PSWriter::ImplIntersect( const PolyPolygon
& rPolyPoly
)
1521 sal_uInt16 i
, nPolyCount
= rPolyPoly
.Count();
1522 for ( i
= 0; i
< nPolyCount
; )
1524 ImplAddPath( rPolyPoly
.GetObject( i
) );
1525 if ( ++i
< nPolyCount
)
1529 ImplExecMode( PS_RET
);
1532 ImplWriteLine( "eoclip newpath" );
1535 //---------------------------------------------------------------------------------
1537 void PSWriter::ImplWriteGradient( const PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
, VirtualDevice
& rVDev
)
1539 VirtualDevice l_aVDev
;
1540 GDIMetaFile aTmpMtf
;
1541 l_aVDev
.SetMapMode( rVDev
.GetMapMode() );
1542 l_aVDev
.AddGradientActions( rPolyPoly
.GetBoundRect(), rGradient
, aTmpMtf
);
1543 ImplWriteActions( aTmpMtf
, rVDev
);
1546 //---------------------------------------------------------------------------------
1548 void PSWriter::ImplPolyPoly( const PolyPolygon
& rPolyPoly
, sal_Bool bTextOutline
)
1550 sal_uInt16 i
, nPolyCount
= rPolyPoly
.Count();
1553 if ( bFillColor
|| bTextOutline
)
1556 ImplWriteTextColor( PS_SPACE
);
1558 ImplWriteFillColor( PS_SPACE
);
1559 for ( i
= 0; i
< nPolyCount
; )
1561 ImplAddPath( rPolyPoly
.GetObject( i
) );
1562 if ( ++i
< nPolyCount
)
1566 ImplExecMode( PS_RET
);
1571 ImplExecMode( PS_RET
);
1575 ImplWriteLineColor( PS_SPACE
);
1576 for ( i
= 0; i
< nPolyCount
; i
++ )
1577 ImplAddPath( rPolyPoly
.GetObject( i
) );
1578 ImplClosePathDraw( PS_RET
);
1583 //---------------------------------------------------------------------------------
1585 void PSWriter::ImplPolyLine( const Polygon
& rPoly
)
1589 ImplWriteLineColor( PS_SPACE
);
1590 sal_uInt16 i
, nPointCount
= rPoly
.GetSize();
1593 if ( nPointCount
> 1 )
1595 ImplMoveTo( rPoly
.GetPoint( 0 ) );
1597 while ( i
< nPointCount
)
1599 if ( ( rPoly
.GetFlags( i
) == POLY_CONTROL
)
1600 && ( ( i
+ 2 ) < nPointCount
)
1601 && ( rPoly
.GetFlags( i
+ 1 ) == POLY_CONTROL
)
1602 && ( rPoly
.GetFlags( i
+ 2 ) != POLY_CONTROL
) )
1604 ImplCurveTo( rPoly
[ i
], rPoly
[ i
+ 1 ], rPoly
[ i
+ 2 ], PS_WRAP
);
1608 ImplLineTo( rPoly
.GetPoint( i
++ ), PS_SPACE
| PS_WRAP
);
1612 // #104645# explicitely close path if polygon is closed
1613 if( rPoly
[ 0 ] == rPoly
[ nPointCount
-1 ] )
1614 ImplClosePathDraw( PS_RET
);
1621 //---------------------------------------------------------------------------------
1623 void PSWriter::ImplSetClipRegion( Region
& rClipRegion
)
1625 if ( !rClipRegion
.IsEmpty() )
1628 RegionHandle hRegionHandle
= rClipRegion
.BeginEnumRects();
1630 while ( rClipRegion
.GetNextEnumRect( hRegionHandle
, aRect
) )
1632 double nX1
= aRect
.Left();
1633 double nY1
= aRect
.Top();
1634 double nX2
= aRect
.Right();
1635 double nY2
= aRect
.Bottom();
1636 ImplWriteDouble( nX1
);
1637 ImplWriteDouble( nY1
);
1638 ImplWriteByte( 'm' );
1639 ImplWriteDouble( nX2
);
1640 ImplWriteDouble( nY1
);
1641 ImplWriteByte( 'l' );
1642 ImplWriteDouble( nX2
);
1643 ImplWriteDouble( nY2
);
1644 ImplWriteByte( 'l' );
1645 ImplWriteDouble( nX1
);
1646 ImplWriteDouble( nY2
);
1647 ImplWriteByte( 'l' );
1648 ImplWriteDouble( nX1
);
1649 ImplWriteDouble( nY1
);
1650 ImplWriteByte( 'l', PS_SPACE
| PS_WRAP
);
1652 rClipRegion
.EndEnumRects( hRegionHandle
);
1653 ImplWriteLine( "eoclip newpath" );
1657 //---------------------------------------------------------------------------------
1658 // possible gfx formats:
1660 // level 1: grayscale 8 bit
1663 // level 2: grayscale 8 bit
1664 // color 1(pal), 4(pal), 8(pal), 24 Bit
1667 void PSWriter::ImplBmp( Bitmap
* pBitmap
, Bitmap
* pMaskBitmap
, const Point
& rPoint
, double nXWidth
, double nYHeightOrg
)
1672 INT32 nHeightOrg
= pBitmap
->GetSizePixel().Height();
1673 INT32 nHeightLeft
= nHeightOrg
;
1674 long nWidth
= pBitmap
->GetSizePixel().Width();
1675 Point
aSourcePos( rPoint
);
1677 while ( nHeightLeft
)
1679 Bitmap
aTileBitmap( *pBitmap
);
1680 long nHeight
= nHeightLeft
;
1681 double nYHeight
= nYHeightOrg
;
1683 BOOL bDoTrans
= FALSE
;
1698 aRect
= Rectangle( Point( 0, nHeightOrg
- nHeightLeft
), Size( (long)nWidth
, (long)nHeight
) );
1699 aRegion
= Region( pMaskBitmap
->CreateRegion( COL_BLACK
, aRect
) );
1701 if ( ( mnLevel
== 1 ) && ( aRegion
.GetRectCount() * 5 > 1000 ) )
1711 if ( nHeight
!= nHeightOrg
)
1713 nYHeight
= nYHeightOrg
* nHeight
/ nHeightOrg
;
1714 aTileBitmap
.Crop( Rectangle( Point( 0, nHeightOrg
- nHeightLeft
), Size( nWidth
, nHeight
) ) );
1718 ImplWriteLine( "gs\npum" );
1719 ImplTranslate( aSourcePos
.X(), aSourcePos
.Y() );
1720 ImplScale( nXWidth
/ nWidth
, nYHeight
/ nHeight
);
1721 RegionHandle hRegionHandle
= aRegion
.BeginEnumRects();
1723 while ( aRegion
.GetNextEnumRect( hRegionHandle
, aRect
) )
1725 aRect
.Move( 0, - ( nHeightOrg
- nHeightLeft
) );
1726 ImplWriteLong( aRect
.Left() );
1727 ImplWriteLong( aRect
.Top() );
1728 ImplWriteByte( 'm' );
1729 ImplWriteLong( aRect
.Right() + 1 );
1730 ImplWriteLong( aRect
.Top() );
1731 ImplWriteByte( 'l' );
1732 ImplWriteLong( aRect
.Right() + 1 );
1733 ImplWriteLong( aRect
.Bottom() + 1 );
1734 ImplWriteByte( 'l' );
1735 ImplWriteLong( aRect
.Left() );
1736 ImplWriteLong( aRect
.Bottom() + 1 );
1737 ImplWriteByte( 'l' );
1738 ImplWriteByte( 'p', PS_SPACE
| PS_WRAP
);
1740 aRegion
.EndEnumRects( hRegionHandle
);
1741 ImplWriteLine( "eoclip newpath" );
1742 ImplWriteLine( "pom" );
1744 BitmapReadAccess
* pAcc
= aTileBitmap
.AcquireReadAccess();
1747 ImplWriteLine( "pum" );
1749 ImplTranslate( aSourcePos
.X(), aSourcePos
.Y() + nYHeight
);
1750 ImplScale( nXWidth
, nYHeight
);
1751 if ( mnLevel
== 1 ) // level 1 is always grayscale !!!
1753 ImplWriteLong( nWidth
);
1754 ImplWriteLong( nHeight
);
1756 ImplWriteLong( nWidth
);
1758 ImplWriteLong( -nHeight
);
1760 ImplWriteLong( nHeight
);
1761 ImplWriteLine( "]" );
1762 *mpPS
<< "{currentfile ";
1763 ImplWriteLong( nWidth
);
1764 ImplWriteLine( "string readhexstring pop}" );
1765 ImplWriteLine( "image" );
1766 for ( long y
= 0; y
< nHeight
; y
++ )
1768 for ( long x
= 0; x
< nWidth
; x
++ )
1770 ImplWriteHexByte( (BYTE
)pAcc
->GetPixel( y
, x
) );
1779 ImplWriteLine( "/DeviceGray setcolorspace" );
1780 ImplWriteLine( "<<" );
1781 ImplWriteLine( "/ImageType 1" );
1783 ImplWriteLong( nWidth
, PS_RET
);
1784 *mpPS
<< "/Height ";
1785 ImplWriteLong( nHeight
, PS_RET
);
1786 ImplWriteLine( "/BitsPerComponent 8" );
1787 ImplWriteLine( "/Decode[0 1]" );
1788 *mpPS
<< "/ImageMatrix[";
1789 ImplWriteLong( nWidth
);
1791 ImplWriteLong( -nHeight
);
1793 ImplWriteLong( nHeight
, PS_NONE
);
1794 ImplWriteByte( ']', PS_RET
);
1795 ImplWriteLine( "/DataSource currentfile" );
1796 ImplWriteLine( "/ASCIIHexDecode filter" );
1797 if ( mbCompression
)
1798 ImplWriteLine( "/LZWDecode filter" );
1799 ImplWriteLine( ">>" );
1800 ImplWriteLine( "image" );
1801 if ( mbCompression
)
1804 for ( long y
= 0; y
< nHeight
; y
++ )
1806 for ( long x
= 0; x
< nWidth
; x
++ )
1808 Compress( (BYTE
)pAcc
->GetPixel( y
, x
) );
1815 for ( long y
= 0; y
< nHeight
; y
++ )
1817 for ( long x
= 0; x
< nWidth
; x
++ )
1819 ImplWriteHexByte( (BYTE
)pAcc
->GetPixel( y
, x
) );
1826 // have we to write a palette ?
1828 if ( pAcc
->HasPalette() )
1830 ImplWriteLine( "[/Indexed /DeviceRGB " );
1831 ImplWriteLong( pAcc
->GetPaletteEntryCount() - 1, PS_RET
);
1832 ImplWriteByte( '<', PS_NONE
);
1833 for ( USHORT i
= 0; i
< pAcc
->GetPaletteEntryCount(); i
++ )
1835 BitmapColor aBitmapColor
= pAcc
->GetPaletteColor( i
);
1836 ImplWriteHexByte( aBitmapColor
.GetRed(), PS_NONE
);
1837 ImplWriteHexByte( aBitmapColor
.GetGreen(), PS_NONE
);
1838 ImplWriteHexByte( aBitmapColor
.GetBlue(), PS_SPACE
| PS_WRAP
);
1840 ImplWriteByte( '>', PS_RET
);
1842 ImplWriteLine( "] setcolorspace" );
1843 ImplWriteLine( "<<" );
1844 ImplWriteLine( "/ImageType 1" );
1846 ImplWriteLong( nWidth
, PS_RET
);
1847 *mpPS
<< "/Height ";
1848 ImplWriteLong( nHeight
, PS_RET
);
1849 ImplWriteLine( "/BitsPerComponent 8" );
1850 ImplWriteLine( "/Decode[0 255]" );
1851 *mpPS
<< "/ImageMatrix[";
1852 ImplWriteLong( nWidth
);
1854 ImplWriteLong( -nHeight
);
1856 ImplWriteLong( nHeight
, PS_NONE
);
1857 ImplWriteByte( ']', PS_RET
);
1858 ImplWriteLine( "/DataSource currentfile" );
1859 ImplWriteLine( "/ASCIIHexDecode filter" );
1860 if ( mbCompression
)
1861 ImplWriteLine( "/LZWDecode filter" );
1862 ImplWriteLine( ">>" );
1863 ImplWriteLine( "image" );
1864 if ( mbCompression
)
1867 for ( long y
= 0; y
< nHeight
; y
++ )
1869 for ( long x
= 0; x
< nWidth
; x
++ )
1871 Compress( (BYTE
)pAcc
->GetPixel( y
, x
) );
1878 for ( long y
= 0; y
< nHeight
; y
++ )
1880 for ( long x
= 0; x
< nWidth
; x
++ )
1882 ImplWriteHexByte( (BYTE
)pAcc
->GetPixel( y
, x
) );
1887 else // 24 bit color
1889 ImplWriteLine( "/DeviceRGB setcolorspace" );
1890 ImplWriteLine( "<<" );
1891 ImplWriteLine( "/ImageType 1" );
1893 ImplWriteLong( nWidth
, PS_RET
);
1894 *mpPS
<< "/Height ";
1895 ImplWriteLong( nHeight
, PS_RET
);
1896 ImplWriteLine( "/BitsPerComponent 8" );
1897 ImplWriteLine( "/Decode[0 1 0 1 0 1]" );
1898 *mpPS
<< "/ImageMatrix[";
1899 ImplWriteLong( nWidth
);
1901 ImplWriteLong( -nHeight
);
1903 ImplWriteLong( nHeight
, PS_NONE
);
1904 ImplWriteByte( ']', PS_RET
);
1905 ImplWriteLine( "/DataSource currentfile" );
1906 ImplWriteLine( "/ASCIIHexDecode filter" );
1907 if ( mbCompression
)
1908 ImplWriteLine( "/LZWDecode filter" );
1909 ImplWriteLine( ">>" );
1910 ImplWriteLine( "image" );
1911 if ( mbCompression
)
1914 for ( long y
= 0; y
< nHeight
; y
++ )
1916 for ( long x
= 0; x
< nWidth
; x
++ )
1918 const BitmapColor
aBitmapColor( pAcc
->GetPixel( y
, x
) );
1919 Compress( aBitmapColor
.GetRed() );
1920 Compress( aBitmapColor
.GetGreen() );
1921 Compress( aBitmapColor
.GetBlue() );
1928 for ( long y
= 0; y
< nHeight
; y
++ )
1930 for ( long x
= 0; x
< nWidth
; x
++ )
1932 const BitmapColor
aBitmapColor( pAcc
->GetPixel( y
, x
) );
1933 ImplWriteHexByte( aBitmapColor
.GetRed() );
1934 ImplWriteHexByte( aBitmapColor
.GetGreen() );
1935 ImplWriteHexByte( aBitmapColor
.GetBlue() );
1941 ImplWriteLine( ">" ); // in Level 2 the dictionary needs to be closed (eod)
1944 ImplWriteLine( "gr" );
1946 ImplWriteLine( "pom" );
1948 aTileBitmap
.ReleaseAccess( pAcc
);
1949 nHeightLeft
-= nHeight
;
1953 aSourcePos
.Y() = (long) ( rPoint
.Y() + ( nYHeightOrg
* ( nHeightOrg
- nHeightLeft
) ) / nHeightOrg
);
1958 //---------------------------------------------------------------------------------
1960 void PSWriter::ImplWriteCharacter( sal_Char nChar
)
1967 ImplWriteByte( (BYTE
)'\\', PS_NONE
);
1969 ImplWriteByte( (BYTE
)nChar
, PS_NONE
);
1972 //---------------------------------------------------------------------------------
1974 void PSWriter::ImplWriteString( const ByteString
& rString
, VirtualDevice
& rVDev
, const INT32
* pDXArry
, BOOL bStretch
)
1976 USHORT nLen
= rString
.Len();
1984 for( i
= 0; i
< nLen
; i
++ )
1987 nx
= pDXArry
[ i
- 1 ];
1988 ImplWriteDouble( ( bStretch
) ? nx
: rVDev
.GetTextWidth( rString
.GetChar( i
) ) );
1989 ImplWriteDouble( nx
);
1990 ImplWriteLine( "(", PS_NONE
);
1991 ImplWriteCharacter( rString
.GetChar( i
) );
1992 ImplWriteLine( ") bs" );
1997 ImplWriteByte( '(', PS_NONE
);
1998 for ( i
= 0; i
< nLen
; i
++ )
1999 ImplWriteCharacter( rString
.GetChar( i
) );
2000 ImplWriteLine( ") sw" );
2005 // ------------------------------------------------------------------------
2007 void PSWriter::ImplText( const String
& rUniString
, const Point
& rPos
, const INT32
* pDXArry
, sal_Int32 nWidth
, VirtualDevice
& rVDev
)
2009 sal_uInt16 nLen
= rUniString
.Len();
2012 if ( mnTextMode
== 0 ) // using glpyh outlines
2014 Font
aNotRotatedFont( maFont
);
2015 aNotRotatedFont
.SetOrientation( 0 );
2017 VirtualDevice
aVirDev( 1 );
2018 aVirDev
.SetMapMode( rVDev
.GetMapMode() );
2019 aVirDev
.SetFont( aNotRotatedFont
);
2020 aVirDev
.SetTextAlign( eTextAlign
);
2022 sal_Int16 nRotation
= maFont
.GetOrientation();
2023 Polygon
aPolyDummy( 1 );
2025 PolyPolygon aPolyPoly
;
2029 aPolyDummy
.SetPoint( aPos
, 0 );
2030 aPolyDummy
.Rotate( rPos
, nRotation
);
2031 aPos
= aPolyDummy
.GetPoint( 0 );
2033 sal_Bool bOldLineColor
= bLineColor
;
2034 bLineColor
= sal_False
;
2035 std::vector
<PolyPolygon
> aPolyPolyVec
;
2036 if ( aVirDev
.GetTextOutlines( aPolyPolyVec
, rUniString
, 0, 0, STRING_LEN
, TRUE
, nWidth
, pDXArry
) )
2038 // always adjust text position to match baseline alignment
2039 ImplWriteLine( "pum" );
2040 ImplWriteDouble( aPos
.X() );
2041 ImplWriteDouble( aPos
.Y() );
2042 ImplWriteLine( "t" );
2045 ImplWriteF( nRotation
, 1 );
2048 std::vector
<PolyPolygon
>::iterator
aIter( aPolyPolyVec
.begin() );
2049 while ( aIter
!= aPolyPolyVec
.end() )
2050 ImplPolyPoly( *aIter
++, sal_True
);
2051 ImplWriteLine( "pom" );
2053 bLineColor
= bOldLineColor
;
2055 else if ( ( mnTextMode
== 1 ) || ( mnTextMode
== 2 ) ) // normal text output
2057 if ( mnTextMode
== 2 ) // forcing output one complete text packet, by
2058 pDXArry
= NULL
; // ignoring the kerning array
2059 ImplSetAttrForText( rPos
);
2060 ByteString
aStr( rUniString
, maFont
.GetCharSet() );
2061 ImplWriteString( aStr
, rVDev
, pDXArry
, nWidth
!= 0 );
2062 if ( maFont
.GetOrientation() )
2063 ImplWriteLine( "gr" );
2067 // ------------------------------------------------------------------------
2069 void PSWriter::ImplSetAttrForText( const Point
& rPoint
)
2071 Point
aPoint( rPoint
);
2073 long nRotation
= maFont
.GetOrientation();
2074 ImplWriteTextColor();
2076 Size aSize
= maFont
.GetSize();
2078 if ( maLastFont
!= maFont
)
2080 if ( maFont
.GetPitch() == PITCH_FIXED
) // a little bit font selection
2081 ImplDefineFont( "Courier", "Oblique" );
2082 else if ( maFont
.GetCharSet() == RTL_TEXTENCODING_SYMBOL
)
2083 ImplWriteLine( "/Symbol findfont" );
2084 else if ( maFont
.GetFamily() == FAMILY_SWISS
)
2085 ImplDefineFont( "Helvetica", "Oblique" );
2087 ImplDefineFont( "Times", "Italic" );
2089 maLastFont
= maFont
;
2090 aSize
= maFont
.GetSize();
2091 ImplWriteDouble( aSize
.Height() );
2094 if ( eTextAlign
!= ALIGN_BASELINE
)
2095 { // PostScript kennt kein FontAlignment
2096 if ( eTextAlign
== ALIGN_TOP
) // -> ich gehe daher davon aus, dass
2097 aPoint
.Y() += ( aSize
.Height() * 4 / 5 ); // der Bereich unter der Baseline
2098 else if ( eTextAlign
== ALIGN_BOTTOM
) // in etwa 20% der Fontsize ausmacht
2099 aPoint
.Y() -= ( aSize
.Height() / 5 );
2101 ImplMoveTo( aPoint
);
2105 ImplWriteF( nRotation
, 1 );
2110 //---------------------------------------------------------------------------------
2112 void PSWriter::ImplDefineFont( const char* pOriginalName
, const char* pItalic
)
2114 *mpPS
<< (BYTE
)'/'; //convert the font pOriginalName using ISOLatin1Encoding
2115 *mpPS
<< pOriginalName
;
2116 switch ( maFont
.GetWeight() )
2118 case WEIGHT_SEMIBOLD
:
2120 case WEIGHT_ULTRABOLD
:
2123 if ( maFont
.GetItalic() != ITALIC_NONE
)
2127 if ( maFont
.GetItalic() != ITALIC_NONE
)
2131 ImplWriteLine( " f" );
2134 //---------------------------------------------------------------------------------
2135 //---------------------------------------------------------------------------------
2136 //---------------------------------------------------------------------------------
2138 void PSWriter::ImplClosePathDraw( ULONG nMode
)
2142 ImplExecMode( nMode
);
2145 void PSWriter::ImplPathDraw()
2149 ImplExecMode( PS_RET
);
2152 //---------------------------------------------------------------------------------
2154 inline void PSWriter::ImplWriteLineColor( ULONG nMode
)
2156 if ( aColor
!= aLineColor
)
2158 aColor
= aLineColor
;
2159 ImplWriteColor( nMode
);
2162 inline void PSWriter::ImplWriteFillColor( ULONG nMode
)
2164 if ( aColor
!= aFillColor
)
2166 aColor
= aFillColor
;
2167 ImplWriteColor( nMode
);
2170 inline void PSWriter::ImplWriteTextColor( ULONG nMode
)
2172 if ( aColor
!= aTextColor
)
2174 aColor
= aTextColor
;
2175 ImplWriteColor( nMode
);
2178 inline void PSWriter::ImplWriteTextFillColor( ULONG nMode
)
2180 if ( aColor
!= aTextFillColor
)
2182 aColor
= aTextFillColor
;
2183 ImplWriteColor( nMode
);
2187 //---------------------------------------------------------------------------------
2189 void PSWriter::ImplWriteColor( ULONG nMode
)
2193 // writes the Color (grayscale) as a Number from 0.000 up to 1.000
2195 ImplWriteF( 1000 * ( (BYTE
)aColor
.GetRed() * 77 + (BYTE
)aColor
.GetGreen() * 151 +
2196 (BYTE
)aColor
.GetBlue() * 28 + 1 ) / 65536, 3, nMode
);
2200 ImplWriteB1 ( (BYTE
)aColor
.GetRed() );
2201 ImplWriteB1 ( (BYTE
)aColor
.GetGreen() );
2202 ImplWriteB1 ( (BYTE
)aColor
.GetBlue() );
2204 *mpPS
<< "c"; // ( c is defined as setrgbcolor or setgray )
2205 ImplExecMode( nMode
);
2208 //---------------------------------------------------------------------------------
2210 double PSWriter::ImplGetScaling( const MapMode
& rMapMode
)
2213 switch ( rMapMode
.GetMapUnit() )
2231 case MAP_1000TH_INCH
:
2234 case MAP_100TH_INCH
:
2237 case MAP_10TH_INCH
:
2256 //---------------------------------------------------------------------------------
2258 void PSWriter::ImplGetMapMode( const MapMode
& rMapMode
)
2260 ImplWriteLine( "tm setmatrix" );
2261 double fMul
= ImplGetScaling( rMapMode
);
2262 double fScaleX
= (double)rMapMode
.GetScaleX() * fMul
;
2263 double fScaleY
= (double)rMapMode
.GetScaleY() * fMul
;
2264 ImplTranslate( rMapMode
.GetOrigin().X() * fScaleX
, rMapMode
.GetOrigin().Y() * fScaleY
);
2265 ImplScale( fScaleX
, fScaleY
);
2268 //---------------------------------------------------------------------------------
2270 inline void PSWriter::ImplExecMode( ULONG nMode
)
2272 if ( nMode
& PS_WRAP
)
2274 if ( mnCursorPos
>= PS_LINESIZE
)
2281 if ( nMode
& PS_SPACE
)
2286 if ( nMode
& PS_RET
)
2293 //---------------------------------------------------------------------------------
2295 inline void PSWriter::ImplWriteLine( const char* pString
, ULONG nMode
)
2298 while ( pString
[ i
] )
2300 *mpPS
<< (BYTE
)pString
[ i
++ ];
2303 ImplExecMode( nMode
);
2306 //---------------------------------------------------------------------------------
2308 void PSWriter::ImplWriteLineInfo( double fLWidth
, double fMLimit
,
2309 SvtGraphicStroke::CapType eLCap
,
2310 SvtGraphicStroke::JoinType eJoin
,
2311 SvtGraphicStroke::DashArray
& rLDash
)
2313 if ( fLineWidth
!= fLWidth
)
2315 fLineWidth
= fLWidth
;
2316 ImplWriteDouble( fLineWidth
);
2317 ImplWriteLine( "lw", PS_SPACE
);
2319 if ( eLineCap
!= eLCap
)
2322 ImplWriteLong( (sal_Int32
)eLineCap
, PS_SPACE
);
2323 ImplWriteLine( "lc", PS_SPACE
);
2325 if ( eJoinType
!= eJoin
)
2328 ImplWriteLong( (sal_Int32
)eJoinType
, PS_SPACE
);
2329 ImplWriteLine( "lj", PS_SPACE
);
2331 if ( eJoinType
== SvtGraphicStroke::joinMiter
)
2333 if ( fMiterLimit
!= fMLimit
)
2335 fMiterLimit
= fMLimit
;
2336 ImplWriteDouble( fMiterLimit
);
2337 ImplWriteLine( "ml", PS_SPACE
);
2340 if ( aDashArray
!= rLDash
)
2342 aDashArray
= rLDash
;
2343 sal_uInt32 j
, i
= aDashArray
.size();
2344 ImplWriteLine( "[", PS_SPACE
);
2345 for ( j
= 0; j
< i
; j
++ )
2346 ImplWriteDouble( aDashArray
[ j
] );
2347 ImplWriteLine( "] 0 ld" );
2351 //---------------------------------------------------------------------------------
2353 void PSWriter::ImplWriteLineInfo( const LineInfo
& rLineInfo
)
2355 SvtGraphicStroke::DashArray l_aDashArray
;
2356 if ( rLineInfo
.GetStyle() == LINE_DASH
)
2357 l_aDashArray
.push_back( 2 );
2358 double fLWidth
= ( ( rLineInfo
.GetWidth() + 1 ) + ( rLineInfo
.GetWidth() + 1 ) ) * 0.5;
2359 ImplWriteLineInfo( fLWidth
, 10.0, SvtGraphicStroke::capButt
, SvtGraphicStroke::joinMiter
, l_aDashArray
);
2362 //---------------------------------------------------------------------------------
2364 void PSWriter::ImplWriteLong( sal_Int32 nNumber
, ULONG nMode
)
2366 const ByteString
aNumber( ByteString::CreateFromInt32( nNumber
) );
2367 ULONG nLen
= aNumber
.Len();
2368 mnCursorPos
+= nLen
;
2369 for ( USHORT n
= 0; n
< nLen
; n
++ )
2370 *mpPS
<< aNumber
.GetChar( n
);
2371 ImplExecMode( nMode
);
2374 //---------------------------------------------------------------------------------
2376 void PSWriter::ImplWriteDouble( double fNumber
, ULONG nMode
)
2380 sal_Int32 nPTemp
= (sal_Int32
)fNumber
;
2381 sal_Int32 nATemp
= labs( (sal_Int32
)( ( fNumber
- nPTemp
) * 100000 ) );
2383 if ( !nPTemp
&& nATemp
&& ( fNumber
< 0.0 ) )
2384 *mpPS
<< (sal_Char
)'-';
2386 ByteString
aNumber1( ByteString::CreateFromInt32( nPTemp
) );
2387 nLength
= aNumber1
.Len();
2388 mnCursorPos
+= nLength
;
2389 for ( sal_Int32 n
= 0; n
< nLength
; n
++ )
2390 *mpPS
<< aNumber1
.GetChar( (sal_uInt16
)n
);
2397 const ByteString
aNumber2( ByteString::CreateFromInt32( nATemp
) );
2399 sal_Int16 n
, nLen
= aNumber2
.Len();
2402 mnCursorPos
+= 6 - nLen
;
2403 for ( n
= 0; n
< ( 5 - nLen
); n
++ )
2408 mnCursorPos
+= nLen
;
2409 for ( n
= 0; n
< nLen
; n
++ )
2411 *mpPS
<< aNumber2
.GetChar( n
);
2413 if ( aNumber2
.GetChar( n
) != '0' )
2417 mpPS
->SeekRel( zCount
);
2419 ImplExecMode( nMode
);
2422 //---------------------------------------------------------------------------------
2424 // writes the number to stream: nNumber / ( 10^nCount )
2426 void PSWriter::ImplWriteF( sal_Int32 nNumber
, ULONG nCount
, ULONG nMode
)
2434 const ByteString
aScaleFactor( ByteString::CreateFromInt32( nNumber
) );
2435 ULONG nLen
= aScaleFactor
.Len();
2436 long nStSize
= ( nCount
+ 1 ) - nLen
;
2445 for ( long i
= 1; i
< nStSize
; i
++ )
2451 mnCursorPos
+= nLen
;
2452 for( USHORT n
= 0UL; n
< nLen
; n
++ )
2454 if ( n
== nLen
- nCount
)
2459 *mpPS
<< aScaleFactor
.GetChar( n
);
2461 ImplExecMode( nMode
);
2464 //---------------------------------------------------------------------------------
2466 void PSWriter::ImplWriteByte( BYTE nNumb
, ULONG nMode
)
2470 ImplExecMode( nMode
);
2473 //---------------------------------------------------------------------------------
2475 void PSWriter::ImplWriteHexByte( BYTE nNumb
, ULONG nMode
)
2477 if ( ( nNumb
>> 4 ) > 9 )
2478 *mpPS
<< (BYTE
)( ( nNumb
>> 4 ) + 'A' - 10 );
2480 *mpPS
<< (BYTE
)( ( nNumb
>> 4 ) + '0' );
2482 if ( ( nNumb
& 0xf ) > 9 )
2483 *mpPS
<< (BYTE
)( ( nNumb
& 0xf ) + 'A' - 10 );
2485 *mpPS
<< (BYTE
)( ( nNumb
& 0xf ) + '0' );
2487 ImplExecMode( nMode
);
2490 //---------------------------------------------------------------------------------
2492 // writes the BYTE nNumb as a Number from 0.000 up to 1.000
2494 void PSWriter::ImplWriteB1( BYTE nNumb
, ULONG nMode
)
2496 ImplWriteF( 1000 * ( nNumb
+ 1 ) / 256 , 3, nMode
);
2500 // ------------------------------------------------------------------------
2502 inline void PSWriter::WriteBits( USHORT nCode
, USHORT nCodeLen
)
2504 dwShift
|= ( nCode
<< ( nOffset
- nCodeLen
) );
2505 nOffset
-= nCodeLen
;
2506 while ( nOffset
< 24 )
2508 ImplWriteHexByte( (BYTE
)( dwShift
>> 24 ) );
2512 if ( nCode
== 257 && nOffset
!= 32 )
2513 ImplWriteHexByte( (BYTE
)( dwShift
>> 24 ) );
2516 // ------------------------------------------------------------------------
2518 void PSWriter::StartCompression()
2523 nClearCode
= 1 << nDataSize
;
2524 nEOICode
= nClearCode
+ 1;
2525 nTableSize
= nEOICode
+ 1;
2526 nCodeSize
= nDataSize
+ 1;
2528 nOffset
= 32; // anzahl freier bits in dwShift
2531 pTable
= new PSLZWCTreeNode
[ 4096 ];
2533 for ( i
= 0; i
< 4096; i
++ )
2535 pTable
[ i
].pBrother
= pTable
[ i
].pFirstChild
= NULL
;
2536 pTable
[ i
].nValue
= (BYTE
)( pTable
[ i
].nCode
= i
);
2539 WriteBits( nClearCode
, nCodeSize
);
2542 // ------------------------------------------------------------------------
2544 void PSWriter::Compress( BYTE nCompThis
)
2552 pPrefix
= pTable
+ nCompThis
;
2557 for( p
= pPrefix
->pFirstChild
; p
!= NULL
; p
= p
->pBrother
)
2559 if ( p
->nValue
== nV
)
2567 WriteBits( pPrefix
->nCode
, nCodeSize
);
2569 if ( nTableSize
== 409 )
2571 WriteBits( nClearCode
, nCodeSize
);
2573 for ( i
= 0; i
< nClearCode
; i
++ )
2574 pTable
[ i
].pFirstChild
= NULL
;
2576 nCodeSize
= nDataSize
+ 1;
2577 nTableSize
= nEOICode
+ 1;
2581 if( nTableSize
== (USHORT
)( ( 1 << nCodeSize
) - 1 ) )
2584 p
= pTable
+ ( nTableSize
++ );
2585 p
->pBrother
= pPrefix
->pFirstChild
;
2586 pPrefix
->pFirstChild
= p
;
2588 p
->pFirstChild
= NULL
;
2591 pPrefix
= pTable
+ nV
;
2596 // ------------------------------------------------------------------------
2598 void PSWriter::EndCompression()
2601 WriteBits( pPrefix
->nCode
, nCodeSize
);
2603 WriteBits( nEOICode
, nCodeSize
);
2607 // ------------------------------------------------------------------------
2609 BYTE
* PSWriter::ImplSearchEntry( BYTE
* pSource
, BYTE
* pDest
, ULONG nComp
, ULONG nSize
)
2611 while ( nComp
-- >= nSize
)
2614 for ( i
= 0; i
< nSize
; i
++ )
2616 if ( ( pSource
[i
]&~0x20 ) != ( pDest
[i
]&~0x20 ) )
2626 // ------------------------------------------------------------------------
2628 BOOL
PSWriter::ImplGetBoundingBox( double* nNumb
, BYTE
* pSource
, ULONG nSize
)
2630 BOOL bRetValue
= FALSE
;
2633 if ( nSize
< 256 ) // we assume that the file is greater than 256 bytes
2636 if ( nSize
< POSTSCRIPT_BOUNDINGSEARCH
)
2639 nBytesRead
= POSTSCRIPT_BOUNDINGSEARCH
;
2641 BYTE
* pDest
= ImplSearchEntry( pSource
, (BYTE
*)"%%BoundingBox:", nBytesRead
, 14 );
2644 int nSecurityCount
= 100; // only 100 bytes following the bounding box will be checked
2645 nNumb
[0] = nNumb
[1] = nNumb
[2] = nNumb
[3] = 0;
2647 for ( int i
= 0; ( i
< 4 ) && nSecurityCount
; i
++ )
2650 BOOL bDivision
= FALSE
;
2651 BOOL bNegative
= FALSE
;
2654 while ( ( --nSecurityCount
) && ( ( *pDest
== ' ' ) || ( *pDest
== 0x9 ) ) )
2656 BYTE nByte
= *pDest
;
2657 while ( nSecurityCount
&& ( nByte
!= ' ' ) && ( nByte
!= 0x9 ) && ( nByte
!= 0xd ) && ( nByte
!= 0xa ) )
2671 if ( ( nByte
< '0' ) || ( nByte
> '9' ) )
2672 nSecurityCount
= 1; // error parsing the bounding box values
2678 nNumb
[i
] += nByte
- '0';
2686 nNumb
[i
] = -nNumb
[i
];
2687 if ( bDivision
&& ( nDivision
!= 1 ) )
2688 nNumb
[i
] /= nDivision
;
2690 if ( nSecurityCount
)
2696 //================== GraphicExport - die exportierte Funktion ================
2698 extern "C" BOOL __LOADONCALLAPI
GraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pFilterConfigItem
, BOOL
)
2701 return aPSWriter
.WritePS( rGraphic
, rStream
, pFilterConfigItem
);
2704 //---------------------------------------------------------------------------------
2706 extern "C" BOOL __LOADONCALLAPI
DoExportDialog( FltCallDialogParameter
& rPara
)
2710 if ( rPara
.pWindow
)
2712 ByteString
aResMgrName( "eps" );
2715 pResMgr
= ResMgr::CreateResMgr( aResMgrName
.GetBuffer(), Application::GetSettings().GetUILocale() );
2719 rPara
.pResMgr
= pResMgr
;
2720 bRet
= ( DlgExportEPS( rPara
).Execute() == RET_OK
);
2730 //================== ein bischen Muell fuer Windows ==========================
2736 static HINSTANCE hDLLInst
= 0; // HANDLE der DLL
2738 extern "C" int CALLBACK
LibMain( HINSTANCE hDLL
, WORD
, WORD nHeap
, LPSTR
)
2750 extern "C" int CALLBACK
WEP( int )