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