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