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