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