1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "headless/svpgdi.hxx"
21 #include "headless/svpbmp.hxx"
23 #include <vcl/sysdata.hxx>
24 #include <basegfx/range/b2drange.hxx>
25 #include <basegfx/range/b2ibox.hxx>
26 #include <basegfx/polygon/b2dpolypolygon.hxx>
27 #include <basegfx/polygon/b2dpolygon.hxx>
28 #include <basegfx/polygon/b2dpolygontools.hxx>
29 #include <basebmp/scanlineformats.hxx>
31 #include <tools/debug.hxx>
33 #if OSL_DEBUG_LEVEL > 2
34 #include <basebmp/debug.hxx>
36 #include <rtl/strbuf.hxx>
42 inline void dbgOut( const basebmp::BitmapDeviceSharedPtr
&
43 #if OSL_DEBUG_LEVEL > 2
48 #if OSL_DEBUG_LEVEL > 2
49 static int dbgStreamNum
= 0;
50 OStringBuffer
aBuf( 256 );
51 aBuf
.append( "debug" );
52 mkdir( aBuf
.getStr(), 0777 );
54 aBuf
.append( sal_Int64(reinterpret_cast<sal_IntPtr
>(rDevice
.get())), 16 );
55 mkdir( aBuf
.getStr(), 0777 );
56 aBuf
.append( "/bmp" );
57 aBuf
.append( sal_Int32(dbgStreamNum
++) );
58 std::fstream
bmpstream( aBuf
.getStr(), std::ios::out
);
59 debugDump( rDevice
, bmpstream
);
63 // ===========================================================================
65 bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect
&, const SalBitmap
& /*rSourceBitmap*/, const SalBitmap
& /*rAlphaBitmap*/ )
67 // TODO(P3) implement alpha blending
71 bool SvpSalGraphics::drawTransformedBitmap(
72 const basegfx::B2DPoint
& rNull
,
73 const basegfx::B2DPoint
& rX
,
74 const basegfx::B2DPoint
& rY
,
75 const SalBitmap
& rSourceBitmap
,
76 const SalBitmap
* pAlphaBitmap
)
78 // here direct support for transformed bitmaps can be impemented
79 (void)rNull
; (void)rX
; (void)rY
; (void)rSourceBitmap
; (void)pAlphaBitmap
;
83 bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8
/*nTransparency*/ )
85 // 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_aDrawMode( basebmp::DrawMode_PAINT
),
97 m_aTextColor( COL_BLACK
),
98 m_eTextFmt( basebmp::FORMAT_EIGHT_BIT_GREY
),
101 for( int i
= 0; i
< MAX_FALLBACK
; ++i
)
102 m_pServerFont
[i
] = NULL
;
105 SvpSalGraphics::~SvpSalGraphics()
111 void SvpSalGraphics::setDevice( basebmp::BitmapDeviceSharedPtr
& rDevice
)
113 m_aOrigDevice
= rDevice
;
117 // determine matching bitmap format for masks
118 basebmp::Format nDeviceFmt
= m_aDevice
->getScanlineFormat();
121 case basebmp::FORMAT_EIGHT_BIT_GREY
:
122 case basebmp::FORMAT_SIXTEEN_BIT_LSB_TC_MASK
:
123 case basebmp::FORMAT_SIXTEEN_BIT_MSB_TC_MASK
:
124 case basebmp::FORMAT_TWENTYFOUR_BIT_TC_MASK
:
125 case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA
:
126 case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB
:
127 case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR
:
128 case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA
:
129 m_eTextFmt
= basebmp::FORMAT_EIGHT_BIT_GREY
;
132 m_eTextFmt
= basebmp::FORMAT_ONE_BIT_LSB_GREY
;
138 void SvpSalGraphics::GetResolution( sal_Int32
& rDPIX
, sal_Int32
& rDPIY
)
143 sal_uInt16
SvpSalGraphics::GetBitCount() const
145 return SvpSalBitmap::getBitCountFromScanlineFormat( m_aDevice
->getScanlineFormat() );
148 long SvpSalGraphics::GetGraphicsWidth() const
150 if( m_aDevice
.get() )
152 basegfx::B2IVector aSize
= m_aOrigDevice
->getSize();
158 void SvpSalGraphics::ResetClipRegion()
160 m_aDevice
= m_aOrigDevice
;
163 m_aClipRegion
.SetNull();
167 // verify clip for the whole area is setup
168 void SvpSalGraphics::ensureClip()
173 m_aDevice
= m_aOrigDevice
;
174 basegfx::B2IVector aSize
= m_aDevice
->getSize();
175 m_aClipMap
= basebmp::createBitmapDevice( aSize
, false, basebmp::FORMAT_ONE_BIT_MSB_GREY
);
176 m_aClipMap
->clear( basebmp::Color(0xFFFFFFFF) );
178 RectangleVector aRectangles
;
179 m_aClipRegion
.GetRegionRectangles(aRectangles
);
181 for(RectangleVector::const_iterator
aRectIter(aRectangles
.begin()); aRectIter
!= aRectangles
.end(); ++aRectIter
)
183 const long nW(aRectIter
->GetWidth());
186 const long nH(aRectIter
->GetHeight());
190 basegfx::B2DPolyPolygon aFull
;
193 basegfx::tools::createPolygonFromRect(
194 basegfx::B2DRectangle(
197 aRectIter
->Left() + nW
,
198 aRectIter
->Top() + nH
)));
199 m_aClipMap
->fillPolyPolygon(aFull
, basebmp::Color(0), basebmp::DrawMode_PAINT
);
206 SvpSalGraphics::ClipUndoHandle::~ClipUndoHandle()
208 if( m_aDevice
.get() )
209 m_rGfx
.m_aDevice
= m_aDevice
;
212 // setup a clip rectangle -only- iff we have to; if aRange
213 // is entirely contained inside an existing clip frame, we
214 // will avoid setting up the clip bitmap. Similarly if the
215 // range doesn't appear at all we return true to avoid
217 bool SvpSalGraphics::isClippedSetup( const basegfx::B2IBox
&aRange
, SvpSalGraphics::ClipUndoHandle
&rUndo
)
222 if( m_aClipRegion
.IsEmpty() ) // no clipping
225 // fprintf( stderr, "ensureClipFor: %d, %d %dx%d\n",
226 // aRange.getMinX(), aRange.getMinY(),
227 // (int)aRange.getWidth(), (int)aRange.getHeight() );
229 // first see if aRange is purely internal to one of the clip regions
230 Rectangle
aRect( Point( aRange
.getMinX(), aRange
.getMinY() ),
231 Size( aRange
.getWidth(), aRange
.getHeight() ) );
233 // then see if we are overlapping with just one
236 RectangleVector aRectangles
;
237 m_aClipRegion
.GetRegionRectangles(aRectangles
);
238 for(RectangleVector::const_iterator
aRectIter(aRectangles
.begin()); aRectIter
!= aRectangles
.end(); ++aRectIter
)
240 if( aRectIter
->IsOver( aRect
) )
242 aHitRect
= *aRectIter
;
247 if( nHit
== 0 ) // rendering outside any clipping region
249 // fprintf (stderr, "denegerate case detected ...\n");
252 else if( nHit
== 1 ) // common path: rendering against just one clipping region
254 if( aHitRect
.IsInside( aRect
) )
256 // fprintf (stderr, " is inside ! avoid deeper clip ...\n");
259 // fprintf (stderr, " operation only overlaps with a single clip zone\n" );
260 rUndo
.m_aDevice
= m_aDevice
;
261 m_aDevice
= basebmp::subsetBitmapDevice( m_aOrigDevice
,
262 basegfx::B2IBox (aHitRect
.Left(),
265 aHitRect
.Bottom()) );
268 // fprintf (stderr, "URK: complex & slow clipping case\n" );
269 // horribly slow & complicated case ...
276 // Clipping by creating unconditional mask bitmaps is horribly
277 // slow so defer it, as much as possible. It is common to get
278 // 3 rectangles pushed, and have to create a vast off-screen
279 // mask only to destroy it shortly afterwards. That is
280 // particularly galling if we render only to a small,
281 // well defined rectangular area inside one of these clip
284 // ensureClipFor() or ensureClip() need to be called before
285 // real rendering. FIXME: we should prolly push this down to
286 // bitmapdevice instead.
287 bool SvpSalGraphics::setClipRegion( const Region
& i_rClip
)
289 m_aClipRegion
= i_rClip
;
291 if( i_rClip
.IsEmpty() )
297 RectangleVector aRectangles
;
298 i_rClip
.GetRegionRectangles(aRectangles
);
300 if(1 == aRectangles
.size())
304 const Rectangle
& aBoundRect
= aRectangles
[0];
305 m_aDevice
= basebmp::subsetBitmapDevice(
307 basegfx::B2IBox(aBoundRect
.Left(),aBoundRect
.Top(),aBoundRect
.Right(),aBoundRect
.Bottom()) );
312 m_bClipSetup
= false;
317 void SvpSalGraphics::SetLineColor()
319 m_bUseLineColor
= false;
322 void SvpSalGraphics::SetLineColor( SalColor nSalColor
)
324 m_bUseLineColor
= true;
325 m_aLineColor
= basebmp::Color( nSalColor
);
328 void SvpSalGraphics::SetFillColor()
330 m_bUseFillColor
= false;
333 void SvpSalGraphics::SetFillColor( SalColor nSalColor
)
335 m_bUseFillColor
= true;
336 m_aFillColor
= basebmp::Color( nSalColor
);
339 void SvpSalGraphics::SetXORMode( bool bSet
, bool )
341 m_aDrawMode
= bSet
? basebmp::DrawMode_XOR
: basebmp::DrawMode_PAINT
;
344 void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor
)
346 m_bUseLineColor
= true;
350 m_aLineColor
= basebmp::Color( 0 );
353 m_aLineColor
= basebmp::Color( 0xffffff );
356 m_aLineColor
= basebmp::Color( 0xffffff );
361 void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor
)
363 m_bUseFillColor
= true;
367 m_aFillColor
= basebmp::Color( 0 );
370 m_aFillColor
= basebmp::Color( 0xffffff );
373 m_aFillColor
= basebmp::Color( 0xffffff );
378 void SvpSalGraphics::drawPixel( long nX
, long nY
)
380 if( m_bUseLineColor
)
383 m_aDevice
->setPixel( basegfx::B2IPoint( nX
, nY
),
392 void SvpSalGraphics::drawPixel( long nX
, long nY
, SalColor nSalColor
)
394 basebmp::Color
aColor( nSalColor
);
396 m_aDevice
->setPixel( basegfx::B2IPoint( nX
, nY
),
404 void SvpSalGraphics::drawLine( long nX1
, long nY1
, long nX2
, long nY2
)
406 if( m_bUseLineColor
)
408 ensureClip(); // FIXME: for ...
409 m_aDevice
->drawLine( basegfx::B2IPoint( nX1
, nY1
),
410 basegfx::B2IPoint( nX2
, nY2
),
418 void SvpSalGraphics::drawRect( long nX
, long nY
, long nWidth
, long nHeight
)
420 if( m_bUseLineColor
|| m_bUseFillColor
)
422 basegfx::B2DPolygon aRect
= basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX
, nY
, nX
+nWidth
, nY
+nHeight
) );
423 ensureClip(); // FIXME: for ...
424 if( m_bUseFillColor
)
426 basegfx::B2DPolyPolygon
aPolyPoly( aRect
);
427 m_aDevice
->fillPolyPolygon( aPolyPoly
, m_aFillColor
, m_aDrawMode
, m_aClipMap
);
429 if( m_bUseLineColor
)
430 m_aDevice
->drawPolygon( aRect
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
435 void SvpSalGraphics::drawPolyLine( sal_uLong nPoints
, const SalPoint
* pPtAry
)
437 if( m_bUseLineColor
&& nPoints
)
439 basegfx::B2DPolygon aPoly
;
440 aPoly
.append( basegfx::B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
441 for( sal_uLong i
= 1; i
< nPoints
; i
++ )
442 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
443 aPoly
.setClosed( false );
444 ensureClip(); // FIXME: for ...
445 m_aDevice
->drawPolygon( aPoly
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
450 void SvpSalGraphics::drawPolygon( sal_uLong nPoints
, const SalPoint
* pPtAry
)
452 if( ( m_bUseLineColor
|| m_bUseFillColor
) && nPoints
)
454 basegfx::B2DPolygon aPoly
;
455 aPoly
.append( basegfx::B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
456 for( sal_uLong i
= 1; i
< nPoints
; i
++ )
457 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
458 ensureClip(); // FIXME: for ...
459 if( m_bUseFillColor
)
461 aPoly
.setClosed( true );
462 m_aDevice
->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly
), m_aFillColor
, m_aDrawMode
, m_aClipMap
);
464 if( m_bUseLineColor
)
466 aPoly
.setClosed( false );
467 m_aDevice
->drawPolygon( aPoly
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
473 void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly
,
474 const sal_uInt32
* pPointCounts
,
475 PCONSTSALPOINT
* pPtAry
)
477 if( ( m_bUseLineColor
|| m_bUseFillColor
) && nPoly
)
479 basegfx::B2DPolyPolygon aPolyPoly
;
480 for( sal_uInt32 nPolygon
= 0; nPolygon
< nPoly
; nPolygon
++ )
482 sal_uInt32 nPoints
= pPointCounts
[nPolygon
];
485 PCONSTSALPOINT pPoints
= pPtAry
[nPolygon
];
486 basegfx::B2DPolygon aPoly
;
487 aPoly
.append( basegfx::B2DPoint( pPoints
->mnX
, pPoints
->mnY
), nPoints
);
488 for( sal_uInt32 i
= 1; i
< nPoints
; i
++ )
489 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPoints
[i
].mnX
, pPoints
[i
].mnY
) );
491 aPolyPoly
.append( aPoly
);
494 ensureClip(); // FIXME: for ...
495 if( m_bUseFillColor
)
497 aPolyPoly
.setClosed( true );
498 m_aDevice
->fillPolyPolygon( aPolyPoly
, m_aFillColor
, m_aDrawMode
, m_aClipMap
);
500 if( m_bUseLineColor
)
502 aPolyPoly
.setClosed( false );
503 nPoly
= aPolyPoly
.count();
504 for( sal_uInt32 i
= 0; i
< nPoly
; i
++ )
505 m_aDevice
->drawPolygon( aPolyPoly
.getB2DPolygon(i
), m_aLineColor
, m_aDrawMode
, m_aClipMap
);
511 bool SvpSalGraphics::drawPolyLine(
512 const ::basegfx::B2DPolygon
&,
513 double /*fTransparency*/,
514 const ::basegfx::B2DVector
& /*rLineWidths*/,
515 basegfx::B2DLineJoin
/*eJoin*/,
516 com::sun::star::drawing::LineCap
/*eLineCap*/)
518 // TODO: implement and advertise OutDevSupport_B2DDraw support
522 sal_Bool
SvpSalGraphics::drawPolyLineBezier( sal_uLong
,
529 sal_Bool
SvpSalGraphics::drawPolygonBezier( sal_uLong
,
536 sal_Bool
SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32
,
538 const SalPoint
* const*,
539 const sal_uInt8
* const* )
544 bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon
&, double /*fTransparency*/ )
546 // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
550 void SvpSalGraphics::copyArea( long nDestX
,
556 sal_uInt16
/*nFlags*/ )
558 basegfx::B2IBox
aSrcRect( nSrcX
, nSrcY
, nSrcX
+nSrcWidth
, nSrcY
+nSrcHeight
);
559 basegfx::B2IBox
aDestRect( nDestX
, nDestY
, nDestX
+nSrcWidth
, nDestY
+nSrcHeight
);
560 // fprintf( stderr, "copyArea %ld pixels - clip region %d\n",
561 // (long)(nSrcWidth * nSrcHeight), m_aClipMap.get() != NULL );
562 SvpSalGraphics::ClipUndoHandle
aUndo( this );
563 if( !isClippedSetup( aDestRect
, aUndo
) )
564 m_aDevice
->drawBitmap( m_aOrigDevice
, aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
568 void SvpSalGraphics::copyBits( const SalTwoRect
& rPosAry
,
569 SalGraphics
* pSrcGraphics
)
571 if( !m_aDevice
.get() )
574 SvpSalGraphics
* pSrc
= pSrcGraphics
?
575 static_cast<SvpSalGraphics
*>(pSrcGraphics
) : this;
576 basegfx::B2IBox
aSrcRect( rPosAry
.mnSrcX
, rPosAry
.mnSrcY
,
577 rPosAry
.mnSrcX
+rPosAry
.mnSrcWidth
,
578 rPosAry
.mnSrcY
+rPosAry
.mnSrcHeight
);
579 basegfx::B2IBox
aDestRect( rPosAry
.mnDestX
, rPosAry
.mnDestY
,
580 rPosAry
.mnDestX
+rPosAry
.mnDestWidth
,
581 rPosAry
.mnDestY
+rPosAry
.mnDestHeight
);
583 SvpSalGraphics::ClipUndoHandle
aUndo( this );
584 if( !isClippedSetup( aDestRect
, aUndo
) )
585 m_aDevice
->drawBitmap( pSrc
->m_aOrigDevice
, aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
589 void SvpSalGraphics::drawBitmap( const SalTwoRect
& rPosAry
,
590 const SalBitmap
& rSalBitmap
)
592 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
593 basegfx::B2IBox
aSrcRect( rPosAry
.mnSrcX
, rPosAry
.mnSrcY
,
594 rPosAry
.mnSrcX
+rPosAry
.mnSrcWidth
,
595 rPosAry
.mnSrcY
+rPosAry
.mnSrcHeight
);
596 basegfx::B2IBox
aDestRect( rPosAry
.mnDestX
, rPosAry
.mnDestY
,
597 rPosAry
.mnDestX
+rPosAry
.mnDestWidth
,
598 rPosAry
.mnDestY
+rPosAry
.mnDestHeight
);
600 SvpSalGraphics::ClipUndoHandle
aUndo( this );
601 if( !isClippedSetup( aDestRect
, aUndo
) )
602 m_aDevice
->drawBitmap( rSrc
.getBitmap(), aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
606 void SvpSalGraphics::drawBitmap( const SalTwoRect
&,
610 // SNI, as in X11 plugin
613 void SvpSalGraphics::drawBitmap( const SalTwoRect
& rPosAry
,
614 const SalBitmap
& rSalBitmap
,
615 const SalBitmap
& rTransparentBitmap
)
617 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
618 const SvpSalBitmap
& rSrcTrans
= static_cast<const SvpSalBitmap
&>(rTransparentBitmap
);
619 basegfx::B2IBox
aSrcRect( rPosAry
.mnSrcX
, rPosAry
.mnSrcY
,
620 rPosAry
.mnSrcX
+rPosAry
.mnSrcWidth
,
621 rPosAry
.mnSrcY
+rPosAry
.mnSrcHeight
);
622 basegfx::B2IBox
aDestRect( rPosAry
.mnDestX
, rPosAry
.mnDestY
,
623 rPosAry
.mnDestX
+rPosAry
.mnDestWidth
,
624 rPosAry
.mnDestY
+rPosAry
.mnDestHeight
);
625 SvpSalGraphics::ClipUndoHandle
aUndo( this );
626 if( !isClippedSetup( aDestRect
, aUndo
) )
627 m_aDevice
->drawMaskedBitmap( rSrc
.getBitmap(), rSrcTrans
.getBitmap(),
628 aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
632 void SvpSalGraphics::drawMask( const SalTwoRect
& rPosAry
,
633 const SalBitmap
& rSalBitmap
,
634 SalColor nMaskColor
)
636 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
637 basegfx::B2IBox
aSrcRect( rPosAry
.mnSrcX
, rPosAry
.mnSrcY
,
638 rPosAry
.mnSrcX
+rPosAry
.mnSrcWidth
,
639 rPosAry
.mnSrcY
+rPosAry
.mnSrcHeight
);
640 basegfx::B2IPoint
aDestPoint( rPosAry
.mnDestX
, rPosAry
.mnDestY
);
642 // BitmapDevice::drawMaskedColor works with 0==transparent,
643 // 255==opaque. drawMask() semantic is the other way
644 // around. Therefore, invert mask.
645 basebmp::BitmapDeviceSharedPtr aCopy
=
646 cloneBitmapDevice( basegfx::B2IVector( rPosAry
.mnSrcWidth
, rPosAry
.mnSrcHeight
),
648 basebmp::Color
aBgColor( COL_WHITE
);
649 aCopy
->clear(aBgColor
);
650 basebmp::Color
aFgColor( COL_BLACK
);
651 aCopy
->drawMaskedColor( aFgColor
, rSrc
.getBitmap(), aSrcRect
, basegfx::B2IPoint() );
653 basebmp::Color
aColor( nMaskColor
);
654 basegfx::B2IBox
aSrcRect2( 0, 0, rPosAry
.mnSrcWidth
, rPosAry
.mnSrcHeight
);
655 const basegfx::B2IBox
aClipRect( aDestPoint
, basegfx::B2ITuple( aSrcRect
.getWidth(), aSrcRect
.getHeight() ) );
657 SvpSalGraphics::ClipUndoHandle
aUndo( this );
658 if( !isClippedSetup( aClipRect
, aUndo
) )
659 m_aDevice
->drawMaskedColor( aColor
, aCopy
, aSrcRect
, aDestPoint
, m_aClipMap
);
663 SalBitmap
* SvpSalGraphics::getBitmap( long nX
, long nY
, long nWidth
, long nHeight
)
665 basebmp::BitmapDeviceSharedPtr aCopy
=
666 cloneBitmapDevice( basegfx::B2IVector( nWidth
, nHeight
),
668 basegfx::B2IBox
aSrcRect( nX
, nY
, nX
+nWidth
, nY
+nHeight
);
669 basegfx::B2IBox
aDestRect( 0, 0, nWidth
, nHeight
);
671 SvpSalGraphics::ClipUndoHandle
aUndo( this );
672 if( !isClippedSetup( aDestRect
, aUndo
) )
673 aCopy
->drawBitmap( m_aOrigDevice
, aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
);
675 SvpSalBitmap
* pBitmap
= new SvpSalBitmap();
676 pBitmap
->setBitmap( aCopy
);
680 SalColor
SvpSalGraphics::getPixel( long nX
, long nY
)
682 basebmp::Color
aColor( m_aOrigDevice
->getPixel( basegfx::B2IPoint( nX
, nY
) ) );
683 return aColor
.toInt32();
686 void SvpSalGraphics::invert( long nX
, long nY
, long nWidth
, long nHeight
, SalInvert
/*nFlags*/ )
688 // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
689 basegfx::B2DPolygon aRect
= basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX
, nY
, nX
+nWidth
, nY
+nHeight
) );
690 basegfx::B2DPolyPolygon
aPolyPoly( aRect
);
691 basegfx::B2IBox
aDestRange( nX
, nY
, nX
+ nWidth
, nY
+ nHeight
);
693 SvpSalGraphics::ClipUndoHandle
aUndo( this );
694 if( !isClippedSetup( aDestRange
, aUndo
) )
695 m_aDevice
->fillPolyPolygon( aPolyPoly
, basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR
, m_aClipMap
);
699 void SvpSalGraphics::invert( sal_uLong nPoints
, const SalPoint
* pPtAry
, SalInvert
/*nFlags*/ )
701 // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
702 basegfx::B2DPolygon aPoly
;
703 aPoly
.append( basegfx::B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
704 for( sal_uLong i
= 1; i
< nPoints
; i
++ )
705 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
706 aPoly
.setClosed( true );
707 ensureClip(); // FIXME for ...
708 m_aDevice
->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly
), basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR
, m_aClipMap
);
712 sal_Bool
SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong
)
717 SystemGraphicsData
SvpSalGraphics::GetGraphicsData() const
719 return SystemGraphicsData();
722 bool SvpSalGraphics::supportsOperation( OutDevSupportType
) const
727 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */