1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svpgdi.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 #include <vcl/sysdata.hxx>
35 #include <basegfx/range/b2drange.hxx>
36 #include <basegfx/range/b2irange.hxx>
37 #include <basegfx/polygon/b2dpolypolygon.hxx>
38 #include <basegfx/polygon/b2dpolygon.hxx>
39 #include <basegfx/polygon/b2dpolygontools.hxx>
40 #include <basebmp/scanlineformats.hxx>
42 #include <tools/debug.hxx>
44 #if OSL_DEBUG_LEVEL > 2
45 #include <basebmp/debug.hxx>
47 #include <rtl/strbuf.hxx>
51 #include <svppspgraphics.hxx>
53 using namespace basegfx
;
54 using namespace basebmp
;
56 inline void dbgOut( const BitmapDeviceSharedPtr
&
57 #if OSL_DEBUG_LEVEL > 2
62 #if OSL_DEBUG_LEVEL > 2
63 static int dbgStreamNum
= 0;
64 rtl::OStringBuffer
aBuf( 256 );
65 aBuf
.append( "debug" );
66 mkdir( aBuf
.getStr(), 0777 );
68 aBuf
.append( sal_Int64(reinterpret_cast<sal_uInt32
>(rDevice
.get())), 16 );
69 mkdir( aBuf
.getStr(), 0777 );
70 aBuf
.append( "/bmp" );
71 aBuf
.append( sal_Int32(dbgStreamNum
++) );
72 std::fstream
bmpstream( aBuf
.getStr(), std::ios::out
);
73 debugDump( rDevice
, bmpstream
);
77 // ===========================================================================
79 bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect
&, const SalBitmap
& /*rSourceBitmap*/, const SalBitmap
& /*rAlphaBitmap*/ )
81 // TODO(P3) implement alpha blending
85 bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8
/*nTransparency*/ )
87 // TODO(P3) implement alpha blending
91 SvpSalGraphics::SvpSalGraphics() :
92 m_bUseLineColor( true ),
93 m_aLineColor( COL_BLACK
),
94 m_bUseFillColor( false ),
95 m_aFillColor( COL_WHITE
),
96 m_aTextColor( COL_BLACK
),
97 m_aDrawMode( DrawMode_PAINT
),
98 m_eTextFmt( Format::EIGHT_BIT_GREY
)
100 for( int i
= 0; i
< MAX_FALLBACK
; ++i
)
101 m_pServerFont
[i
] = NULL
;
104 SvpSalGraphics::~SvpSalGraphics()
108 void SvpSalGraphics::setDevice( BitmapDeviceSharedPtr
& rDevice
)
111 m_aOrigDevice
= rDevice
;
114 // determine matching bitmap format for masks
115 sal_uInt32 nDeviceFmt
= m_aDevice
->getScanlineFormat();
116 DBG_ASSERT( (nDeviceFmt
<= (sal_uInt32
)Format::MAX
), "SVP::setDevice() with invalid bitmap format" );
119 case Format::EIGHT_BIT_GREY
:
120 case Format::SIXTEEN_BIT_LSB_TC_MASK
:
121 case Format::SIXTEEN_BIT_MSB_TC_MASK
:
122 case Format::TWENTYFOUR_BIT_TC_MASK
:
123 case Format::THIRTYTWO_BIT_TC_MASK
:
124 m_eTextFmt
= Format::EIGHT_BIT_GREY
;
127 m_eTextFmt
= Format::ONE_BIT_LSB_GREY
;
132 void SvpSalGraphics::GetResolution( sal_Int32
& rDPIX
, sal_Int32
& rDPIY
)
137 USHORT
SvpSalGraphics::GetBitCount()
139 return SvpElement::getBitCountFromScanlineFormat( m_aDevice
->getScanlineFormat() );
142 long SvpSalGraphics::GetGraphicsWidth() const
144 if( m_aDevice
.get() )
146 B2IVector aSize
= m_aDevice
->getSize();
152 void SvpSalGraphics::ResetClipRegion()
154 m_aDevice
= m_aOrigDevice
;
158 void SvpSalGraphics::BeginSetClipRegion( ULONG n
)
166 m_aDevice
= m_aOrigDevice
;
167 B2IVector aSize
= m_aDevice
->getSize();
168 m_aClipMap
= createBitmapDevice( aSize
, false, Format::ONE_BIT_MSB_GREY
);
169 m_aClipMap
->clear( basebmp::Color(0xFFFFFFFF) );
173 BOOL
SvpSalGraphics::unionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
177 B2DPolyPolygon aFull
;
178 aFull
.append( tools::createPolygonFromRect( B2DRectangle( nX
, nY
, nX
+nWidth
, nY
+nHeight
) ) );
179 m_aClipMap
->fillPolyPolygon( aFull
, basebmp::Color(0), DrawMode_PAINT
);
183 m_aDevice
= basebmp::subsetBitmapDevice( m_aOrigDevice
,
184 basegfx::B2IRange(nX
,nY
,nX
+nWidth
,nY
+nHeight
) );
190 bool SvpSalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon
& )
192 // TODO: implement and advertise OutDevSupport_B2DClip support
196 void SvpSalGraphics::EndSetClipRegion()
200 void SvpSalGraphics::SetLineColor()
202 m_bUseLineColor
= false;
205 void SvpSalGraphics::SetLineColor( SalColor nSalColor
)
207 m_bUseLineColor
= true;
208 m_aLineColor
= basebmp::Color( nSalColor
);
211 void SvpSalGraphics::SetFillColor()
213 m_bUseFillColor
= false;
216 void SvpSalGraphics::SetFillColor( SalColor nSalColor
)
218 m_bUseFillColor
= true;
219 m_aFillColor
= basebmp::Color( nSalColor
);
222 void SvpSalGraphics::SetXORMode( bool bSet
, bool )
224 m_aDrawMode
= bSet
? DrawMode_XOR
: DrawMode_PAINT
;
227 void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor
)
229 m_bUseLineColor
= true;
233 m_aLineColor
= basebmp::Color( 0 );
236 m_aLineColor
= basebmp::Color( 0xffffff );
239 m_aLineColor
= basebmp::Color( 0xffffff );
244 void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor
)
246 m_bUseFillColor
= true;
250 m_aFillColor
= basebmp::Color( 0 );
253 m_aFillColor
= basebmp::Color( 0xffffff );
256 m_aFillColor
= basebmp::Color( 0xffffff );
261 void SvpSalGraphics::SetTextColor( SalColor nSalColor
)
263 m_aTextColor
= basebmp::Color( nSalColor
);
266 void SvpSalGraphics::drawPixel( long nX
, long nY
)
268 if( m_bUseLineColor
)
269 m_aDevice
->setPixel( B2IPoint( nX
, nY
),
277 void SvpSalGraphics::drawPixel( long nX
, long nY
, SalColor nSalColor
)
279 basebmp::Color
aColor( nSalColor
);
280 m_aDevice
->setPixel( B2IPoint( nX
, nY
),
288 void SvpSalGraphics::drawLine( long nX1
, long nY1
, long nX2
, long nY2
)
290 if( m_bUseLineColor
)
291 m_aDevice
->drawLine( B2IPoint( nX1
, nY1
),
292 B2IPoint( nX2
, nY2
),
299 void SvpSalGraphics::drawRect( long nX
, long nY
, long nWidth
, long nHeight
)
301 if( m_bUseLineColor
|| m_bUseFillColor
)
303 B2DPolygon aRect
= tools::createPolygonFromRect( B2DRectangle( nX
, nY
, nX
+nWidth
, nY
+nHeight
) );
304 if( m_bUseFillColor
)
306 B2DPolyPolygon
aPolyPoly( aRect
);
307 m_aDevice
->fillPolyPolygon( aPolyPoly
, m_aFillColor
, m_aDrawMode
, m_aClipMap
);
309 if( m_bUseLineColor
)
310 m_aDevice
->drawPolygon( aRect
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
315 void SvpSalGraphics::drawPolyLine( ULONG nPoints
, const SalPoint
* pPtAry
)
317 if( m_bUseLineColor
&& nPoints
)
320 aPoly
.append( B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
321 for( ULONG i
= 1; i
< nPoints
; i
++ )
322 aPoly
.setB2DPoint( i
, B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
323 aPoly
.setClosed( false );
324 m_aDevice
->drawPolygon( aPoly
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
329 void SvpSalGraphics::drawPolygon( ULONG nPoints
, const SalPoint
* pPtAry
)
331 if( ( m_bUseLineColor
|| m_bUseFillColor
) && nPoints
)
334 aPoly
.append( B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
335 for( ULONG i
= 1; i
< nPoints
; i
++ )
336 aPoly
.setB2DPoint( i
, B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
337 if( m_bUseFillColor
)
339 aPoly
.setClosed( true );
340 m_aDevice
->fillPolyPolygon( B2DPolyPolygon(aPoly
), m_aFillColor
, m_aDrawMode
, m_aClipMap
);
342 if( m_bUseLineColor
)
344 aPoly
.setClosed( false );
345 m_aDevice
->drawPolygon( aPoly
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
351 void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly
,
352 const sal_uInt32
* pPointCounts
,
353 PCONSTSALPOINT
* pPtAry
)
355 if( ( m_bUseLineColor
|| m_bUseFillColor
) && nPoly
)
357 B2DPolyPolygon aPolyPoly
;
358 for( sal_uInt32 nPolygon
= 0; nPolygon
< nPoly
; nPolygon
++ )
360 sal_uInt32 nPoints
= pPointCounts
[nPolygon
];
363 PCONSTSALPOINT pPoints
= pPtAry
[nPolygon
];
365 aPoly
.append( B2DPoint( pPoints
->mnX
, pPoints
->mnY
), nPoints
);
366 for( ULONG i
= 1; i
< nPoints
; i
++ )
367 aPoly
.setB2DPoint( i
, B2DPoint( pPoints
[i
].mnX
, pPoints
[i
].mnY
) );
369 aPolyPoly
.append( aPoly
);
372 if( m_bUseFillColor
)
374 aPolyPoly
.setClosed( true );
375 m_aDevice
->fillPolyPolygon( aPolyPoly
, m_aFillColor
, m_aDrawMode
, m_aClipMap
);
377 if( m_bUseLineColor
)
379 aPolyPoly
.setClosed( false );
380 nPoly
= aPolyPoly
.count();
381 for( sal_uInt32 i
= 0; i
< nPoly
; i
++ )
382 m_aDevice
->drawPolygon( aPolyPoly
.getB2DPolygon(i
), m_aLineColor
, m_aDrawMode
, m_aClipMap
);
388 bool SvpSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon
&, const ::basegfx::B2DVector
& /*rLineWidths*/, basegfx::B2DLineJoin
/*eJoin*/ )
390 // TODO: implement and advertise OutDevSupport_B2DDraw support
394 sal_Bool
SvpSalGraphics::drawPolyLineBezier( ULONG
,
401 sal_Bool
SvpSalGraphics::drawPolygonBezier( ULONG
,
408 sal_Bool
SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32
,
410 const SalPoint
* const*,
416 bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon
&, double /*fTransparency*/ )
418 // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
422 void SvpSalGraphics::copyArea( long nDestX
,
430 B2IRange
aSrcRect( nSrcX
, nSrcY
, nSrcX
+nSrcWidth
, nSrcY
+nSrcHeight
);
431 B2IRange
aDestRect( nDestX
, nDestY
, nDestX
+nSrcWidth
, nDestY
+nSrcHeight
);
432 m_aDevice
->drawBitmap( m_aOrigDevice
, aSrcRect
, aDestRect
, DrawMode_PAINT
, m_aClipMap
);
436 void SvpSalGraphics::copyBits( const SalTwoRect
* pPosAry
,
437 SalGraphics
* pSrcGraphics
)
439 SvpSalGraphics
* pSrc
= pSrcGraphics
?
440 static_cast<SvpSalGraphics
*>(pSrcGraphics
) : this;
441 B2IRange
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
442 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
443 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
444 B2IRange
aDestRect( pPosAry
->mnDestX
, pPosAry
->mnDestY
,
445 pPosAry
->mnDestX
+pPosAry
->mnDestWidth
,
446 pPosAry
->mnDestY
+pPosAry
->mnDestHeight
);
447 m_aDevice
->drawBitmap( pSrc
->m_aOrigDevice
, aSrcRect
, aDestRect
, DrawMode_PAINT
, m_aClipMap
);
451 void SvpSalGraphics::drawBitmap( const SalTwoRect
* pPosAry
,
452 const SalBitmap
& rSalBitmap
)
454 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
455 B2IRange
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
456 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
457 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
458 B2IRange
aDestRect( pPosAry
->mnDestX
, pPosAry
->mnDestY
,
459 pPosAry
->mnDestX
+pPosAry
->mnDestWidth
,
460 pPosAry
->mnDestY
+pPosAry
->mnDestHeight
);
461 m_aDevice
->drawBitmap( rSrc
.getBitmap(), aSrcRect
, aDestRect
, DrawMode_PAINT
, m_aClipMap
);
465 void SvpSalGraphics::drawBitmap( const SalTwoRect
*,
469 // SNI, as in X11 plugin
472 void SvpSalGraphics::drawBitmap( const SalTwoRect
* pPosAry
,
473 const SalBitmap
& rSalBitmap
,
474 const SalBitmap
& rTransparentBitmap
)
476 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
477 const SvpSalBitmap
& rSrcTrans
= static_cast<const SvpSalBitmap
&>(rTransparentBitmap
);
478 B2IRange
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
479 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
480 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
481 B2IRange
aDestRect( pPosAry
->mnDestX
, pPosAry
->mnDestY
,
482 pPosAry
->mnDestX
+pPosAry
->mnDestWidth
,
483 pPosAry
->mnDestY
+pPosAry
->mnDestHeight
);
484 m_aDevice
->drawMaskedBitmap( rSrc
.getBitmap(), rSrcTrans
.getBitmap(), aSrcRect
, aDestRect
, DrawMode_PAINT
, m_aClipMap
);
488 void SvpSalGraphics::drawMask( const SalTwoRect
* pPosAry
,
489 const SalBitmap
& rSalBitmap
,
490 SalColor nMaskColor
)
492 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
493 B2IRange
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
494 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
495 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
496 B2IPoint
aDestPoint( pPosAry
->mnDestX
, pPosAry
->mnDestY
);
498 // BitmapDevice::drawMaskedColor works with 0==transparent,
499 // 255==opaque. drawMask() semantic is the other way
500 // around. Therefore, invert mask.
501 BitmapDeviceSharedPtr aCopy
=
502 cloneBitmapDevice( B2IVector( pPosAry
->mnSrcWidth
, pPosAry
->mnSrcHeight
),
504 basebmp::Color
aBgColor( COL_WHITE
);
505 aCopy
->clear(aBgColor
);
506 basebmp::Color
aFgColor( COL_BLACK
);
507 aCopy
->drawMaskedColor( aFgColor
, rSrc
.getBitmap(), aSrcRect
, B2IPoint() );
509 basebmp::Color
aColor( nMaskColor
);
510 B2IRange
aSrcRect2( 0, 0, pPosAry
->mnSrcWidth
, pPosAry
->mnSrcHeight
);
511 m_aDevice
->drawMaskedColor( aColor
, aCopy
, aSrcRect
, aDestPoint
, m_aClipMap
);
515 SalBitmap
* SvpSalGraphics::getBitmap( long nX
, long nY
, long nWidth
, long nHeight
)
517 BitmapDeviceSharedPtr aCopy
=
518 cloneBitmapDevice( B2IVector( nWidth
, nHeight
),
520 B2IRange
aSrcRect( nX
, nY
, nX
+nWidth
, nY
+nHeight
);
521 B2IRange
aDestRect( 0, 0, nWidth
, nHeight
);
522 aCopy
->drawBitmap( m_aOrigDevice
, aSrcRect
, aDestRect
, DrawMode_PAINT
);
524 SvpSalBitmap
* pBitmap
= new SvpSalBitmap();
525 pBitmap
->setBitmap( aCopy
);
529 SalColor
SvpSalGraphics::getPixel( long nX
, long nY
)
531 basebmp::Color
aColor( m_aDevice
->getPixel( B2IPoint( nX
, nY
) ) );
532 return aColor
.toInt32();
535 void SvpSalGraphics::invert( long nX
, long nY
, long nWidth
, long nHeight
, SalInvert
/*nFlags*/ )
537 // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
538 B2DPolygon aRect
= tools::createPolygonFromRect( B2DRectangle( nX
, nY
, nX
+nWidth
, nY
+nHeight
) );
539 B2DPolyPolygon
aPolyPoly( aRect
);
540 m_aDevice
->fillPolyPolygon( aPolyPoly
, basebmp::Color( 0xffffff ), DrawMode_XOR
, m_aClipMap
);
544 void SvpSalGraphics::invert( ULONG nPoints
, const SalPoint
* pPtAry
, SalInvert
/*nFlags*/ )
546 // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
548 aPoly
.append( B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
549 for( ULONG i
= 1; i
< nPoints
; i
++ )
550 aPoly
.setB2DPoint( i
, B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
551 aPoly
.setClosed( true );
552 m_aDevice
->fillPolyPolygon( B2DPolyPolygon(aPoly
), basebmp::Color( 0xffffff ), DrawMode_XOR
, m_aClipMap
);
556 BOOL
SvpSalGraphics::drawEPS( long, long, long, long, void*, ULONG
)
561 SystemFontData
SvpSalGraphics::GetSysFontData( int nFallbacklevel
) const
563 SystemFontData aSysFontData
;
565 if (nFallbacklevel
>= MAX_FALLBACK
) nFallbacklevel
= MAX_FALLBACK
- 1;
566 if (nFallbacklevel
< 0 ) nFallbacklevel
= 0;
568 aSysFontData
.nSize
= sizeof( SystemFontData
);
569 aSysFontData
.nFontId
= 0;
570 aSysFontData
.nFontFlags
= 0;
571 aSysFontData
.bFakeBold
= false;
572 aSysFontData
.bFakeItalic
= false;
573 aSysFontData
.bAntialias
= true;
577 SystemGraphicsData
SvpSalGraphics::GetGraphicsData() const
579 SystemGraphicsData aRes
;
580 aRes
.nSize
= sizeof(aRes
);
582 aRes
.pRenderFormat
= 0;
586 bool SvpSalGraphics::supportsOperation( OutDevSupportType
) const