xref: /trunk/main/vcl/unx/headless/svpgdi.cxx (revision 5f27b83c)
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::drawTransformedBitmap(
79     const basegfx::B2DPoint& rNull,
80     const basegfx::B2DPoint& rX,
81     const basegfx::B2DPoint& rY,
82     const SalBitmap& rSourceBitmap,
83     const SalBitmap* pAlphaBitmap)
84 {
85     // here direct support for transformed bitmaps can be impemented
86     (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
87     return false;
88 }
89 
90 bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ )
91 {
92 	// TODO(P3) implement alpha blending
93 	return false;
94 }
95 
96 SvpSalGraphics::SvpSalGraphics() :
97     m_bUseLineColor( true ),
98     m_aLineColor( COL_BLACK ),
99     m_bUseFillColor( false ),
100     m_aFillColor( COL_WHITE ),
101     m_aTextColor( COL_BLACK ),
102     m_aDrawMode( DrawMode_PAINT ),
103     m_eTextFmt( Format::EIGHT_BIT_GREY )
104 {
105     for( int i = 0; i < MAX_FALLBACK; ++i )
106         m_pServerFont[i] = NULL;
107 }
108 
109 SvpSalGraphics::~SvpSalGraphics()
110 {
111 }
112 
113 void SvpSalGraphics::setDevice( BitmapDeviceSharedPtr& rDevice )
114 {
115     m_aDevice = rDevice;
116     m_aOrigDevice = rDevice;
117     m_aClipMap.reset();
118 
119     // determine matching bitmap format for masks
120     sal_uInt32 nDeviceFmt = m_aDevice->getScanlineFormat();
121     DBG_ASSERT( (nDeviceFmt <= (sal_uInt32)Format::MAX), "SVP::setDevice() with invalid bitmap format" );
122     switch( nDeviceFmt )
123     {
124         case Format::EIGHT_BIT_GREY:
125         case Format::SIXTEEN_BIT_LSB_TC_MASK:
126         case Format::SIXTEEN_BIT_MSB_TC_MASK:
127         case Format::TWENTYFOUR_BIT_TC_MASK:
128         case Format::THIRTYTWO_BIT_TC_MASK:
129             m_eTextFmt = Format::EIGHT_BIT_GREY;
130             break;
131         default:
132             m_eTextFmt = Format::ONE_BIT_LSB_GREY;
133             break;
134     }
135 }
136 
137 void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
138 {
139     rDPIX = rDPIY = 96;
140 }
141 
142 sal_uInt16 SvpSalGraphics::GetBitCount()
143 {
144     return SvpElement::getBitCountFromScanlineFormat( m_aDevice->getScanlineFormat() );
145 }
146 
147 long SvpSalGraphics::GetGraphicsWidth() const
148 {
149     if( m_aDevice.get() )
150     {
151         B2IVector aSize = m_aDevice->getSize();
152         return aSize.getX();
153     }
154     return 0;
155 }
156 
157 void SvpSalGraphics::ResetClipRegion()
158 {
159     m_aDevice = m_aOrigDevice;
160     m_aClipMap.reset();
161 }
162 
163 bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
164 {
165     if( i_rClip.IsEmpty() )
166     {
167         m_aClipMap.reset();
168         return true;
169     }
170 
171     RectangleVector aRectangles;
172     i_rClip.GetRegionRectangles(aRectangles);
173 
174     if(1 == aRectangles.size())
175     {
176         m_aClipMap.reset();
177         const Rectangle& aBoundRect = aRectangles[0];
178         m_aDevice = basebmp::subsetBitmapDevice(
179             m_aOrigDevice,
180             basegfx::B2IRange(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
181         return true;
182     }
183 
184     m_aDevice = m_aOrigDevice;
185     B2IVector aSize = m_aDevice->getSize();
186     m_aClipMap = createBitmapDevice( aSize, false, Format::ONE_BIT_MSB_GREY );
187     m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
188 
189     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
190     {
191         const long nW(aRectIter->GetWidth());
192 
193         if(nW)
194         {
195             const long nH(aRectIter->GetHeight());
196 
197             if(nH)
198             {
199                 B2DPolyPolygon aFull;
200 
201                 aFull.append(
202                     tools::createPolygonFromRect(
203                         B2DRectangle(
204                             aRectIter->Left(),
205                             aRectIter->Top(),
206                             aRectIter->Left() + nW,
207                             aRectIter->Top() + nH)));
208                 m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), DrawMode_PAINT);
209             }
210         }
211     }
212 
213     //ImplRegionInfo aInfo;
214     //long nX, nY, nW, nH;
215     //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
216     //while( bRegionRect )
217     //{
218     //    if ( nW && nH )
219     //    {
220     //        B2DPolyPolygon aFull;
221     //        aFull.append( tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nW, nY+nH ) ) );
222     //        m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), DrawMode_PAINT );
223     //    }
224     //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
225     //}
226     return true;
227 }
228 
229 void SvpSalGraphics::SetLineColor()
230 {
231     m_bUseLineColor = false;
232 }
233 
234 void SvpSalGraphics::SetLineColor( SalColor nSalColor )
235 {
236     m_bUseLineColor = true;
237     m_aLineColor = basebmp::Color( nSalColor );
238 }
239 
240 void SvpSalGraphics::SetFillColor()
241 {
242     m_bUseFillColor = false;
243 }
244 
245 void SvpSalGraphics::SetFillColor( SalColor nSalColor )
246 {
247     m_bUseFillColor = true;
248     m_aFillColor = basebmp::Color( nSalColor );
249 }
250 
251 void SvpSalGraphics::SetXORMode( bool bSet, bool )
252 {
253     m_aDrawMode = bSet ? DrawMode_XOR : DrawMode_PAINT;
254 }
255 
256 void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor )
257 {
258     m_bUseLineColor = true;
259     switch( nROPColor )
260     {
261         case SAL_ROP_0:
262             m_aLineColor = basebmp::Color( 0 );
263             break;
264         case SAL_ROP_1:
265             m_aLineColor = basebmp::Color( 0xffffff );
266             break;
267         case SAL_ROP_INVERT:
268             m_aLineColor = basebmp::Color( 0xffffff );
269             break;
270     }
271 }
272 
273 void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor )
274 {
275     m_bUseFillColor = true;
276     switch( nROPColor )
277     {
278         case SAL_ROP_0:
279             m_aFillColor = basebmp::Color( 0 );
280             break;
281         case SAL_ROP_1:
282             m_aFillColor = basebmp::Color( 0xffffff );
283             break;
284         case SAL_ROP_INVERT:
285             m_aFillColor = basebmp::Color( 0xffffff );
286             break;
287     }
288 }
289 
290 void SvpSalGraphics::SetTextColor( SalColor nSalColor )
291 {
292     m_aTextColor = basebmp::Color( nSalColor );
293 }
294 
295 void SvpSalGraphics::drawPixel( long nX, long nY )
296 {
297     if( m_bUseLineColor )
298         m_aDevice->setPixel( B2IPoint( nX, nY ),
299                              m_aLineColor,
300                              m_aDrawMode,
301                              m_aClipMap
302                              );
303     dbgOut( m_aDevice );
304 }
305 
306 void SvpSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
307 {
308     basebmp::Color aColor( nSalColor );
309     m_aDevice->setPixel( B2IPoint( nX, nY ),
310                          aColor,
311                          m_aDrawMode,
312                          m_aClipMap
313                          );
314     dbgOut( m_aDevice );
315 }
316 
317 void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
318 {
319     if( m_bUseLineColor )
320         m_aDevice->drawLine( B2IPoint( nX1, nY1 ),
321                              B2IPoint( nX2, nY2 ),
322                              m_aLineColor,
323                              m_aDrawMode,
324                              m_aClipMap );
325     dbgOut( m_aDevice );
326 }
327 
328 void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
329 {
330     if( m_bUseLineColor || m_bUseFillColor )
331     {
332         B2DPolygon aRect = tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
333         if( m_bUseFillColor )
334         {
335             B2DPolyPolygon aPolyPoly( aRect );
336             m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
337         }
338         if( m_bUseLineColor )
339             m_aDevice->drawPolygon( aRect, m_aLineColor, m_aDrawMode, m_aClipMap );
340     }
341     dbgOut( m_aDevice );
342 }
343 
344 void SvpSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry )
345 {
346     if( m_bUseLineColor && nPoints )
347     {
348         B2DPolygon aPoly;
349         aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
350         for( sal_uLong i = 1; i < nPoints; i++ )
351             aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
352         aPoly.setClosed( false );
353         m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
354     }
355     dbgOut( m_aDevice );
356 }
357 
358 void SvpSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry )
359 {
360     if( ( m_bUseLineColor || m_bUseFillColor ) && nPoints )
361     {
362         B2DPolygon aPoly;
363         aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
364         for( sal_uLong i = 1; i < nPoints; i++ )
365             aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
366         if( m_bUseFillColor )
367         {
368             aPoly.setClosed( true );
369             m_aDevice->fillPolyPolygon( B2DPolyPolygon(aPoly), m_aFillColor, m_aDrawMode, m_aClipMap );
370         }
371         if( m_bUseLineColor )
372         {
373             aPoly.setClosed( false );
374             m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
375         }
376     }
377     dbgOut( m_aDevice );
378 }
379 
380 void SvpSalGraphics::drawPolyPolygon( sal_uInt32        nPoly,
381                                       const sal_uInt32* pPointCounts,
382                                       PCONSTSALPOINT*   pPtAry )
383 {
384     if( ( m_bUseLineColor || m_bUseFillColor ) && nPoly )
385     {
386         B2DPolyPolygon aPolyPoly;
387         for( sal_uInt32 nPolygon = 0; nPolygon < nPoly; nPolygon++ )
388         {
389             sal_uInt32 nPoints = pPointCounts[nPolygon];
390             if( nPoints )
391             {
392                 PCONSTSALPOINT pPoints = pPtAry[nPolygon];
393                 B2DPolygon aPoly;
394                 aPoly.append( B2DPoint( pPoints->mnX, pPoints->mnY ), nPoints );
395                 for( sal_uInt32 i = 1; i < nPoints; i++ )
396                     aPoly.setB2DPoint( i, B2DPoint( pPoints[i].mnX, pPoints[i].mnY ) );
397 
398                 aPolyPoly.append( aPoly );
399             }
400         }
401         if( m_bUseFillColor )
402         {
403             aPolyPoly.setClosed( true );
404             m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
405         }
406         if( m_bUseLineColor )
407         {
408             aPolyPoly.setClosed( false );
409             nPoly = aPolyPoly.count();
410             for( sal_uInt32 i = 0; i < nPoly; i++ )
411                 m_aDevice->drawPolygon( aPolyPoly.getB2DPolygon(i), m_aLineColor, m_aDrawMode, m_aClipMap );
412         }
413     }
414     dbgOut( m_aDevice );
415 }
416 
417 bool SvpSalGraphics::drawPolyLine(
418     const ::basegfx::B2DPolygon&,
419     double /*fTransparency*/,
420     const ::basegfx::B2DVector& /*rLineWidths*/,
421     basegfx::B2DLineJoin /*eJoin*/,
422     com::sun::star::drawing::LineCap /*eLineCap*/)
423 {
424         // TODO: implement and advertise OutDevSupport_B2DDraw support
425         return false;
426 }
427 
428 sal_Bool SvpSalGraphics::drawPolyLineBezier( sal_uLong,
429                                              const SalPoint*,
430                                              const sal_uInt8* )
431 {
432     return sal_False;
433 }
434 
435 sal_Bool SvpSalGraphics::drawPolygonBezier( sal_uLong,
436                                             const SalPoint*,
437                                             const sal_uInt8* )
438 {
439     return sal_False;
440 }
441 
442 sal_Bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
443                                                 const sal_uInt32*,
444                                                 const SalPoint* const*,
445                                                 const sal_uInt8* const* )
446 {
447     return sal_False;
448 }
449 
450 bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
451 {
452     // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
453     return false;
454 }
455 
456 void SvpSalGraphics::copyArea( long nDestX,
457                                       long nDestY,
458                                       long nSrcX,
459                                       long nSrcY,
460                                       long nSrcWidth,
461                                       long nSrcHeight,
462                                       sal_uInt16 /*nFlags*/ )
463 {
464     B2IRange aSrcRect( nSrcX, nSrcY, nSrcX+nSrcWidth, nSrcY+nSrcHeight );
465     B2IRange aDestRect( nDestX, nDestY, nDestX+nSrcWidth, nDestY+nSrcHeight );
466     m_aDevice->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
467     dbgOut( m_aDevice );
468 }
469 
470 void SvpSalGraphics::copyBits( const SalTwoRect& rPosAry,
471                                SalGraphics*      pSrcGraphics )
472 {
473     SvpSalGraphics* pSrc = pSrcGraphics ?
474         static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
475     B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
476                        rPosAry.mnSrcX+rPosAry.mnSrcWidth,
477                        rPosAry.mnSrcY+rPosAry.mnSrcHeight );
478     B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
479                         rPosAry.mnDestX+rPosAry.mnDestWidth,
480                         rPosAry.mnDestY+rPosAry.mnDestHeight );
481     m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
482     dbgOut( m_aDevice );
483 }
484 
485 void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
486 {
487     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
488     B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
489                        rPosAry.mnSrcX+rPosAry.mnSrcWidth,
490                        rPosAry.mnSrcY+rPosAry.mnSrcHeight );
491     B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
492                         rPosAry.mnDestX+rPosAry.mnDestWidth,
493                         rPosAry.mnDestY+rPosAry.mnDestHeight );
494     m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
495     dbgOut( m_aDevice );
496 }
497 
498 void SvpSalGraphics::drawBitmap( const SalTwoRect&,
499                                  const SalBitmap&,
500                                  SalColor )
501 {
502     // SNI, as in X11 plugin
503 }
504 
505 void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
506                                  const SalBitmap& rSalBitmap,
507                                  const SalBitmap& rTransparentBitmap )
508 {
509     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
510     const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap);
511     B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
512                        rPosAry.mnSrcX+rPosAry.mnSrcWidth,
513                        rPosAry.mnSrcY+rPosAry.mnSrcHeight );
514     B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
515                         rPosAry.mnDestX+rPosAry.mnDestWidth,
516                         rPosAry.mnDestY+rPosAry.mnDestHeight );
517     m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
518     dbgOut( m_aDevice );
519 }
520 
521 void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry,
522                                const SalBitmap& rSalBitmap,
523                                SalColor nMaskColor )
524 {
525     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
526     B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
527                        rPosAry.mnSrcX+rPosAry.mnSrcWidth,
528                        rPosAry.mnSrcY+rPosAry.mnSrcHeight );
529     B2IPoint aDestPoint( rPosAry.mnDestX, rPosAry.mnDestY );
530 
531     // BitmapDevice::drawMaskedColor works with 0==transparent,
532     // 255==opaque. drawMask() semantic is the other way
533     // around. Therefore, invert mask.
534     BitmapDeviceSharedPtr aCopy =
535         cloneBitmapDevice( B2IVector( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ),
536                            rSrc.getBitmap() );
537     basebmp::Color aBgColor( COL_WHITE );
538     aCopy->clear(aBgColor);
539     basebmp::Color aFgColor( COL_BLACK );
540     aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, B2IPoint() );
541 
542     basebmp::Color aColor( nMaskColor );
543     B2IRange aSrcRect2( 0, 0, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight );
544     m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap );
545     dbgOut( m_aDevice );
546 }
547 
548 SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
549 {
550     BitmapDeviceSharedPtr aCopy =
551         cloneBitmapDevice( B2IVector( nWidth, nHeight ),
552                            m_aDevice );
553     B2IRange aSrcRect( nX, nY, nX+nWidth, nY+nHeight );
554     B2IRange aDestRect( 0, 0, nWidth, nHeight );
555     aCopy->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT );
556 
557     SvpSalBitmap* pBitmap = new SvpSalBitmap();
558     pBitmap->setBitmap( aCopy );
559     return pBitmap;
560 }
561 
562 SalColor SvpSalGraphics::getPixel( long nX, long nY )
563 {
564     basebmp::Color aColor( m_aDevice->getPixel( B2IPoint( nX, nY ) ) );
565     return aColor.toInt32();
566 }
567 
568 void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert /*nFlags*/ )
569 {
570     // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
571     B2DPolygon aRect = tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
572     B2DPolyPolygon aPolyPoly( aRect );
573     m_aDevice->fillPolyPolygon( aPolyPoly, basebmp::Color( 0xffffff ), DrawMode_XOR, m_aClipMap );
574     dbgOut( m_aDevice );
575 }
576 
577 void SvpSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert /*nFlags*/ )
578 {
579     // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
580     B2DPolygon aPoly;
581     aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
582     for( sal_uLong i = 1; i < nPoints; i++ )
583         aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
584     aPoly.setClosed( true );
585     m_aDevice->fillPolyPolygon( B2DPolyPolygon(aPoly), basebmp::Color( 0xffffff ), DrawMode_XOR, m_aClipMap );
586     dbgOut( m_aDevice );
587 }
588 
589 sal_Bool SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong )
590 {
591     return sal_False;
592 }
593 
594 SystemFontData SvpSalGraphics::GetSysFontData( int nFallbacklevel ) const
595 {
596     SystemFontData aSysFontData;
597 
598     if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1;
599     if (nFallbacklevel < 0 ) nFallbacklevel = 0;
600 
601     aSysFontData.nSize = sizeof( SystemFontData );
602     aSysFontData.nFontId = 0;
603     aSysFontData.nFontFlags = 0;
604     aSysFontData.bFakeBold = false;
605     aSysFontData.bFakeItalic = false;
606     aSysFontData.bAntialias = true;
607     return aSysFontData;
608 }
609 
610 SystemGraphicsData SvpSalGraphics::GetGraphicsData() const
611 {
612     SystemGraphicsData aRes;
613     aRes.nSize = sizeof(aRes);
614 	aRes.hDrawable = 0;
615 	aRes.pRenderFormat = 0;
616     return aRes;
617 }
618 
619 bool SvpSalGraphics::supportsOperation( OutDevSupportType ) const
620 {
621     return false;
622 }
623 
624