Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <tools/solar.h>
31 : : #include <tools/stream.hxx>
32 : : #include <tools/poly.hxx>
33 : : #include <vcl/svapp.hxx>
34 : : #include <vcl/metaact.hxx>
35 : : #include <vcl/graph.hxx>
36 : : #include <vcl/bmpacc.hxx>
37 : : #include <vcl/region.hxx>
38 : : #include <vcl/metric.hxx>
39 : : #include <vcl/font.hxx>
40 : : #include <vcl/virdev.hxx>
41 : : #include <vcl/msgbox.hxx>
42 : : #include <vcl/cvtgrf.hxx>
43 : : #include <vcl/gradient.hxx>
44 : : #include <unotools/configmgr.hxx>
45 : : #include <svl/solar.hrc>
46 : : #include <svtools/fltcall.hxx>
47 : : #include <svtools/FilterConfigItem.hxx>
48 : : #include <vcl/graphictools.hxx>
49 : : #include <vcl/rendergraphicrasterizer.hxx>
50 : : #include "strings.hrc"
51 : :
52 : : #include <math.h>
53 : :
54 : : using namespace ::com::sun::star::uno;
55 : :
56 : : #define POSTSCRIPT_BOUNDINGSEARCH 0x1000 // we only try to get the BoundingBox
57 : : // in the first 4096 bytes
58 : :
59 : : #define EPS_PREVIEW_TIFF 1
60 : : #define EPS_PREVIEW_EPSI 2
61 : :
62 : : #define PS_LINESIZE 70 // maximum number of characters a line in the output
63 : :
64 : : #define PS_NONE 0 // formating mode: action which is inserted behind the output
65 : : #define PS_SPACE 1
66 : : #define PS_RET 2
67 : : #define PS_WRAP 4
68 : :
69 : : // -----------------------------Feld-Typen-------------------------------
70 : :
71 : 0 : struct ChrSet
72 : : {
73 : : struct ChrSet * pSucc;
74 : : sal_uInt8 nSet;
75 : : String aName;
76 : : FontWeight eWeight;
77 : : };
78 : :
79 : 0 : struct StackMember
80 : : {
81 : : struct StackMember * pSucc;
82 : : Color aGlobalCol;
83 : : sal_Bool bLineCol;
84 : : Color aLineCol;
85 : : sal_Bool bFillCol;
86 : : Color aFillCol;
87 : : Color aTextCol;
88 : : sal_Bool bTextFillCol;
89 : : Color aTextFillCol;
90 : : Color aBackgroundCol;
91 : : Font aFont;
92 : : TextAlign eTextAlign;
93 : :
94 : : double fLineWidth;
95 : : double fMiterLimit;
96 : : SvtGraphicStroke::CapType eLineCap;
97 : : SvtGraphicStroke::JoinType eJoinType;
98 : : SvtGraphicStroke::DashArray aDashArray;
99 : : };
100 : :
101 : : struct PSLZWCTreeNode
102 : : {
103 : :
104 : : PSLZWCTreeNode* pBrother; // naechster Knoten, der den selben Vater hat
105 : : PSLZWCTreeNode* pFirstChild; // erster Sohn
106 : : sal_uInt16 nCode; // Der Code fuer den String von Pixelwerten, der sich ergibt, wenn
107 : : sal_uInt16 nValue; // Der Pixelwert
108 : : };
109 : :
110 : : class PSWriter
111 : : {
112 : : private:
113 : : sal_Bool mbStatus;
114 : : sal_uLong mnLevelWarning; // number of embedded eps files which was not exported
115 : : sal_uLong mnLastPercent; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
116 : : sal_uInt32 mnLatestPush; // offset auf streamposition, an der zuletzt gepusht wurde
117 : :
118 : : long mnLevel; // dialog options
119 : : sal_Bool mbGrayScale;
120 : : sal_Bool mbCompression;
121 : : sal_Int32 mnPreview;
122 : : sal_Int32 mnTextMode;
123 : :
124 : : SvStream* mpPS;
125 : : const GDIMetaFile* pMTF;
126 : : GDIMetaFile* pAMTF; // only created if Graphics is not a Metafile
127 : : VirtualDevice aVDev;
128 : :
129 : : double nBoundingX1; // this represents the bounding box
130 : : double nBoundingY1;
131 : : double nBoundingX2;
132 : : double nBoundingY2;
133 : : //
134 : : StackMember* pGDIStack;
135 : : sal_uLong mnCursorPos; // aktuelle Cursorposition im Output
136 : : Color aColor; // aktuelle Farbe die fuer den Output benutzt wird
137 : : sal_Bool bLineColor;
138 : : Color aLineColor; // aktuelle GDIMetafile Farbeinstellungen
139 : : sal_Bool bFillColor; //
140 : : Color aFillColor; //
141 : : Color aTextColor; //
142 : : sal_Bool bTextFillColor; //
143 : : Color aTextFillColor; //
144 : : Color aBackgroundColor; //
145 : : sal_Bool bRegionChanged;
146 : : TextAlign eTextAlign; //
147 : :
148 : : double fLineWidth;
149 : : double fMiterLimit;
150 : : SvtGraphicStroke::CapType eLineCap;
151 : : SvtGraphicStroke::JoinType eJoinType;
152 : : SvtGraphicStroke::DashArray aDashArray;
153 : :
154 : : Font maFont;
155 : : Font maLastFont;
156 : : sal_uInt8 nChrSet;
157 : : ChrSet* pChrSetList; // Liste der Character-Sets
158 : : sal_uInt8 nNextChrSetId; // die erste unbenutzte ChrSet-Id
159 : :
160 : : PSLZWCTreeNode* pTable; // LZW compression data
161 : : PSLZWCTreeNode* pPrefix; // the compression is as same as the TIFF compression
162 : : sal_uInt16 nDataSize;
163 : : sal_uInt16 nClearCode;
164 : : sal_uInt16 nEOICode;
165 : : sal_uInt16 nTableSize;
166 : : sal_uInt16 nCodeSize;
167 : : sal_uLong nOffset;
168 : : sal_uLong dwShift;
169 : :
170 : : com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
171 : :
172 : : void ImplWriteProlog( const Graphic* pPreviewEPSI = NULL );
173 : : void ImplWriteEpilog();
174 : : void ImplWriteActions( const GDIMetaFile& rMtf, VirtualDevice& rVDev );
175 : :
176 : : // this method makes LF's, space inserting and word wrapping as used in all nMode
177 : : // parameters
178 : : inline void ImplExecMode( sal_uLong nMode );
179 : :
180 : : // writes char[] + LF to stream
181 : : inline void ImplWriteLine( const char*, sal_uLong nMode = PS_RET );
182 : :
183 : : // writes ( nNumb / 10^nCount ) in ASCII format to stream
184 : : void ImplWriteF( sal_Int32 nNumb, sal_uLong nCount = 3, sal_uLong nMode = PS_SPACE );
185 : :
186 : : // writes a double in ASCII format to stream
187 : : void ImplWriteDouble( double, sal_uLong nMode = PS_SPACE );
188 : :
189 : : // writes a long in ASCII format to stream
190 : : void ImplWriteLong( sal_Int32 nNumb, sal_uLong nMode = PS_SPACE );
191 : :
192 : : // writes a byte in ASCII format to stream
193 : : void ImplWriteByte( sal_uInt8 nNumb, sal_uLong nMode = PS_SPACE );
194 : :
195 : : // writes a byte in ASCII (hex) format to stream
196 : : void ImplWriteHexByte( sal_uInt8 nNumb, sal_uLong nMode = PS_WRAP );
197 : :
198 : : // writes nNumb as number from 0.000 till 1.000 in ASCII format to stream
199 : : void ImplWriteB1( sal_uInt8 nNumb, sal_uLong nMode = PS_SPACE );
200 : :
201 : : inline void ImplWritePoint( const Point&, sal_uInt32 nMode = PS_SPACE );
202 : : void ImplMoveTo( const Point&, sal_uInt32 nMode = PS_SPACE );
203 : : void ImplLineTo( const Point&, sal_uInt32 nMode = PS_SPACE );
204 : : void ImplCurveTo( const Point& rP1, const Point& rP2, const Point& rP3, sal_uInt32 nMode = PS_SPACE );
205 : : void ImplTranslate( const double& fX, const double& fY, sal_uInt32 nMode = PS_RET );
206 : : void ImplScale( const double& fX, const double& fY, sal_uInt32 nMode = PS_RET );
207 : :
208 : : void ImplWriteLine( const Polygon & rPolygon );
209 : : void ImplAddPath( const Polygon & rPolygon );
210 : : void ImplWriteLineInfo( double fLineWidth, double fMiterLimit, SvtGraphicStroke::CapType eLineCap,
211 : : SvtGraphicStroke::JoinType eJoinType, SvtGraphicStroke::DashArray& rDashArray );
212 : : void ImplWriteLineInfo( const LineInfo& rLineInfo );
213 : : void ImplRect( const Rectangle & rRectangle );
214 : : void ImplRectFill ( const Rectangle & rRectangle );
215 : : void ImplWriteGradient( const PolyPolygon& rPolyPoly, const Gradient& rGradient, VirtualDevice& rVDev );
216 : : void ImplIntersect( const PolyPolygon& rPolyPoly );
217 : : void ImplPolyPoly( const PolyPolygon & rPolyPolygon, sal_Bool bTextOutline = sal_False );
218 : : void ImplPolyLine( const Polygon & rPolygon );
219 : :
220 : : void ImplSetClipRegion( Region& rRegion );
221 : : void ImplBmp( Bitmap*, Bitmap*, const Point &, double nWidth, double nHeight );
222 : : void ImplText( const String& rUniString, const Point& rPos, const sal_Int32* pDXArry, sal_Int32 nWidth, VirtualDevice& rVDev );
223 : : void ImplSetAttrForText( const Point & rPoint );
224 : : void ImplWriteCharacter( sal_Char );
225 : : void ImplWriteString( const rtl::OString&, VirtualDevice& rVDev, const sal_Int32* pDXArry = NULL, sal_Bool bStretch = sal_False );
226 : : void ImplDefineFont( const char*, const char* );
227 : :
228 : : void ImplClosePathDraw( sal_uLong nMode = PS_RET );
229 : : void ImplPathDraw();
230 : :
231 : : inline void ImplWriteLineColor( sal_uLong nMode = PS_RET );
232 : : inline void ImplWriteFillColor( sal_uLong nMode = PS_RET );
233 : : inline void ImplWriteTextColor( sal_uLong nMode = PS_RET );
234 : : inline void ImplWriteTextFillColor( sal_uLong nMode = PS_RET );
235 : : void ImplWriteColor( sal_uLong nMode );
236 : :
237 : : double ImplGetScaling( const MapMode& );
238 : : void ImplGetMapMode( const MapMode& );
239 : : sal_Bool ImplGetBoundingBox( double* nNumb, sal_uInt8* pSource, sal_uLong nSize );
240 : : sal_uInt8* ImplSearchEntry( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nComp, sal_uLong nSize );
241 : : // LZW methods
242 : : void StartCompression();
243 : : void Compress( sal_uInt8 nSrc );
244 : : void EndCompression();
245 : : inline void WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen );
246 : :
247 : : public:
248 : : sal_Bool WritePS( const Graphic& rGraphic, SvStream& rTargetStream, FilterConfigItem* );
249 : : PSWriter();
250 : : ~PSWriter();
251 : : };
252 : :
253 : : //========================== Methoden von PSWriter ==========================
254 : :
255 : : //---------------------------------------------------------------------------------
256 : :
257 : 0 : PSWriter::PSWriter()
258 : : {
259 : 0 : pAMTF = NULL;
260 : 0 : }
261 : :
262 : :
263 : 0 : PSWriter::~PSWriter()
264 : : {
265 : 0 : delete pAMTF;
266 : 0 : }
267 : :
268 : : //---------------------------------------------------------------------------------
269 : :
270 : 0 : sal_Bool PSWriter::WritePS( const Graphic& rGraphic, SvStream& rTargetStream, FilterConfigItem* pFilterConfigItem )
271 : : {
272 : 0 : sal_uInt32 nStreamPosition = 0, nPSPosition = 0; // -Wall warning, unset, check
273 : :
274 : 0 : mbStatus = sal_True;
275 : 0 : mnPreview = 0;
276 : 0 : mnLevelWarning = 0;
277 : 0 : mnLastPercent = 0;
278 : 0 : mnLatestPush = 0xEFFFFFFE;
279 : :
280 : 0 : if ( pFilterConfigItem )
281 : : {
282 : 0 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
283 : 0 : if ( xStatusIndicator.is() )
284 : : {
285 : 0 : rtl::OUString aMsg;
286 : 0 : xStatusIndicator->start( aMsg, 100 );
287 : : }
288 : : }
289 : :
290 : 0 : mpPS = &rTargetStream;
291 : 0 : mpPS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
292 : :
293 : : // default values for the dialog options
294 : 0 : mnLevel = 2;
295 : 0 : mbGrayScale = sal_False;
296 : : #ifdef UNX // don't compress by default on unix as ghostscript is unable to read LZW compressed eps
297 : 0 : mbCompression = sal_False;
298 : : #else
299 : : mbCompression = sal_True;
300 : : #endif
301 : 0 : mnTextMode = 0; // default0 : export glyph outlines
302 : :
303 : : // try to get the dialog selection
304 : 0 : if ( pFilterConfigItem )
305 : : {
306 : : ResMgr* pResMgr;
307 : :
308 : 0 : pResMgr = ResMgr::CreateResMgr( "eps", Application::GetSettings().GetUILocale() );
309 : :
310 : 0 : if( pResMgr )
311 : : {
312 : 0 : String aPreviewStr( RTL_CONSTASCII_USTRINGPARAM( "Preview" ) );
313 : 0 : String aVersionStr( RTL_CONSTASCII_USTRINGPARAM( "Version" ) );
314 : 0 : String aColorStr( RTL_CONSTASCII_USTRINGPARAM( "ColorFormat" ) );
315 : 0 : String aComprStr( RTL_CONSTASCII_USTRINGPARAM( "CompressionMode" ) );
316 : : #ifdef UNX // don't put binary tiff preview ahead of postscript code by default on unix as ghostscript is unable to read it
317 : 0 : mnPreview = pFilterConfigItem->ReadInt32( aPreviewStr, 0 );
318 : : #else
319 : : mnPreview = pFilterConfigItem->ReadInt32( aPreviewStr, 1 );
320 : : #endif
321 : 0 : mnLevel = pFilterConfigItem->ReadInt32( aVersionStr, 2 );
322 : 0 : if ( mnLevel != 1 )
323 : 0 : mnLevel = 2;
324 : 0 : mbGrayScale = pFilterConfigItem->ReadInt32( aColorStr, 1 ) == 2;
325 : : #ifdef UNX // don't compress by default on unix as ghostscript is unable to read LZW compressed eps
326 : 0 : mbCompression = pFilterConfigItem->ReadInt32( aComprStr, 0 ) != 0;
327 : : #else
328 : : mbCompression = pFilterConfigItem->ReadInt32( aComprStr, 1 ) == 1;
329 : : #endif
330 : 0 : String sTextMode( RTL_CONSTASCII_USTRINGPARAM( "TextMode" ) );
331 : 0 : mnTextMode = pFilterConfigItem->ReadInt32( sTextMode, 0 );
332 : 0 : if ( mnTextMode > 2 )
333 : 0 : mnTextMode = 0;
334 : 0 : delete pResMgr;
335 : : }
336 : : }
337 : :
338 : : // compression is not available for Level 1
339 : 0 : if ( mnLevel == 1 )
340 : : {
341 : 0 : mbGrayScale = sal_True;
342 : 0 : mbCompression = sal_False;
343 : : }
344 : :
345 : 0 : if ( mnPreview & EPS_PREVIEW_TIFF )
346 : : {
347 : 0 : rTargetStream << (sal_uInt32)0xC6D3D0C5;
348 : 0 : nStreamPosition = rTargetStream.Tell();
349 : 0 : rTargetStream << (sal_uInt32)0 << (sal_uInt32)0 << (sal_uInt32)0 << (sal_uInt32)0
350 : 0 : << nStreamPosition + 26 << (sal_uInt32)0 << (sal_uInt16)0xffff;
351 : :
352 : : sal_uInt32 nErrCode;
353 : 0 : if ( mbGrayScale )
354 : : {
355 : 0 : BitmapEx aTempBitmapEx( rGraphic.GetBitmapEx() );
356 : 0 : aTempBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
357 : 0 : nErrCode = GraphicConverter::Export( rTargetStream, aTempBitmapEx, CVT_TIF ) ;
358 : : }
359 : : else
360 : 0 : nErrCode = GraphicConverter::Export( rTargetStream, rGraphic, CVT_TIF ) ;
361 : :
362 : 0 : if ( nErrCode == ERRCODE_NONE )
363 : : {
364 : 0 : rTargetStream.Seek( STREAM_SEEK_TO_END );
365 : 0 : nPSPosition = rTargetStream.Tell();
366 : 0 : rTargetStream.Seek( nStreamPosition + 20 );
367 : 0 : rTargetStream << nPSPosition - 30; // size of tiff gfx
368 : 0 : rTargetStream.Seek( nPSPosition );
369 : : }
370 : : else
371 : : {
372 : 0 : mnPreview &=~ EPS_PREVIEW_TIFF;
373 : 0 : rTargetStream.Seek( nStreamPosition - 4 );
374 : : }
375 : : }
376 : :
377 : : // global default value setting
378 : : ChrSet* pCS;
379 : : StackMember* pGS;
380 : :
381 : 0 : if (rGraphic.GetType() == GRAPHIC_GDIMETAFILE)
382 : 0 : pMTF = &rGraphic.GetGDIMetaFile();
383 : 0 : else if (rGraphic.GetGDIMetaFile().GetActionSize())
384 : 0 : pMTF = pAMTF = new GDIMetaFile( rGraphic.GetGDIMetaFile() );
385 : : else
386 : : {
387 : 0 : Bitmap aBmp( rGraphic.GetBitmap() );
388 : 0 : pAMTF = new GDIMetaFile();
389 : 0 : VirtualDevice aTmpVDev;
390 : 0 : pAMTF->Record( &aTmpVDev );
391 : 0 : aTmpVDev.DrawBitmap( Point(), aBmp );
392 : 0 : pAMTF->Stop();
393 : 0 : pAMTF->SetPrefSize( aBmp.GetSizePixel() );
394 : 0 : pMTF = pAMTF;
395 : : }
396 : 0 : aVDev.SetMapMode( pMTF->GetPrefMapMode() );
397 : 0 : nBoundingX1 = nBoundingY1 = 0;
398 : 0 : nBoundingX2 = pMTF->GetPrefSize().Width();
399 : 0 : nBoundingY2 = pMTF->GetPrefSize().Height();
400 : :
401 : 0 : pGDIStack = NULL;
402 : 0 : aColor = Color( COL_TRANSPARENT );
403 : 0 : bLineColor = sal_True;
404 : 0 : aLineColor = Color( COL_BLACK );
405 : 0 : bFillColor = sal_True;
406 : 0 : aFillColor = Color( COL_WHITE );
407 : 0 : bTextFillColor = sal_True;
408 : 0 : aTextFillColor = Color( COL_BLACK );
409 : 0 : fLineWidth = 1;
410 : 0 : fMiterLimit = 15; // use same limit as most graphic systems and basegfx
411 : 0 : eLineCap = SvtGraphicStroke::capButt;
412 : 0 : eJoinType = SvtGraphicStroke::joinMiter;
413 : 0 : aBackgroundColor = Color( COL_WHITE );
414 : 0 : eTextAlign = ALIGN_BASELINE;
415 : 0 : bRegionChanged = sal_False;
416 : :
417 : 0 : nChrSet = 0x00;
418 : 0 : pChrSetList = NULL;
419 : 0 : nNextChrSetId = 1;
420 : :
421 : 0 : if( pMTF->GetActionSize() )
422 : : {
423 : 0 : ImplWriteProlog( ( mnPreview & EPS_PREVIEW_EPSI ) ? &rGraphic : NULL );
424 : 0 : mnCursorPos = 0;
425 : 0 : ImplWriteActions( *pMTF, aVDev );
426 : 0 : ImplWriteEpilog();
427 : 0 : if ( mnPreview & EPS_PREVIEW_TIFF )
428 : : {
429 : 0 : sal_uInt32 nPosition = rTargetStream.Tell();
430 : 0 : rTargetStream.Seek( nStreamPosition );
431 : 0 : rTargetStream << nPSPosition;
432 : 0 : rTargetStream << nPosition - nPSPosition;
433 : 0 : rTargetStream.Seek( nPosition );
434 : : }
435 : 0 : while( pChrSetList )
436 : : {
437 : 0 : pCS=pChrSetList;
438 : 0 : pChrSetList=pCS->pSucc;
439 : 0 : delete pCS;
440 : : }
441 : 0 : while( pGDIStack )
442 : : {
443 : 0 : pGS=pGDIStack;
444 : 0 : pGDIStack=pGS->pSucc;
445 : 0 : delete pGS;
446 : : }
447 : : }
448 : : else
449 : 0 : mbStatus = sal_False;
450 : :
451 : 0 : if ( mbStatus && mnLevelWarning && pFilterConfigItem )
452 : : {
453 : : ResMgr* pResMgr;
454 : 0 : pResMgr = ResMgr::CreateResMgr( "eps", Application::GetSettings().GetUILocale() );
455 : 0 : if( pResMgr )
456 : : {
457 : 0 : InfoBox aInfoBox( NULL, String( ResId( KEY_VERSION_CHECK, *pResMgr ) ) );
458 : 0 : aInfoBox.Execute();
459 : 0 : delete pResMgr;
460 : : }
461 : : }
462 : :
463 : 0 : if ( xStatusIndicator.is() )
464 : 0 : xStatusIndicator->end();
465 : :
466 : 0 : return mbStatus;
467 : : }
468 : :
469 : : //---------------------------------------------------------------------------------
470 : :
471 : 0 : void PSWriter::ImplWriteProlog( const Graphic* pPreview )
472 : : {
473 : 0 : ImplWriteLine( "%!PS-Adobe-3.0 EPSF-3.0 " );
474 : 0 : *mpPS << "%%BoundingBox: "; // BoundingBox
475 : 0 : ImplWriteLong( 0 );
476 : 0 : ImplWriteLong( 0 );
477 : 0 : Size aSizePoint = Application::GetDefaultDevice()->LogicToLogic( pMTF->GetPrefSize(),
478 : 0 : pMTF->GetPrefMapMode(), MAP_POINT );
479 : 0 : ImplWriteLong( aSizePoint.Width() );
480 : 0 : ImplWriteLong( aSizePoint.Height() ,PS_RET );
481 : 0 : ImplWriteLine( "%%Pages: 0" );
482 : 0 : ::rtl::OUStringBuffer aCreator;
483 : 0 : aCreator.appendAscii( RTL_CONSTASCII_STRINGPARAM( "%%Creator: " ) );
484 : 0 : aCreator.append( utl::ConfigManager::getProductName() );
485 : 0 : aCreator.appendAscii( RTL_CONSTASCII_STRINGPARAM( " " ) );
486 : 0 : aCreator.append( utl::ConfigManager::getProductVersion() );
487 : 0 : ImplWriteLine( ::rtl::OUStringToOString( aCreator.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr() );
488 : 0 : ImplWriteLine( "%%Title: none" );
489 : 0 : ImplWriteLine( "%%CreationDate: none" );
490 : :
491 : : // defaults
492 : :
493 : 0 : *mpPS << "%%LanguageLevel: "; // Language level
494 : 0 : ImplWriteLong( mnLevel, PS_RET );
495 : 0 : if ( !mbGrayScale && mnLevel == 1 )
496 : 0 : ImplWriteLine( "%%Extensions: CMYK" ); // CMYK extension is to set in color mode in level 1
497 : 0 : ImplWriteLine( "%%EndComments" );
498 : 0 : if ( pPreview && aSizePoint.Width() && aSizePoint.Height() )
499 : : {
500 : 0 : Size aSizeBitmap( ( aSizePoint.Width() + 7 ) & ~7, aSizePoint.Height() );
501 : 0 : Bitmap aTmpBitmap( pPreview->GetBitmap() );
502 : 0 : aTmpBitmap.Scale( aSizeBitmap, BMP_SCALE_BEST );
503 : 0 : aTmpBitmap.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
504 : 0 : BitmapReadAccess* pAcc = aTmpBitmap.AcquireReadAccess();
505 : 0 : if ( pAcc )
506 : : {
507 : 0 : *mpPS << "%%BeginPreview: "; // BoundingBox
508 : 0 : ImplWriteLong( aSizeBitmap.Width() );
509 : 0 : ImplWriteLong( aSizeBitmap.Height() );
510 : 0 : *mpPS << "1 ";
511 : 0 : sal_Int32 nLines = aSizeBitmap.Width() / 312;
512 : 0 : if ( ( nLines * 312 ) != aSizeBitmap.Width() )
513 : 0 : nLines++;
514 : 0 : nLines *= aSizeBitmap.Height();
515 : 0 : ImplWriteLong( nLines );
516 : : char nVal;
517 : 0 : sal_Int32 nX, nY, nCount2, nCount = 4;
518 : 0 : const BitmapColor aBlack( pAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
519 : 0 : for ( nY = 0; nY < aSizeBitmap.Height(); nY++ )
520 : : {
521 : 0 : nCount2 = 0;
522 : 0 : nVal = 0;
523 : 0 : for ( nX = 0; nX < aSizeBitmap.Width(); nX++ )
524 : : {
525 : 0 : if ( !nCount2 )
526 : : {
527 : 0 : ImplExecMode( PS_RET );
528 : 0 : *mpPS << "%";
529 : 0 : nCount2 = 312;
530 : : }
531 : 0 : nVal <<= 1;
532 : 0 : if ( pAcc->GetPixel( nY, nX ) == aBlack )
533 : 0 : nVal |= 1;
534 : 0 : if ( ! ( --nCount ) )
535 : : {
536 : 0 : if ( nVal > 9 )
537 : 0 : nVal += 'A' - 10;
538 : : else
539 : 0 : nVal += '0';
540 : 0 : *mpPS << nVal;
541 : 0 : nVal = 0;
542 : 0 : nCount += 4;
543 : : }
544 : 0 : nCount2--;
545 : : }
546 : : }
547 : 0 : aTmpBitmap.ReleaseAccess( pAcc );
548 : 0 : ImplExecMode( PS_RET );
549 : 0 : ImplWriteLine( "%%EndPreview" );
550 : 0 : }
551 : : }
552 : 0 : ImplWriteLine( "%%BeginProlog" );
553 : 0 : ImplWriteLine( "%%BeginResource: procset SDRes-Prolog 1.0 0" );
554 : :
555 : : // BEGIN EPSF
556 : 0 : ImplWriteLine( "/b4_inc_state save def\n/dict_count countdictstack def\n/op_count count 1 sub def\nuserdict begin" );
557 : 0 : ImplWriteLine( "0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath" );
558 : 0 : ImplWriteLine( "/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if" );
559 : :
560 : 0 : ImplWriteLine( "/bdef {bind def} bind def" ); // der neue operator bdef wird erzeugt
561 : 0 : if ( mbGrayScale )
562 : 0 : ImplWriteLine( "/c {setgray} bdef" );
563 : : else
564 : 0 : ImplWriteLine( "/c {setrgbcolor} bdef" );
565 : 0 : ImplWriteLine( "/l {neg lineto} bdef" );
566 : 0 : ImplWriteLine( "/rl {neg rlineto} bdef" );
567 : 0 : ImplWriteLine( "/lc {setlinecap} bdef" );
568 : 0 : ImplWriteLine( "/lj {setlinejoin} bdef" );
569 : 0 : ImplWriteLine( "/lw {setlinewidth} bdef" );
570 : 0 : ImplWriteLine( "/ml {setmiterlimit} bdef" );
571 : 0 : ImplWriteLine( "/ld {setdash} bdef" );
572 : 0 : ImplWriteLine( "/m {neg moveto} bdef" );
573 : 0 : ImplWriteLine( "/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef" );
574 : 0 : ImplWriteLine( "/r {rotate} bdef" );
575 : 0 : ImplWriteLine( "/t {neg translate} bdef" );
576 : 0 : ImplWriteLine( "/s {scale} bdef" );
577 : 0 : ImplWriteLine( "/sw {show} bdef" );
578 : 0 : ImplWriteLine( "/gs {gsave} bdef" );
579 : 0 : ImplWriteLine( "/gr {grestore} bdef" );
580 : :
581 : 0 : ImplWriteLine( "/f {findfont dup length dict begin" ); // Setfont
582 : 0 : ImplWriteLine( "{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def" );
583 : 0 : ImplWriteLine( "currentdict end /NFont exch definefont pop /NFont findfont} bdef" );
584 : :
585 : 0 : ImplWriteLine( "/p {closepath} bdef" );
586 : 0 : ImplWriteLine( "/sf {scalefont setfont} bdef" );
587 : :
588 : 0 : ImplWriteLine( "/ef {eofill}bdef" ); // close path and fill
589 : 0 : ImplWriteLine( "/pc {closepath stroke}bdef" ); // close path and draw
590 : 0 : ImplWriteLine( "/ps {stroke}bdef" ); // draw current path
591 : 0 : ImplWriteLine( "/pum {matrix currentmatrix}bdef" ); // pushes the current matrix
592 : 0 : ImplWriteLine( "/pom {setmatrix}bdef" ); // pops the matrix
593 : 0 : 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" );
594 : 0 : ImplWriteLine( "%%EndResource" );
595 : 0 : ImplWriteLine( "%%EndProlog" );
596 : 0 : ImplWriteLine( "%%BeginSetup" );
597 : 0 : ImplWriteLine( "%%EndSetup" );
598 : 0 : ImplWriteLine( "%%Page: 1 1" );
599 : 0 : ImplWriteLine( "%%BeginPageSetup" );
600 : 0 : ImplWriteLine( "%%EndPageSetup" );
601 : 0 : ImplWriteLine( "pum" );
602 : 0 : ImplScale( (double)aSizePoint.Width() / (double)pMTF->GetPrefSize().Width(), (double)aSizePoint.Height() / (double)pMTF->GetPrefSize().Height() );
603 : 0 : ImplWriteDouble( 0 );
604 : 0 : ImplWriteDouble( -pMTF->GetPrefSize().Height() );
605 : 0 : ImplWriteLine( "t" );
606 : 0 : ImplWriteLine( "/tm matrix currentmatrix def" );
607 : 0 : }
608 : :
609 : : //---------------------------------------------------------------------------------
610 : :
611 : 0 : void PSWriter::ImplWriteEpilog()
612 : : {
613 : 0 : ImplTranslate( 0, nBoundingY2 );
614 : 0 : ImplWriteLine( "pom" );
615 : 0 : ImplWriteLine( "count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore" );
616 : :
617 : 0 : ImplWriteLine( "%%PageTrailer" );
618 : 0 : ImplWriteLine( "%%Trailer" );
619 : :
620 : 0 : ImplWriteLine( "%%EOF" );
621 : 0 : }
622 : :
623 : : //---------------------------------------------------------------------------------
624 : : //---------------------------------------------------------------------------------
625 : : //---------------------------------------------------------------------------------
626 : :
627 : 0 : void PSWriter::ImplWriteActions( const GDIMetaFile& rMtf, VirtualDevice& rVDev )
628 : : {
629 : 0 : PolyPolygon aFillPath;
630 : :
631 : 0 : for( size_t nCurAction = 0, nCount = rMtf.GetActionSize(); nCurAction < nCount; nCurAction++ )
632 : : {
633 : 0 : MetaAction* pMA = rMtf.GetAction( nCurAction );
634 : :
635 : 0 : switch( pMA->GetType() )
636 : : {
637 : : case META_NULL_ACTION :
638 : 0 : break;
639 : :
640 : : case META_PIXEL_ACTION :
641 : : {
642 : 0 : Color aOldLineColor( aLineColor );
643 : 0 : aLineColor = ( (const MetaPixelAction*) pMA )->GetColor();
644 : 0 : ImplWriteLineColor( PS_SPACE );
645 : 0 : ImplMoveTo( ( (const MetaPixelAction*)pMA )->GetPoint() );
646 : 0 : ImplLineTo( ( (const MetaPixelAction*)pMA )->GetPoint() );
647 : 0 : ImplPathDraw();
648 : 0 : aLineColor = aOldLineColor;
649 : : }
650 : 0 : break;
651 : :
652 : : case META_POINT_ACTION :
653 : : {
654 : 0 : ImplWriteLineColor( PS_SPACE );
655 : 0 : ImplMoveTo( ( (const MetaPointAction*)pMA )->GetPoint() );
656 : 0 : ImplLineTo( ( (const MetaPointAction*)pMA )->GetPoint() );
657 : 0 : ImplPathDraw();
658 : : }
659 : 0 : break;
660 : :
661 : : case META_LINE_ACTION :
662 : : {
663 : 0 : const LineInfo& rLineInfo = ( ( const MetaLineAction*)pMA )->GetLineInfo();
664 : 0 : ImplWriteLineInfo( rLineInfo );
665 : 0 : if ( bLineColor )
666 : : {
667 : 0 : ImplWriteLineColor( PS_SPACE );
668 : 0 : ImplMoveTo( ( (const MetaLineAction*) pMA )->GetStartPoint() );
669 : 0 : ImplLineTo( ( (const MetaLineAction*) pMA )->GetEndPoint() );
670 : 0 : ImplPathDraw();
671 : : }
672 : : }
673 : 0 : break;
674 : :
675 : : case META_RECT_ACTION :
676 : : {
677 : 0 : ImplRect( ( (const MetaRectAction*) pMA )->GetRect() );
678 : : }
679 : 0 : break;
680 : :
681 : : case META_ROUNDRECT_ACTION :
682 : 0 : ImplRect( ( (const MetaRoundRectAction*) pMA )->GetRect() );
683 : 0 : break;
684 : :
685 : : case META_ELLIPSE_ACTION :
686 : : {
687 : 0 : Rectangle aRect = ( ( (const MetaEllipseAction*) pMA )->GetRect() );
688 : 0 : Point aCenter = aRect.Center();
689 : 0 : Polygon aPoly( aCenter, aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
690 : 0 : PolyPolygon aPolyPoly( aPoly );
691 : 0 : ImplPolyPoly( aPolyPoly );
692 : : }
693 : 0 : break;
694 : :
695 : : case META_ARC_ACTION :
696 : : {
697 : 0 : Polygon aPoly( ( (const MetaArcAction*)pMA )->GetRect(), ( (const MetaArcAction*)pMA )->GetStartPoint(),
698 : 0 : ( (const MetaArcAction*)pMA )->GetEndPoint(), POLY_ARC );
699 : 0 : PolyPolygon aPolyPoly( aPoly );
700 : 0 : ImplPolyPoly( aPolyPoly );
701 : : }
702 : 0 : break;
703 : :
704 : : case META_PIE_ACTION :
705 : : {
706 : 0 : Polygon aPoly( ( (const MetaPieAction*)pMA )->GetRect(), ( (const MetaPieAction*)pMA )->GetStartPoint(),
707 : 0 : ( (const MetaPieAction*)pMA )->GetEndPoint(), POLY_PIE );
708 : 0 : PolyPolygon aPolyPoly( aPoly );
709 : 0 : ImplPolyPoly( aPolyPoly );
710 : : }
711 : 0 : break;
712 : :
713 : : case META_CHORD_ACTION :
714 : : {
715 : 0 : Polygon aPoly( ( (const MetaChordAction*)pMA )->GetRect(), ( (const MetaChordAction*)pMA )->GetStartPoint(),
716 : 0 : ( (const MetaChordAction*)pMA )->GetEndPoint(), POLY_CHORD );
717 : 0 : PolyPolygon aPolyPoly( aPoly );
718 : 0 : ImplPolyPoly( aPolyPoly );
719 : : }
720 : 0 : break;
721 : :
722 : : case META_POLYLINE_ACTION :
723 : : {
724 : 0 : Polygon aPoly( ( (const MetaPolyLineAction*) pMA )->GetPolygon() );
725 : 0 : const LineInfo& rLineInfo = ( ( const MetaPolyLineAction*)pMA )->GetLineInfo();
726 : 0 : ImplWriteLineInfo( rLineInfo );
727 : :
728 : 0 : if(basegfx::B2DLINEJOIN_NONE == rLineInfo.GetLineJoin()
729 : 0 : && rLineInfo.GetWidth() > 1)
730 : : {
731 : : // emulate B2DLINEJOIN_NONE by creating single edges
732 : 0 : const sal_uInt16 nPoints(aPoly.GetSize());
733 : 0 : const bool bCurve(aPoly.HasFlags());
734 : :
735 : 0 : for(sal_uInt16 a(0); a + 1 < nPoints; a++)
736 : : {
737 : 0 : if(bCurve
738 : 0 : && POLY_NORMAL != aPoly.GetFlags(a + 1)
739 : : && a + 2 < nPoints
740 : 0 : && POLY_NORMAL != aPoly.GetFlags(a + 2)
741 : : && a + 3 < nPoints)
742 : : {
743 : : const Polygon aSnippet(4,
744 : 0 : aPoly.GetConstPointAry() + a,
745 : 0 : aPoly.GetConstFlagAry() + a);
746 : 0 : ImplPolyLine(aSnippet);
747 : 0 : a += 2;
748 : : }
749 : : else
750 : : {
751 : : const Polygon aSnippet(2,
752 : 0 : aPoly.GetConstPointAry() + a);
753 : 0 : ImplPolyLine(aSnippet);
754 : : }
755 : : }
756 : : }
757 : : else
758 : : {
759 : 0 : ImplPolyLine( aPoly );
760 : 0 : }
761 : : }
762 : 0 : break;
763 : :
764 : : case META_POLYGON_ACTION :
765 : : {
766 : 0 : PolyPolygon aPolyPoly( ( (const MetaPolygonAction*) pMA )->GetPolygon() );
767 : 0 : ImplPolyPoly( aPolyPoly );
768 : : }
769 : 0 : break;
770 : :
771 : : case META_POLYPOLYGON_ACTION :
772 : : {
773 : 0 : ImplPolyPoly( ( (const MetaPolyPolygonAction*) pMA )->GetPolyPolygon() );
774 : : }
775 : 0 : break;
776 : :
777 : : case META_TEXT_ACTION:
778 : : {
779 : 0 : const MetaTextAction * pA = (const MetaTextAction*) pMA;
780 : :
781 : 0 : String aUniStr( pA->GetText(), pA->GetIndex(), pA->GetLen() );
782 : 0 : Point aPoint( pA->GetPoint() );
783 : :
784 : 0 : ImplText( aUniStr, aPoint, NULL, 0, rVDev );
785 : : }
786 : 0 : break;
787 : :
788 : : case META_TEXTRECT_ACTION:
789 : : {
790 : : OSL_FAIL( "Unsupported action: TextRect...Action!" );
791 : : }
792 : 0 : break;
793 : :
794 : : case META_STRETCHTEXT_ACTION :
795 : : {
796 : 0 : const MetaStretchTextAction* pA = (const MetaStretchTextAction*)pMA;
797 : 0 : String aUniStr( pA->GetText(), pA->GetIndex(), pA->GetLen() );
798 : 0 : Point aPoint( pA->GetPoint() );
799 : :
800 : 0 : ImplText( aUniStr, aPoint, NULL, pA->GetWidth(), rVDev );
801 : : }
802 : 0 : break;
803 : :
804 : : case META_TEXTARRAY_ACTION:
805 : : {
806 : 0 : const MetaTextArrayAction* pA = (const MetaTextArrayAction*)pMA;
807 : 0 : String aUniStr( pA->GetText(), pA->GetIndex(), pA->GetLen() );
808 : 0 : Point aPoint( pA->GetPoint() );
809 : :
810 : 0 : ImplText( aUniStr, aPoint, pA->GetDXArray(), 0, rVDev );
811 : : }
812 : 0 : break;
813 : :
814 : : case META_BMP_ACTION :
815 : : {
816 : 0 : Bitmap aBitmap = ( (const MetaBmpAction*)pMA )->GetBitmap();
817 : 0 : if ( mbGrayScale )
818 : 0 : aBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );
819 : 0 : Point aPoint = ( (const MetaBmpAction*) pMA )->GetPoint();
820 : 0 : Size aSize( rVDev.PixelToLogic( aBitmap.GetSizePixel() ) );
821 : 0 : ImplBmp( &aBitmap, NULL, aPoint, aSize.Width(), aSize.Height() );
822 : : }
823 : 0 : break;
824 : :
825 : : case META_BMPSCALE_ACTION :
826 : : {
827 : 0 : Bitmap aBitmap = ( (const MetaBmpScaleAction*)pMA )->GetBitmap();
828 : 0 : if ( mbGrayScale )
829 : 0 : aBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );
830 : 0 : Point aPoint = ( (const MetaBmpScaleAction*) pMA )->GetPoint();
831 : 0 : Size aSize = ( (const MetaBmpScaleAction*)pMA )->GetSize();
832 : 0 : ImplBmp( &aBitmap, NULL, aPoint, aSize.Width(), aSize.Height() );
833 : : }
834 : 0 : break;
835 : :
836 : : case META_BMPSCALEPART_ACTION :
837 : : {
838 : 0 : Bitmap aBitmap( ( (const MetaBmpScalePartAction*)pMA )->GetBitmap() );
839 : 0 : aBitmap.Crop( Rectangle( ( (const MetaBmpScalePartAction*)pMA )->GetSrcPoint(),
840 : 0 : ( (const MetaBmpScalePartAction*)pMA )->GetSrcSize() ) );
841 : 0 : if ( mbGrayScale )
842 : 0 : aBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );
843 : 0 : Point aPoint = ( (const MetaBmpScalePartAction*) pMA)->GetDestPoint();
844 : 0 : Size aSize = ( (const MetaBmpScalePartAction*)pMA )->GetDestSize();
845 : 0 : ImplBmp( &aBitmap, NULL, aPoint, aSize.Width(), aSize.Height() );
846 : : }
847 : 0 : break;
848 : :
849 : : case META_BMPEX_ACTION :
850 : : {
851 : 0 : BitmapEx aBitmapEx( ( (MetaBmpExAction*)pMA)->GetBitmapEx() );
852 : 0 : Bitmap aBitmap( aBitmapEx.GetBitmap() );
853 : 0 : if ( mbGrayScale )
854 : 0 : aBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );
855 : 0 : Bitmap aMask( aBitmapEx.GetMask() );
856 : 0 : Point aPoint( ( (const MetaBmpExAction*) pMA )->GetPoint() );
857 : 0 : Size aSize( rVDev.PixelToLogic( aBitmap.GetSizePixel() ) );
858 : 0 : ImplBmp( &aBitmap, &aMask, aPoint, aSize.Width(), aSize.Height() );
859 : : }
860 : 0 : break;
861 : :
862 : : case META_BMPEXSCALE_ACTION :
863 : : {
864 : 0 : BitmapEx aBitmapEx( ( (MetaBmpExScaleAction*)pMA)->GetBitmapEx() );
865 : 0 : Bitmap aBitmap( aBitmapEx.GetBitmap() );
866 : 0 : if ( mbGrayScale )
867 : 0 : aBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );
868 : 0 : Bitmap aMask( aBitmapEx.GetMask() );
869 : 0 : Point aPoint = ( (const MetaBmpExScaleAction*) pMA)->GetPoint();
870 : 0 : Size aSize( ( (const MetaBmpExScaleAction*)pMA )->GetSize() );
871 : 0 : ImplBmp( &aBitmap, &aMask, aPoint, aSize.Width(), aSize.Height() );
872 : : }
873 : 0 : break;
874 : :
875 : : case META_BMPEXSCALEPART_ACTION :
876 : : {
877 : 0 : BitmapEx aBitmapEx( ( (const MetaBmpExScalePartAction*)pMA )->GetBitmapEx() );
878 : 0 : aBitmapEx.Crop( Rectangle( ( (const MetaBmpExScalePartAction*)pMA )->GetSrcPoint(),
879 : 0 : ( (const MetaBmpExScalePartAction*)pMA )->GetSrcSize() ) );
880 : 0 : Bitmap aBitmap( aBitmapEx.GetBitmap() );
881 : 0 : if ( mbGrayScale )
882 : 0 : aBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );
883 : 0 : Bitmap aMask( aBitmapEx.GetMask() );
884 : 0 : Point aPoint = ( (const MetaBmpExScalePartAction*) pMA)->GetDestPoint();
885 : 0 : Size aSize = ( (const MetaBmpExScalePartAction*)pMA )->GetDestSize();
886 : 0 : ImplBmp( &aBitmap, &aMask, aPoint, aSize.Width(), aSize.Height() );
887 : : }
888 : 0 : break;
889 : :
890 : : // Unsupported Actions
891 : : case META_MASK_ACTION:
892 : : case META_MASKSCALE_ACTION:
893 : : case META_MASKSCALEPART_ACTION:
894 : : {
895 : : OSL_FAIL( "Unsupported action: MetaMask...Action!" );
896 : : }
897 : 0 : break;
898 : :
899 : : case META_GRADIENT_ACTION :
900 : : {
901 : 0 : PolyPolygon aPolyPoly( ( (const MetaGradientAction*)pMA)->GetRect() );
902 : 0 : ImplWriteGradient( aPolyPoly, ( (const MetaGradientAction*) pMA )->GetGradient(), rVDev );
903 : : }
904 : 0 : break;
905 : :
906 : : case META_GRADIENTEX_ACTION :
907 : : {
908 : 0 : PolyPolygon aPolyPoly( ( (const MetaGradientExAction*)pMA)->GetPolyPolygon() );
909 : 0 : ImplWriteGradient( aPolyPoly, ( (const MetaGradientExAction*) pMA )->GetGradient(), rVDev );
910 : : }
911 : 0 : break;
912 : :
913 : : case META_HATCH_ACTION :
914 : : {
915 : 0 : VirtualDevice l_aVDev;
916 : 0 : GDIMetaFile aTmpMtf;
917 : :
918 : 0 : l_aVDev.SetMapMode( rVDev.GetMapMode() );
919 : 0 : l_aVDev.AddHatchActions( ( (const MetaHatchAction*)pMA)->GetPolyPolygon(),
920 : 0 : ( (const MetaHatchAction*)pMA )->GetHatch(), aTmpMtf );
921 : 0 : ImplWriteActions( aTmpMtf, rVDev );
922 : : }
923 : 0 : break;
924 : :
925 : : case META_WALLPAPER_ACTION :
926 : : {
927 : 0 : const MetaWallpaperAction* pA = (const MetaWallpaperAction*)pMA;
928 : 0 : Rectangle aRect = pA->GetRect();
929 : 0 : Wallpaper aWallpaper = pA->GetWallpaper();
930 : :
931 : 0 : if ( aWallpaper.IsBitmap() )
932 : : {
933 : 0 : BitmapEx aBitmapEx = aWallpaper.GetBitmap();
934 : 0 : Bitmap aBitmap( aBitmapEx.GetBitmap() );
935 : 0 : if ( aBitmapEx.IsTransparent() )
936 : : {
937 : 0 : if ( aWallpaper.IsGradient() )
938 : : {
939 : :
940 : : // gradient action
941 : :
942 : : }
943 : 0 : Bitmap aMask( aBitmapEx.GetMask() );
944 : 0 : ImplBmp( &aBitmap, &aMask, Point( aRect.Left(), aRect.Top() ), aRect.GetWidth(), aRect.GetHeight() );
945 : : }
946 : : else
947 : 0 : ImplBmp( &aBitmap, NULL, Point( aRect.Left(), aRect.Top() ), aRect.GetWidth(), aRect.GetHeight() );
948 : :
949 : : // wallpaper Style
950 : :
951 : : }
952 : 0 : else if ( aWallpaper.IsGradient() )
953 : : {
954 : :
955 : : // gradient action
956 : :
957 : : }
958 : : else
959 : : {
960 : 0 : aColor = aWallpaper.GetColor();
961 : 0 : ImplRectFill( aRect );
962 : 0 : }
963 : : }
964 : 0 : break;
965 : :
966 : : case META_ISECTRECTCLIPREGION_ACTION:
967 : : {
968 : 0 : const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
969 : 0 : Region aRegion( pA->GetRect() );
970 : 0 : ImplSetClipRegion( aRegion );
971 : : }
972 : 0 : break;
973 : :
974 : : case META_CLIPREGION_ACTION:
975 : : {
976 : 0 : const MetaClipRegionAction* pA = (const MetaClipRegionAction*) pMA;
977 : 0 : Region aRegion( pA->GetRegion() );
978 : 0 : ImplSetClipRegion( aRegion );
979 : : }
980 : 0 : break;
981 : :
982 : : case META_ISECTREGIONCLIPREGION_ACTION:
983 : : {
984 : 0 : const MetaISectRegionClipRegionAction* pA = (const MetaISectRegionClipRegionAction*) pMA;
985 : 0 : Region aRegion( pA->GetRegion() );
986 : 0 : ImplSetClipRegion( aRegion );
987 : : }
988 : 0 : break;
989 : :
990 : : case META_MOVECLIPREGION_ACTION:
991 : : {
992 : : /*
993 : : if ( !aClipRegion.IsEmpty() )
994 : : {
995 : : const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*) pMA;
996 : : aClipRegion.Move( pA->GetHorzMove(), pA->GetVertMove() );
997 : : ImplSetClipRegion();
998 : : }
999 : : */
1000 : : }
1001 : 0 : break;
1002 : :
1003 : : case META_LINECOLOR_ACTION :
1004 : : {
1005 : 0 : if ( ( (const MetaLineColorAction*) pMA)->IsSetting() )
1006 : : {
1007 : 0 : bLineColor = sal_True;
1008 : 0 : aLineColor = ( (const MetaLineColorAction*) pMA )->GetColor();
1009 : : }
1010 : : else
1011 : 0 : bLineColor = sal_False;
1012 : : }
1013 : 0 : break;
1014 : :
1015 : : case META_FILLCOLOR_ACTION :
1016 : : {
1017 : 0 : if ( ( (const MetaFillColorAction*) pMA )->IsSetting() )
1018 : : {
1019 : 0 : bFillColor = sal_True;
1020 : 0 : aFillColor = ( (const MetaFillColorAction*) pMA )->GetColor();
1021 : : }
1022 : : else
1023 : 0 : bFillColor = sal_False;
1024 : : }
1025 : 0 : break;
1026 : :
1027 : : case META_TEXTCOLOR_ACTION :
1028 : : {
1029 : 0 : aTextColor = ( (const MetaTextColorAction*) pMA )->GetColor();
1030 : : }
1031 : 0 : break;
1032 : :
1033 : : case META_TEXTFILLCOLOR_ACTION :
1034 : : {
1035 : 0 : if ( ( (const MetaTextFillColorAction*) pMA )->IsSetting() )
1036 : : {
1037 : 0 : bTextFillColor = sal_True;
1038 : 0 : aTextFillColor = ( (const MetaTextFillColorAction*) pMA )->GetColor();
1039 : : }
1040 : : else
1041 : 0 : bTextFillColor = sal_False;
1042 : : }
1043 : 0 : break;
1044 : :
1045 : : case META_TEXTALIGN_ACTION :
1046 : : {
1047 : 0 : eTextAlign = ( (const MetaTextAlignAction*) pMA )->GetTextAlign();
1048 : : }
1049 : 0 : break;
1050 : :
1051 : : case META_MAPMODE_ACTION :
1052 : : {
1053 : 0 : pMA->Execute( &rVDev );
1054 : 0 : ImplGetMapMode( rVDev.GetMapMode() );
1055 : : }
1056 : 0 : break;
1057 : :
1058 : : case META_FONT_ACTION :
1059 : : {
1060 : 0 : maFont = ((const MetaFontAction*)pMA)->GetFont();
1061 : 0 : rVDev.SetFont( maFont );
1062 : : }
1063 : 0 : break;
1064 : :
1065 : : case META_PUSH_ACTION :
1066 : : {
1067 : 0 : rVDev.Push(((const MetaPushAction*)pMA)->GetFlags() );
1068 : 0 : StackMember* pGS = new StackMember;
1069 : 0 : pGS->pSucc = pGDIStack;
1070 : 0 : pGDIStack = pGS;
1071 : 0 : pGS->aDashArray = aDashArray;
1072 : 0 : pGS->eJoinType = eJoinType;
1073 : 0 : pGS->eLineCap = eLineCap;
1074 : 0 : pGS->fLineWidth = fLineWidth;
1075 : 0 : pGS->fMiterLimit = fMiterLimit;
1076 : 0 : pGS->eTextAlign = eTextAlign;
1077 : 0 : pGS->aGlobalCol = aColor;
1078 : 0 : pGS->bLineCol = bLineColor;
1079 : 0 : pGS->aLineCol = aLineColor;
1080 : 0 : pGS->bFillCol = bFillColor;
1081 : 0 : pGS->aFillCol = aFillColor;
1082 : 0 : pGS->aTextCol = aTextColor;
1083 : 0 : pGS->bTextFillCol = bTextFillColor;
1084 : 0 : pGS->aTextFillCol = aTextFillColor;
1085 : 0 : pGS->aBackgroundCol = aBackgroundColor;
1086 : 0 : bRegionChanged = sal_False;
1087 : 0 : pGS->aFont = maFont;
1088 : 0 : mnLatestPush = mpPS->Tell();
1089 : 0 : ImplWriteLine( "gs" );
1090 : : }
1091 : 0 : break;
1092 : :
1093 : : case META_POP_ACTION :
1094 : : {
1095 : 0 : rVDev.Pop();
1096 : : StackMember* pGS;
1097 : 0 : if( pGDIStack )
1098 : : {
1099 : 0 : pGS = pGDIStack;
1100 : 0 : pGDIStack = pGS->pSucc;
1101 : 0 : aDashArray = pGS->aDashArray;
1102 : 0 : eJoinType = pGS->eJoinType;
1103 : 0 : eLineCap = pGS->eLineCap;
1104 : 0 : fLineWidth = pGS->fLineWidth;
1105 : 0 : fMiterLimit = pGS->fMiterLimit;
1106 : 0 : eTextAlign = pGS->eTextAlign;
1107 : 0 : aColor = pGS->aGlobalCol;
1108 : 0 : bLineColor = pGS->bLineCol;
1109 : 0 : aLineColor = pGS->aLineCol;
1110 : 0 : bFillColor = pGS->bFillCol;
1111 : 0 : aFillColor = pGS->aFillCol;
1112 : 0 : aTextColor = pGS->aTextCol;
1113 : 0 : bTextFillColor = pGS->bTextFillCol;
1114 : 0 : aTextFillColor = pGS->aTextFillCol;
1115 : 0 : aBackgroundColor = pGS->aBackgroundCol;
1116 : 0 : maFont = pGS->aFont;
1117 : 0 : maLastFont = Font(); // set maLastFont != maFont -> so that
1118 : 0 : delete pGS;
1119 : 0 : sal_uInt32 nCurrentPos = mpPS->Tell();
1120 : 0 : if ( nCurrentPos - 3 == mnLatestPush )
1121 : : {
1122 : 0 : mpPS->Seek( mnLatestPush );
1123 : 0 : ImplWriteLine( " " );
1124 : 0 : mpPS->Seek( mnLatestPush );
1125 : : }
1126 : : else
1127 : 0 : ImplWriteLine( "gr" );
1128 : : }
1129 : : }
1130 : 0 : break;
1131 : :
1132 : : case META_EPS_ACTION :
1133 : : {
1134 : 0 : GfxLink aGfxLink = ( (const MetaEPSAction*) pMA )->GetLink();
1135 : 0 : const GDIMetaFile aSubstitute( ( ( const MetaEPSAction*) pMA )->GetSubstitute() );
1136 : :
1137 : 0 : sal_Bool bLevelConflict = sal_False;
1138 : 0 : sal_uInt8* pSource = (sal_uInt8*) aGfxLink.GetData();
1139 : 0 : sal_uLong nSize = aGfxLink.GetDataSize();
1140 : 0 : sal_uLong nParseThis = POSTSCRIPT_BOUNDINGSEARCH;
1141 : 0 : if ( nSize < 64 ) // assuming eps is larger than 64 bytes
1142 : 0 : pSource = NULL;
1143 : 0 : if ( nParseThis > nSize )
1144 : 0 : nParseThis = nSize;
1145 : :
1146 : 0 : if ( pSource && ( mnLevel == 1 ) )
1147 : : {
1148 : 0 : sal_uInt8* pFound = ImplSearchEntry( pSource, (sal_uInt8*)"%%LanguageLevel:", nParseThis - 10, 16 );
1149 : 0 : if ( pFound )
1150 : : {
1151 : 0 : sal_uInt8 k, i = 10;
1152 : 0 : pFound += 16;
1153 : 0 : while ( --i )
1154 : : {
1155 : 0 : k = *pFound++;
1156 : 0 : if ( ( k > '0' ) && ( k <= '9' ) )
1157 : : {
1158 : 0 : if ( k != '1' )
1159 : : {
1160 : 0 : bLevelConflict = sal_True;
1161 : 0 : mnLevelWarning++;
1162 : : }
1163 : 0 : break;
1164 : : }
1165 : : }
1166 : : }
1167 : : }
1168 : 0 : if ( !bLevelConflict )
1169 : : {
1170 : : double nBoundingBox[4];
1171 : 0 : if ( pSource && ImplGetBoundingBox( nBoundingBox, pSource, nParseThis ) )
1172 : : {
1173 : 0 : Point aPoint = ( (const MetaEPSAction*) pMA )->GetPoint();
1174 : 0 : Size aSize = ( (const MetaEPSAction*) pMA )->GetSize();
1175 : :
1176 : 0 : MapMode aMapMode( aSubstitute.GetPrefMapMode() );
1177 : 0 : Size aOutSize( rVDev.LogicToLogic( aSize, rVDev.GetMapMode(), aMapMode ) );
1178 : 0 : Point aOrigin( rVDev.LogicToLogic( aPoint, rVDev.GetMapMode(), aMapMode ) );
1179 : 0 : aOrigin.Y() += aOutSize.Height();
1180 : 0 : aMapMode.SetOrigin( aOrigin );
1181 : 0 : aMapMode.SetScaleX( aOutSize.Width() / ( nBoundingBox[ 2 ] - nBoundingBox[ 0 ] ) );
1182 : 0 : aMapMode.SetScaleY( aOutSize.Height() / ( nBoundingBox[ 3 ] - nBoundingBox[ 1 ] ) );
1183 : 0 : ImplWriteLine( "gs" );
1184 : 0 : ImplGetMapMode( aMapMode );
1185 : 0 : ImplWriteLine( "%%BeginDocument:" );
1186 : 0 : mpPS->Write( pSource, aGfxLink.GetDataSize() );
1187 : 0 : ImplWriteLine( "%%EndDocument\ngr" );
1188 : : }
1189 : 0 : }
1190 : : }
1191 : 0 : break;
1192 : :
1193 : : case META_TRANSPARENT_ACTION:
1194 : : {
1195 : : // ImplLine( ( (const MetaTransparentAction*) pMA )->GetPolyPolygon() );
1196 : : }
1197 : 0 : break;
1198 : :
1199 : : case META_RASTEROP_ACTION:
1200 : : {
1201 : 0 : pMA->Execute( &rVDev );
1202 : : }
1203 : 0 : break;
1204 : :
1205 : : case META_FLOATTRANSPARENT_ACTION:
1206 : : {
1207 : 0 : const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
1208 : :
1209 : 0 : GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
1210 : 0 : Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
1211 : 0 : const Size aSrcSize( aTmpMtf.GetPrefSize() );
1212 : 0 : const Point aDestPt( pA->GetPoint() );
1213 : 0 : const Size aDestSize( pA->GetSize() );
1214 : 0 : const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
1215 : 0 : const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
1216 : : long nMoveX, nMoveY;
1217 : :
1218 : 0 : if( fScaleX != 1.0 || fScaleY != 1.0 )
1219 : : {
1220 : 0 : aTmpMtf.Scale( fScaleX, fScaleY );
1221 : 0 : aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
1222 : : }
1223 : :
1224 : 0 : nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
1225 : :
1226 : 0 : if( nMoveX || nMoveY )
1227 : 0 : aTmpMtf.Move( nMoveX, nMoveY );
1228 : :
1229 : 0 : ImplWriteActions( aTmpMtf, rVDev );
1230 : : }
1231 : 0 : break;
1232 : :
1233 : : case META_COMMENT_ACTION:
1234 : : {
1235 : 0 : const MetaCommentAction* pA = (const MetaCommentAction*) pMA;
1236 : 0 : if ( pA->GetComment().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("XGRAD_SEQ_BEGIN")) )
1237 : : {
1238 : 0 : const MetaGradientExAction* pGradAction = NULL;
1239 : 0 : while( ++nCurAction < nCount )
1240 : : {
1241 : 0 : MetaAction* pAction = rMtf.GetAction( nCurAction );
1242 : 0 : if( pAction->GetType() == META_GRADIENTEX_ACTION )
1243 : 0 : pGradAction = (const MetaGradientExAction*) pAction;
1244 : 0 : else if( ( pAction->GetType() == META_COMMENT_ACTION ) &&
1245 : 0 : ( ( (const MetaCommentAction*) pAction )->GetComment().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("XGRAD_SEQ_END")) ) )
1246 : : {
1247 : 0 : break;
1248 : : }
1249 : : }
1250 : 0 : if( pGradAction )
1251 : 0 : ImplWriteGradient( pGradAction->GetPolyPolygon(), pGradAction->GetGradient(), rVDev );
1252 : : }
1253 : 0 : else if ( pA->GetComment().equalsL(RTL_CONSTASCII_STRINGPARAM("XPATHFILL_SEQ_END")) )
1254 : : {
1255 : 0 : if ( aFillPath.Count() )
1256 : : {
1257 : 0 : aFillPath = PolyPolygon();
1258 : 0 : ImplWriteLine( "gr" );
1259 : : }
1260 : : }
1261 : : else
1262 : : {
1263 : 0 : const sal_uInt8* pData = pA->GetData();
1264 : 0 : if ( pData )
1265 : : {
1266 : 0 : SvMemoryStream aMemStm( (void*)pData, pA->GetDataSize(), STREAM_READ );
1267 : 0 : sal_Bool bSkipSequence = sal_False;
1268 : 0 : rtl::OString sSeqEnd;
1269 : :
1270 : 0 : if( pA->GetComment().equalsL(RTL_CONSTASCII_STRINGPARAM( "XPATHSTROKE_SEQ_BEGIN" )) )
1271 : : {
1272 : 0 : sSeqEnd = rtl::OString(RTL_CONSTASCII_STRINGPARAM("XPATHSTROKE_SEQ_END"));
1273 : 0 : SvtGraphicStroke aStroke;
1274 : 0 : aMemStm >> aStroke;
1275 : :
1276 : 0 : Polygon aPath;
1277 : 0 : aStroke.getPath( aPath );
1278 : :
1279 : 0 : PolyPolygon aStartArrow;
1280 : 0 : PolyPolygon aEndArrow;
1281 : : // double fTransparency( aStroke.getTransparency() );
1282 : 0 : double fStrokeWidth( aStroke.getStrokeWidth() );
1283 : 0 : SvtGraphicStroke::JoinType eJT( aStroke.getJoinType() );
1284 : 0 : SvtGraphicStroke::DashArray l_aDashArray;
1285 : :
1286 : 0 : aStroke.getStartArrow( aStartArrow );
1287 : 0 : aStroke.getEndArrow( aEndArrow );
1288 : 0 : aStroke.getDashArray( l_aDashArray );
1289 : :
1290 : 0 : bSkipSequence = sal_True;
1291 : 0 : if ( l_aDashArray.size() > 11 ) // ps dasharray limit is 11
1292 : 0 : bSkipSequence = sal_False;
1293 : 0 : if ( aStartArrow.Count() || aEndArrow.Count() )
1294 : 0 : bSkipSequence = sal_False;
1295 : 0 : if ( (sal_uInt32)eJT > 2 )
1296 : 0 : bSkipSequence = sal_False;
1297 : 0 : if ( l_aDashArray.size() && ( fStrokeWidth != 0.0 ) )
1298 : 0 : bSkipSequence = sal_False;
1299 : 0 : if ( bSkipSequence )
1300 : : {
1301 : : ImplWriteLineInfo( fStrokeWidth, aStroke.getMiterLimit(),
1302 : 0 : aStroke.getCapType(), eJT, l_aDashArray );
1303 : 0 : ImplPolyLine( aPath );
1304 : 0 : }
1305 : : }
1306 : 0 : else if (pA->GetComment().equalsL(RTL_CONSTASCII_STRINGPARAM("XPATHFILL_SEQ_BEGIN")))
1307 : : {
1308 : 0 : sSeqEnd = rtl::OString(RTL_CONSTASCII_STRINGPARAM("XPATHFILL_SEQ_END"));
1309 : 0 : SvtGraphicFill aFill;
1310 : 0 : aMemStm >> aFill;
1311 : 0 : switch( aFill.getFillType() )
1312 : : {
1313 : : case SvtGraphicFill::fillSolid :
1314 : : {
1315 : 0 : bSkipSequence = sal_True;
1316 : 0 : PolyPolygon aPolyPoly;
1317 : 0 : aFill.getPath( aPolyPoly );
1318 : 0 : sal_uInt16 i, nPolyCount = aPolyPoly.Count();
1319 : 0 : if ( nPolyCount )
1320 : : {
1321 : 0 : aFillColor = aFill.getFillColor();
1322 : 0 : ImplWriteFillColor( PS_SPACE );
1323 : 0 : for ( i = 0; i < nPolyCount; )
1324 : : {
1325 : 0 : ImplAddPath( aPolyPoly.GetObject( i ) );
1326 : 0 : if ( ++i < nPolyCount )
1327 : : {
1328 : 0 : *mpPS << "p";
1329 : 0 : mnCursorPos += 2;
1330 : 0 : ImplExecMode( PS_RET );
1331 : : }
1332 : : }
1333 : 0 : *mpPS << "p ef";
1334 : 0 : mnCursorPos += 4;
1335 : 0 : ImplExecMode( PS_RET );
1336 : 0 : }
1337 : : }
1338 : 0 : break;
1339 : :
1340 : : case SvtGraphicFill::fillTexture :
1341 : : {
1342 : 0 : aFill.getPath( aFillPath );
1343 : :
1344 : : /* normally an object filling is consisting of three MetaActions:
1345 : : MetaBitmapAction using RasterOp xor,
1346 : : MetaPolyPolygonAction using RasterOp rop_0
1347 : : MetaBitmapAction using RasterOp xor
1348 : :
1349 : : Because RasterOps cannot been used in Postscript, we have to
1350 : : replace these actions. The MetaComment "XPATHFILL_SEQ_BEGIN" is
1351 : : providing the clippath of the object. The following loop is
1352 : : trying to find the bitmap that is matching the clippath, so that
1353 : : only one bitmap is exported, otherwise if the bitmap is not
1354 : : locatable, all metaactions are played normally.
1355 : : */
1356 : 0 : sal_uInt32 nCommentStartAction = nCurAction;
1357 : 0 : sal_uInt32 nBitmapCount = 0;
1358 : 0 : sal_uInt32 nBitmapAction = 0;
1359 : :
1360 : 0 : sal_Bool bOk = sal_True;
1361 : 0 : while( bOk && ( ++nCurAction < nCount ) )
1362 : : {
1363 : 0 : MetaAction* pAction = rMtf.GetAction( nCurAction );
1364 : 0 : switch( pAction->GetType() )
1365 : : {
1366 : : case META_BMPSCALE_ACTION :
1367 : : case META_BMPSCALEPART_ACTION :
1368 : : case META_BMPEXSCALE_ACTION :
1369 : : case META_BMPEXSCALEPART_ACTION :
1370 : : case META_RENDERGRAPHIC_ACTION :
1371 : : {
1372 : 0 : nBitmapCount++;
1373 : 0 : nBitmapAction = nCurAction;
1374 : : }
1375 : 0 : break;
1376 : : case META_COMMENT_ACTION :
1377 : : {
1378 : 0 : if (((const MetaCommentAction*)pAction)->GetComment().equalsL(RTL_CONSTASCII_STRINGPARAM("XPATHFILL_SEQ_END")))
1379 : 0 : bOk = sal_False;
1380 : : }
1381 : 0 : break;
1382 : : }
1383 : : }
1384 : 0 : if( nBitmapCount == 2 )
1385 : : {
1386 : 0 : ImplWriteLine( "gs" );
1387 : 0 : ImplIntersect( aFillPath );
1388 : 0 : GDIMetaFile aTempMtf;
1389 : 0 : aTempMtf.AddAction( rMtf.GetAction( nBitmapAction )->Clone() );
1390 : 0 : ImplWriteActions( aTempMtf, rVDev );
1391 : 0 : ImplWriteLine( "gr" );
1392 : 0 : aFillPath = PolyPolygon();
1393 : : }
1394 : : else
1395 : 0 : nCurAction = nCommentStartAction + 1;
1396 : : }
1397 : 0 : break;
1398 : :
1399 : : case SvtGraphicFill::fillGradient :
1400 : 0 : aFill.getPath( aFillPath );
1401 : 0 : break;
1402 : :
1403 : : case SvtGraphicFill::fillHatch :
1404 : 0 : break;
1405 : : }
1406 : 0 : if ( aFillPath.Count() )
1407 : : {
1408 : 0 : ImplWriteLine( "gs" );
1409 : 0 : ImplIntersect( aFillPath );
1410 : 0 : }
1411 : : }
1412 : 0 : if ( bSkipSequence )
1413 : : {
1414 : 0 : while( ++nCurAction < nCount )
1415 : : {
1416 : 0 : pMA = rMtf.GetAction( nCurAction );
1417 : 0 : if ( pMA->GetType() == META_COMMENT_ACTION )
1418 : : {
1419 : 0 : rtl::OString sComment( ((MetaCommentAction*)pMA)->GetComment() );
1420 : 0 : if ( sComment.equals( sSeqEnd ) )
1421 : 0 : break;
1422 : : }
1423 : : }
1424 : 0 : }
1425 : : }
1426 : : }
1427 : : }
1428 : 0 : break;
1429 : :
1430 : : case( META_RENDERGRAPHIC_ACTION ):
1431 : : {
1432 : 0 : const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
1433 : 0 : const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
1434 : 0 : const BitmapEx aBmpEx( aRasterizer.Rasterize( rVDev.LogicToPixel( pA->GetSize() ) ) );
1435 : 0 : Bitmap aBmp( aBmpEx.GetBitmap() );
1436 : :
1437 : 0 : if ( mbGrayScale )
1438 : 0 : aBmp.Convert( BMP_CONVERSION_8BIT_GREYS );
1439 : :
1440 : 0 : Bitmap aMask( aBmpEx.GetMask() );
1441 : 0 : Size aSize( pA->GetSize() );
1442 : :
1443 : 0 : ImplBmp( &aBmp, &aMask, pA->GetPoint(), aSize.Width(), aSize.Height() );
1444 : : }
1445 : 0 : break;
1446 : : }
1447 : 0 : }
1448 : 0 : }
1449 : :
1450 : :
1451 : :
1452 : : //---------------------------------------------------------------------------------
1453 : :
1454 : 0 : inline void PSWriter::ImplWritePoint( const Point& rPoint, sal_uInt32 nMode )
1455 : : {
1456 : 0 : ImplWriteDouble( rPoint.X() );
1457 : 0 : ImplWriteDouble( rPoint.Y(), nMode );
1458 : 0 : }
1459 : :
1460 : : //---------------------------------------------------------------------------------
1461 : :
1462 : 0 : void PSWriter::ImplMoveTo( const Point& rPoint, sal_uInt32 nMode )
1463 : : {
1464 : 0 : ImplWritePoint( rPoint );
1465 : 0 : ImplWriteByte( 'm' );
1466 : 0 : ImplExecMode( nMode );
1467 : 0 : }
1468 : :
1469 : : //---------------------------------------------------------------------------------
1470 : :
1471 : 0 : void PSWriter::ImplLineTo( const Point& rPoint, sal_uInt32 nMode )
1472 : : {
1473 : 0 : ImplWritePoint( rPoint );
1474 : 0 : ImplWriteByte( 'l' );
1475 : 0 : ImplExecMode( nMode );
1476 : 0 : }
1477 : :
1478 : : //---------------------------------------------------------------------------------
1479 : :
1480 : 0 : void PSWriter::ImplCurveTo( const Point& rP1, const Point& rP2, const Point& rP3, sal_uInt32 nMode )
1481 : : {
1482 : 0 : ImplWritePoint( rP1 );
1483 : 0 : ImplWritePoint( rP2 );
1484 : 0 : ImplWritePoint( rP3 );
1485 : 0 : *mpPS << "ct ";
1486 : 0 : ImplExecMode( nMode );
1487 : 0 : }
1488 : :
1489 : : //---------------------------------------------------------------------------------
1490 : :
1491 : 0 : void PSWriter::ImplTranslate( const double& fX, const double& fY, sal_uInt32 nMode )
1492 : : {
1493 : 0 : ImplWriteDouble( fX );
1494 : 0 : ImplWriteDouble( fY );
1495 : 0 : ImplWriteByte( 't' );
1496 : 0 : ImplExecMode( nMode );
1497 : 0 : }
1498 : :
1499 : : //---------------------------------------------------------------------------------
1500 : :
1501 : 0 : void PSWriter::ImplScale( const double& fX, const double& fY, sal_uInt32 nMode )
1502 : : {
1503 : 0 : ImplWriteDouble( fX );
1504 : 0 : ImplWriteDouble( fY );
1505 : 0 : ImplWriteByte( 's' );
1506 : 0 : ImplExecMode( nMode );
1507 : 0 : }
1508 : :
1509 : : //---------------------------------------------------------------------------------
1510 : :
1511 : 0 : void PSWriter::ImplRect( const Rectangle & rRect )
1512 : : {
1513 : 0 : if ( bFillColor )
1514 : 0 : ImplRectFill( rRect );
1515 : 0 : if ( bLineColor )
1516 : : {
1517 : 0 : double nWidth = rRect.GetWidth();
1518 : 0 : double nHeight = rRect.GetHeight();
1519 : :
1520 : 0 : ImplWriteLineColor( PS_SPACE );
1521 : 0 : ImplMoveTo( rRect.TopLeft() );
1522 : 0 : ImplWriteDouble( nWidth );
1523 : 0 : *mpPS << "0 rl 0 ";
1524 : 0 : ImplWriteDouble( nHeight );
1525 : 0 : *mpPS << "rl ";
1526 : 0 : ImplWriteDouble( nWidth );
1527 : 0 : *mpPS << "neg 0 rl ";
1528 : 0 : ImplClosePathDraw();
1529 : : }
1530 : 0 : *mpPS << (sal_uInt8)10;
1531 : 0 : mnCursorPos = 0;
1532 : 0 : }
1533 : :
1534 : : //---------------------------------------------------------------------------------
1535 : :
1536 : 0 : void PSWriter::ImplRectFill( const Rectangle & rRect )
1537 : : {
1538 : 0 : double nWidth = rRect.GetWidth();
1539 : 0 : double nHeight = rRect.GetHeight();
1540 : :
1541 : 0 : ImplWriteFillColor( PS_SPACE );
1542 : 0 : ImplMoveTo( rRect.TopLeft() );
1543 : 0 : ImplWriteDouble( nWidth );
1544 : 0 : *mpPS << "0 rl 0 ";
1545 : 0 : ImplWriteDouble( nHeight );
1546 : 0 : *mpPS << "rl ";
1547 : 0 : ImplWriteDouble( nWidth );
1548 : 0 : *mpPS << "neg 0 rl ef ";
1549 : 0 : *mpPS << "p ef";
1550 : 0 : mnCursorPos += 2;
1551 : 0 : ImplExecMode( PS_RET );
1552 : 0 : }
1553 : :
1554 : : //---------------------------------------------------------------------------------
1555 : :
1556 : 0 : void PSWriter::ImplAddPath( const Polygon & rPolygon )
1557 : : {
1558 : 0 : sal_uInt16 nPointCount = rPolygon.GetSize();
1559 : 0 : if ( nPointCount > 1 )
1560 : : {
1561 : 0 : sal_uInt16 i = 1;
1562 : 0 : ImplMoveTo( rPolygon.GetPoint( 0 ) );
1563 : 0 : while ( i < nPointCount )
1564 : : {
1565 : 0 : if ( ( rPolygon.GetFlags( i ) == POLY_CONTROL )
1566 : : && ( ( i + 2 ) < nPointCount )
1567 : 0 : && ( rPolygon.GetFlags( i + 1 ) == POLY_CONTROL )
1568 : 0 : && ( rPolygon.GetFlags( i + 2 ) != POLY_CONTROL ) )
1569 : : {
1570 : 0 : ImplCurveTo( rPolygon[ i ], rPolygon[ i + 1 ], rPolygon[ i + 2 ], PS_WRAP );
1571 : 0 : i += 3;
1572 : : }
1573 : : else
1574 : 0 : ImplLineTo( rPolygon.GetPoint( i++ ), PS_SPACE | PS_WRAP );
1575 : : }
1576 : : }
1577 : 0 : }
1578 : :
1579 : : //---------------------------------------------------------------------------------
1580 : :
1581 : 0 : void PSWriter::ImplIntersect( const PolyPolygon& rPolyPoly )
1582 : : {
1583 : 0 : sal_uInt16 i, nPolyCount = rPolyPoly.Count();
1584 : 0 : for ( i = 0; i < nPolyCount; )
1585 : : {
1586 : 0 : ImplAddPath( rPolyPoly.GetObject( i ) );
1587 : 0 : if ( ++i < nPolyCount )
1588 : : {
1589 : 0 : *mpPS << "p";
1590 : 0 : mnCursorPos += 2;
1591 : 0 : ImplExecMode( PS_RET );
1592 : : }
1593 : : }
1594 : 0 : ImplWriteLine( "eoclip newpath" );
1595 : 0 : }
1596 : :
1597 : : //---------------------------------------------------------------------------------
1598 : :
1599 : 0 : void PSWriter::ImplWriteGradient( const PolyPolygon& rPolyPoly, const Gradient& rGradient, VirtualDevice& rVDev )
1600 : : {
1601 : 0 : VirtualDevice l_aVDev;
1602 : 0 : GDIMetaFile aTmpMtf;
1603 : 0 : l_aVDev.SetMapMode( rVDev.GetMapMode() );
1604 : 0 : l_aVDev.AddGradientActions( rPolyPoly.GetBoundRect(), rGradient, aTmpMtf );
1605 : 0 : ImplWriteActions( aTmpMtf, rVDev );
1606 : 0 : }
1607 : :
1608 : : //---------------------------------------------------------------------------------
1609 : :
1610 : 0 : void PSWriter::ImplPolyPoly( const PolyPolygon & rPolyPoly, sal_Bool bTextOutline )
1611 : : {
1612 : 0 : sal_uInt16 i, nPolyCount = rPolyPoly.Count();
1613 : 0 : if ( nPolyCount )
1614 : : {
1615 : 0 : if ( bFillColor || bTextOutline )
1616 : : {
1617 : 0 : if ( bTextOutline )
1618 : 0 : ImplWriteTextColor( PS_SPACE );
1619 : : else
1620 : 0 : ImplWriteFillColor( PS_SPACE );
1621 : 0 : for ( i = 0; i < nPolyCount; )
1622 : : {
1623 : 0 : ImplAddPath( rPolyPoly.GetObject( i ) );
1624 : 0 : if ( ++i < nPolyCount )
1625 : : {
1626 : 0 : *mpPS << "p";
1627 : 0 : mnCursorPos += 2;
1628 : 0 : ImplExecMode( PS_RET );
1629 : : }
1630 : : }
1631 : 0 : *mpPS << "p ef";
1632 : 0 : mnCursorPos += 4;
1633 : 0 : ImplExecMode( PS_RET );
1634 : : }
1635 : 0 : if ( bLineColor )
1636 : : {
1637 : 0 : ImplWriteLineColor( PS_SPACE );
1638 : 0 : for ( i = 0; i < nPolyCount; i++ )
1639 : 0 : ImplAddPath( rPolyPoly.GetObject( i ) );
1640 : 0 : ImplClosePathDraw( PS_RET );
1641 : : }
1642 : : }
1643 : 0 : }
1644 : :
1645 : : //---------------------------------------------------------------------------------
1646 : :
1647 : 0 : void PSWriter::ImplPolyLine( const Polygon & rPoly )
1648 : : {
1649 : 0 : if ( bLineColor )
1650 : : {
1651 : 0 : ImplWriteLineColor( PS_SPACE );
1652 : 0 : sal_uInt16 i, nPointCount = rPoly.GetSize();
1653 : 0 : if ( nPointCount )
1654 : : {
1655 : 0 : if ( nPointCount > 1 )
1656 : : {
1657 : 0 : ImplMoveTo( rPoly.GetPoint( 0 ) );
1658 : 0 : i = 1;
1659 : 0 : while ( i < nPointCount )
1660 : : {
1661 : 0 : if ( ( rPoly.GetFlags( i ) == POLY_CONTROL )
1662 : : && ( ( i + 2 ) < nPointCount )
1663 : 0 : && ( rPoly.GetFlags( i + 1 ) == POLY_CONTROL )
1664 : 0 : && ( rPoly.GetFlags( i + 2 ) != POLY_CONTROL ) )
1665 : : {
1666 : 0 : ImplCurveTo( rPoly[ i ], rPoly[ i + 1 ], rPoly[ i + 2 ], PS_WRAP );
1667 : 0 : i += 3;
1668 : : }
1669 : : else
1670 : 0 : ImplLineTo( rPoly.GetPoint( i++ ), PS_SPACE | PS_WRAP );
1671 : : }
1672 : : }
1673 : :
1674 : : // #104645# explicitly close path if polygon is closed
1675 : 0 : if( rPoly[ 0 ] == rPoly[ nPointCount-1 ] )
1676 : 0 : ImplClosePathDraw( PS_RET );
1677 : : else
1678 : 0 : ImplPathDraw();
1679 : : }
1680 : : }
1681 : 0 : }
1682 : :
1683 : : //---------------------------------------------------------------------------------
1684 : :
1685 : 0 : void PSWriter::ImplSetClipRegion( Region& rClipRegion )
1686 : : {
1687 : 0 : if ( !rClipRegion.IsEmpty() )
1688 : : {
1689 : 0 : Rectangle aRect;
1690 : 0 : RegionHandle hRegionHandle = rClipRegion.BeginEnumRects();
1691 : :
1692 : 0 : while ( rClipRegion.GetNextEnumRect( hRegionHandle, aRect ) )
1693 : : {
1694 : 0 : double nX1 = aRect.Left();
1695 : 0 : double nY1 = aRect.Top();
1696 : 0 : double nX2 = aRect.Right();
1697 : 0 : double nY2 = aRect.Bottom();
1698 : 0 : ImplWriteDouble( nX1 );
1699 : 0 : ImplWriteDouble( nY1 );
1700 : 0 : ImplWriteByte( 'm' );
1701 : 0 : ImplWriteDouble( nX2 );
1702 : 0 : ImplWriteDouble( nY1 );
1703 : 0 : ImplWriteByte( 'l' );
1704 : 0 : ImplWriteDouble( nX2 );
1705 : 0 : ImplWriteDouble( nY2 );
1706 : 0 : ImplWriteByte( 'l' );
1707 : 0 : ImplWriteDouble( nX1 );
1708 : 0 : ImplWriteDouble( nY2 );
1709 : 0 : ImplWriteByte( 'l' );
1710 : 0 : ImplWriteDouble( nX1 );
1711 : 0 : ImplWriteDouble( nY1 );
1712 : 0 : ImplWriteByte( 'l', PS_SPACE | PS_WRAP );
1713 : : };
1714 : 0 : rClipRegion.EndEnumRects( hRegionHandle );
1715 : 0 : ImplWriteLine( "eoclip newpath" );
1716 : : }
1717 : 0 : }
1718 : :
1719 : : //---------------------------------------------------------------------------------
1720 : : // possible gfx formats:
1721 : : //
1722 : : // level 1: grayscale 8 bit
1723 : : // color 24 bit
1724 : : //
1725 : : // level 2: grayscale 8 bit
1726 : : // color 1(pal), 4(pal), 8(pal), 24 Bit
1727 : : //
1728 : :
1729 : 0 : void PSWriter::ImplBmp( Bitmap* pBitmap, Bitmap* pMaskBitmap, const Point & rPoint, double nXWidth, double nYHeightOrg )
1730 : : {
1731 : 0 : if ( !pBitmap )
1732 : : return;
1733 : :
1734 : 0 : sal_Int32 nHeightOrg = pBitmap->GetSizePixel().Height();
1735 : 0 : sal_Int32 nHeightLeft = nHeightOrg;
1736 : 0 : long nWidth = pBitmap->GetSizePixel().Width();
1737 : 0 : Point aSourcePos( rPoint );
1738 : :
1739 : 0 : while ( nHeightLeft )
1740 : : {
1741 : 0 : Bitmap aTileBitmap( *pBitmap );
1742 : 0 : long nHeight = nHeightLeft;
1743 : 0 : double nYHeight = nYHeightOrg;
1744 : :
1745 : 0 : sal_Bool bDoTrans = sal_False;
1746 : :
1747 : 0 : Rectangle aRect;
1748 : 0 : Region aRegion;
1749 : :
1750 : 0 : if ( pMaskBitmap )
1751 : : {
1752 : 0 : bDoTrans = sal_True;
1753 : 0 : while (sal_True)
1754 : : {
1755 : 0 : if ( mnLevel == 1 )
1756 : : {
1757 : 0 : if ( nHeight > 10 )
1758 : 0 : nHeight = 8;
1759 : : }
1760 : 0 : aRect = Rectangle( Point( 0, nHeightOrg - nHeightLeft ), Size( (long)nWidth, (long)nHeight ) );
1761 : 0 : aRegion = Region( pMaskBitmap->CreateRegion( COL_BLACK, aRect ) );
1762 : :
1763 : 0 : if ( ( mnLevel == 1 ) && ( aRegion.GetRectCount() * 5 > 1000 ) )
1764 : : {
1765 : 0 : nHeight >>= 1;
1766 : 0 : if ( nHeight < 2 )
1767 : : return;
1768 : 0 : continue;
1769 : : }
1770 : 0 : break;
1771 : : }
1772 : : }
1773 : 0 : if ( nHeight != nHeightOrg )
1774 : : {
1775 : 0 : nYHeight = nYHeightOrg * nHeight / nHeightOrg;
1776 : 0 : aTileBitmap.Crop( Rectangle( Point( 0, nHeightOrg - nHeightLeft ), Size( nWidth, nHeight ) ) );
1777 : : }
1778 : 0 : if ( bDoTrans )
1779 : : {
1780 : 0 : ImplWriteLine( "gs\npum" );
1781 : 0 : ImplTranslate( aSourcePos.X(), aSourcePos.Y() );
1782 : 0 : ImplScale( nXWidth / nWidth, nYHeight / nHeight );
1783 : 0 : RegionHandle hRegionHandle = aRegion.BeginEnumRects();
1784 : :
1785 : 0 : while ( aRegion.GetNextEnumRect( hRegionHandle, aRect ) )
1786 : : {
1787 : 0 : aRect.Move( 0, - ( nHeightOrg - nHeightLeft ) );
1788 : 0 : ImplWriteLong( aRect.Left() );
1789 : 0 : ImplWriteLong( aRect.Top() );
1790 : 0 : ImplWriteByte( 'm' );
1791 : 0 : ImplWriteLong( aRect.Right() + 1 );
1792 : 0 : ImplWriteLong( aRect.Top() );
1793 : 0 : ImplWriteByte( 'l' );
1794 : 0 : ImplWriteLong( aRect.Right() + 1 );
1795 : 0 : ImplWriteLong( aRect.Bottom() + 1 );
1796 : 0 : ImplWriteByte( 'l' );
1797 : 0 : ImplWriteLong( aRect.Left() );
1798 : 0 : ImplWriteLong( aRect.Bottom() + 1 );
1799 : 0 : ImplWriteByte( 'l' );
1800 : 0 : ImplWriteByte( 'p', PS_SPACE | PS_WRAP );
1801 : : };
1802 : 0 : aRegion.EndEnumRects( hRegionHandle );
1803 : 0 : ImplWriteLine( "eoclip newpath" );
1804 : 0 : ImplWriteLine( "pom" );
1805 : : }
1806 : 0 : BitmapReadAccess* pAcc = aTileBitmap.AcquireReadAccess();
1807 : :
1808 : 0 : if (!bDoTrans )
1809 : 0 : ImplWriteLine( "pum" );
1810 : :
1811 : 0 : ImplTranslate( aSourcePos.X(), aSourcePos.Y() + nYHeight );
1812 : 0 : ImplScale( nXWidth, nYHeight );
1813 : 0 : if ( mnLevel == 1 ) // level 1 is always grayscale !!!
1814 : : {
1815 : 0 : ImplWriteLong( nWidth );
1816 : 0 : ImplWriteLong( nHeight );
1817 : 0 : *mpPS << "8 [";
1818 : 0 : ImplWriteLong( nWidth );
1819 : 0 : *mpPS << "0 0 ";
1820 : 0 : ImplWriteLong( -nHeight );
1821 : 0 : ImplWriteLong( 0 );
1822 : 0 : ImplWriteLong( nHeight );
1823 : 0 : ImplWriteLine( "]" );
1824 : 0 : *mpPS << "{currentfile ";
1825 : 0 : ImplWriteLong( nWidth );
1826 : 0 : ImplWriteLine( "string readhexstring pop}" );
1827 : 0 : ImplWriteLine( "image" );
1828 : 0 : for ( long y = 0; y < nHeight; y++ )
1829 : : {
1830 : 0 : for ( long x = 0; x < nWidth; x++ )
1831 : : {
1832 : 0 : ImplWriteHexByte( (sal_uInt8)pAcc->GetPixel( y, x ) );
1833 : : }
1834 : : }
1835 : 0 : *mpPS << (sal_uInt8)10;
1836 : : }
1837 : : else // Level 2
1838 : : {
1839 : 0 : if ( mbGrayScale )
1840 : : {
1841 : 0 : ImplWriteLine( "/DeviceGray setcolorspace" );
1842 : 0 : ImplWriteLine( "<<" );
1843 : 0 : ImplWriteLine( "/ImageType 1" );
1844 : 0 : *mpPS << "/Width ";
1845 : 0 : ImplWriteLong( nWidth, PS_RET );
1846 : 0 : *mpPS << "/Height ";
1847 : 0 : ImplWriteLong( nHeight, PS_RET );
1848 : 0 : ImplWriteLine( "/BitsPerComponent 8" );
1849 : 0 : ImplWriteLine( "/Decode[0 1]" );
1850 : 0 : *mpPS << "/ImageMatrix[";
1851 : 0 : ImplWriteLong( nWidth );
1852 : 0 : *mpPS << "0 0 ";
1853 : 0 : ImplWriteLong( -nHeight );
1854 : 0 : ImplWriteLong( 0 );
1855 : 0 : ImplWriteLong( nHeight, PS_NONE );
1856 : 0 : ImplWriteByte( ']', PS_RET );
1857 : 0 : ImplWriteLine( "/DataSource currentfile" );
1858 : 0 : ImplWriteLine( "/ASCIIHexDecode filter" );
1859 : 0 : if ( mbCompression )
1860 : 0 : ImplWriteLine( "/LZWDecode filter" );
1861 : 0 : ImplWriteLine( ">>" );
1862 : 0 : ImplWriteLine( "image" );
1863 : 0 : if ( mbCompression )
1864 : : {
1865 : 0 : StartCompression();
1866 : 0 : for ( long y = 0; y < nHeight; y++ )
1867 : : {
1868 : 0 : for ( long x = 0; x < nWidth; x++ )
1869 : : {
1870 : 0 : Compress( (sal_uInt8)pAcc->GetPixel( y, x ) );
1871 : : }
1872 : : }
1873 : 0 : EndCompression();
1874 : : }
1875 : : else
1876 : : {
1877 : 0 : for ( long y = 0; y < nHeight; y++ )
1878 : : {
1879 : 0 : for ( long x = 0; x < nWidth; x++ )
1880 : : {
1881 : 0 : ImplWriteHexByte( (sal_uInt8)pAcc->GetPixel( y, x ) );
1882 : : }
1883 : : }
1884 : : }
1885 : : }
1886 : : else
1887 : : {
1888 : : // have we to write a palette ?
1889 : :
1890 : 0 : if ( pAcc->HasPalette() )
1891 : : {
1892 : 0 : ImplWriteLine( "[/Indexed /DeviceRGB " );
1893 : 0 : ImplWriteLong( pAcc->GetPaletteEntryCount() - 1, PS_RET );
1894 : 0 : ImplWriteByte( '<', PS_NONE );
1895 : 0 : for ( sal_uInt16 i = 0; i < pAcc->GetPaletteEntryCount(); i++ )
1896 : : {
1897 : 0 : BitmapColor aBitmapColor = pAcc->GetPaletteColor( i );
1898 : 0 : ImplWriteHexByte( aBitmapColor.GetRed(), PS_NONE );
1899 : 0 : ImplWriteHexByte( aBitmapColor.GetGreen(), PS_NONE );
1900 : 0 : ImplWriteHexByte( aBitmapColor.GetBlue(), PS_SPACE | PS_WRAP );
1901 : 0 : }
1902 : 0 : ImplWriteByte( '>', PS_RET );
1903 : :
1904 : 0 : ImplWriteLine( "] setcolorspace" );
1905 : 0 : ImplWriteLine( "<<" );
1906 : 0 : ImplWriteLine( "/ImageType 1" );
1907 : 0 : *mpPS << "/Width ";
1908 : 0 : ImplWriteLong( nWidth, PS_RET );
1909 : 0 : *mpPS << "/Height ";
1910 : 0 : ImplWriteLong( nHeight, PS_RET );
1911 : 0 : ImplWriteLine( "/BitsPerComponent 8" );
1912 : 0 : ImplWriteLine( "/Decode[0 255]" );
1913 : 0 : *mpPS << "/ImageMatrix[";
1914 : 0 : ImplWriteLong( nWidth );
1915 : 0 : *mpPS << "0 0 ";
1916 : 0 : ImplWriteLong( -nHeight );
1917 : 0 : ImplWriteLong( 0);
1918 : 0 : ImplWriteLong( nHeight, PS_NONE );
1919 : 0 : ImplWriteByte( ']', PS_RET );
1920 : 0 : ImplWriteLine( "/DataSource currentfile" );
1921 : 0 : ImplWriteLine( "/ASCIIHexDecode filter" );
1922 : 0 : if ( mbCompression )
1923 : 0 : ImplWriteLine( "/LZWDecode filter" );
1924 : 0 : ImplWriteLine( ">>" );
1925 : 0 : ImplWriteLine( "image" );
1926 : 0 : if ( mbCompression )
1927 : : {
1928 : 0 : StartCompression();
1929 : 0 : for ( long y = 0; y < nHeight; y++ )
1930 : : {
1931 : 0 : for ( long x = 0; x < nWidth; x++ )
1932 : : {
1933 : 0 : Compress( (sal_uInt8)pAcc->GetPixel( y, x ) );
1934 : : }
1935 : : }
1936 : 0 : EndCompression();
1937 : : }
1938 : : else
1939 : : {
1940 : 0 : for ( long y = 0; y < nHeight; y++ )
1941 : : {
1942 : 0 : for ( long x = 0; x < nWidth; x++ )
1943 : : {
1944 : 0 : ImplWriteHexByte( (sal_uInt8)pAcc->GetPixel( y, x ) );
1945 : : }
1946 : : }
1947 : : }
1948 : : }
1949 : : else // 24 bit color
1950 : : {
1951 : 0 : ImplWriteLine( "/DeviceRGB setcolorspace" );
1952 : 0 : ImplWriteLine( "<<" );
1953 : 0 : ImplWriteLine( "/ImageType 1" );
1954 : 0 : *mpPS << "/Width ";
1955 : 0 : ImplWriteLong( nWidth, PS_RET );
1956 : 0 : *mpPS << "/Height ";
1957 : 0 : ImplWriteLong( nHeight, PS_RET );
1958 : 0 : ImplWriteLine( "/BitsPerComponent 8" );
1959 : 0 : ImplWriteLine( "/Decode[0 1 0 1 0 1]" );
1960 : 0 : *mpPS << "/ImageMatrix[";
1961 : 0 : ImplWriteLong( nWidth );
1962 : 0 : *mpPS << "0 0 ";
1963 : 0 : ImplWriteLong( -nHeight );
1964 : 0 : ImplWriteLong( 0 );
1965 : 0 : ImplWriteLong( nHeight, PS_NONE );
1966 : 0 : ImplWriteByte( ']', PS_RET );
1967 : 0 : ImplWriteLine( "/DataSource currentfile" );
1968 : 0 : ImplWriteLine( "/ASCIIHexDecode filter" );
1969 : 0 : if ( mbCompression )
1970 : 0 : ImplWriteLine( "/LZWDecode filter" );
1971 : 0 : ImplWriteLine( ">>" );
1972 : 0 : ImplWriteLine( "image" );
1973 : 0 : if ( mbCompression )
1974 : : {
1975 : 0 : StartCompression();
1976 : 0 : for ( long y = 0; y < nHeight; y++ )
1977 : : {
1978 : 0 : for ( long x = 0; x < nWidth; x++ )
1979 : : {
1980 : 0 : const BitmapColor aBitmapColor( pAcc->GetPixel( y, x ) );
1981 : 0 : Compress( aBitmapColor.GetRed() );
1982 : 0 : Compress( aBitmapColor.GetGreen() );
1983 : 0 : Compress( aBitmapColor.GetBlue() );
1984 : 0 : }
1985 : : }
1986 : 0 : EndCompression();
1987 : : }
1988 : : else
1989 : : {
1990 : 0 : for ( long y = 0; y < nHeight; y++ )
1991 : : {
1992 : 0 : for ( long x = 0; x < nWidth; x++ )
1993 : : {
1994 : 0 : const BitmapColor aBitmapColor( pAcc->GetPixel( y, x ) );
1995 : 0 : ImplWriteHexByte( aBitmapColor.GetRed() );
1996 : 0 : ImplWriteHexByte( aBitmapColor.GetGreen() );
1997 : 0 : ImplWriteHexByte( aBitmapColor.GetBlue() );
1998 : 0 : }
1999 : : }
2000 : : }
2001 : : }
2002 : : }
2003 : 0 : ImplWriteLine( ">" ); // in Level 2 the dictionary needs to be closed (eod)
2004 : : }
2005 : 0 : if ( bDoTrans )
2006 : 0 : ImplWriteLine( "gr" );
2007 : : else
2008 : 0 : ImplWriteLine( "pom" );
2009 : :
2010 : 0 : aTileBitmap.ReleaseAccess( pAcc );
2011 : 0 : nHeightLeft -= nHeight;
2012 : 0 : if ( nHeightLeft )
2013 : : {
2014 : 0 : nHeightLeft++;
2015 : 0 : aSourcePos.Y() = (long) ( rPoint.Y() + ( nYHeightOrg * ( nHeightOrg - nHeightLeft ) ) / nHeightOrg );
2016 : : }
2017 : 0 : }
2018 : : }
2019 : :
2020 : : //---------------------------------------------------------------------------------
2021 : :
2022 : 0 : void PSWriter::ImplWriteCharacter( sal_Char nChar )
2023 : : {
2024 : 0 : switch( nChar )
2025 : : {
2026 : : case '(' :
2027 : : case ')' :
2028 : : case '\\' :
2029 : 0 : ImplWriteByte( (sal_uInt8)'\\', PS_NONE );
2030 : : }
2031 : 0 : ImplWriteByte( (sal_uInt8)nChar, PS_NONE );
2032 : 0 : }
2033 : :
2034 : : //---------------------------------------------------------------------------------
2035 : :
2036 : 0 : void PSWriter::ImplWriteString( const rtl::OString& rString, VirtualDevice& rVDev, const sal_Int32* pDXArry, sal_Bool bStretch )
2037 : : {
2038 : 0 : sal_Int32 nLen = rString.getLength();
2039 : 0 : if ( nLen )
2040 : : {
2041 : 0 : if ( pDXArry )
2042 : : {
2043 : 0 : double nx = 0;
2044 : :
2045 : 0 : for (sal_Int32 i = 0; i < nLen; ++i)
2046 : : {
2047 : 0 : if ( i > 0 )
2048 : 0 : nx = pDXArry[ i - 1 ];
2049 : 0 : ImplWriteDouble( ( bStretch ) ? nx : rVDev.GetTextWidth( rtl::OUString(rString[i]) ) );
2050 : 0 : ImplWriteDouble( nx );
2051 : 0 : ImplWriteLine( "(", PS_NONE );
2052 : 0 : ImplWriteCharacter( rString[i] );
2053 : 0 : ImplWriteLine( ") bs" );
2054 : : }
2055 : : }
2056 : : else
2057 : : {
2058 : 0 : ImplWriteByte( '(', PS_NONE );
2059 : 0 : for (sal_Int32 i = 0; i < nLen; ++i)
2060 : 0 : ImplWriteCharacter( rString[i] );
2061 : 0 : ImplWriteLine( ") sw" );
2062 : : }
2063 : : }
2064 : 0 : }
2065 : :
2066 : : // ------------------------------------------------------------------------
2067 : :
2068 : 0 : void PSWriter::ImplText( const String& rUniString, const Point& rPos, const sal_Int32* pDXArry, sal_Int32 nWidth, VirtualDevice& rVDev )
2069 : : {
2070 : 0 : sal_uInt16 nLen = rUniString.Len();
2071 : 0 : if ( !nLen )
2072 : 0 : return;
2073 : 0 : if ( mnTextMode == 0 ) // using glpyh outlines
2074 : : {
2075 : 0 : Font aNotRotatedFont( maFont );
2076 : 0 : aNotRotatedFont.SetOrientation( 0 );
2077 : :
2078 : 0 : VirtualDevice aVirDev( 1 );
2079 : 0 : aVirDev.SetMapMode( rVDev.GetMapMode() );
2080 : 0 : aVirDev.SetFont( aNotRotatedFont );
2081 : 0 : aVirDev.SetTextAlign( eTextAlign );
2082 : :
2083 : 0 : sal_Int16 nRotation = maFont.GetOrientation();
2084 : 0 : Polygon aPolyDummy( 1 );
2085 : :
2086 : 0 : PolyPolygon aPolyPoly;
2087 : 0 : Point aPos( rPos );
2088 : 0 : if ( nRotation )
2089 : : {
2090 : 0 : aPolyDummy.SetPoint( aPos, 0 );
2091 : 0 : aPolyDummy.Rotate( rPos, nRotation );
2092 : 0 : aPos = aPolyDummy.GetPoint( 0 );
2093 : : }
2094 : 0 : sal_Bool bOldLineColor = bLineColor;
2095 : 0 : bLineColor = sal_False;
2096 : 0 : std::vector<PolyPolygon> aPolyPolyVec;
2097 : 0 : if ( aVirDev.GetTextOutlines( aPolyPolyVec, rUniString, 0, 0, STRING_LEN, sal_True, nWidth, pDXArry ) )
2098 : : {
2099 : : // always adjust text position to match baseline alignment
2100 : 0 : ImplWriteLine( "pum" );
2101 : 0 : ImplWriteDouble( aPos.X() );
2102 : 0 : ImplWriteDouble( aPos.Y() );
2103 : 0 : ImplWriteLine( "t" );
2104 : 0 : if ( nRotation )
2105 : : {
2106 : 0 : ImplWriteF( nRotation, 1 );
2107 : 0 : *mpPS << "r ";
2108 : : }
2109 : 0 : std::vector<PolyPolygon>::iterator aIter( aPolyPolyVec.begin() );
2110 : 0 : while ( aIter != aPolyPolyVec.end() )
2111 : 0 : ImplPolyPoly( *aIter++, sal_True );
2112 : 0 : ImplWriteLine( "pom" );
2113 : : }
2114 : 0 : bLineColor = bOldLineColor;
2115 : : }
2116 : 0 : else if ( ( mnTextMode == 1 ) || ( mnTextMode == 2 ) ) // normal text output
2117 : : {
2118 : 0 : if ( mnTextMode == 2 ) // forcing output one complete text packet, by
2119 : 0 : pDXArry = NULL; // ignoring the kerning array
2120 : 0 : ImplSetAttrForText( rPos );
2121 : : rtl::OString aStr(rtl::OUStringToOString(rUniString,
2122 : 0 : maFont.GetCharSet()));
2123 : 0 : ImplWriteString( aStr, rVDev, pDXArry, nWidth != 0 );
2124 : 0 : if ( maFont.GetOrientation() )
2125 : 0 : ImplWriteLine( "gr" );
2126 : : }
2127 : : }
2128 : :
2129 : : // ------------------------------------------------------------------------
2130 : :
2131 : 0 : void PSWriter::ImplSetAttrForText( const Point& rPoint )
2132 : : {
2133 : 0 : Point aPoint( rPoint );
2134 : :
2135 : 0 : long nRotation = maFont.GetOrientation();
2136 : 0 : ImplWriteTextColor();
2137 : :
2138 : 0 : Size aSize = maFont.GetSize();
2139 : :
2140 : 0 : if ( maLastFont != maFont )
2141 : : {
2142 : 0 : if ( maFont.GetPitch() == PITCH_FIXED ) // a little bit font selection
2143 : 0 : ImplDefineFont( "Courier", "Oblique" );
2144 : 0 : else if ( maFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
2145 : 0 : ImplWriteLine( "/Symbol findfont" );
2146 : 0 : else if ( maFont.GetFamily() == FAMILY_SWISS )
2147 : 0 : ImplDefineFont( "Helvetica", "Oblique" );
2148 : : else
2149 : 0 : ImplDefineFont( "Times", "Italic" );
2150 : :
2151 : 0 : maLastFont = maFont;
2152 : 0 : aSize = maFont.GetSize();
2153 : 0 : ImplWriteDouble( aSize.Height() );
2154 : 0 : *mpPS << "sf ";
2155 : : }
2156 : 0 : if ( eTextAlign != ALIGN_BASELINE )
2157 : : { // PostScript kennt kein FontAlignment
2158 : 0 : if ( eTextAlign == ALIGN_TOP ) // -> ich gehe daher davon aus, dass
2159 : 0 : aPoint.Y() += ( aSize.Height() * 4 / 5 ); // der Bereich unter der Baseline
2160 : 0 : else if ( eTextAlign == ALIGN_BOTTOM ) // in etwa 20% der Fontsize ausmacht
2161 : 0 : aPoint.Y() -= ( aSize.Height() / 5 );
2162 : : }
2163 : 0 : ImplMoveTo( aPoint );
2164 : 0 : if ( nRotation )
2165 : : {
2166 : 0 : *mpPS << "gs ";
2167 : 0 : ImplWriteF( nRotation, 1 );
2168 : 0 : *mpPS << "r ";
2169 : : }
2170 : 0 : }
2171 : :
2172 : : //---------------------------------------------------------------------------------
2173 : :
2174 : 0 : void PSWriter::ImplDefineFont( const char* pOriginalName, const char* pItalic )
2175 : : {
2176 : 0 : *mpPS << (sal_uInt8)'/'; //convert the font pOriginalName using ISOLatin1Encoding
2177 : 0 : *mpPS << pOriginalName;
2178 : 0 : switch ( maFont.GetWeight() )
2179 : : {
2180 : : case WEIGHT_SEMIBOLD :
2181 : : case WEIGHT_BOLD :
2182 : : case WEIGHT_ULTRABOLD :
2183 : : case WEIGHT_BLACK :
2184 : 0 : *mpPS << "-Bold";
2185 : 0 : if ( maFont.GetItalic() != ITALIC_NONE )
2186 : 0 : *mpPS << pItalic;
2187 : 0 : break;
2188 : : default:
2189 : 0 : if ( maFont.GetItalic() != ITALIC_NONE )
2190 : 0 : *mpPS << pItalic;
2191 : 0 : break;
2192 : : }
2193 : 0 : ImplWriteLine( " f" );
2194 : 0 : }
2195 : :
2196 : : //---------------------------------------------------------------------------------
2197 : : //---------------------------------------------------------------------------------
2198 : : //---------------------------------------------------------------------------------
2199 : :
2200 : 0 : void PSWriter::ImplClosePathDraw( sal_uLong nMode )
2201 : : {
2202 : 0 : *mpPS << "pc";
2203 : 0 : mnCursorPos += 2;
2204 : 0 : ImplExecMode( nMode );
2205 : 0 : }
2206 : :
2207 : 0 : void PSWriter::ImplPathDraw()
2208 : : {
2209 : 0 : *mpPS << "ps";
2210 : 0 : mnCursorPos += 2;
2211 : 0 : ImplExecMode( PS_RET );
2212 : 0 : }
2213 : :
2214 : : //---------------------------------------------------------------------------------
2215 : :
2216 : 0 : inline void PSWriter::ImplWriteLineColor( sal_uLong nMode )
2217 : : {
2218 : 0 : if ( aColor != aLineColor )
2219 : : {
2220 : 0 : aColor = aLineColor;
2221 : 0 : ImplWriteColor( nMode );
2222 : : }
2223 : 0 : }
2224 : 0 : inline void PSWriter::ImplWriteFillColor( sal_uLong nMode )
2225 : : {
2226 : 0 : if ( aColor != aFillColor )
2227 : : {
2228 : 0 : aColor = aFillColor;
2229 : 0 : ImplWriteColor( nMode );
2230 : : }
2231 : 0 : }
2232 : 0 : inline void PSWriter::ImplWriteTextColor( sal_uLong nMode )
2233 : : {
2234 : 0 : if ( aColor != aTextColor )
2235 : : {
2236 : 0 : aColor = aTextColor;
2237 : 0 : ImplWriteColor( nMode );
2238 : : }
2239 : 0 : }
2240 : : inline void PSWriter::ImplWriteTextFillColor( sal_uLong nMode )
2241 : : {
2242 : : if ( aColor != aTextFillColor )
2243 : : {
2244 : : aColor = aTextFillColor;
2245 : : ImplWriteColor( nMode );
2246 : : }
2247 : : }
2248 : :
2249 : : //---------------------------------------------------------------------------------
2250 : :
2251 : 0 : void PSWriter::ImplWriteColor( sal_uLong nMode )
2252 : : {
2253 : 0 : if ( mbGrayScale )
2254 : : {
2255 : : // writes the Color (grayscale) as a Number from 0.000 up to 1.000
2256 : :
2257 : 0 : ImplWriteF( 1000 * ( (sal_uInt8)aColor.GetRed() * 77 + (sal_uInt8)aColor.GetGreen() * 151 +
2258 : 0 : (sal_uInt8)aColor.GetBlue() * 28 + 1 ) / 65536, 3, nMode );
2259 : : }
2260 : : else
2261 : : {
2262 : 0 : ImplWriteB1 ( (sal_uInt8)aColor.GetRed() );
2263 : 0 : ImplWriteB1 ( (sal_uInt8)aColor.GetGreen() );
2264 : 0 : ImplWriteB1 ( (sal_uInt8)aColor.GetBlue() );
2265 : : }
2266 : 0 : *mpPS << "c"; // ( c is defined as setrgbcolor or setgray )
2267 : 0 : ImplExecMode( nMode );
2268 : 0 : }
2269 : :
2270 : : //---------------------------------------------------------------------------------
2271 : :
2272 : 0 : double PSWriter::ImplGetScaling( const MapMode& rMapMode )
2273 : : {
2274 : : double nMul;
2275 : 0 : switch ( rMapMode.GetMapUnit() )
2276 : : {
2277 : : case MAP_PIXEL :
2278 : : case MAP_SYSFONT :
2279 : : case MAP_APPFONT :
2280 : :
2281 : : case MAP_100TH_MM :
2282 : 0 : nMul = 1;
2283 : 0 : break;
2284 : : case MAP_10TH_MM :
2285 : 0 : nMul = 10;
2286 : 0 : break;
2287 : : case MAP_MM :
2288 : 0 : nMul = 100;
2289 : 0 : break;
2290 : : case MAP_CM :
2291 : 0 : nMul = 1000;
2292 : 0 : break;
2293 : : case MAP_1000TH_INCH :
2294 : 0 : nMul = 2.54;
2295 : 0 : break;
2296 : : case MAP_100TH_INCH :
2297 : 0 : nMul = 25.4;
2298 : 0 : break;
2299 : : case MAP_10TH_INCH :
2300 : 0 : nMul = 254;
2301 : 0 : break;
2302 : : case MAP_INCH :
2303 : 0 : nMul = 2540;
2304 : 0 : break;
2305 : : case MAP_TWIP :
2306 : 0 : nMul = 1.76388889;
2307 : 0 : break;
2308 : : case MAP_POINT :
2309 : 0 : nMul = 35.27777778;
2310 : 0 : break;
2311 : : default:
2312 : 0 : nMul = 1.0;
2313 : 0 : break;
2314 : : }
2315 : 0 : return nMul;
2316 : : }
2317 : :
2318 : : //---------------------------------------------------------------------------------
2319 : :
2320 : 0 : void PSWriter::ImplGetMapMode( const MapMode& rMapMode )
2321 : : {
2322 : 0 : ImplWriteLine( "tm setmatrix" );
2323 : 0 : double fMul = ImplGetScaling( rMapMode );
2324 : 0 : double fScaleX = (double)rMapMode.GetScaleX() * fMul;
2325 : 0 : double fScaleY = (double)rMapMode.GetScaleY() * fMul;
2326 : 0 : ImplTranslate( rMapMode.GetOrigin().X() * fScaleX, rMapMode.GetOrigin().Y() * fScaleY );
2327 : 0 : ImplScale( fScaleX, fScaleY );
2328 : 0 : }
2329 : :
2330 : : //---------------------------------------------------------------------------------
2331 : :
2332 : 0 : inline void PSWriter::ImplExecMode( sal_uLong nMode )
2333 : : {
2334 : 0 : if ( nMode & PS_WRAP )
2335 : : {
2336 : 0 : if ( mnCursorPos >= PS_LINESIZE )
2337 : : {
2338 : 0 : mnCursorPos = 0;
2339 : 0 : *mpPS << (sal_uInt8)0xa;
2340 : 0 : return;
2341 : : }
2342 : : }
2343 : 0 : if ( nMode & PS_SPACE )
2344 : : {
2345 : 0 : *mpPS << (sal_uInt8)32;
2346 : 0 : mnCursorPos++;
2347 : : }
2348 : 0 : if ( nMode & PS_RET )
2349 : : {
2350 : 0 : *mpPS << (sal_uInt8)0xa;
2351 : 0 : mnCursorPos = 0;
2352 : : }
2353 : : }
2354 : :
2355 : : //---------------------------------------------------------------------------------
2356 : :
2357 : 0 : inline void PSWriter::ImplWriteLine( const char* pString, sal_uLong nMode )
2358 : : {
2359 : 0 : sal_uLong i = 0;
2360 : 0 : while ( pString[ i ] )
2361 : : {
2362 : 0 : *mpPS << (sal_uInt8)pString[ i++ ];
2363 : : }
2364 : 0 : mnCursorPos += i;
2365 : 0 : ImplExecMode( nMode );
2366 : 0 : }
2367 : :
2368 : : //---------------------------------------------------------------------------------
2369 : :
2370 : 0 : void PSWriter::ImplWriteLineInfo( double fLWidth, double fMLimit,
2371 : : SvtGraphicStroke::CapType eLCap,
2372 : : SvtGraphicStroke::JoinType eJoin,
2373 : : SvtGraphicStroke::DashArray& rLDash )
2374 : : {
2375 : 0 : if ( fLineWidth != fLWidth )
2376 : : {
2377 : 0 : fLineWidth = fLWidth;
2378 : 0 : ImplWriteDouble( fLineWidth );
2379 : 0 : ImplWriteLine( "lw", PS_SPACE );
2380 : : }
2381 : 0 : if ( eLineCap != eLCap )
2382 : : {
2383 : 0 : eLineCap = eLCap;
2384 : 0 : ImplWriteLong( (sal_Int32)eLineCap, PS_SPACE );
2385 : 0 : ImplWriteLine( "lc", PS_SPACE );
2386 : : }
2387 : 0 : if ( eJoinType != eJoin )
2388 : : {
2389 : 0 : eJoinType = eJoin;
2390 : 0 : ImplWriteLong( (sal_Int32)eJoinType, PS_SPACE );
2391 : 0 : ImplWriteLine( "lj", PS_SPACE );
2392 : : }
2393 : 0 : if ( eJoinType == SvtGraphicStroke::joinMiter )
2394 : : {
2395 : 0 : if ( fMiterLimit != fMLimit )
2396 : : {
2397 : 0 : fMiterLimit = fMLimit;
2398 : 0 : ImplWriteDouble( fMiterLimit );
2399 : 0 : ImplWriteLine( "ml", PS_SPACE );
2400 : : }
2401 : : }
2402 : 0 : if ( aDashArray != rLDash )
2403 : : {
2404 : 0 : aDashArray = rLDash;
2405 : 0 : sal_uInt32 j, i = aDashArray.size();
2406 : 0 : ImplWriteLine( "[", PS_SPACE );
2407 : 0 : for ( j = 0; j < i; j++ )
2408 : 0 : ImplWriteDouble( aDashArray[ j ] );
2409 : 0 : ImplWriteLine( "] 0 ld" );
2410 : : }
2411 : 0 : }
2412 : :
2413 : : //---------------------------------------------------------------------------------
2414 : :
2415 : 0 : void PSWriter::ImplWriteLineInfo( const LineInfo& rLineInfo )
2416 : : {
2417 : 0 : SvtGraphicStroke::DashArray l_aDashArray;
2418 : 0 : if ( rLineInfo.GetStyle() == LINE_DASH )
2419 : 0 : l_aDashArray.push_back( 2 );
2420 : 0 : const double fLWidth(( ( rLineInfo.GetWidth() + 1 ) + ( rLineInfo.GetWidth() + 1 ) ) * 0.5);
2421 : 0 : SvtGraphicStroke::JoinType aJoinType(SvtGraphicStroke::joinMiter);
2422 : :
2423 : 0 : switch(rLineInfo.GetLineJoin())
2424 : : {
2425 : : default: // B2DLINEJOIN_NONE, B2DLINEJOIN_MIDDLE
2426 : : // do NOT use SvtGraphicStroke::joinNone here
2427 : : // since it will be written as numerical value directly
2428 : : // and is NOT a valid EPS value
2429 : 0 : break;
2430 : : case basegfx::B2DLINEJOIN_MITER:
2431 : 0 : aJoinType = SvtGraphicStroke::joinMiter;
2432 : 0 : break;
2433 : : case basegfx::B2DLINEJOIN_BEVEL:
2434 : 0 : aJoinType = SvtGraphicStroke::joinBevel;
2435 : 0 : break;
2436 : : case basegfx::B2DLINEJOIN_ROUND:
2437 : 0 : aJoinType = SvtGraphicStroke::joinRound;
2438 : 0 : break;
2439 : : }
2440 : :
2441 : 0 : ImplWriteLineInfo( fLWidth, fMiterLimit, SvtGraphicStroke::capButt, aJoinType, l_aDashArray );
2442 : 0 : }
2443 : :
2444 : : //---------------------------------------------------------------------------------
2445 : :
2446 : 0 : void PSWriter::ImplWriteLong(sal_Int32 nNumber, sal_uLong nMode)
2447 : : {
2448 : 0 : const rtl::OString aNumber(rtl::OString::valueOf(nNumber));
2449 : 0 : mnCursorPos += aNumber.getLength();
2450 : 0 : *mpPS << aNumber.getStr();
2451 : 0 : ImplExecMode(nMode);
2452 : 0 : }
2453 : :
2454 : : //---------------------------------------------------------------------------------
2455 : :
2456 : 0 : void PSWriter::ImplWriteDouble( double fNumber, sal_uLong nMode )
2457 : : {
2458 : 0 : sal_Int32 nPTemp = (sal_Int32)fNumber;
2459 : 0 : sal_Int32 nATemp = labs( (sal_Int32)( ( fNumber - nPTemp ) * 100000 ) );
2460 : :
2461 : 0 : if ( !nPTemp && nATemp && ( fNumber < 0.0 ) )
2462 : 0 : *mpPS << (sal_Char)'-';
2463 : :
2464 : 0 : const rtl::OString aNumber1(rtl::OString::valueOf(nPTemp));
2465 : 0 : *mpPS << aNumber1.getStr();
2466 : 0 : mnCursorPos += aNumber1.getLength();
2467 : :
2468 : 0 : if ( nATemp )
2469 : : {
2470 : 0 : int zCount = 0;
2471 : 0 : *mpPS << (sal_uInt8)'.';
2472 : 0 : mnCursorPos++;
2473 : 0 : const rtl::OString aNumber2(rtl::OString::valueOf(nATemp));
2474 : :
2475 : 0 : sal_Int16 n, nLen = aNumber2.getLength();
2476 : 0 : if ( nLen < 8 )
2477 : : {
2478 : 0 : mnCursorPos += 6 - nLen;
2479 : 0 : for ( n = 0; n < ( 5 - nLen ); n++ )
2480 : : {
2481 : 0 : *mpPS << (sal_uInt8)'0';
2482 : : }
2483 : : }
2484 : 0 : mnCursorPos += nLen;
2485 : 0 : for ( n = 0; n < nLen; n++ )
2486 : : {
2487 : 0 : *mpPS << aNumber2[n];
2488 : 0 : zCount--;
2489 : 0 : if ( aNumber2[n] != '0' )
2490 : 0 : zCount = 0;
2491 : : }
2492 : 0 : if ( zCount )
2493 : 0 : mpPS->SeekRel( zCount );
2494 : : }
2495 : 0 : ImplExecMode( nMode );
2496 : 0 : }
2497 : :
2498 : : //---------------------------------------------------------------------------------
2499 : :
2500 : : // writes the number to stream: nNumber / ( 10^nCount )
2501 : :
2502 : 0 : void PSWriter::ImplWriteF( sal_Int32 nNumber, sal_uLong nCount, sal_uLong nMode )
2503 : : {
2504 : 0 : if ( nNumber < 0 )
2505 : : {
2506 : 0 : *mpPS << (sal_uInt8)'-';
2507 : 0 : nNumber = -nNumber;
2508 : 0 : mnCursorPos++;
2509 : : }
2510 : 0 : const rtl::OString aScaleFactor(rtl::OString::valueOf(nNumber));
2511 : 0 : sal_uLong nLen = aScaleFactor.getLength();
2512 : 0 : long nStSize = ( nCount + 1 ) - nLen;
2513 : 0 : if ( nStSize >= 1 )
2514 : : {
2515 : 0 : *mpPS << (sal_uInt8)'0';
2516 : 0 : mnCursorPos++;
2517 : : }
2518 : 0 : if ( nStSize >= 2 )
2519 : : {
2520 : 0 : *mpPS << (sal_uInt8)'.';
2521 : 0 : for ( long i = 1; i < nStSize; i++ )
2522 : : {
2523 : 0 : *mpPS << (sal_uInt8)'0';
2524 : 0 : mnCursorPos++;
2525 : : }
2526 : : }
2527 : 0 : mnCursorPos += nLen;
2528 : 0 : for( sal_uInt16 n = 0UL; n < nLen; n++ )
2529 : : {
2530 : 0 : if ( n == nLen - nCount )
2531 : : {
2532 : 0 : *mpPS << (sal_uInt8)'.';
2533 : 0 : mnCursorPos++;
2534 : : }
2535 : 0 : *mpPS << aScaleFactor[n];
2536 : : }
2537 : 0 : ImplExecMode( nMode );
2538 : 0 : }
2539 : :
2540 : : //---------------------------------------------------------------------------------
2541 : :
2542 : 0 : void PSWriter::ImplWriteByte( sal_uInt8 nNumb, sal_uLong nMode )
2543 : : {
2544 : 0 : *mpPS << ( nNumb );
2545 : 0 : mnCursorPos++;
2546 : 0 : ImplExecMode( nMode );
2547 : 0 : }
2548 : :
2549 : : //---------------------------------------------------------------------------------
2550 : :
2551 : 0 : void PSWriter::ImplWriteHexByte( sal_uInt8 nNumb, sal_uLong nMode )
2552 : : {
2553 : 0 : if ( ( nNumb >> 4 ) > 9 )
2554 : 0 : *mpPS << (sal_uInt8)( ( nNumb >> 4 ) + 'A' - 10 );
2555 : : else
2556 : 0 : *mpPS << (sal_uInt8)( ( nNumb >> 4 ) + '0' );
2557 : :
2558 : 0 : if ( ( nNumb & 0xf ) > 9 )
2559 : 0 : *mpPS << (sal_uInt8)( ( nNumb & 0xf ) + 'A' - 10 );
2560 : : else
2561 : 0 : *mpPS << (sal_uInt8)( ( nNumb & 0xf ) + '0' );
2562 : 0 : mnCursorPos += 2;
2563 : 0 : ImplExecMode( nMode );
2564 : 0 : }
2565 : :
2566 : : //---------------------------------------------------------------------------------
2567 : :
2568 : : // writes the sal_uInt8 nNumb as a Number from 0.000 up to 1.000
2569 : :
2570 : 0 : void PSWriter::ImplWriteB1( sal_uInt8 nNumb, sal_uLong nMode )
2571 : : {
2572 : 0 : ImplWriteF( 1000 * ( nNumb + 1 ) / 256 , 3, nMode );
2573 : 0 : }
2574 : :
2575 : :
2576 : : // ------------------------------------------------------------------------
2577 : :
2578 : 0 : inline void PSWriter::WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen )
2579 : : {
2580 : 0 : dwShift |= ( nCode << ( nOffset - nCodeLen ) );
2581 : 0 : nOffset -= nCodeLen;
2582 : 0 : while ( nOffset < 24 )
2583 : : {
2584 : 0 : ImplWriteHexByte( (sal_uInt8)( dwShift >> 24 ) );
2585 : 0 : dwShift <<= 8;
2586 : 0 : nOffset += 8;
2587 : : }
2588 : 0 : if ( nCode == 257 && nOffset != 32 )
2589 : 0 : ImplWriteHexByte( (sal_uInt8)( dwShift >> 24 ) );
2590 : 0 : }
2591 : :
2592 : : // ------------------------------------------------------------------------
2593 : :
2594 : 0 : void PSWriter::StartCompression()
2595 : : {
2596 : : sal_uInt16 i;
2597 : 0 : nDataSize = 8;
2598 : :
2599 : 0 : nClearCode = 1 << nDataSize;
2600 : 0 : nEOICode = nClearCode + 1;
2601 : 0 : nTableSize = nEOICode + 1;
2602 : 0 : nCodeSize = nDataSize + 1;
2603 : :
2604 : 0 : nOffset = 32; // anzahl freier bits in dwShift
2605 : 0 : dwShift = 0;
2606 : :
2607 : 0 : pTable = new PSLZWCTreeNode[ 4096 ];
2608 : :
2609 : 0 : for ( i = 0; i < 4096; i++ )
2610 : : {
2611 : 0 : pTable[ i ].pBrother = pTable[ i ].pFirstChild = NULL;
2612 : 0 : pTable[ i ].nValue = (sal_uInt8)( pTable[ i ].nCode = i );
2613 : : }
2614 : 0 : pPrefix = NULL;
2615 : 0 : WriteBits( nClearCode, nCodeSize );
2616 : 0 : }
2617 : :
2618 : : // ------------------------------------------------------------------------
2619 : :
2620 : 0 : void PSWriter::Compress( sal_uInt8 nCompThis )
2621 : : {
2622 : : PSLZWCTreeNode* p;
2623 : : sal_uInt16 i;
2624 : : sal_uInt8 nV;
2625 : :
2626 : 0 : if( !pPrefix )
2627 : : {
2628 : 0 : pPrefix = pTable + nCompThis;
2629 : : }
2630 : : else
2631 : : {
2632 : 0 : nV = nCompThis;
2633 : 0 : for( p = pPrefix->pFirstChild; p != NULL; p = p->pBrother )
2634 : : {
2635 : 0 : if ( p->nValue == nV )
2636 : 0 : break;
2637 : : }
2638 : :
2639 : 0 : if( p )
2640 : 0 : pPrefix = p;
2641 : : else
2642 : : {
2643 : 0 : WriteBits( pPrefix->nCode, nCodeSize );
2644 : :
2645 : 0 : if ( nTableSize == 409 )
2646 : : {
2647 : 0 : WriteBits( nClearCode, nCodeSize );
2648 : :
2649 : 0 : for ( i = 0; i < nClearCode; i++ )
2650 : 0 : pTable[ i ].pFirstChild = NULL;
2651 : :
2652 : 0 : nCodeSize = nDataSize + 1;
2653 : 0 : nTableSize = nEOICode + 1;
2654 : : }
2655 : : else
2656 : : {
2657 : 0 : if( nTableSize == (sal_uInt16)( ( 1 << nCodeSize ) - 1 ) )
2658 : 0 : nCodeSize++;
2659 : :
2660 : 0 : p = pTable + ( nTableSize++ );
2661 : 0 : p->pBrother = pPrefix->pFirstChild;
2662 : 0 : pPrefix->pFirstChild = p;
2663 : 0 : p->nValue = nV;
2664 : 0 : p->pFirstChild = NULL;
2665 : : }
2666 : :
2667 : 0 : pPrefix = pTable + nV;
2668 : : }
2669 : : }
2670 : 0 : }
2671 : :
2672 : : // ------------------------------------------------------------------------
2673 : :
2674 : 0 : void PSWriter::EndCompression()
2675 : : {
2676 : 0 : if( pPrefix )
2677 : 0 : WriteBits( pPrefix->nCode, nCodeSize );
2678 : :
2679 : 0 : WriteBits( nEOICode, nCodeSize );
2680 : 0 : delete[] pTable;
2681 : 0 : }
2682 : :
2683 : : // ------------------------------------------------------------------------
2684 : :
2685 : 0 : sal_uInt8* PSWriter::ImplSearchEntry( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nComp, sal_uLong nSize )
2686 : : {
2687 : 0 : while ( nComp-- >= nSize )
2688 : : {
2689 : : sal_uLong i;
2690 : 0 : for ( i = 0; i < nSize; i++ )
2691 : : {
2692 : 0 : if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
2693 : 0 : break;
2694 : : }
2695 : 0 : if ( i == nSize )
2696 : 0 : return pSource;
2697 : 0 : pSource++;
2698 : : }
2699 : 0 : return NULL;
2700 : : }
2701 : :
2702 : : // ------------------------------------------------------------------------
2703 : :
2704 : 0 : sal_Bool PSWriter::ImplGetBoundingBox( double* nNumb, sal_uInt8* pSource, sal_uLong nSize )
2705 : : {
2706 : 0 : sal_Bool bRetValue = sal_False;
2707 : : sal_uLong nBytesRead;
2708 : :
2709 : 0 : if ( nSize < 256 ) // we assume that the file is greater than 256 bytes
2710 : 0 : return sal_False;
2711 : :
2712 : 0 : if ( nSize < POSTSCRIPT_BOUNDINGSEARCH )
2713 : 0 : nBytesRead = nSize;
2714 : : else
2715 : 0 : nBytesRead = POSTSCRIPT_BOUNDINGSEARCH;
2716 : :
2717 : 0 : sal_uInt8* pDest = ImplSearchEntry( pSource, (sal_uInt8*)"%%BoundingBox:", nBytesRead, 14 );
2718 : 0 : if ( pDest )
2719 : : {
2720 : 0 : int nSecurityCount = 100; // only 100 bytes following the bounding box will be checked
2721 : 0 : nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
2722 : 0 : pDest += 14;
2723 : 0 : for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
2724 : : {
2725 : 0 : int nDivision = 1;
2726 : 0 : sal_Bool bDivision = sal_False;
2727 : 0 : sal_Bool bNegative = sal_False;
2728 : 0 : sal_Bool bValid = sal_True;
2729 : :
2730 : 0 : while ( ( --nSecurityCount ) && ( ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) )
2731 : 0 : pDest++;
2732 : 0 : sal_uInt8 nByte = *pDest;
2733 : 0 : while ( nSecurityCount && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
2734 : : {
2735 : 0 : switch ( nByte )
2736 : : {
2737 : : case '.' :
2738 : 0 : if ( bDivision )
2739 : 0 : bValid = sal_False;
2740 : : else
2741 : 0 : bDivision = sal_True;
2742 : 0 : break;
2743 : : case '-' :
2744 : 0 : bNegative = sal_True;
2745 : 0 : break;
2746 : : default :
2747 : 0 : if ( ( nByte < '0' ) || ( nByte > '9' ) )
2748 : 0 : nSecurityCount = 1; // error parsing the bounding box values
2749 : 0 : else if ( bValid )
2750 : : {
2751 : 0 : if ( bDivision )
2752 : 0 : nDivision*=10;
2753 : 0 : nNumb[i] *= 10;
2754 : 0 : nNumb[i] += nByte - '0';
2755 : : }
2756 : 0 : break;
2757 : : }
2758 : 0 : nSecurityCount--;
2759 : 0 : nByte = *(++pDest);
2760 : : }
2761 : 0 : if ( bNegative )
2762 : 0 : nNumb[i] = -nNumb[i];
2763 : 0 : if ( bDivision && ( nDivision != 1 ) )
2764 : 0 : nNumb[i] /= nDivision;
2765 : : }
2766 : 0 : if ( nSecurityCount)
2767 : 0 : bRetValue = sal_True;
2768 : : }
2769 : 0 : return bRetValue;
2770 : : }
2771 : :
2772 : : //================== GraphicExport - die exportierte Funktion ================
2773 : :
2774 : : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI
2775 : 0 : GraphicExport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool)
2776 : : {
2777 : 0 : PSWriter aPSWriter;
2778 : 0 : return aPSWriter.WritePS( rGraphic, rStream, pFilterConfigItem );
2779 : : }
2780 : :
2781 : :
2782 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|