merge the formfield patch from ooo-build
[ooovba.git] / goodies / source / filter.vcl / eps / eps.cxx
blobe7c7b072265cc3f02fb58db77ca92c947ee5c84e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eps.cxx,v $
10 * $Revision: 1.37 $
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"
34 #include <vcl/sv.h>
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"
54 #include "dlgeps.hrc"
55 #include "dlgeps.hxx"
57 #include <math.h>
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
68 #define PS_SPACE 1
69 #define PS_RET 2
70 #define PS_WRAP 4
72 // -----------------------------Feld-Typen-------------------------------
74 struct ChrSet
76 struct ChrSet * pSucc;
77 BYTE nSet;
78 String aName;
79 FontWeight eWeight;
82 struct StackMember
84 struct StackMember * pSucc;
85 Color aGlobalCol;
86 BOOL bLineCol;
87 Color aLineCol;
88 BOOL bFillCol;
89 Color aFillCol;
90 Color aTextCol;
91 BOOL bTextFillCol;
92 Color aTextFillCol;
93 Color aBackgroundCol;
94 Font aFont;
95 TextAlign eTextAlign;
97 double fLineWidth;
98 double fMiterLimit;
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
113 class PSWriter
115 private:
116 BOOL mbStatus;
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;
124 sal_Int32 mnPreview;
125 sal_Int32 mnTextMode;
127 SvStream* mpPS;
128 const GDIMetaFile* pMTF;
129 GDIMetaFile* pAMTF; // only created if Graphics is not a Metafile
130 VirtualDevice aVDev;
132 double nBoundingX1; // this represents the bounding box
133 double nBoundingY1;
134 double nBoundingX2;
135 double nBoundingY2;
137 StackMember* pGDIStack;
138 ULONG mnCursorPos; // aktuelle Cursorposition im Output
139 Color aColor; // aktuelle Farbe die fuer den Output benutzt wird
140 BOOL bLineColor;
141 Color aLineColor; // aktuelle GDIMetafile Farbeinstellungen
142 BOOL bFillColor; //
143 Color aFillColor; //
144 Color aTextColor; //
145 BOOL bTextFillColor; //
146 Color aTextFillColor; //
147 Color aBackgroundColor; //
148 BOOL bRegionChanged;
149 TextAlign eTextAlign; //
151 double fLineWidth;
152 double fMiterLimit;
153 SvtGraphicStroke::CapType eLineCap;
154 SvtGraphicStroke::JoinType eJoinType;
155 SvtGraphicStroke::DashArray aDashArray;
157 Font maFont;
158 Font maLastFont;
159 BYTE nChrSet;
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
165 USHORT nDataSize;
166 USHORT nClearCode;
167 USHORT nEOICode;
168 USHORT nTableSize;
169 USHORT nCodeSize;
170 ULONG nOffset;
171 ULONG dwShift;
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
180 // parameters
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 );
232 void ImplPathDraw();
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 );
244 // LZW methods
245 void StartCompression();
246 void Compress( BYTE nSrc );
247 void EndCompression();
248 inline void WriteBits( USHORT nCode, USHORT nCodeLen );
250 public:
251 BOOL WritePS( const Graphic& rGraphic, SvStream& rTargetStream, FilterConfigItem* );
252 PSWriter();
253 ~PSWriter();
256 //========================== Methoden von PSWriter ==========================
258 //---------------------------------------------------------------------------------
260 PSWriter::PSWriter()
262 pAMTF = NULL;
266 PSWriter::~PSWriter()
268 delete pAMTF;
271 //---------------------------------------------------------------------------------
273 BOOL PSWriter::WritePS( const Graphic& rGraphic, SvStream& rTargetStream, FilterConfigItem* pFilterConfigItem )
275 UINT32 nStreamPosition = 0, nPSPosition = 0; // -Wall warning, unset, check
277 mbStatus = TRUE;
278 mnPreview = 0;
279 mnLevelWarning = 0;
280 mnLastPercent = 0;
281 mnLatestPush = 0xEFFFFFFE;
283 if ( pFilterConfigItem )
285 xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
286 if ( xStatusIndicator.is() )
288 rtl::OUString aMsg;
289 xStatusIndicator->start( aMsg, 100 );
293 mpPS = &rTargetStream;
294 mpPS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
296 // default values for the dialog options
297 mnLevel = 2;
298 mbGrayScale = FALSE;
299 #ifdef UNX // don't compress by default on unix as ghostscript is unable to read LZW compressed eps
300 mbCompression = FALSE;
301 #else
302 mbCompression = TRUE;
303 #endif
304 mnTextMode = 0; // default0 : export glyph outlines
306 // try to get the dialog selection
307 if ( pFilterConfigItem )
309 ByteString aResMgrName( "eps" );
310 ResMgr* pResMgr;
312 pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
314 if( pResMgr )
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 );
322 #else
323 mnPreview = pFilterConfigItem->ReadInt32( aPreviewStr, 1 );
324 #endif
325 mnLevel = pFilterConfigItem->ReadInt32( aVersionStr, 2 );
326 if ( mnLevel != 1 )
327 mnLevel = 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;
331 #else
332 mbCompression = pFilterConfigItem->ReadInt32( aComprStr, 1 ) == 1;
333 #endif
334 String sTextMode( RTL_CONSTASCII_USTRINGPARAM( "TextMode" ) );
335 mnTextMode = pFilterConfigItem->ReadInt32( sTextMode, 0 );
336 if ( mnTextMode > 2 )
337 mnTextMode = 0;
338 delete pResMgr;
342 // compression is not available for Level 1
343 if ( mnLevel == 1 )
345 mbGrayScale = TRUE;
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;
356 UINT32 nErrCode;
357 if ( mbGrayScale )
359 BitmapEx aTempBitmapEx( rGraphic.GetBitmapEx() );
360 aTempBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
361 nErrCode = GraphicConverter::Export( rTargetStream, aTempBitmapEx, CVT_TIF ) ;
363 else
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 );
374 else
376 mnPreview &=~ EPS_PREVIEW_TIFF;
377 rTargetStream.Seek( nStreamPosition - 4 );
381 // global default value setting
382 ChrSet* pCS;
383 StackMember* pGS;
385 if ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE )
386 pMTF = &rGraphic.GetGDIMetaFile();
387 else
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();
394 pGDIStack = NULL;
395 aColor = Color( COL_TRANSPARENT );
396 bLineColor = TRUE;
397 aLineColor = Color( COL_BLACK );
398 bFillColor = TRUE;
399 aFillColor = Color( COL_WHITE );
400 bTextFillColor = TRUE;
401 aTextFillColor = Color( COL_BLACK );
402 fLineWidth = 1;
403 fMiterLimit = 10;
404 eLineCap = SvtGraphicStroke::capButt;
405 eJoinType = SvtGraphicStroke::joinMiter;
406 aBackgroundColor = Color( COL_WHITE );
407 eTextAlign = ALIGN_BASELINE;
408 bRegionChanged = FALSE;
410 nChrSet = 0x00;
411 pChrSetList = NULL;
412 nNextChrSetId = 1;
414 if( pMTF->GetActionCount() )
416 ImplWriteProlog( ( mnPreview & EPS_PREVIEW_EPSI ) ? &rGraphic : NULL );
417 mnCursorPos = 0;
418 ImplWriteActions( *pMTF, aVDev );
419 ImplWriteEpilog();
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 );
428 while( pChrSetList )
430 pCS=pChrSetList;
431 pChrSetList=pCS->pSucc;
432 delete pCS;
434 while( pGDIStack )
436 pGS=pGDIStack;
437 pGDIStack=pGS->pSucc;
438 delete pGS;
441 else
442 mbStatus = FALSE;
444 if ( mbStatus && mnLevelWarning && pFilterConfigItem )
446 ByteString aResMgrName( "eps" );
447 ResMgr* pResMgr;
448 pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
449 if( pResMgr )
451 InfoBox aInfoBox( NULL, String( ResId( KEY_VERSION_CHECK, *pResMgr ) ) );
452 aInfoBox.Execute();
453 delete pResMgr;
457 if ( xStatusIndicator.is() )
458 xStatusIndicator->end();
460 return mbStatus;
463 //---------------------------------------------------------------------------------
465 void PSWriter::ImplWriteProlog( const Graphic* pPreview )
467 ImplWriteLine( "%!PS-Adobe-3.0 EPSF-3.0 " );
468 *mpPS << "%%BoundingBox: "; // BoundingBox
469 ImplWriteLong( 0 );
470 ImplWriteLong( 0 );
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" );
480 // defaults
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();
494 if ( pAcc )
496 *mpPS << "%%BeginPreview: "; // BoundingBox
497 ImplWriteLong( aSizeBitmap.Width() );
498 ImplWriteLong( aSizeBitmap.Height() );
499 *mpPS << "1 ";
500 INT32 nLines = aSizeBitmap.Width() / 312;
501 if ( ( nLines * 312 ) != aSizeBitmap.Width() )
502 nLines++;
503 nLines *= aSizeBitmap.Height();
504 ImplWriteLong( nLines );
505 char nVal;
506 INT32 nX, nY, nCount2, nCount = 4;
507 const BitmapColor aBlack( pAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
508 for ( nY = 0; nY < aSizeBitmap.Height(); nY++ )
510 nCount2 = 0;
511 nVal = 0;
512 for ( nX = 0; nX < aSizeBitmap.Width(); nX++ )
514 if ( !nCount2 )
516 ImplExecMode( PS_RET );
517 *mpPS << "%";
518 nCount2 = 312;
520 nVal <<= 1;
521 if ( pAcc->GetPixel( nY, nX ) == aBlack )
522 nVal |= 1;
523 if ( ! ( --nCount ) )
525 if ( nVal > 9 )
526 nVal += 'A' - 10;
527 else
528 nVal += '0';
529 *mpPS << nVal;
530 nVal = 0;
531 nCount += 4;
533 nCount2--;
536 aTmpBitmap.ReleaseAccess( pAcc );
537 ImplExecMode( PS_RET );
538 ImplWriteLine( "%%EndPreview" );
541 ImplWriteLine( "%%BeginProlog" );
542 ImplWriteLine( "%%BeginResource: procset SDRes-Prolog 1.0 0" );
544 // BEGIN EPSF
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
550 if ( mbGrayScale )
551 ImplWriteLine( "/c {setgray} bdef" );
552 else
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 :
627 break;
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() );
636 ImplPathDraw();
637 aLineColor = aOldLineColor;
639 break;
641 case META_POINT_ACTION :
643 ImplWriteLineColor( PS_SPACE );
644 ImplMoveTo( ( (const MetaPointAction*)pMA )->GetPoint() );
645 ImplLineTo( ( (const MetaPointAction*)pMA )->GetPoint() );
646 ImplPathDraw();
648 break;
650 case META_LINE_ACTION :
652 const LineInfo& rLineInfo = ( ( const MetaLineAction*)pMA )->GetLineInfo();
653 ImplWriteLineInfo( rLineInfo );
654 if ( bLineColor )
656 ImplWriteLineColor( PS_SPACE );
657 ImplMoveTo( ( (const MetaLineAction*) pMA )->GetStartPoint() );
658 ImplLineTo( ( (const MetaLineAction*) pMA )->GetEndPoint() );
659 ImplPathDraw();
662 break;
664 case META_RECT_ACTION :
666 ImplRect( ( (const MetaRectAction*) pMA )->GetRect() );
668 break;
670 case META_ROUNDRECT_ACTION :
671 ImplRect( ( (const MetaRoundRectAction*) pMA )->GetRect() );
672 break;
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 );
682 break;
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 );
691 break;
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 );
700 break;
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 );
709 break;
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 );
718 break;
720 case META_POLYGON_ACTION :
722 PolyPolygon aPolyPoly( ( (const MetaPolygonAction*) pMA )->GetPolygon() );
723 ImplPolyPoly( aPolyPoly );
725 break;
727 case META_POLYPOLYGON_ACTION :
729 ImplPolyPoly( ( (const MetaPolyPolygonAction*) pMA )->GetPolyPolygon() );
731 break;
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 );
742 break;
744 case META_TEXTRECT_ACTION:
746 DBG_ERROR( "Unsupported action: TextRect...Action!" );
748 break;
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 );
758 break;
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 );
768 break;
770 case META_BMP_ACTION :
772 Bitmap aBitmap = ( (const MetaBmpAction*)pMA )->GetBitmap();
773 if ( mbGrayScale )
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() );
779 break;
781 case META_BMPSCALE_ACTION :
783 Bitmap aBitmap = ( (const MetaBmpScaleAction*)pMA )->GetBitmap();
784 if ( mbGrayScale )
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() );
790 break;
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() ) );
797 if ( mbGrayScale )
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() );
803 break;
805 case META_BMPEX_ACTION :
807 BitmapEx aBitmapEx( ( (MetaBmpExAction*)pMA)->GetBitmapEx() );
808 Bitmap aBitmap( aBitmapEx.GetBitmap() );
809 if ( mbGrayScale )
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() );
816 break;
818 case META_BMPEXSCALE_ACTION :
820 BitmapEx aBitmapEx( ( (MetaBmpExScaleAction*)pMA)->GetBitmapEx() );
821 Bitmap aBitmap( aBitmapEx.GetBitmap() );
822 if ( mbGrayScale )
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() );
829 break;
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() );
837 if ( mbGrayScale )
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() );
844 break;
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!" );
853 break;
855 case META_GRADIENT_ACTION :
857 PolyPolygon aPolyPoly( ( (const MetaGradientAction*)pMA)->GetRect() );
858 ImplWriteGradient( aPolyPoly, ( (const MetaGradientAction*) pMA )->GetGradient(), rVDev );
860 break;
862 case META_GRADIENTEX_ACTION :
864 PolyPolygon aPolyPoly( ( (const MetaGradientExAction*)pMA)->GetPolyPolygon() );
865 ImplWriteGradient( aPolyPoly, ( (const MetaGradientExAction*) pMA )->GetGradient(), rVDev );
867 break;
869 case META_HATCH_ACTION :
871 VirtualDevice l_aVDev;
872 GDIMetaFile aTmpMtf;
874 l_aVDev.SetMapMode( rVDev.GetMapMode() );
875 l_aVDev.AddHatchActions( ( (const MetaHatchAction*)pMA)->GetPolyPolygon(),
876 ( (const MetaHatchAction*)pMA )->GetHatch(), aTmpMtf );
877 ImplWriteActions( aTmpMtf, rVDev );
879 break;
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() )
896 // gradient action
899 Bitmap aMask( aBitmapEx.GetMask() );
900 ImplBmp( &aBitmap, &aMask, Point( aRect.Left(), aRect.Top() ), aRect.GetWidth(), aRect.GetHeight() );
902 else
903 ImplBmp( &aBitmap, NULL, Point( aRect.Left(), aRect.Top() ), aRect.GetWidth(), aRect.GetHeight() );
905 // wallpaper Style
908 else if ( aWallpaper.IsGradient() )
911 // gradient action
914 else
916 aColor = aWallpaper.GetColor();
917 ImplRectFill( aRect );
920 break;
922 case META_ISECTRECTCLIPREGION_ACTION:
924 const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
925 Region aRegion( pA->GetRect() );
926 ImplSetClipRegion( aRegion );
928 break;
930 case META_CLIPREGION_ACTION:
932 const MetaClipRegionAction* pA = (const MetaClipRegionAction*) pMA;
933 Region aRegion( pA->GetRegion() );
934 ImplSetClipRegion( aRegion );
936 break;
938 case META_ISECTREGIONCLIPREGION_ACTION:
940 const MetaISectRegionClipRegionAction* pA = (const MetaISectRegionClipRegionAction*) pMA;
941 Region aRegion( pA->GetRegion() );
942 ImplSetClipRegion( aRegion );
944 break;
946 case META_MOVECLIPREGION_ACTION:
949 if ( !aClipRegion.IsEmpty() )
951 const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*) pMA;
952 aClipRegion.Move( pA->GetHorzMove(), pA->GetVertMove() );
953 ImplSetClipRegion();
957 break;
959 case META_LINECOLOR_ACTION :
961 if ( ( (const MetaLineColorAction*) pMA)->IsSetting() )
963 bLineColor = TRUE;
964 aLineColor = ( (const MetaLineColorAction*) pMA )->GetColor();
966 else
967 bLineColor = FALSE;
969 break;
971 case META_FILLCOLOR_ACTION :
973 if ( ( (const MetaFillColorAction*) pMA )->IsSetting() )
975 bFillColor = TRUE;
976 aFillColor = ( (const MetaFillColorAction*) pMA )->GetColor();
978 else
979 bFillColor = FALSE;
981 break;
983 case META_TEXTCOLOR_ACTION :
985 aTextColor = ( (const MetaTextColorAction*) pMA )->GetColor();
987 break;
989 case META_TEXTFILLCOLOR_ACTION :
991 if ( ( (const MetaTextFillColorAction*) pMA )->IsSetting() )
993 bTextFillColor = TRUE;
994 aTextFillColor = ( (const MetaTextFillColorAction*) pMA )->GetColor();
996 else
997 bTextFillColor = FALSE;
999 break;
1001 case META_TEXTALIGN_ACTION :
1003 eTextAlign = ( (const MetaTextAlignAction*) pMA )->GetTextAlign();
1005 break;
1007 case META_MAPMODE_ACTION :
1009 pMA->Execute( &rVDev );
1010 ImplGetMapMode( rVDev.GetMapMode() );
1012 break;
1014 case META_FONT_ACTION :
1016 maFont = ((const MetaFontAction*)pMA)->GetFont();
1017 rVDev.SetFont( maFont );
1019 break;
1021 case META_PUSH_ACTION :
1023 rVDev.Push(((const MetaPushAction*)pMA)->GetFlags() );
1024 StackMember* pGS = new StackMember;
1025 pGS->pSucc = pGDIStack;
1026 pGDIStack = pGS;
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" );
1047 break;
1049 case META_POP_ACTION :
1051 rVDev.Pop();
1052 StackMember* pGS;
1053 if( pGDIStack )
1055 pGS = pGDIStack;
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
1074 delete pGS;
1075 sal_uInt32 nCurrentPos = mpPS->Tell();
1076 if ( nCurrentPos - 3 == mnLatestPush )
1078 mpPS->Seek( mnLatestPush );
1079 ImplWriteLine( " " );
1080 mpPS->Seek( mnLatestPush );
1082 else
1083 ImplWriteLine( "gr" );
1086 break;
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
1098 pSource = NULL;
1099 if ( nParseThis > nSize )
1100 nParseThis = nSize;
1102 if ( pSource && ( mnLevel == 1 ) )
1104 BYTE* pFound = ImplSearchEntry( pSource, (BYTE*)"%%LanguageLevel:", nParseThis - 10, 16 );
1105 if ( pFound )
1107 BYTE k, i = 10;
1108 pFound += 16;
1109 while ( --i )
1111 k = *pFound++;
1112 if ( ( k > '0' ) && ( k <= '9' ) )
1114 if ( k != '1' )
1116 bLevelConflict = TRUE;
1117 mnLevelWarning++;
1119 break;
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" );
1147 break;
1149 case META_TRANSPARENT_ACTION:
1151 // ImplLine( ( (const MetaTransparentAction*) pMA )->GetPolyPolygon() );
1153 break;
1155 case META_RASTEROP_ACTION:
1157 pMA->Execute( &rVDev );
1159 break;
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 );
1187 break;
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 ) )
1203 break;
1206 if( pGradAction )
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" );
1217 else
1219 const BYTE* pData = pA->GetData();
1220 if ( pData )
1222 SvMemoryStream aMemStm( (void*)pData, pA->GetDataSize(), STREAM_READ );
1223 sal_Bool bSkipSequence = sal_False;
1224 ByteString sSeqEnd;
1226 if( pA->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" ) )
1228 sSeqEnd = ByteString( "XPATHSTROKE_SEQ_END" );
1229 SvtGraphicStroke aStroke;
1230 aMemStm >> aStroke;
1232 Polygon aPath;
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;
1266 aMemStm >> 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();
1275 if ( nPolyCount )
1277 aFillColor = aFill.getFillColor();
1278 ImplWriteFillColor( PS_SPACE );
1279 for ( i = 0; i < nPolyCount; )
1281 ImplAddPath( aPolyPoly.GetObject( i ) );
1282 if ( ++i < nPolyCount )
1284 *mpPS << "p";
1285 mnCursorPos += 2;
1286 ImplExecMode( PS_RET );
1289 *mpPS << "p ef";
1290 mnCursorPos += 4;
1291 ImplExecMode( PS_RET );
1294 break;
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 :
1327 nBitmapCount++;
1328 nBitmapAction = nCurAction;
1330 break;
1331 case META_COMMENT_ACTION :
1333 if (((const MetaCommentAction*)pAction)->GetComment().Equals( "XPATHFILL_SEQ_END" ))
1334 bOk = sal_False;
1336 break;
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();
1349 else
1350 nCurAction = nCommentStartAction + 1;
1352 break;
1354 case SvtGraphicFill::fillGradient :
1355 aFill.getPath( aFillPath );
1356 break;
1358 case SvtGraphicFill::fillHatch :
1359 break;
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 ) )
1376 break;
1383 break;
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 );
1423 *mpPS << "ct ";
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 )
1451 if ( bFillColor )
1452 ImplRectFill( rRect );
1453 if ( bLineColor )
1455 double nWidth = rRect.GetWidth();
1456 double nHeight = rRect.GetHeight();
1458 ImplWriteLineColor( PS_SPACE );
1459 ImplMoveTo( rRect.TopLeft() );
1460 ImplWriteDouble( nWidth );
1461 *mpPS << "0 rl 0 ";
1462 ImplWriteDouble( nHeight );
1463 *mpPS << "rl ";
1464 ImplWriteDouble( nWidth );
1465 *mpPS << "neg 0 rl ";
1466 ImplClosePathDraw();
1468 *mpPS << (BYTE)10;
1469 mnCursorPos = 0;
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 );
1482 *mpPS << "0 rl 0 ";
1483 ImplWriteDouble( nHeight );
1484 *mpPS << "rl ";
1485 ImplWriteDouble( nWidth );
1486 *mpPS << "neg 0 rl ef ";
1487 *mpPS << "p ef";
1488 mnCursorPos += 2;
1489 ImplExecMode( PS_RET );
1492 //---------------------------------------------------------------------------------
1494 void PSWriter::ImplAddPath( const Polygon & rPolygon )
1496 USHORT i = 1;
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 );
1509 i += 3;
1511 else
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 )
1527 *mpPS << "p";
1528 mnCursorPos += 2;
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();
1551 if ( nPolyCount )
1553 if ( bFillColor || bTextOutline )
1555 if ( bTextOutline )
1556 ImplWriteTextColor( PS_SPACE );
1557 else
1558 ImplWriteFillColor( PS_SPACE );
1559 for ( i = 0; i < nPolyCount; )
1561 ImplAddPath( rPolyPoly.GetObject( i ) );
1562 if ( ++i < nPolyCount )
1564 *mpPS << "p";
1565 mnCursorPos += 2;
1566 ImplExecMode( PS_RET );
1569 *mpPS << "p ef";
1570 mnCursorPos += 4;
1571 ImplExecMode( PS_RET );
1573 if ( bLineColor )
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 )
1587 if ( bLineColor )
1589 ImplWriteLineColor( PS_SPACE );
1590 sal_uInt16 i, nPointCount = rPoly.GetSize();
1591 if ( nPointCount )
1593 if ( nPointCount > 1 )
1595 ImplMoveTo( rPoly.GetPoint( 0 ) );
1596 i = 1;
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 );
1605 i += 3;
1607 else
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 );
1615 else
1616 ImplPathDraw();
1621 //---------------------------------------------------------------------------------
1623 void PSWriter::ImplSetClipRegion( Region& rClipRegion )
1625 if ( !rClipRegion.IsEmpty() )
1627 Rectangle aRect;
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
1661 // color 24 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 )
1669 if ( !pBitmap )
1670 return;
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;
1685 Rectangle aRect;
1686 Region aRegion;
1688 if ( pMaskBitmap )
1690 bDoTrans = TRUE;
1691 while (TRUE)
1693 if ( mnLevel == 1 )
1695 if ( nHeight > 10 )
1696 nHeight = 8;
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 ) )
1703 nHeight >>= 1;
1704 if ( nHeight < 2 )
1705 return;
1706 continue;
1708 break;
1711 if ( nHeight != nHeightOrg )
1713 nYHeight = nYHeightOrg * nHeight / nHeightOrg;
1714 aTileBitmap.Crop( Rectangle( Point( 0, nHeightOrg - nHeightLeft ), Size( nWidth, nHeight ) ) );
1716 if ( bDoTrans )
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();
1746 if (!bDoTrans )
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 );
1755 *mpPS << "8 [";
1756 ImplWriteLong( nWidth );
1757 *mpPS << "0 0 ";
1758 ImplWriteLong( -nHeight );
1759 ImplWriteLong( 0 );
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 ) );
1773 *mpPS << (BYTE)10;
1775 else // Level 2
1777 if ( mbGrayScale )
1779 ImplWriteLine( "/DeviceGray setcolorspace" );
1780 ImplWriteLine( "<<" );
1781 ImplWriteLine( "/ImageType 1" );
1782 *mpPS << "/Width ";
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 );
1790 *mpPS << "0 0 ";
1791 ImplWriteLong( -nHeight );
1792 ImplWriteLong( 0 );
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 )
1803 StartCompression();
1804 for ( long y = 0; y < nHeight; y++ )
1806 for ( long x = 0; x < nWidth; x++ )
1808 Compress( (BYTE)pAcc->GetPixel( y, x ) );
1811 EndCompression();
1813 else
1815 for ( long y = 0; y < nHeight; y++ )
1817 for ( long x = 0; x < nWidth; x++ )
1819 ImplWriteHexByte( (BYTE)pAcc->GetPixel( y, x ) );
1824 else
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" );
1845 *mpPS << "/Width ";
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 );
1853 *mpPS << "0 0 ";
1854 ImplWriteLong( -nHeight );
1855 ImplWriteLong( 0);
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 )
1866 StartCompression();
1867 for ( long y = 0; y < nHeight; y++ )
1869 for ( long x = 0; x < nWidth; x++ )
1871 Compress( (BYTE)pAcc->GetPixel( y, x ) );
1874 EndCompression();
1876 else
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" );
1892 *mpPS << "/Width ";
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 );
1900 *mpPS << "0 0 ";
1901 ImplWriteLong( -nHeight );
1902 ImplWriteLong( 0 );
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 )
1913 StartCompression();
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() );
1924 EndCompression();
1926 else
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)
1943 if ( bDoTrans )
1944 ImplWriteLine( "gr" );
1945 else
1946 ImplWriteLine( "pom" );
1948 aTileBitmap.ReleaseAccess( pAcc );
1949 nHeightLeft -= nHeight;
1950 if ( nHeightLeft )
1952 nHeightLeft++;
1953 aSourcePos.Y() = (long) ( rPoint.Y() + ( nYHeightOrg * ( nHeightOrg - nHeightLeft ) ) / nHeightOrg );
1958 //---------------------------------------------------------------------------------
1960 void PSWriter::ImplWriteCharacter( sal_Char nChar )
1962 switch( nChar )
1964 case '(' :
1965 case ')' :
1966 case '\\' :
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();
1977 if ( nLen )
1979 USHORT i;
1980 if ( pDXArry )
1982 double nx = 0;
1984 for( i = 0; i < nLen; i++ )
1986 if ( i > 0 )
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" );
1995 else
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();
2010 if ( !nLen )
2011 return;
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;
2026 Point aPos( rPos );
2027 if ( nRotation )
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" );
2043 if ( nRotation )
2045 ImplWriteF( nRotation, 1 );
2046 *mpPS << "r ";
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" );
2086 else
2087 ImplDefineFont( "Times", "Italic" );
2089 maLastFont = maFont;
2090 aSize = maFont.GetSize();
2091 ImplWriteDouble( aSize.Height() );
2092 *mpPS << "sf ";
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 );
2102 if ( nRotation )
2104 *mpPS << "gs ";
2105 ImplWriteF( nRotation, 1 );
2106 *mpPS << "r ";
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 :
2119 case WEIGHT_BOLD :
2120 case WEIGHT_ULTRABOLD :
2121 case WEIGHT_BLACK :
2122 *mpPS << "-Bold";
2123 if ( maFont.GetItalic() != ITALIC_NONE )
2124 *mpPS << pItalic;
2125 break;
2126 default:
2127 if ( maFont.GetItalic() != ITALIC_NONE )
2128 *mpPS << pItalic;
2129 break;
2131 ImplWriteLine( " f" );
2134 //---------------------------------------------------------------------------------
2135 //---------------------------------------------------------------------------------
2136 //---------------------------------------------------------------------------------
2138 void PSWriter::ImplClosePathDraw( ULONG nMode )
2140 *mpPS << "pc";
2141 mnCursorPos += 2;
2142 ImplExecMode( nMode );
2145 void PSWriter::ImplPathDraw()
2147 *mpPS << "ps";
2148 mnCursorPos += 2;
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 )
2191 if ( mbGrayScale )
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 );
2198 else
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 )
2212 double nMul;
2213 switch ( rMapMode.GetMapUnit() )
2215 case MAP_PIXEL :
2216 case MAP_SYSFONT :
2217 case MAP_APPFONT :
2219 case MAP_100TH_MM :
2220 nMul = 1;
2221 break;
2222 case MAP_10TH_MM :
2223 nMul = 10;
2224 break;
2225 case MAP_MM :
2226 nMul = 100;
2227 break;
2228 case MAP_CM :
2229 nMul = 1000;
2230 break;
2231 case MAP_1000TH_INCH :
2232 nMul = 2.54;
2233 break;
2234 case MAP_100TH_INCH :
2235 nMul = 25.4;
2236 break;
2237 case MAP_10TH_INCH :
2238 nMul = 254;
2239 break;
2240 case MAP_INCH :
2241 nMul = 2540;
2242 break;
2243 case MAP_TWIP :
2244 nMul = 1.76388889;
2245 break;
2246 case MAP_POINT :
2247 nMul = 35.27777778;
2248 break;
2249 default:
2250 nMul = 1.0;
2251 break;
2253 return nMul;
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 )
2276 mnCursorPos = 0;
2277 *mpPS << (BYTE)0xa;
2278 return;
2281 if ( nMode & PS_SPACE )
2283 *mpPS << (BYTE)32;
2284 mnCursorPos++;
2286 if ( nMode & PS_RET )
2288 *mpPS << (BYTE)0xa;
2289 mnCursorPos = 0;
2293 //---------------------------------------------------------------------------------
2295 inline void PSWriter::ImplWriteLine( const char* pString, ULONG nMode )
2297 ULONG i = 0;
2298 while ( pString[ i ] )
2300 *mpPS << (BYTE)pString[ i++ ];
2302 mnCursorPos += 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 )
2321 eLineCap = eLCap;
2322 ImplWriteLong( (sal_Int32)eLineCap, PS_SPACE );
2323 ImplWriteLine( "lc", PS_SPACE );
2325 if ( eJoinType != eJoin )
2327 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 )
2378 sal_Int32 nLength;
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 );
2392 int zCount = 0;
2393 if ( nATemp )
2395 *mpPS << (BYTE)'.';
2396 mnCursorPos++;
2397 const ByteString aNumber2( ByteString::CreateFromInt32( nATemp ) );
2399 sal_Int16 n, nLen = aNumber2.Len();
2400 if ( nLen < 8 )
2402 mnCursorPos += 6 - nLen;
2403 for ( n = 0; n < ( 5 - nLen ); n++ )
2405 *mpPS << (BYTE)'0';
2408 mnCursorPos += nLen;
2409 for ( n = 0; n < nLen; n++ )
2411 *mpPS << aNumber2.GetChar( n );
2412 zCount--;
2413 if ( aNumber2.GetChar( n ) != '0' )
2414 zCount = 0;
2416 if ( zCount )
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 )
2428 if ( nNumber < 0 )
2430 *mpPS << (BYTE)'-';
2431 nNumber = -nNumber;
2432 mnCursorPos++;
2434 const ByteString aScaleFactor( ByteString::CreateFromInt32( nNumber ) );
2435 ULONG nLen = aScaleFactor.Len();
2436 long nStSize = ( nCount + 1 ) - nLen;
2437 if ( nStSize >= 1 )
2439 *mpPS << (BYTE)'0';
2440 mnCursorPos++;
2442 if ( nStSize >= 2 )
2444 *mpPS << (BYTE)'.';
2445 for ( long i = 1; i < nStSize; i++ )
2447 *mpPS << (BYTE)'0';
2448 mnCursorPos++;
2451 mnCursorPos += nLen;
2452 for( USHORT n = 0UL; n < nLen; n++ )
2454 if ( n == nLen - nCount )
2456 *mpPS << (BYTE)'.';
2457 mnCursorPos++;
2459 *mpPS << aScaleFactor.GetChar( n );
2461 ImplExecMode( nMode );
2464 //---------------------------------------------------------------------------------
2466 void PSWriter::ImplWriteByte( BYTE nNumb, ULONG nMode )
2468 *mpPS << ( nNumb );
2469 mnCursorPos++;
2470 ImplExecMode( nMode );
2473 //---------------------------------------------------------------------------------
2475 void PSWriter::ImplWriteHexByte( BYTE nNumb, ULONG nMode )
2477 if ( ( nNumb >> 4 ) > 9 )
2478 *mpPS << (BYTE)( ( nNumb >> 4 ) + 'A' - 10 );
2479 else
2480 *mpPS << (BYTE)( ( nNumb >> 4 ) + '0' );
2482 if ( ( nNumb & 0xf ) > 9 )
2483 *mpPS << (BYTE)( ( nNumb & 0xf ) + 'A' - 10 );
2484 else
2485 *mpPS << (BYTE)( ( nNumb & 0xf ) + '0' );
2486 mnCursorPos += 2;
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 ) );
2509 dwShift <<= 8;
2510 nOffset += 8;
2512 if ( nCode == 257 && nOffset != 32 )
2513 ImplWriteHexByte( (BYTE)( dwShift >> 24 ) );
2516 // ------------------------------------------------------------------------
2518 void PSWriter::StartCompression()
2520 USHORT i;
2521 nDataSize = 8;
2523 nClearCode = 1 << nDataSize;
2524 nEOICode = nClearCode + 1;
2525 nTableSize = nEOICode + 1;
2526 nCodeSize = nDataSize + 1;
2528 nOffset = 32; // anzahl freier bits in dwShift
2529 dwShift = 0;
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 );
2538 pPrefix = NULL;
2539 WriteBits( nClearCode, nCodeSize );
2542 // ------------------------------------------------------------------------
2544 void PSWriter::Compress( BYTE nCompThis )
2546 PSLZWCTreeNode* p;
2547 USHORT i;
2548 BYTE nV;
2550 if( !pPrefix )
2552 pPrefix = pTable + nCompThis;
2554 else
2556 nV = nCompThis;
2557 for( p = pPrefix->pFirstChild; p != NULL; p = p->pBrother )
2559 if ( p->nValue == nV )
2560 break;
2563 if( p )
2564 pPrefix = p;
2565 else
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;
2579 else
2581 if( nTableSize == (USHORT)( ( 1 << nCodeSize ) - 1 ) )
2582 nCodeSize++;
2584 p = pTable + ( nTableSize++ );
2585 p->pBrother = pPrefix->pFirstChild;
2586 pPrefix->pFirstChild = p;
2587 p->nValue = nV;
2588 p->pFirstChild = NULL;
2591 pPrefix = pTable + nV;
2596 // ------------------------------------------------------------------------
2598 void PSWriter::EndCompression()
2600 if( pPrefix )
2601 WriteBits( pPrefix->nCode, nCodeSize );
2603 WriteBits( nEOICode, nCodeSize );
2604 delete[] pTable;
2607 // ------------------------------------------------------------------------
2609 BYTE* PSWriter::ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
2611 while ( nComp-- >= nSize )
2613 ULONG i;
2614 for ( i = 0; i < nSize; i++ )
2616 if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
2617 break;
2619 if ( i == nSize )
2620 return pSource;
2621 pSource++;
2623 return NULL;
2626 // ------------------------------------------------------------------------
2628 BOOL PSWriter::ImplGetBoundingBox( double* nNumb, BYTE* pSource, ULONG nSize )
2630 BOOL bRetValue = FALSE;
2631 ULONG nBytesRead;
2633 if ( nSize < 256 ) // we assume that the file is greater than 256 bytes
2634 return FALSE;
2636 if ( nSize < POSTSCRIPT_BOUNDINGSEARCH )
2637 nBytesRead = nSize;
2638 else
2639 nBytesRead = POSTSCRIPT_BOUNDINGSEARCH;
2641 BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nBytesRead, 14 );
2642 if ( pDest )
2644 int nSecurityCount = 100; // only 100 bytes following the bounding box will be checked
2645 nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
2646 pDest += 14;
2647 for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
2649 int nDivision = 1;
2650 BOOL bDivision = FALSE;
2651 BOOL bNegative = FALSE;
2652 BOOL bValid = TRUE;
2654 while ( ( --nSecurityCount ) && ( ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) )
2655 pDest++;
2656 BYTE nByte = *pDest;
2657 while ( nSecurityCount && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
2659 switch ( nByte )
2661 case '.' :
2662 if ( bDivision )
2663 bValid = FALSE;
2664 else
2665 bDivision = TRUE;
2666 break;
2667 case '-' :
2668 bNegative = TRUE;
2669 break;
2670 default :
2671 if ( ( nByte < '0' ) || ( nByte > '9' ) )
2672 nSecurityCount = 1; // error parsing the bounding box values
2673 else if ( bValid )
2675 if ( bDivision )
2676 nDivision*=10;
2677 nNumb[i] *= 10;
2678 nNumb[i] += nByte - '0';
2680 break;
2682 nSecurityCount--;
2683 nByte = *(++pDest);
2685 if ( bNegative )
2686 nNumb[i] = -nNumb[i];
2687 if ( bDivision && ( nDivision != 1 ) )
2688 nNumb[i] /= nDivision;
2690 if ( nSecurityCount)
2691 bRetValue = TRUE;
2693 return bRetValue;
2696 //================== GraphicExport - die exportierte Funktion ================
2698 extern "C" BOOL __LOADONCALLAPI GraphicExport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem, BOOL)
2700 PSWriter aPSWriter;
2701 return aPSWriter.WritePS( rGraphic, rStream, pFilterConfigItem );
2704 //---------------------------------------------------------------------------------
2706 extern "C" BOOL __LOADONCALLAPI DoExportDialog( FltCallDialogParameter& rPara )
2708 BOOL bRet = FALSE;
2710 if ( rPara.pWindow )
2712 ByteString aResMgrName( "eps" );
2713 ResMgr* pResMgr;
2715 pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
2717 if( pResMgr )
2719 rPara.pResMgr = pResMgr;
2720 bRet = ( DlgExportEPS( rPara ).Execute() == RET_OK );
2721 delete pResMgr;
2723 else
2724 bRet = TRUE;
2727 return bRet;
2730 //================== ein bischen Muell fuer Windows ==========================
2731 #ifndef GCC
2732 #endif
2734 #ifdef WIN
2736 static HINSTANCE hDLLInst = 0; // HANDLE der DLL
2738 extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
2740 #ifndef WNT
2741 if ( nHeap )
2742 UnlockData( 0 );
2743 #endif
2745 hDLLInst = hDLL;
2747 return TRUE;
2750 extern "C" int CALLBACK WEP( int )
2752 return 1;
2755 #endif