LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/eps - eps.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 1483 0.0 %
Date: 2014-04-11 Functions: 0 54 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10