LCOV - code coverage report
Current view: top level - vcl/generic/print - common_gfx.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 27 630 4.3 %
Date: 2014-04-11 Functions: 6 45 13.3 %
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 <sal/config.h>
      21             : 
      22             : #include <cstdlib>
      23             : 
      24             : #include "psputil.hxx"
      25             : #include "glyphset.hxx"
      26             : 
      27             : #include "generic/printergfx.hxx"
      28             : #include "generic/printerjob.hxx"
      29             : #include "fontmanager.hxx"
      30             : #include "vcl/strhelper.hxx"
      31             : #include "vcl/printerinfomanager.hxx"
      32             : 
      33             : #include "tools/debug.hxx"
      34             : #include "tools/color.hxx"
      35             : #include "tools/poly.hxx"
      36             : 
      37             : using namespace psp ;
      38             : 
      39             : static const sal_Int32 nMaxTextColumn = 80;
      40             : 
      41         558 : GraphicsStatus::GraphicsStatus() :
      42             :         mbArtItalic( false ),
      43             :         mbArtBold( false ),
      44             :         mnTextHeight( 0 ),
      45             :         mnTextWidth( 0 ),
      46         558 :         mfLineWidth( -1 )
      47             : {
      48         558 : }
      49             : 
      50             : /*
      51             :  * non graphics graphics routines
      52             :  */
      53             : 
      54             : bool
      55           0 : PrinterGfx::Init (PrinterJob &rPrinterJob)
      56             : {
      57           0 :     mpPageHeader = rPrinterJob.GetCurrentPageHeader ();
      58           0 :     mpPageBody   = rPrinterJob.GetCurrentPageBody ();
      59           0 :     mnDepth      = rPrinterJob.GetDepth ();
      60           0 :     mnPSLevel    = rPrinterJob.GetPostscriptLevel ();
      61           0 :     mbColor      = rPrinterJob.IsColorPrinter ();
      62             : 
      63           0 :     mnDpi = rPrinterJob.GetResolution();
      64           0 :     rPrinterJob.GetScale (mfScaleX, mfScaleY);
      65           0 :     const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( rPrinterJob.GetPrinterName() ) );
      66           0 :     mbUploadPS42Fonts = rInfo.m_pParser ? ( rInfo.m_pParser->isType42Capable() ? true : false ) : false;
      67             : 
      68           0 :     return true;
      69             : }
      70             : 
      71             : bool
      72         279 : PrinterGfx::Init (const JobData& rData)
      73             : {
      74         279 :     mpPageHeader    = NULL;
      75         279 :     mpPageBody      = NULL;
      76         279 :     mnDepth         = rData.m_nColorDepth;
      77         279 :     mnPSLevel       = rData.m_nPSLevel ? rData.m_nPSLevel : (rData.m_pParser ? rData.m_pParser->getLanguageLevel() : 2 );
      78         279 :     mbColor         = rData.m_nColorDevice ? ( rData.m_nColorDevice == -1 ? false : true ) : (( rData.m_pParser ?  (rData.m_pParser->isColorDevice() ? true : false ) : true ) );
      79         279 :     int nRes = rData.m_aContext.getRenderResolution();
      80         279 :     mnDpi           = nRes;
      81         279 :     mfScaleX        = (double)72.0 / (double)mnDpi;
      82         279 :     mfScaleY        = (double)72.0 / (double)mnDpi;
      83         279 :     const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( rData.m_aPrinterName ) );
      84         279 :     mbUploadPS42Fonts = rInfo.m_pParser ? ( rInfo.m_pParser->isType42Capable() ? true : false ) : false;
      85             : 
      86         279 :     return true;
      87             : }
      88             : 
      89             : sal_uInt16
      90           0 : PrinterGfx::GetBitCount ()
      91             : {
      92           0 :     return mnDepth;
      93             : }
      94             : 
      95         279 : PrinterGfx::PrinterGfx() :
      96             :         mpPageHeader (NULL),
      97             :         mpPageBody (NULL),
      98             :         mnFontID (0),
      99             :         mnFallbackID (0),
     100             :         mnTextAngle (0),
     101             :         mbTextVertical (false),
     102         279 :         mrFontMgr (PrintFontManager::get()),
     103             :         mbCompressBmp (true),
     104             :         maFillColor (0xff,0,0),
     105             :         maTextColor (0,0,0),
     106         558 :         maLineColor (0, 0xff, 0)
     107             : {
     108         279 :     maVirtualStatus.mfLineWidth = 1.0;
     109         279 :     maVirtualStatus.mnTextHeight = 12;
     110         279 :     maVirtualStatus.mnTextWidth = 0;
     111             : 
     112         279 :     maGraphicsStack.push_back( GraphicsStatus() );
     113         279 : }
     114             : 
     115         269 : PrinterGfx::~PrinterGfx()
     116             : {
     117         269 : }
     118             : 
     119             : void
     120           0 : PrinterGfx::Clear()
     121             : {
     122           0 :     mpPageHeader                    = NULL;
     123           0 :     mpPageBody                      = NULL;
     124           0 :     mnFontID                        = 0;
     125           0 :     maVirtualStatus                 = GraphicsStatus();
     126           0 :     maVirtualStatus.mnTextHeight    = 12;
     127           0 :     maVirtualStatus.mnTextWidth     = 0;
     128           0 :     maVirtualStatus.mfLineWidth     = 1.0;
     129           0 :     mbTextVertical                  = false;
     130           0 :     maLineColor                     = PrinterColor();
     131           0 :     maFillColor                     = PrinterColor();
     132           0 :     maTextColor                     = PrinterColor();
     133           0 :     mbCompressBmp                   = true;
     134           0 :     mnDpi                           = 300;
     135           0 :     mnDepth                         = 24;
     136           0 :     mnPSLevel                       = 2;
     137           0 :     mbColor                         = true;
     138           0 :     mnTextAngle                     = 0;
     139             : 
     140           0 :     maClipRegion.clear();
     141           0 :     maGraphicsStack.clear();
     142           0 :     maGraphicsStack.push_back( GraphicsStatus() );
     143           0 : }
     144             : 
     145             : /*
     146             :  * clip region handling
     147             :  */
     148             : 
     149             : void
     150           0 : PrinterGfx::ResetClipRegion()
     151             : {
     152           0 :     maClipRegion.clear();
     153           0 :     PSGRestore ();
     154           0 :     PSGSave (); // get "clean" clippath
     155           0 : }
     156             : 
     157             : void
     158           0 : PrinterGfx::BeginSetClipRegion( sal_uInt32 )
     159             : {
     160           0 :     maClipRegion.clear();
     161           0 : }
     162             : 
     163             : bool
     164           0 : PrinterGfx::UnionClipRegion (sal_Int32 nX,sal_Int32 nY,sal_Int32 nDX,sal_Int32 nDY)
     165             : {
     166           0 :     if( nDX && nDY )
     167           0 :         maClipRegion.push_back (Rectangle(Point(nX,nY ), Size(nDX,nDY)));
     168           0 :     return true;
     169             : }
     170             : 
     171             : bool
     172           0 : PrinterGfx::JoinVerticalClipRectangles( std::list< Rectangle >::iterator& it,
     173             :                                         Point& rOldPoint, sal_Int32& rColumn )
     174             : {
     175           0 :     bool bSuccess = false;
     176             : 
     177           0 :     std::list< Rectangle >::iterator tempit, nextit;
     178           0 :     nextit = it;
     179           0 :     ++nextit;
     180           0 :     std::list< Point > leftside, rightside;
     181             : 
     182           0 :     Rectangle aLastRect( *it );
     183           0 :     leftside.push_back( Point( it->Left(), it->Top() ) );
     184           0 :     rightside.push_back( Point( it->Right()+1, it->Top() ) );
     185           0 :     while( nextit != maClipRegion.end() )
     186             :     {
     187           0 :         tempit = nextit;
     188           0 :         ++tempit;
     189           0 :         if( nextit->Top() == aLastRect.Bottom()+1 )
     190             :         {
     191           0 :             if(
     192           0 :                ( nextit->Left() >= aLastRect.Left() && nextit->Left() <= aLastRect.Right() ) // left endpoint touches last rectangle
     193           0 :                ||
     194           0 :                ( nextit->Right() >= aLastRect.Left() && nextit->Right() <= aLastRect.Right() ) // right endpoint touches last rectangle
     195           0 :                ||
     196           0 :                ( nextit->Left() <= aLastRect.Left() && nextit->Right() >= aLastRect.Right() ) // whole line touches last rectangle
     197             :                )
     198             :             {
     199           0 :                 if( aLastRect.GetHeight() > 1                           ||
     200           0 :                     std::abs( aLastRect.Left() - nextit->Left() ) > 2        ||
     201           0 :                     std::abs( aLastRect.Right() - nextit->Right() ) > 2
     202             :                     )
     203             :                 {
     204           0 :                     leftside.push_back( Point( aLastRect.Left(), aLastRect.Bottom()+1 ) );
     205           0 :                     rightside.push_back( Point( aLastRect.Right()+1, aLastRect.Bottom()+1 ) );
     206             :                 }
     207           0 :                 aLastRect = *nextit;
     208           0 :                 leftside.push_back( aLastRect.TopLeft() );
     209           0 :                 rightside.push_back( aLastRect.TopRight() );
     210           0 :                 maClipRegion.erase( nextit );
     211             :             }
     212             :         }
     213           0 :         nextit = tempit;
     214             :     }
     215           0 :     if( leftside.size() > 1 )
     216             :     {
     217             :         // push the last coordinates
     218           0 :         leftside.push_back( Point( aLastRect.Left(), aLastRect.Bottom()+1 ) );
     219           0 :         rightside.push_back( Point( aLastRect.Right()+1, aLastRect.Bottom()+1 ) );
     220             : 
     221             :         // cool, we can concatenate rectangles
     222           0 :         const int nDX = -65536, nDY = 65536;
     223           0 :         int nNewDX = 0, nNewDY = 0;
     224             : 
     225           0 :         Point aLastPoint = leftside.front();
     226           0 :         PSBinMoveTo (aLastPoint, rOldPoint, rColumn);
     227           0 :         leftside.pop_front();
     228           0 :         while( leftside.begin() != leftside.end() )
     229             :         {
     230           0 :             Point aPoint (leftside.front());
     231           0 :             leftside.pop_front();
     232             :             // may have been the last one
     233           0 :             if( leftside.begin() != leftside.end() )
     234             :             {
     235           0 :                 nNewDX = aPoint.X() - aLastPoint.X();
     236           0 :                 nNewDY = aPoint.Y() - aLastPoint.Y();
     237           0 :                 if( nNewDX != 0 &&
     238           0 :                     (double)nNewDY/(double)nNewDX == (double)nDY/(double)nDX )
     239           0 :                     continue;
     240             :             }
     241           0 :             PSBinLineTo (aPoint, rOldPoint, rColumn);
     242           0 :             aLastPoint = aPoint;
     243             :         }
     244             : 
     245           0 :         aLastPoint = rightside.back();
     246           0 :         PSBinLineTo (aLastPoint, rOldPoint, rColumn);
     247           0 :         rightside.pop_back();
     248           0 :         while( rightside.begin() != rightside.end() )
     249             :         {
     250           0 :             Point aPoint (rightside.back());
     251           0 :             rightside.pop_back();
     252           0 :             if( rightside.begin() != rightside.end() )
     253             :             {
     254           0 :                 nNewDX = aPoint.X() - aLastPoint.X();
     255           0 :                 nNewDY = aPoint.Y() - aLastPoint.Y();
     256           0 :                 if( nNewDX != 0 &&
     257           0 :                     (double)nNewDY/(double)nNewDX == (double)nDY/(double)nDX )
     258           0 :                     continue;
     259             :             }
     260           0 :             PSBinLineTo (aPoint, rOldPoint, rColumn);
     261             :         }
     262             : 
     263           0 :         tempit = it;
     264           0 :         ++tempit;
     265           0 :         maClipRegion.erase( it );
     266           0 :         it = tempit;
     267           0 :         bSuccess = true;
     268             :     }
     269           0 :     return bSuccess;
     270             : }
     271             : 
     272             : void
     273           0 : PrinterGfx::EndSetClipRegion()
     274             : {
     275           0 :     PSGRestore ();
     276           0 :     PSGSave (); // get "clean" clippath
     277             : 
     278           0 :     PSBinStartPath ();
     279           0 :     Point aOldPoint (0, 0);
     280           0 :     sal_Int32 nColumn = 0;
     281             : 
     282           0 :     std::list< Rectangle >::iterator it = maClipRegion.begin();
     283           0 :     while( it != maClipRegion.end() )
     284             :     {
     285             :         // try to concatenate adjacent rectangles
     286             :         // first try in y direction, then in x direction
     287           0 :         if( ! JoinVerticalClipRectangles( it, aOldPoint, nColumn ) )
     288             :         {
     289             :             // failed, so it is a single rectangle
     290           0 :             PSBinMoveTo (it->TopLeft(),                          aOldPoint, nColumn );
     291           0 :             PSBinLineTo (Point( it->Left(), it->Bottom()+1 ),    aOldPoint, nColumn );
     292           0 :             PSBinLineTo (Point( it->Right()+1, it->Bottom()+1 ), aOldPoint, nColumn );
     293           0 :             PSBinLineTo (Point( it->Right()+1, it->Top() ),      aOldPoint, nColumn );
     294           0 :             ++it;
     295             :         }
     296             :     }
     297             : 
     298           0 :     PSBinEndPath ();
     299             : 
     300           0 :     WritePS (mpPageBody, "closepath clip newpath\n");
     301           0 :     maClipRegion.clear();
     302           0 : }
     303             : 
     304             : /*
     305             :  * draw graphic primitives
     306             :  */
     307             : 
     308             : void
     309           0 : PrinterGfx::DrawRect (const Rectangle& rRectangle )
     310             : {
     311             :     char pRect [128];
     312           0 :     sal_Int32 nChar = 0;
     313             : 
     314           0 :     nChar  = psp::getValueOf (rRectangle.TopLeft().X(),     pRect);
     315           0 :     nChar += psp::appendStr (" ",                           pRect + nChar);
     316           0 :     nChar += psp::getValueOf (rRectangle.TopLeft().Y(),     pRect + nChar);
     317           0 :     nChar += psp::appendStr (" ",                           pRect + nChar);
     318           0 :     nChar += psp::getValueOf (rRectangle.GetWidth(),        pRect + nChar);
     319           0 :     nChar += psp::appendStr (" ",                           pRect + nChar);
     320           0 :     nChar += psp::getValueOf (rRectangle.GetHeight(),       pRect + nChar);
     321           0 :     nChar += psp::appendStr (" ",                           pRect + nChar);
     322             : 
     323           0 :     if( maFillColor.Is() )
     324             :     {
     325           0 :         PSSetColor (maFillColor);
     326           0 :         PSSetColor ();
     327           0 :         WritePS (mpPageBody, pRect, nChar);
     328           0 :         WritePS (mpPageBody, "rectfill\n");
     329             :     }
     330           0 :     if( maLineColor.Is() )
     331             :     {
     332           0 :         PSSetColor (maLineColor);
     333           0 :         PSSetColor ();
     334           0 :         PSSetLineWidth ();
     335           0 :         WritePS (mpPageBody, pRect, nChar);
     336           0 :         WritePS (mpPageBody, "rectstroke\n");
     337             :     }
     338           0 : }
     339             : 
     340             : void
     341           0 : PrinterGfx::DrawLine (const Point& rFrom, const Point& rTo)
     342             : {
     343           0 :     if( maLineColor.Is() )
     344             :     {
     345           0 :         PSSetColor (maLineColor);
     346           0 :         PSSetColor ();
     347           0 :         PSSetLineWidth ();
     348             : 
     349           0 :         PSMoveTo (rFrom);
     350           0 :         PSLineTo (rTo);
     351           0 :         WritePS (mpPageBody, "stroke\n" );
     352             :     }
     353           0 : }
     354             : 
     355             : void
     356           0 : PrinterGfx::DrawPixel (const Point& rPoint, const PrinterColor& rPixelColor)
     357             : {
     358           0 :     if( rPixelColor.Is() )
     359             :     {
     360           0 :         PSSetColor (rPixelColor);
     361           0 :         PSSetColor ();
     362             : 
     363           0 :         PSMoveTo (rPoint);
     364           0 :         PSLineTo (Point (rPoint.X ()+1, rPoint.Y ()));
     365           0 :         PSLineTo (Point (rPoint.X ()+1, rPoint.Y ()+1));
     366           0 :         PSLineTo (Point (rPoint.X (), rPoint.Y ()+1));
     367           0 :         WritePS (mpPageBody, "fill\n" );
     368             :     }
     369           0 : }
     370             : 
     371             : void
     372           0 : PrinterGfx::DrawPolyLine (sal_uInt32 nPoints, const Point* pPath)
     373             : {
     374           0 :     if( maLineColor.Is() && nPoints && pPath )
     375             :     {
     376           0 :         PSSetColor (maLineColor);
     377           0 :         PSSetColor ();
     378           0 :         PSSetLineWidth ();
     379             : 
     380           0 :         PSBinCurrentPath (nPoints, pPath);
     381             : 
     382           0 :         WritePS (mpPageBody, "stroke\n" );
     383             :     }
     384           0 : }
     385             : 
     386             : void
     387           0 : PrinterGfx::DrawPolygon (sal_uInt32 nPoints, const Point* pPath)
     388             : {
     389             :     // premature end of operation
     390           0 :     if (!(nPoints > 1) || (pPath == NULL) || !(maFillColor.Is() || maLineColor.Is()))
     391           0 :         return;
     392             : 
     393             :     // setup closed path
     394           0 :     Point aPoint( 0, 0 );
     395           0 :     sal_Int32 nColumn( 0 );
     396             : 
     397           0 :     PSBinStartPath();
     398           0 :     PSBinMoveTo( pPath[0], aPoint, nColumn );
     399           0 :     for( unsigned int n = 1; n < nPoints; n++ )
     400           0 :         PSBinLineTo( pPath[n], aPoint, nColumn );
     401           0 :     if( pPath[0] != pPath[nPoints-1] )
     402           0 :         PSBinLineTo( pPath[0], aPoint, nColumn );
     403           0 :     PSBinEndPath();
     404             : 
     405             :     // fill the polygon first, then draw the border, note that fill and
     406             :     // stroke reset the currentpath
     407             : 
     408             :     // if fill and stroke, save the current path
     409           0 :     if( maFillColor.Is() && maLineColor.Is())
     410           0 :         PSGSave();
     411             : 
     412           0 :     if (maFillColor.Is ())
     413             :     {
     414           0 :         PSSetColor (maFillColor);
     415           0 :         PSSetColor ();
     416           0 :         WritePS (mpPageBody, "eofill\n");
     417             :     }
     418             : 
     419             :     // restore the current path
     420           0 :     if( maFillColor.Is() && maLineColor.Is())
     421           0 :         PSGRestore();
     422             : 
     423           0 :     if (maLineColor.Is ())
     424             :     {
     425           0 :         PSSetColor (maLineColor);
     426           0 :         PSSetColor ();
     427           0 :         PSSetLineWidth ();
     428           0 :         WritePS (mpPageBody, "stroke\n");
     429             :     }
     430             : }
     431             : 
     432             : void
     433           0 : PrinterGfx::DrawPolyPolygon (sal_uInt32 nPoly, const sal_uInt32* pSizes, const Point** pPaths )
     434             : {
     435             :     // sanity check
     436           0 :     if ( !nPoly || !pPaths || !(maFillColor.Is() || maLineColor.Is()))
     437           0 :         return;
     438             : 
     439             :     // setup closed path
     440           0 :     for( unsigned int i = 0; i < nPoly; i++ )
     441             :     {
     442           0 :         Point aPoint( 0, 0 );
     443           0 :         sal_Int32 nColumn( 0 );
     444             : 
     445           0 :         PSBinStartPath();
     446           0 :         PSBinMoveTo( pPaths[i][0], aPoint, nColumn );
     447           0 :         for( unsigned int n = 1; n < pSizes[i]; n++ )
     448           0 :             PSBinLineTo( pPaths[i][n], aPoint, nColumn );
     449           0 :         if( pPaths[i][0] != pPaths[i][pSizes[i]-1] )
     450           0 :                 PSBinLineTo( pPaths[i][0], aPoint, nColumn );
     451           0 :         PSBinEndPath();
     452             :     }
     453             : 
     454             :     // if eofill and stroke, save the current path
     455           0 :     if( maFillColor.Is() && maLineColor.Is())
     456           0 :         PSGSave();
     457             : 
     458             :     // first draw area
     459           0 :     if( maFillColor.Is() )
     460             :     {
     461           0 :         PSSetColor (maFillColor);
     462           0 :         PSSetColor ();
     463           0 :         WritePS (mpPageBody, "eofill\n");
     464             :     }
     465             : 
     466             :     // restore the current path
     467           0 :     if( maFillColor.Is() && maLineColor.Is())
     468           0 :         PSGRestore();
     469             : 
     470             :     // now draw outlines
     471           0 :     if( maLineColor.Is() )
     472             :     {
     473           0 :         PSSetColor (maLineColor);
     474           0 :         PSSetColor ();
     475           0 :         PSSetLineWidth ();
     476           0 :         WritePS (mpPageBody, "stroke\n");
     477             :     }
     478             : }
     479             : 
     480             : /*
     481             :  * Bezier Polygon Drawing methods.
     482             :  */
     483             : 
     484             : void
     485           0 : PrinterGfx::DrawPolyLineBezier (sal_uInt32 nPoints, const Point* pPath, const sal_uInt8* pFlgAry)
     486             : {
     487           0 :     const sal_uInt32 nBezString= 1024;
     488             :     sal_Char pString[nBezString];
     489             : 
     490           0 :     if ( nPoints > 1 && maLineColor.Is() && pPath )
     491             :     {
     492           0 :         PSSetColor (maLineColor);
     493           0 :         PSSetColor ();
     494           0 :         PSSetLineWidth ();
     495             : 
     496           0 :         snprintf(pString, nBezString, "%li %li moveto\n", pPath[0].X(), pPath[0].Y());
     497           0 :         WritePS(mpPageBody, pString);
     498             : 
     499             :         // Handle the drawing of mixed lines mixed with curves
     500             :         // - a normal point followed by a normal point is a line
     501             :         // - a normal point followed by 2 control points and a normal point is a curve
     502           0 :         for (unsigned int i=1; i<nPoints;)
     503             :         {
     504           0 :             if (pFlgAry[i] != POLY_CONTROL) //If the next point is a POLY_NORMAL, we're drawing a line
     505             :             {
     506           0 :                 snprintf(pString, nBezString, "%li %li lineto\n", pPath[i].X(), pPath[i].Y());
     507           0 :                 i++;
     508             :             }
     509             :             else //Otherwise we're drawing a spline
     510             :             {
     511           0 :                 if (i+2 >= nPoints)
     512           0 :                     return; //Error: wrong sequence of contol/normal points somehow
     513           0 :                 if ((pFlgAry[i] == POLY_CONTROL) && (pFlgAry[i+1] == POLY_CONTROL) &&
     514           0 :                     (pFlgAry[i+2] != POLY_CONTROL))
     515             :                 {
     516             :                     snprintf(pString, nBezString, "%li %li %li %li %li %li curveto\n",
     517             :                              pPath[i].X(), pPath[i].Y(),
     518             :                              pPath[i+1].X(), pPath[i+1].Y(),
     519           0 :                              pPath[i+2].X(), pPath[i+2].Y());
     520             :                 }
     521             :                 else
     522             :                 {
     523             :                     OSL_FAIL( "PrinterGfx::DrawPolyLineBezier: Strange output" );
     524             :                 }
     525           0 :                 i+=3;
     526             :             }
     527           0 :             WritePS(mpPageBody, pString);
     528             :         }
     529             : 
     530             :         // now draw outlines
     531           0 :         WritePS (mpPageBody, "stroke\n");
     532             :     }
     533             : }
     534             : 
     535             : void
     536           0 : PrinterGfx::DrawPolygonBezier (sal_uInt32 nPoints, const Point* pPath, const sal_uInt8* pFlgAry)
     537             : {
     538           0 :     const sal_uInt32 nBezString = 1024;
     539             :     sal_Char pString[nBezString];
     540             :     // premature end of operation
     541           0 :     if (!(nPoints > 1) || (pPath == NULL) || !(maFillColor.Is() || maLineColor.Is()))
     542           0 :         return;
     543             : 
     544           0 :     snprintf(pString, nBezString, "%li %li moveto\n", pPath[0].X(), pPath[0].Y());
     545           0 :     WritePS(mpPageBody, pString); //Move to the starting point for the PolyPoygon
     546           0 :     for (unsigned int i=1; i < nPoints;)
     547             :     {
     548           0 :         if (pFlgAry[i] != POLY_CONTROL)
     549             :         {
     550           0 :             snprintf(pString, nBezString, "%li %li lineto\n", pPath[i].X(), pPath[i].Y());
     551           0 :             WritePS(mpPageBody, pString);
     552           0 :             i++;
     553             :         }
     554             :         else
     555             :         {
     556           0 :             if (i+2 >= nPoints)
     557           0 :                 return; //Error: wrong sequence of contol/normal points somehow
     558           0 :             if ((pFlgAry[i] == POLY_CONTROL) && (pFlgAry[i+1] == POLY_CONTROL) &&
     559           0 :                     (pFlgAry[i+2] != POLY_CONTROL))
     560             :             {
     561             :                 snprintf(pString, nBezString, "%li %li %li %li %li %li curveto\n",
     562             :                         pPath[i].X(), pPath[i].Y(),
     563             :                         pPath[i+1].X(), pPath[i+1].Y(),
     564           0 :                         pPath[i+2].X(), pPath[i+2].Y());
     565           0 :                 WritePS(mpPageBody, pString);
     566             :             }
     567             :             else
     568             :             {
     569             :                 OSL_FAIL( "PrinterGfx::DrawPolygonBezier: Strange output" );
     570             :             }
     571           0 :             i+=3;
     572             :         }
     573             :     }
     574             : 
     575             :     // if fill and stroke, save the current path
     576           0 :     if( maFillColor.Is() && maLineColor.Is())
     577           0 :         PSGSave();
     578             : 
     579           0 :     if (maFillColor.Is ())
     580             :     {
     581           0 :         PSSetColor (maFillColor);
     582           0 :         PSSetColor ();
     583           0 :         WritePS (mpPageBody, "eofill\n");
     584             :     }
     585             : 
     586             :     // restore the current path
     587           0 :     if( maFillColor.Is() && maLineColor.Is())
     588           0 :         PSGRestore();
     589             : }
     590             : 
     591             : void
     592           0 : PrinterGfx::DrawPolyPolygonBezier (sal_uInt32 nPoly, const sal_uInt32 * pPoints, const Point* const * pPtAry, const sal_uInt8* const* pFlgAry)
     593             : {
     594           0 :     const sal_uInt32 nBezString = 1024;
     595             :     sal_Char pString[nBezString];
     596           0 :     if ( !nPoly || !pPtAry || !pPoints || !(maFillColor.Is() || maLineColor.Is()))
     597           0 :         return;
     598             : 
     599           0 :     for (unsigned int i=0; i<nPoly;i++)
     600             :     {
     601           0 :         sal_uInt32 nPoints = pPoints[i];
     602             :         // sanity check
     603           0 :         if( nPoints == 0 || pPtAry[i] == NULL )
     604           0 :             continue;
     605             : 
     606           0 :         snprintf(pString, nBezString, "%li %li moveto\n", pPtAry[i][0].X(), pPtAry[i][0].Y()); //Move to the starting point
     607           0 :         WritePS(mpPageBody, pString);
     608           0 :         for (unsigned int j=1; j < nPoints;)
     609             :         {
     610             :             // if no flag array exists for this polygon, then it must be a regular
     611             :             // polygon without beziers
     612           0 :             if ( ! pFlgAry[i] || pFlgAry[i][j] != POLY_CONTROL)
     613             :             {
     614           0 :                 snprintf(pString, nBezString, "%li %li lineto\n", pPtAry[i][j].X(), pPtAry[i][j].Y());
     615           0 :                 WritePS(mpPageBody, pString);
     616           0 :                 j++;
     617             :             }
     618             :             else
     619             :             {
     620           0 :                 if (j+2 >= nPoints)
     621           0 :                     break; //Error: wrong sequence of contol/normal points somehow
     622           0 :                 if ((pFlgAry[i][j] == POLY_CONTROL) && (pFlgAry[i][j+1] == POLY_CONTROL) && (pFlgAry[i][j+2] != POLY_CONTROL))
     623             :                 {
     624             :                     snprintf(pString, nBezString, "%li %li %li %li %li %li curveto\n",
     625           0 :                             pPtAry[i][j].X(), pPtAry[i][j].Y(),
     626           0 :                             pPtAry[i][j+1].X(), pPtAry[i][j+1].Y(),
     627           0 :                             pPtAry[i][j+2].X(), pPtAry[i][j+2].Y());
     628           0 :                     WritePS(mpPageBody, pString);
     629             :                 }
     630             :                 else
     631             :                 {
     632             :                     OSL_FAIL( "PrinterGfx::DrawPolyPolygonBezier: Strange output" );
     633             :                 }
     634           0 :                 j+=3;
     635             :             }
     636             :         }
     637             :     }
     638             : 
     639             :     // if fill and stroke, save the current path
     640           0 :     if( maFillColor.Is() && maLineColor.Is())
     641           0 :         PSGSave();
     642             : 
     643           0 :     if (maFillColor.Is ())
     644             :     {
     645           0 :         PSSetColor (maFillColor);
     646           0 :         PSSetColor ();
     647           0 :         WritePS (mpPageBody, "eofill\n");
     648             :     }
     649             : 
     650             :     // restore the current path
     651           0 :     if( maFillColor.Is() && maLineColor.Is())
     652           0 :         PSGRestore();
     653             : }
     654             : 
     655             : /*
     656             :  * postscript generating routines
     657             :  */
     658             : void
     659           0 : PrinterGfx::PSGSave ()
     660             : {
     661           0 :     WritePS (mpPageBody, "gsave\n" );
     662           0 :     GraphicsStatus aNewState;
     663           0 :     if( maGraphicsStack.begin() != maGraphicsStack.end() )
     664           0 :         aNewState = maGraphicsStack.front();
     665           0 :     maGraphicsStack.push_front( aNewState );
     666           0 : }
     667             : 
     668             : void
     669           0 : PrinterGfx::PSGRestore ()
     670             : {
     671           0 :     WritePS (mpPageBody, "grestore\n" );
     672           0 :     if( maGraphicsStack.begin() == maGraphicsStack.end() )
     673           0 :         WritePS (mpPageBody, "Error: too many grestores\n" );
     674             :     else
     675           0 :         maGraphicsStack.pop_front();
     676           0 : }
     677             : 
     678             : void
     679           0 : PrinterGfx::PSSetLineWidth ()
     680             : {
     681           0 :     if( currentState().mfLineWidth != maVirtualStatus.mfLineWidth )
     682             :     {
     683             :         char pBuffer[128];
     684           0 :         sal_Int32 nChar = 0;
     685             : 
     686           0 :         currentState().mfLineWidth = maVirtualStatus.mfLineWidth;
     687           0 :         nChar  = psp::getValueOfDouble (pBuffer, maVirtualStatus.mfLineWidth, 5);
     688           0 :         nChar += psp::appendStr (" setlinewidth\n", pBuffer + nChar);
     689           0 :         WritePS (mpPageBody, pBuffer, nChar);
     690             :     }
     691           0 : }
     692             : 
     693             : void
     694           0 : PrinterGfx::PSSetColor ()
     695             : {
     696           0 :     PrinterColor& rColor( maVirtualStatus.maColor );
     697             : 
     698           0 :     if( currentState().maColor != rColor )
     699             :     {
     700           0 :         currentState().maColor = rColor;
     701             : 
     702             :         char pBuffer[128];
     703           0 :         sal_Int32 nChar = 0;
     704             : 
     705           0 :         if( mbColor )
     706             :         {
     707             :             nChar  = psp::getValueOfDouble (pBuffer,
     708           0 :                                             (double)rColor.GetRed() / 255.0, 5);
     709           0 :             nChar += psp::appendStr (" ", pBuffer + nChar);
     710             :             nChar += psp::getValueOfDouble (pBuffer + nChar,
     711           0 :                                             (double)rColor.GetGreen() / 255.0, 5);
     712           0 :             nChar += psp::appendStr (" ", pBuffer + nChar);
     713             :             nChar += psp::getValueOfDouble (pBuffer + nChar,
     714           0 :                                             (double)rColor.GetBlue() / 255.0, 5);
     715           0 :             nChar += psp::appendStr (" setrgbcolor\n", pBuffer + nChar );
     716             :         }
     717             :         else
     718             :         {
     719           0 :             Color aColor( rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() );
     720           0 :             sal_uInt8 nCol = aColor.GetLuminance();
     721           0 :             nChar  = psp::getValueOfDouble( pBuffer, (double)nCol / 255.0, 5 );
     722           0 :             nChar += psp::appendStr( " setgray\n", pBuffer + nChar );
     723             :         }
     724             : 
     725           0 :         WritePS (mpPageBody, pBuffer, nChar);
     726             :     }
     727           0 : }
     728             : 
     729             : void
     730           0 : PrinterGfx::PSSetFont ()
     731             : {
     732           0 :     GraphicsStatus& rCurrent( currentState() );
     733           0 :     if( maVirtualStatus.maFont          != rCurrent.maFont          ||
     734           0 :         maVirtualStatus.mnTextHeight    != rCurrent.mnTextHeight    ||
     735           0 :         maVirtualStatus.maEncoding      != rCurrent.maEncoding      ||
     736           0 :         maVirtualStatus.mnTextWidth     != rCurrent.mnTextWidth     ||
     737           0 :         maVirtualStatus.mbArtBold       != rCurrent.mbArtBold       ||
     738           0 :         maVirtualStatus.mbArtItalic     != rCurrent.mbArtItalic
     739             :         )
     740             :     {
     741           0 :         rCurrent.maFont              = maVirtualStatus.maFont;
     742           0 :         rCurrent.maEncoding          = maVirtualStatus.maEncoding;
     743           0 :         rCurrent.mnTextWidth         = maVirtualStatus.mnTextWidth;
     744           0 :         rCurrent.mnTextHeight        = maVirtualStatus.mnTextHeight;
     745           0 :         rCurrent.mbArtItalic         = maVirtualStatus.mbArtItalic;
     746           0 :         rCurrent.mbArtBold           = maVirtualStatus.mbArtBold;
     747             : 
     748           0 :         sal_Int32 nTextHeight = rCurrent.mnTextHeight;
     749             :         sal_Int32 nTextWidth  = rCurrent.mnTextWidth ? rCurrent.mnTextWidth
     750           0 :                                                      : rCurrent.mnTextHeight;
     751             : 
     752             :         sal_Char  pSetFont [256];
     753           0 :         sal_Int32 nChar = 0;
     754             : 
     755             :         // postscript based fonts need reencoding
     756           0 :         if (   (   rCurrent.maEncoding == RTL_TEXTENCODING_MS_1252)
     757           0 :             || (   rCurrent.maEncoding == RTL_TEXTENCODING_ISO_8859_1)
     758           0 :             || (   rCurrent.maEncoding >= RTL_TEXTENCODING_USER_START
     759           0 :                 && rCurrent.maEncoding <= RTL_TEXTENCODING_USER_END)
     760             :            )
     761             :         {
     762             :             OString aReencodedFont =
     763             :                         psp::GlyphSet::GetReencodedFontName (rCurrent.maEncoding,
     764           0 :                                                                 rCurrent.maFont);
     765             : 
     766           0 :             nChar += psp::appendStr  ("(",          pSetFont + nChar);
     767             :             nChar += psp::appendStr  (aReencodedFont.getStr(),
     768           0 :                                                     pSetFont + nChar);
     769             :             nChar += psp::appendStr  (") cvn findfont ",
     770           0 :                                                     pSetFont + nChar);
     771             :         }
     772             :         else
     773             :         // tt based fonts mustn't reencode, the encoding is implied by the fontname
     774             :         // same for symbol type1 fonts, dont try to touch them
     775             :         {
     776           0 :             nChar += psp::appendStr  ("(",          pSetFont + nChar);
     777             :             nChar += psp::appendStr  (rCurrent.maFont.getStr(),
     778           0 :                                                     pSetFont + nChar);
     779             :             nChar += psp::appendStr  (") cvn findfont ",
     780           0 :                                                     pSetFont + nChar);
     781             :         }
     782             : 
     783           0 :         if( ! rCurrent.mbArtItalic )
     784             :         {
     785           0 :             nChar += psp::getValueOf (nTextWidth,   pSetFont + nChar);
     786           0 :             nChar += psp::appendStr  (" ",          pSetFont + nChar);
     787           0 :             nChar += psp::getValueOf (-nTextHeight, pSetFont + nChar);
     788           0 :             nChar += psp::appendStr  (" matrix scale makefont setfont\n", pSetFont + nChar);
     789             :         }
     790             :         else // skew 15 degrees to right
     791             :         {
     792           0 :             nChar += psp::appendStr  ( " [",        pSetFont + nChar);
     793           0 :             nChar += psp::getValueOf (nTextWidth,   pSetFont + nChar);
     794           0 :             nChar += psp::appendStr  (" 0 ",        pSetFont + nChar);
     795           0 :             nChar += psp::getValueOfDouble (pSetFont + nChar, 0.27*(double)nTextWidth, 3 );
     796           0 :             nChar += psp::appendStr  ( " ",         pSetFont + nChar);
     797           0 :             nChar += psp::getValueOf (-nTextHeight, pSetFont + nChar);
     798             : 
     799           0 :             nChar += psp::appendStr  (" 0 0] makefont setfont\n", pSetFont + nChar);
     800             :         }
     801             : 
     802           0 :         WritePS (mpPageBody, pSetFont);
     803             :     }
     804           0 : }
     805             : 
     806             : void
     807           0 : PrinterGfx::PSRotate (sal_Int32 nAngle)
     808             : {
     809           0 :     sal_Int32 nPostScriptAngle = -nAngle;
     810           0 :     while( nPostScriptAngle < 0 )
     811           0 :         nPostScriptAngle += 3600;
     812             : 
     813           0 :     if (nPostScriptAngle == 0)
     814           0 :         return;
     815             : 
     816           0 :     sal_Int32 nFullAngle  = nPostScriptAngle / 10;
     817           0 :     sal_Int32 nTenthAngle = nPostScriptAngle % 10;
     818             : 
     819             :     sal_Char  pRotate [48];
     820           0 :     sal_Int32 nChar = 0;
     821             : 
     822           0 :     nChar  = psp::getValueOf (nFullAngle,  pRotate);
     823           0 :     nChar += psp::appendStr (".",          pRotate + nChar);
     824           0 :     nChar += psp::getValueOf (nTenthAngle, pRotate + nChar);
     825           0 :     nChar += psp::appendStr (" rotate\n",  pRotate + nChar);
     826             : 
     827           0 :     WritePS (mpPageBody, pRotate);
     828             : }
     829             : 
     830             : void
     831           0 : PrinterGfx::PSPointOp (const Point& rPoint, const sal_Char* pOperator)
     832             : {
     833             :     sal_Char  pPSCommand [48];
     834           0 :     sal_Int32 nChar = 0;
     835             : 
     836           0 :     nChar  = psp::getValueOf (rPoint.X(), pPSCommand);
     837           0 :     nChar += psp::appendStr  (" ",        pPSCommand + nChar);
     838           0 :     nChar += psp::getValueOf (rPoint.Y(), pPSCommand + nChar);
     839           0 :     nChar += psp::appendStr  (" ",        pPSCommand + nChar);
     840           0 :     nChar += psp::appendStr  (pOperator,  pPSCommand + nChar);
     841           0 :     nChar += psp::appendStr  ("\n",       pPSCommand + nChar);
     842             : 
     843             :     DBG_ASSERT (nChar < 48, "Buffer overflow in PSPointOp");
     844             : 
     845           0 :     WritePS (mpPageBody, pPSCommand);
     846           0 : }
     847             : 
     848             : void
     849           0 : PrinterGfx::PSTranslate (const Point& rPoint)
     850             : {
     851           0 :     PSPointOp (rPoint, "translate");
     852           0 : }
     853             : 
     854             : void
     855           0 : PrinterGfx::PSMoveTo (const Point& rPoint)
     856             : {
     857           0 :     PSPointOp (rPoint, "moveto");
     858           0 : }
     859             : 
     860             : void
     861           0 : PrinterGfx::PSLineTo (const Point& rPoint)
     862             : {
     863           0 :     PSPointOp (rPoint, "lineto");
     864           0 : }
     865             : 
     866             : /* get a compressed representation of the path information */
     867             : 
     868             : #define DEBUG_BINPATH 0
     869             : 
     870             : void
     871           0 : PrinterGfx::PSBinLineTo (const Point& rCurrent, Point& rOld, sal_Int32& nColumn)
     872             : {
     873             : #if (DEBUG_BINPATH == 1)
     874             :     PSLineTo (rCurrent);
     875             : #else
     876           0 :     PSBinPath (rCurrent, rOld, lineto, nColumn);
     877             : #endif
     878           0 : }
     879             : 
     880             : void
     881           0 : PrinterGfx::PSBinMoveTo (const Point& rCurrent, Point& rOld, sal_Int32& nColumn)
     882             : {
     883             : #if (DEBUG_BINPATH == 1)
     884             :     PSMoveTo (rCurrent);
     885             : #else
     886           0 :     PSBinPath (rCurrent, rOld, moveto, nColumn);
     887             : #endif
     888           0 : }
     889             : 
     890             : void
     891           0 : PrinterGfx::PSBinStartPath ()
     892             : {
     893             : #if (DEBUG_BINPATH == 1)
     894             :     WritePS (mpPageBody, "% PSBinStartPath\n");
     895             : #else
     896           0 :     WritePS (mpPageBody, "readpath\n" );
     897             : #endif
     898           0 : }
     899             : 
     900             : void
     901           0 : PrinterGfx::PSBinEndPath ()
     902             : {
     903             : #if (DEBUG_BINPATH == 1)
     904             :     WritePS (mpPageBody, "% PSBinEndPath\n");
     905             : #else
     906           0 :     WritePS (mpPageBody, "~\n");
     907             : #endif
     908           0 : }
     909             : 
     910             : void
     911           0 : PrinterGfx::PSBinCurrentPath (sal_uInt32 nPoints, const Point* pPath)
     912             : {
     913             :     // create the path
     914           0 :     Point     aPoint (0, 0);
     915           0 :     sal_Int32 nColumn = 0;
     916             : 
     917           0 :     PSBinStartPath ();
     918           0 :     PSBinMoveTo (*pPath, aPoint, nColumn);
     919           0 :     for (unsigned int i = 1; i < nPoints; i++)
     920           0 :         PSBinLineTo (pPath[i], aPoint, nColumn);
     921           0 :     PSBinEndPath ();
     922           0 : }
     923             : 
     924             : void
     925           0 : PrinterGfx::PSBinPath (const Point& rCurrent, Point& rOld,
     926             :                        pspath_t eType, sal_Int32& nColumn)
     927             : {
     928           0 :     sal_Char  pPath[48] = {0};
     929             :     sal_Int32 nChar;
     930             : 
     931             :     // create the hex representation of the dx and dy path shift, store the field
     932             :     // width as it is needed for the building the command
     933           0 :     sal_Int32 nXPrec = getAlignedHexValueOf (rCurrent.X() - rOld.X(), pPath + 1);
     934           0 :     sal_Int32 nYPrec = getAlignedHexValueOf (rCurrent.Y() - rOld.Y(), pPath + 1 + nXPrec);
     935           0 :     pPath [ 1 + nXPrec + nYPrec ] = 0;
     936             : 
     937             :     // build the command, it is a char with bit represention 000cxxyy
     938             :     // c represents the char, xx and yy repr. the field width of the dx and dy shift,
     939             :     // dx and dy represent the number of bytes to read after the opcode
     940           0 :     sal_Char cCmd = (eType == lineto ? (sal_Char)0x00 : (sal_Char)0x10);
     941           0 :     switch (nYPrec)
     942             :     {
     943           0 :         case 2: break;
     944           0 :         case 4: cCmd |= 0x01;   break;
     945           0 :         case 6: cCmd |= 0x02;   break;
     946           0 :         case 8: cCmd |= 0x03;   break;
     947             :         default:    OSL_FAIL("invalid x precision in binary path");
     948             :     }
     949           0 :     switch (nXPrec)
     950             :     {
     951           0 :         case 2: break;
     952           0 :         case 4: cCmd |= 0x04;   break;
     953           0 :         case 6: cCmd |= 0x08;   break;
     954           0 :         case 8: cCmd |= 0x0c;   break;
     955             :         default:    OSL_FAIL("invalid y precision in binary path");
     956             :     }
     957           0 :     cCmd += 'A';
     958           0 :     pPath[0] = cCmd;
     959             : 
     960             :     // write the command to file,
     961             :     // line breaking at column nMaxTextColumn (80)
     962           0 :     nChar = 1 + nXPrec + nYPrec;
     963           0 :     if ((nColumn + nChar) > nMaxTextColumn)
     964             :     {
     965           0 :         sal_Int32 nSegment = nMaxTextColumn - nColumn;
     966             : 
     967           0 :         WritePS (mpPageBody, pPath, nSegment);
     968           0 :         WritePS (mpPageBody, "\n", 1);
     969           0 :         WritePS (mpPageBody, pPath + nSegment, nChar - nSegment);
     970             : 
     971           0 :         nColumn  = nChar - nSegment;
     972             :     }
     973             :     else
     974             :     {
     975           0 :         WritePS (mpPageBody, pPath, nChar);
     976             : 
     977           0 :         nColumn += nChar;
     978             :     }
     979             : 
     980           0 :     rOld = rCurrent;
     981           0 : }
     982             : 
     983             : void
     984           0 : PrinterGfx::PSScale (double fScaleX, double fScaleY)
     985             : {
     986             :     sal_Char  pScale [48];
     987           0 :     sal_Int32 nChar = 0;
     988             : 
     989           0 :     nChar  = psp::getValueOfDouble (pScale, fScaleX, 5);
     990           0 :     nChar += psp::appendStr        (" ", pScale + nChar);
     991           0 :     nChar += psp::getValueOfDouble (pScale + nChar, fScaleY, 5);
     992           0 :     nChar += psp::appendStr        (" scale\n", pScale + nChar);
     993             : 
     994           0 :     WritePS (mpPageBody, pScale);
     995           0 : }
     996             : 
     997             : /* psshowtext helper routines: draw an hex string for show/xshow */
     998             : void
     999           0 : PrinterGfx::PSHexString (const unsigned char* pString, sal_Int16 nLen)
    1000             : {
    1001             :     sal_Char pHexString [128];
    1002           0 :     sal_Int32 nChar = 0;
    1003             : 
    1004           0 :     nChar = psp::appendStr ("<", pHexString);
    1005           0 :     for (int i = 0; i < nLen; i++)
    1006             :     {
    1007           0 :         if (nChar >= (nMaxTextColumn - 1))
    1008             :         {
    1009           0 :             nChar += psp::appendStr ("\n", pHexString + nChar);
    1010           0 :             WritePS (mpPageBody, pHexString, nChar);
    1011           0 :             nChar = 0;
    1012             :         }
    1013           0 :         nChar += psp::getHexValueOf ((sal_Int32)pString[i], pHexString + nChar);
    1014             :     }
    1015             : 
    1016           0 :     nChar += psp::appendStr (">\n", pHexString + nChar);
    1017           0 :     WritePS (mpPageBody, pHexString, nChar);
    1018           0 : }
    1019             : 
    1020             : /* psshowtext helper routines: draw an array for xshow ps operator */
    1021             : void
    1022           0 : PrinterGfx::PSDeltaArray (const sal_Int32 *pArray, sal_Int16 nEntries)
    1023             : {
    1024             :     sal_Char pPSArray [128];
    1025           0 :     sal_Int32 nChar = 0;
    1026             : 
    1027           0 :     nChar  = psp::appendStr  ("[", pPSArray + nChar);
    1028           0 :     nChar += psp::getValueOf (pArray[0], pPSArray + nChar);
    1029             : 
    1030           0 :     for (int i = 1; i < nEntries; i++)
    1031             :     {
    1032           0 :         if (nChar >= (nMaxTextColumn - 1))
    1033             :         {
    1034           0 :             nChar += psp::appendStr ("\n", pPSArray + nChar);
    1035           0 :             WritePS (mpPageBody, pPSArray, nChar);
    1036           0 :             nChar = 0;
    1037             :         }
    1038             : 
    1039           0 :         nChar += psp::appendStr  (" ", pPSArray + nChar);
    1040           0 :         nChar += psp::getValueOf (pArray[i] - pArray[i-1], pPSArray + nChar);
    1041             :     }
    1042             : 
    1043           0 :     nChar  += psp::appendStr (" 0]\n", pPSArray + nChar);
    1044           0 :     WritePS (mpPageBody, pPSArray);
    1045           0 : }
    1046             : 
    1047             : /* the DrawText equivalent, pDeltaArray may be NULL. For Type1 fonts or single byte
    1048             :  * fonts in general nBytes and nGlyphs is the same. For printer resident Composite
    1049             :  * fonts it may be different (these fonts may be SJIS encoded for example) */
    1050             : void
    1051           0 : PrinterGfx::PSShowText (const unsigned char* pStr, sal_Int16 nGlyphs, sal_Int16 nBytes,
    1052             :                         const sal_Int32* pDeltaArray)
    1053             : {
    1054           0 :     PSSetColor (maTextColor);
    1055           0 :     PSSetColor ();
    1056           0 :     PSSetFont  ();
    1057             :     // rotate the user coordinate system
    1058           0 :     if (mnTextAngle != 0)
    1059             :     {
    1060           0 :         PSGSave ();
    1061           0 :         PSRotate (mnTextAngle);
    1062             :     }
    1063             : 
    1064             :     sal_Char pBuffer[256];
    1065           0 :     if( maVirtualStatus.mbArtBold )
    1066             :     {
    1067           0 :         sal_Int32 nLW = maVirtualStatus.mnTextWidth;
    1068           0 :         if( nLW == 0 )
    1069           0 :             nLW = maVirtualStatus.mnTextHeight;
    1070             :         else
    1071           0 :             nLW = nLW < maVirtualStatus.mnTextHeight ? nLW : maVirtualStatus.mnTextHeight;
    1072           0 :         psp::getValueOfDouble( pBuffer, (double)nLW / 30.0 );
    1073             :     }
    1074             :     // dispatch to the drawing method
    1075           0 :     if (pDeltaArray == NULL)
    1076             :     {
    1077           0 :         PSHexString (pStr, nBytes);
    1078             : 
    1079           0 :         if( maVirtualStatus.mbArtBold )
    1080             :         {
    1081           0 :             WritePS( mpPageBody, pBuffer );
    1082           0 :             WritePS( mpPageBody, " bshow\n" );
    1083             :         }
    1084             :         else
    1085           0 :             WritePS (mpPageBody, "show\n");
    1086             :     }
    1087             :     else
    1088             :     {
    1089           0 :         PSHexString (pStr, nBytes);
    1090           0 :         PSDeltaArray (pDeltaArray, nGlyphs - 1);
    1091           0 :         if( maVirtualStatus.mbArtBold )
    1092             :         {
    1093           0 :             WritePS( mpPageBody, pBuffer );
    1094           0 :             WritePS( mpPageBody, " bxshow\n" );
    1095             :         }
    1096             :         else
    1097           0 :             WritePS (mpPageBody, "xshow\n");
    1098             :     }
    1099             : 
    1100             :     // restore the user coordinate system
    1101           0 :     if (mnTextAngle != 0)
    1102           0 :         PSGRestore ();
    1103           0 : }
    1104             : 
    1105             : void
    1106           0 : PrinterGfx::PSComment( const sal_Char* pComment )
    1107             : {
    1108           0 :     const sal_Char* pLast = pComment;
    1109           0 :     while( pComment && *pComment )
    1110             :     {
    1111           0 :         while( *pComment && *pComment != '\n' && *pComment != '\r' )
    1112           0 :             pComment++;
    1113           0 :         if( pComment - pLast > 1 )
    1114             :         {
    1115           0 :             WritePS( mpPageBody, "% ", 2 );
    1116           0 :             WritePS( mpPageBody, pLast, pComment - pLast );
    1117           0 :             WritePS( mpPageBody, "\n", 1 );
    1118             :         }
    1119           0 :         if( *pComment )
    1120           0 :             pLast = ++pComment;
    1121             :     }
    1122           0 : }
    1123             : 
    1124             : bool
    1125           0 : PrinterGfx::DrawEPS( const Rectangle& rBoundingBox, void* pPtr, sal_uInt32 nSize )
    1126             : {
    1127           0 :     if( nSize == 0 )
    1128           0 :         return true;
    1129           0 :     if( ! mpPageBody )
    1130           0 :         return false;
    1131             : 
    1132           0 :     bool bSuccess = false;
    1133             : 
    1134             :     // first search the BoundingBox of the EPS data
    1135           0 :     SvMemoryStream aStream( pPtr, nSize, STREAM_READ );
    1136           0 :     aStream.Seek( STREAM_SEEK_TO_BEGIN );
    1137           0 :     OString aLine;
    1138             : 
    1139           0 :     OString aDocTitle;
    1140           0 :     double fLeft = 0, fRight = 0, fTop = 0, fBottom = 0;
    1141           0 :     bool bEndComments = false;
    1142           0 :     while( ! aStream.IsEof()
    1143           0 :            && ( ( fLeft == 0 && fRight == 0 && fTop == 0 && fBottom == 0 ) ||
    1144           0 :                 ( aDocTitle.isEmpty() && bEndComments == false ) )
    1145             :            )
    1146             :     {
    1147           0 :         aStream.ReadLine( aLine );
    1148           0 :         if( aLine.getLength() > 1 && aLine[0] == '%' )
    1149             :         {
    1150           0 :             char cChar = aLine[1];
    1151           0 :             if( cChar == '%' )
    1152             :             {
    1153           0 :                 if( aLine.matchIgnoreAsciiCase( OString( "%%BoundingBox:") ) )
    1154             :                 {
    1155           0 :                     aLine = WhitespaceToSpace( aLine.getToken(1, ':') );
    1156           0 :                     if( !aLine.isEmpty() && aLine.indexOf( "atend" ) == -1 )
    1157             :                     {
    1158           0 :                         fLeft   = StringToDouble( GetCommandLineToken( 0, aLine ) );
    1159           0 :                         fBottom = StringToDouble( GetCommandLineToken( 1, aLine ) );
    1160           0 :                         fRight  = StringToDouble( GetCommandLineToken( 2, aLine ) );
    1161           0 :                         fTop    = StringToDouble( GetCommandLineToken( 3, aLine ) );
    1162             :                     }
    1163             :                 }
    1164           0 :                 else if( aLine.matchIgnoreAsciiCase( "%%Title:" ) )
    1165           0 :                     aDocTitle = WhitespaceToSpace( aLine.copy( 8 ) );
    1166           0 :                 else if( aLine.matchIgnoreAsciiCase( "%%EndComments" ) )
    1167           0 :                     bEndComments = true;
    1168             :             }
    1169           0 :             else if( cChar == ' ' || cChar == '\t' || cChar == '\r' || cChar == '\n' )
    1170           0 :                 bEndComments = true;
    1171             :         }
    1172             :         else
    1173           0 :             bEndComments = true;
    1174             :     }
    1175             : 
    1176             :     static sal_uInt16 nEps = 0;
    1177           0 :     if( aDocTitle.isEmpty() )
    1178           0 :         aDocTitle = OString::number(nEps++);
    1179             : 
    1180           0 :     if( fLeft != fRight && fTop != fBottom )
    1181             :     {
    1182           0 :         double fScaleX = (double)rBoundingBox.GetWidth()/(fRight-fLeft);
    1183           0 :         double fScaleY = -(double)rBoundingBox.GetHeight()/(fTop-fBottom);
    1184           0 :         Point aTranslatePoint( (int)(rBoundingBox.Left()-fLeft*fScaleX),
    1185           0 :                                (int)(rBoundingBox.Bottom()+1-fBottom*fScaleY) );
    1186             :         // prepare EPS
    1187             :         WritePS( mpPageBody,
    1188             :                  "/b4_Inc_state save def\n"
    1189             :                  "/dict_count countdictstack def\n"
    1190             :                  "/op_count count 1 sub def\n"
    1191             :                  "userdict begin\n"
    1192             :                  "/showpage {} def\n"
    1193             :                  "0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin\n"
    1194             :                  "10 setmiterlimit [] 0 setdash newpath\n"
    1195             :                  "/languagelevel where\n"
    1196             :                  "{pop languagelevel\n"
    1197             :                  "1 ne\n"
    1198             :                  "  {false setstrokeadjust false setoverprint\n"
    1199             :                  "  } if\n"
    1200           0 :                  "}if\n" );
    1201             :         // set up clip path and scale
    1202           0 :         BeginSetClipRegion( 1 );
    1203           0 :         UnionClipRegion( rBoundingBox.Left(), rBoundingBox.Top(), rBoundingBox.GetWidth(), rBoundingBox.GetHeight() );
    1204           0 :         EndSetClipRegion();
    1205           0 :         PSTranslate( aTranslatePoint );
    1206           0 :         PSScale( fScaleX, fScaleY );
    1207             : 
    1208             :         // DSC requires BeginDocument
    1209           0 :         WritePS( mpPageBody, "%%BeginDocument: " );
    1210           0 :         WritePS( mpPageBody, aDocTitle );
    1211           0 :         WritePS( mpPageBody, "\n" );
    1212             : 
    1213             :         // write the EPS data
    1214             :         sal_uInt64 nOutLength;
    1215           0 :         mpPageBody->write( pPtr, nSize, nOutLength );
    1216           0 :         bSuccess = nOutLength == nSize;
    1217             : 
    1218             :         // corresponding EndDocument
    1219           0 :         if( ((char*)pPtr)[ nSize-1 ] != '\n' )
    1220           0 :             WritePS( mpPageBody, "\n" );
    1221           0 :         WritePS( mpPageBody, "%%EndDocument\n" );
    1222             : 
    1223             :         // clean up EPS
    1224             :         WritePS( mpPageBody,
    1225             :                  "count op_count sub {pop} repeat\n"
    1226             :                  "countdictstack dict_count sub {end} repeat\n"
    1227           0 :                  "b4_Inc_state restore\n" );
    1228             :     }
    1229           0 :     return bSuccess;
    1230         516 : }
    1231             : 
    1232             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10