xref: /trunk/main/vcl/unx/headless/svpgdi.cxx (revision e6f63103)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "svpgdi.hxx"
25 #include "svpbmp.hxx"
26 
27 #include <vcl/sysdata.hxx>
28 #include <basegfx/range/b2drange.hxx>
29 #include <basegfx/range/b2irange.hxx>
30 #include <basegfx/polygon/b2dpolypolygon.hxx>
31 #include <basegfx/polygon/b2dpolygon.hxx>
32 #include <basegfx/polygon/b2dpolygontools.hxx>
33 #include <basebmp/scanlineformats.hxx>
34 
35 #include <tools/debug.hxx>
36 
37 #if OSL_DEBUG_LEVEL > 2
38 #include <basebmp/debug.hxx>
39 #include <fstream>
40 #include <rtl/strbuf.hxx>
41 #include <sys/stat.h>
42 #endif
43 
44 #include <svppspgraphics.hxx>
45 
46 using namespace basegfx;
47 using namespace basebmp;
48 
49 inline void dbgOut( const BitmapDeviceSharedPtr&
50 #if OSL_DEBUG_LEVEL > 2
51 rDevice
52 #endif
53 )
54 {
55     #if OSL_DEBUG_LEVEL > 2
56     static int dbgStreamNum = 0;
57     rtl::OStringBuffer aBuf( 256 );
58     aBuf.append( "debug" );
59     mkdir( aBuf.getStr(), 0777 );
60     aBuf.append( "/" );
61     aBuf.append( sal_Int64(reinterpret_cast<sal_uInt32>(rDevice.get())), 16 );
62     mkdir( aBuf.getStr(), 0777 );
63     aBuf.append( "/bmp" );
64     aBuf.append( sal_Int32(dbgStreamNum++) );
65     std::fstream bmpstream( aBuf.getStr(), std::ios::out );
66     debugDump( rDevice, bmpstream );
67     #endif
68 }
69 
70 // ===========================================================================
71 
72 bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSourceBitmap*/, const SalBitmap& /*rAlphaBitmap*/ )
73 {
74 	// TODO(P3) implement alpha blending
75 	return false;
76 }
77 
78 bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ )
79 {
80 	// TODO(P3) implement alpha blending
81 	return false;
82 }
83 
84 SvpSalGraphics::SvpSalGraphics() :
85     m_bUseLineColor( true ),
86     m_aLineColor( COL_BLACK ),
87     m_bUseFillColor( false ),
88     m_aFillColor( COL_WHITE ),
89     m_aTextColor( COL_BLACK ),
90     m_aDrawMode( DrawMode_PAINT ),
91     m_eTextFmt( Format::EIGHT_BIT_GREY )
92 {
93     for( int i = 0; i < MAX_FALLBACK; ++i )
94         m_pServerFont[i] = NULL;
95 }
96 
97 SvpSalGraphics::~SvpSalGraphics()
98 {
99 }
100 
101 void SvpSalGraphics::setDevice( BitmapDeviceSharedPtr& rDevice )
102 {
103     m_aDevice = rDevice;
104     m_aOrigDevice = rDevice;
105     m_aClipMap.reset();
106 
107     // determine matching bitmap format for masks
108     sal_uInt32 nDeviceFmt = m_aDevice->getScanlineFormat();
109     DBG_ASSERT( (nDeviceFmt <= (sal_uInt32)Format::MAX), "SVP::setDevice() with invalid bitmap format" );
110     switch( nDeviceFmt )
111     {
112         case Format::EIGHT_BIT_GREY:
113         case Format::SIXTEEN_BIT_LSB_TC_MASK:
114         case Format::SIXTEEN_BIT_MSB_TC_MASK:
115         case Format::TWENTYFOUR_BIT_TC_MASK:
116         case Format::THIRTYTWO_BIT_TC_MASK:
117             m_eTextFmt = Format::EIGHT_BIT_GREY;
118             break;
119         default:
120             m_eTextFmt = Format::ONE_BIT_LSB_GREY;
121             break;
122     }
123 }
124 
125 void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
126 {
127     rDPIX = rDPIY = 96;
128 }
129 
130 sal_uInt16 SvpSalGraphics::GetBitCount()
131 {
132     return SvpElement::getBitCountFromScanlineFormat( m_aDevice->getScanlineFormat() );
133 }
134 
135 long SvpSalGraphics::GetGraphicsWidth() const
136 {
137     if( m_aDevice.get() )
138     {
139         B2IVector aSize = m_aDevice->getSize();
140         return aSize.getX();
141     }
142     return 0;
143 }
144 
145 void SvpSalGraphics::ResetClipRegion()
146 {
147     m_aDevice = m_aOrigDevice;
148     m_aClipMap.reset();
149 }
150 
151 bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
152 {
153     if( i_rClip.IsEmpty() )
154     {
155         m_aClipMap.reset();
156         return true;
157     }
158 
159     RectangleVector aRectangles;
160     i_rClip.GetRegionRectangles(aRectangles);
161 
162     if(1 == aRectangles.size())
163     {
164         m_aClipMap.reset();
165         const Rectangle& aBoundRect = aRectangles[0];
166         m_aDevice = basebmp::subsetBitmapDevice(
167             m_aOrigDevice,
168             basegfx::B2IRange(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
169         return true;
170     }
171 
172     m_aDevice = m_aOrigDevice;
173     B2IVector aSize = m_aDevice->getSize();
174     m_aClipMap = createBitmapDevice( aSize, false, Format::ONE_BIT_MSB_GREY );
175     m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
176 
177     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
178     {
179         const long nW(aRectIter->GetWidth());
180 
181         if(nW)
182         {
183             const long nH(aRectIter->GetHeight());
184 
185             if(nH)
186             {
187                 B2DPolyPolygon aFull;
188 
189                 aFull.append(
190                     tools::createPolygonFromRect(
191                         B2DRectangle(
192                             aRectIter->Left(),
193                             aRectIter->Top(),
194                             aRectIter->Left() + nW,
195                             aRectIter->Top() + nH)));
196                 m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), DrawMode_PAINT);
197             }
198         }
199     }
200 
201     //ImplRegionInfo aInfo;
202     //long nX, nY, nW, nH;
203     //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
204     //while( bRegionRect )
205     //{
206     //    if ( nW && nH )
207     //    {
208     //        B2DPolyPolygon aFull;
209     //        aFull.append( tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nW, nY+nH ) ) );
210     //        m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), DrawMode_PAINT );
211     //    }
212     //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
213     //}
214     return true;
215 }
216 
217 void SvpSalGraphics::SetLineColor()
218 {
219     m_bUseLineColor = false;
220 }
221 
222 void SvpSalGraphics::SetLineColor( SalColor nSalColor )
223 {
224     m_bUseLineColor = true;
225     m_aLineColor = basebmp::Color( nSalColor );
226 }
227 
228 void SvpSalGraphics::SetFillColor()
229 {
230     m_bUseFillColor = false;
231 }
232 
233 void SvpSalGraphics::SetFillColor( SalColor nSalColor )
234 {
235     m_bUseFillColor = true;
236     m_aFillColor = basebmp::Color( nSalColor );
237 }
238 
239 void SvpSalGraphics::SetXORMode( bool bSet, bool )
240 {
241     m_aDrawMode = bSet ? DrawMode_XOR : DrawMode_PAINT;
242 }
243 
244 void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor )
245 {
246     m_bUseLineColor = true;
247     switch( nROPColor )
248     {
249         case SAL_ROP_0:
250             m_aLineColor = basebmp::Color( 0 );
251             break;
252         case SAL_ROP_1:
253             m_aLineColor = basebmp::Color( 0xffffff );
254             break;
255         case SAL_ROP_INVERT:
256             m_aLineColor = basebmp::Color( 0xffffff );
257             break;
258     }
259 }
260 
261 void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor )
262 {
263     m_bUseFillColor = true;
264     switch( nROPColor )
265     {
266         case SAL_ROP_0:
267             m_aFillColor = basebmp::Color( 0 );
268             break;
269         case SAL_ROP_1:
270             m_aFillColor = basebmp::Color( 0xffffff );
271             break;
272         case SAL_ROP_INVERT:
273             m_aFillColor = basebmp::Color( 0xffffff );
274             break;
275     }
276 }
277 
278 void SvpSalGraphics::SetTextColor( SalColor nSalColor )
279 {
280     m_aTextColor = basebmp::Color( nSalColor );
281 }
282 
283 void SvpSalGraphics::drawPixel( long nX, long nY )
284 {
285     if( m_bUseLineColor )
286         m_aDevice->setPixel( B2IPoint( nX, nY ),
287                              m_aLineColor,
288                              m_aDrawMode,
289                              m_aClipMap
290                              );
291     dbgOut( m_aDevice );
292 }
293 
294 void SvpSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
295 {
296     basebmp::Color aColor( nSalColor );
297     m_aDevice->setPixel( B2IPoint( nX, nY ),
298                          aColor,
299                          m_aDrawMode,
300                          m_aClipMap
301                          );
302     dbgOut( m_aDevice );
303 }
304 
305 void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
306 {
307     if( m_bUseLineColor )
308         m_aDevice->drawLine( B2IPoint( nX1, nY1 ),
309                              B2IPoint( nX2, nY2 ),
310                              m_aLineColor,
311                              m_aDrawMode,
312                              m_aClipMap );
313     dbgOut( m_aDevice );
314 }
315 
316 void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
317 {
318     if( m_bUseLineColor || m_bUseFillColor )
319     {
320         B2DPolygon aRect = tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
321         if( m_bUseFillColor )
322         {
323             B2DPolyPolygon aPolyPoly( aRect );
324             m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
325         }
326         if( m_bUseLineColor )
327             m_aDevice->drawPolygon( aRect, m_aLineColor, m_aDrawMode, m_aClipMap );
328     }
329     dbgOut( m_aDevice );
330 }
331 
332 void SvpSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry )
333 {
334     if( m_bUseLineColor && nPoints )
335     {
336         B2DPolygon aPoly;
337         aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
338         for( sal_uLong i = 1; i < nPoints; i++ )
339             aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
340         aPoly.setClosed( false );
341         m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
342     }
343     dbgOut( m_aDevice );
344 }
345 
346 void SvpSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry )
347 {
348     if( ( m_bUseLineColor || m_bUseFillColor ) && nPoints )
349     {
350         B2DPolygon aPoly;
351         aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
352         for( sal_uLong i = 1; i < nPoints; i++ )
353             aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
354         if( m_bUseFillColor )
355         {
356             aPoly.setClosed( true );
357             m_aDevice->fillPolyPolygon( B2DPolyPolygon(aPoly), m_aFillColor, m_aDrawMode, m_aClipMap );
358         }
359         if( m_bUseLineColor )
360         {
361             aPoly.setClosed( false );
362             m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
363         }
364     }
365     dbgOut( m_aDevice );
366 }
367 
368 void SvpSalGraphics::drawPolyPolygon( sal_uInt32        nPoly,
369                                       const sal_uInt32* pPointCounts,
370                                       PCONSTSALPOINT*   pPtAry )
371 {
372     if( ( m_bUseLineColor || m_bUseFillColor ) && nPoly )
373     {
374         B2DPolyPolygon aPolyPoly;
375         for( sal_uInt32 nPolygon = 0; nPolygon < nPoly; nPolygon++ )
376         {
377             sal_uInt32 nPoints = pPointCounts[nPolygon];
378             if( nPoints )
379             {
380                 PCONSTSALPOINT pPoints = pPtAry[nPolygon];
381                 B2DPolygon aPoly;
382                 aPoly.append( B2DPoint( pPoints->mnX, pPoints->mnY ), nPoints );
383                 for( sal_uInt32 i = 1; i < nPoints; i++ )
384                     aPoly.setB2DPoint( i, B2DPoint( pPoints[i].mnX, pPoints[i].mnY ) );
385 
386                 aPolyPoly.append( aPoly );
387             }
388         }
389         if( m_bUseFillColor )
390         {
391             aPolyPoly.setClosed( true );
392             m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
393         }
394         if( m_bUseLineColor )
395         {
396             aPolyPoly.setClosed( false );
397             nPoly = aPolyPoly.count();
398             for( sal_uInt32 i = 0; i < nPoly; i++ )
399                 m_aDevice->drawPolygon( aPolyPoly.getB2DPolygon(i), m_aLineColor, m_aDrawMode, m_aClipMap );
400         }
401     }
402     dbgOut( m_aDevice );
403 }
404 
405 bool SvpSalGraphics::drawPolyLine(
406     const ::basegfx::B2DPolygon&,
407     double /*fTransparency*/,
408     const ::basegfx::B2DVector& /*rLineWidths*/,
409     basegfx::B2DLineJoin /*eJoin*/,
410     com::sun::star::drawing::LineCap /*eLineCap*/)
411 {
412         // TODO: implement and advertise OutDevSupport_B2DDraw support
413         return false;
414 }
415 
416 sal_Bool SvpSalGraphics::drawPolyLineBezier( sal_uLong,
417                                              const SalPoint*,
418                                              const sal_uInt8* )
419 {
420     return sal_False;
421 }
422 
423 sal_Bool SvpSalGraphics::drawPolygonBezier( sal_uLong,
424                                             const SalPoint*,
425                                             const sal_uInt8* )
426 {
427     return sal_False;
428 }
429 
430 sal_Bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
431                                                 const sal_uInt32*,
432                                                 const SalPoint* const*,
433                                                 const sal_uInt8* const* )
434 {
435     return sal_False;
436 }
437 
438 bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
439 {
440     // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
441     return false;
442 }
443 
444 void SvpSalGraphics::copyArea( long nDestX,
445                                       long nDestY,
446                                       long nSrcX,
447                                       long nSrcY,
448                                       long nSrcWidth,
449                                       long nSrcHeight,
450                                       sal_uInt16 /*nFlags*/ )
451 {
452     B2IRange aSrcRect( nSrcX, nSrcY, nSrcX+nSrcWidth, nSrcY+nSrcHeight );
453     B2IRange aDestRect( nDestX, nDestY, nDestX+nSrcWidth, nDestY+nSrcHeight );
454     m_aDevice->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
455     dbgOut( m_aDevice );
456 }
457 
458 void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry,
459                                SalGraphics*      pSrcGraphics )
460 {
461     SvpSalGraphics* pSrc = pSrcGraphics ?
462         static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
463     B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
464                        pPosAry->mnSrcX+pPosAry->mnSrcWidth,
465                        pPosAry->mnSrcY+pPosAry->mnSrcHeight );
466     B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
467                         pPosAry->mnDestX+pPosAry->mnDestWidth,
468                         pPosAry->mnDestY+pPosAry->mnDestHeight );
469     m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
470     dbgOut( m_aDevice );
471 }
472 
473 void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
474                                         const SalBitmap& rSalBitmap )
475 {
476     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
477     B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
478                        pPosAry->mnSrcX+pPosAry->mnSrcWidth,
479                        pPosAry->mnSrcY+pPosAry->mnSrcHeight );
480     B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
481                         pPosAry->mnDestX+pPosAry->mnDestWidth,
482                         pPosAry->mnDestY+pPosAry->mnDestHeight );
483     m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
484     dbgOut( m_aDevice );
485 }
486 
487 void SvpSalGraphics::drawBitmap( const SalTwoRect*,
488                                  const SalBitmap&,
489                                  SalColor )
490 {
491     // SNI, as in X11 plugin
492 }
493 
494 void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
495                                  const SalBitmap& rSalBitmap,
496                                  const SalBitmap& rTransparentBitmap )
497 {
498     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
499     const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap);
500     B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
501                        pPosAry->mnSrcX+pPosAry->mnSrcWidth,
502                        pPosAry->mnSrcY+pPosAry->mnSrcHeight );
503     B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
504                         pPosAry->mnDestX+pPosAry->mnDestWidth,
505                         pPosAry->mnDestY+pPosAry->mnDestHeight );
506     m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
507     dbgOut( m_aDevice );
508 }
509 
510 void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry,
511                                const SalBitmap& rSalBitmap,
512                                SalColor nMaskColor )
513 {
514     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
515     B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
516                        pPosAry->mnSrcX+pPosAry->mnSrcWidth,
517                        pPosAry->mnSrcY+pPosAry->mnSrcHeight );
518     B2IPoint aDestPoint( pPosAry->mnDestX, pPosAry->mnDestY );
519 
520     // BitmapDevice::drawMaskedColor works with 0==transparent,
521     // 255==opaque. drawMask() semantic is the other way
522     // around. Therefore, invert mask.
523     BitmapDeviceSharedPtr aCopy =
524         cloneBitmapDevice( B2IVector( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ),
525                            rSrc.getBitmap() );
526     basebmp::Color aBgColor( COL_WHITE );
527     aCopy->clear(aBgColor);
528     basebmp::Color aFgColor( COL_BLACK );
529     aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, B2IPoint() );
530 
531     basebmp::Color aColor( nMaskColor );
532     B2IRange aSrcRect2( 0, 0, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight );
533     m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap );
534     dbgOut( m_aDevice );
535 }
536 
537 SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
538 {
539     BitmapDeviceSharedPtr aCopy =
540         cloneBitmapDevice( B2IVector( nWidth, nHeight ),
541                            m_aDevice );
542     B2IRange aSrcRect( nX, nY, nX+nWidth, nY+nHeight );
543     B2IRange aDestRect( 0, 0, nWidth, nHeight );
544     aCopy->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT );
545 
546     SvpSalBitmap* pBitmap = new SvpSalBitmap();
547     pBitmap->setBitmap( aCopy );
548     return pBitmap;
549 }
550 
551 SalColor SvpSalGraphics::getPixel( long nX, long nY )
552 {
553     basebmp::Color aColor( m_aDevice->getPixel( B2IPoint( nX, nY ) ) );
554     return aColor.toInt32();
555 }
556 
557 void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert /*nFlags*/ )
558 {
559     // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
560     B2DPolygon aRect = tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
561     B2DPolyPolygon aPolyPoly( aRect );
562     m_aDevice->fillPolyPolygon( aPolyPoly, basebmp::Color( 0xffffff ), DrawMode_XOR, m_aClipMap );
563     dbgOut( m_aDevice );
564 }
565 
566 void SvpSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert /*nFlags*/ )
567 {
568     // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
569     B2DPolygon aPoly;
570     aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
571     for( sal_uLong i = 1; i < nPoints; i++ )
572         aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
573     aPoly.setClosed( true );
574     m_aDevice->fillPolyPolygon( B2DPolyPolygon(aPoly), basebmp::Color( 0xffffff ), DrawMode_XOR, m_aClipMap );
575     dbgOut( m_aDevice );
576 }
577 
578 sal_Bool SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong )
579 {
580     return sal_False;
581 }
582 
583 SystemFontData SvpSalGraphics::GetSysFontData( int nFallbacklevel ) const
584 {
585     SystemFontData aSysFontData;
586 
587     if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1;
588     if (nFallbacklevel < 0 ) nFallbacklevel = 0;
589 
590     aSysFontData.nSize = sizeof( SystemFontData );
591     aSysFontData.nFontId = 0;
592     aSysFontData.nFontFlags = 0;
593     aSysFontData.bFakeBold = false;
594     aSysFontData.bFakeItalic = false;
595     aSysFontData.bAntialias = true;
596     return aSysFontData;
597 }
598 
599 SystemGraphicsData SvpSalGraphics::GetGraphicsData() const
600 {
601     SystemGraphicsData aRes;
602     aRes.nSize = sizeof(aRes);
603 	aRes.hDrawable = 0;
604 	aRes.pRenderFormat = 0;
605     return aRes;
606 }
607 
608 bool SvpSalGraphics::supportsOperation( OutDevSupportType ) const
609 {
610     return false;
611 }
612 
613