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>
43 inline void dbgOut( const basebmp::BitmapDeviceSharedPtr
&
44 #if OSL_DEBUG_LEVEL > 2
49 #if OSL_DEBUG_LEVEL > 2
50 static int dbgStreamNum
= 0;
51 rtl::OStringBuffer
aBuf( 256 );
52 aBuf
.append( "debug" );
53 mkdir( aBuf
.getStr(), 0777 );
55 aBuf
.append( sal_Int64(reinterpret_cast<sal_IntPtr
>(rDevice
.get())), 16 );
56 mkdir( aBuf
.getStr(), 0777 );
57 aBuf
.append( "/bmp" );
58 aBuf
.append( sal_Int32(dbgStreamNum
++) );
59 std::fstream
bmpstream( aBuf
.getStr(), std::ios::out
);
60 debugDump( rDevice
, bmpstream
);
64 // ===========================================================================
66 bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect
&, const SalBitmap
& /*rSourceBitmap*/, const SalBitmap
& /*rAlphaBitmap*/ )
68 // TODO(P3) implement alpha blending
72 bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8
/*nTransparency*/ )
74 // TODO(P3) implement alpha blending
78 SvpSalGraphics::SvpSalGraphics() :
79 m_bUseLineColor( true ),
80 m_aLineColor( COL_BLACK
),
81 m_bUseFillColor( false ),
82 m_aFillColor( COL_WHITE
),
83 m_aTextColor( COL_BLACK
),
84 m_aDrawMode( basebmp::DrawMode_PAINT
),
85 m_eTextFmt( basebmp::Format::EIGHT_BIT_GREY
),
88 for( int i
= 0; i
< MAX_FALLBACK
; ++i
)
89 m_pServerFont
[i
] = NULL
;
92 SvpSalGraphics::~SvpSalGraphics()
96 void SvpSalGraphics::setDevice( basebmp::BitmapDeviceSharedPtr
& rDevice
)
98 m_aOrigDevice
= rDevice
;
101 // determine matching bitmap format for masks
102 sal_uInt32 nDeviceFmt
= m_aDevice
->getScanlineFormat();
103 DBG_ASSERT( (nDeviceFmt
<= (sal_uInt32
)basebmp::Format::MAX
), "SVP::setDevice() with invalid bitmap format" );
106 case basebmp::Format::EIGHT_BIT_GREY
:
107 case basebmp::Format::SIXTEEN_BIT_LSB_TC_MASK
:
108 case basebmp::Format::SIXTEEN_BIT_MSB_TC_MASK
:
109 case basebmp::Format::TWENTYFOUR_BIT_TC_MASK
:
110 case basebmp::Format::THIRTYTWO_BIT_TC_MASK_BGRA
:
111 case basebmp::Format::THIRTYTWO_BIT_TC_MASK_ARGB
:
112 case basebmp::Format::THIRTYTWO_BIT_TC_MASK_ABGR
:
113 case basebmp::Format::THIRTYTWO_BIT_TC_MASK_RGBA
:
114 m_eTextFmt
= basebmp::Format::EIGHT_BIT_GREY
;
117 m_eTextFmt
= basebmp::Format::ONE_BIT_LSB_GREY
;
122 void SvpSalGraphics::GetResolution( sal_Int32
& rDPIX
, sal_Int32
& rDPIY
)
127 sal_uInt16
SvpSalGraphics::GetBitCount() const
129 return SvpElement::getBitCountFromScanlineFormat( m_aDevice
->getScanlineFormat() );
132 long SvpSalGraphics::GetGraphicsWidth() const
134 if( m_aDevice
.get() )
136 basegfx::B2IVector aSize
= m_aOrigDevice
->getSize();
142 void SvpSalGraphics::ResetClipRegion()
144 m_aDevice
= m_aOrigDevice
;
147 m_aClipRegion
.SetNull();
151 // verify clip for the whole area is setup
152 void SvpSalGraphics::ensureClip()
157 m_aDevice
= m_aOrigDevice
;
158 basegfx::B2IVector aSize
= m_aDevice
->getSize();
159 m_aClipMap
= basebmp::createBitmapDevice( aSize
, false, basebmp::Format::ONE_BIT_MSB_GREY
);
160 m_aClipMap
->clear( basebmp::Color(0xFFFFFFFF) );
162 // fprintf( stderr, "non rect clip region set with %d rects:\n",
163 // (int)m_aClipRegion.GetRectCount() );
164 ImplRegionInfo aInfo
;
166 bool bRegionRect
= m_aClipRegion
.ImplGetFirstRect(aInfo
, nX
, nY
, nW
, nH
);
171 basegfx::B2DPolyPolygon aFull
;
172 aFull
.append( basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX
, nY
, nX
+nW
, nY
+nH
) ) );
173 m_aClipMap
->fillPolyPolygon( aFull
, basebmp::Color(0), basebmp::DrawMode_PAINT
);
175 // fprintf( stderr, "\t %ld,%ld %ldx%ld\n", nX, nY, nW, nH );
176 bRegionRect
= m_aClipRegion
.ImplGetNextRect( aInfo
, nX
, nY
, nW
, nH
);
181 SvpSalGraphics::ClipUndoHandle::~ClipUndoHandle()
183 if( m_aDevice
.get() )
184 m_rGfx
.m_aDevice
= m_aDevice
;
187 // setup a clip rectangle -only- iff we have to; if aRange
188 // is entirely contained inside an existing clip frame, we
189 // will avoid setting up the clip bitmap. Similarly if the
190 // range doesn't appear at all we return true to avoid
192 bool SvpSalGraphics::isClippedSetup( const basegfx::B2IBox
&aRange
, SvpSalGraphics::ClipUndoHandle
&rUndo
)
197 if( m_aClipRegion
.IsEmpty() ) // no clipping
200 // fprintf( stderr, "ensureClipFor: %d, %d %dx%d\n",
201 // aRange.getMinX(), aRange.getMinY(),
202 // (int)aRange.getWidth(), (int)aRange.getHeight() );
204 // first see if aRange is purely internal to one of the clip regions
205 Rectangle
aRect( Point( aRange
.getMinX(), aRange
.getMinY() ),
206 Size( aRange
.getWidth(), aRange
.getHeight() ) );
208 // then see if we are overlapping with just one
210 Rectangle aIterRect
, aHitRect
;
211 RegionHandle aHnd
= m_aClipRegion
.BeginEnumRects();
212 while( m_aClipRegion
.GetNextEnumRect( aHnd
, aIterRect
) )
214 if( aIterRect
.IsOver( aRect
) )
216 aHitRect
= aIterRect
;
220 m_aClipRegion
.EndEnumRects (aHnd
);
222 if( nHit
== 0 ) // rendering outside any clipping region
224 // fprintf (stderr, "denegerate case detected ...\n");
227 else if( nHit
== 1 ) // common path: rendering against just one clipping region
229 if( aHitRect
.IsInside( aRect
) )
231 // fprintf (stderr, " is inside ! avoid deeper clip ...\n");
234 // fprintf (stderr, " operation only overlaps with a single clip zone\n" );
235 rUndo
.m_aDevice
= m_aDevice
;
236 m_aDevice
= basebmp::subsetBitmapDevice( m_aOrigDevice
,
237 basegfx::B2IBox (aHitRect
.Left(),
240 aHitRect
.Bottom()) );
243 // fprintf (stderr, "URK: complex & slow clipping case\n" );
244 // horribly slow & complicated case ...
251 // Clipping by creating unconditional mask bitmaps is horribly
252 // slow so defer it, as much as possible. It is common to get
253 // 3 rectangles pushed, and have to create a vast off-screen
254 // mask only to destroy it shortly afterwards. That is
255 // particularly galling if we render only to a small,
256 // well defined rectangular area inside one of these clip
259 // ensureClipFor() or ensureClip() need to be called before
260 // real rendering. FIXME: we should prolly push this down to
261 // bitmapdevice instead.
262 bool SvpSalGraphics::setClipRegion( const Region
& i_rClip
)
264 m_aClipRegion
= i_rClip
;
266 if( i_rClip
.IsEmpty() )
269 else if( i_rClip
.GetRectCount() == 1 )
272 Rectangle
aBoundRect( i_rClip
.GetBoundRect() );
273 m_aDevice
= basebmp::subsetBitmapDevice( m_aOrigDevice
,
274 basegfx::B2IBox(aBoundRect
.Left(),aBoundRect
.Top(),aBoundRect
.Right(),aBoundRect
.Bottom()) );
278 m_bClipSetup
= false;
283 void SvpSalGraphics::SetLineColor()
285 m_bUseLineColor
= false;
288 void SvpSalGraphics::SetLineColor( SalColor nSalColor
)
290 m_bUseLineColor
= true;
291 m_aLineColor
= basebmp::Color( nSalColor
);
294 void SvpSalGraphics::SetFillColor()
296 m_bUseFillColor
= false;
299 void SvpSalGraphics::SetFillColor( SalColor nSalColor
)
301 m_bUseFillColor
= true;
302 m_aFillColor
= basebmp::Color( nSalColor
);
305 void SvpSalGraphics::SetXORMode( bool bSet
, bool )
307 m_aDrawMode
= bSet
? basebmp::DrawMode_XOR
: basebmp::DrawMode_PAINT
;
310 void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor
)
312 m_bUseLineColor
= true;
316 m_aLineColor
= basebmp::Color( 0 );
319 m_aLineColor
= basebmp::Color( 0xffffff );
322 m_aLineColor
= basebmp::Color( 0xffffff );
327 void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor
)
329 m_bUseFillColor
= true;
333 m_aFillColor
= basebmp::Color( 0 );
336 m_aFillColor
= basebmp::Color( 0xffffff );
339 m_aFillColor
= basebmp::Color( 0xffffff );
344 void SvpSalGraphics::SetTextColor( SalColor nSalColor
)
346 m_aTextColor
= basebmp::Color( nSalColor
);
349 void SvpSalGraphics::drawPixel( long nX
, long nY
)
351 if( m_bUseLineColor
)
354 m_aDevice
->setPixel( basegfx::B2IPoint( nX
, nY
),
363 void SvpSalGraphics::drawPixel( long nX
, long nY
, SalColor nSalColor
)
365 basebmp::Color
aColor( nSalColor
);
367 m_aDevice
->setPixel( basegfx::B2IPoint( nX
, nY
),
375 void SvpSalGraphics::drawLine( long nX1
, long nY1
, long nX2
, long nY2
)
377 if( m_bUseLineColor
)
379 ensureClip(); // FIXME: for ...
380 m_aDevice
->drawLine( basegfx::B2IPoint( nX1
, nY1
),
381 basegfx::B2IPoint( nX2
, nY2
),
389 void SvpSalGraphics::drawRect( long nX
, long nY
, long nWidth
, long nHeight
)
391 if( m_bUseLineColor
|| m_bUseFillColor
)
393 basegfx::B2DPolygon aRect
= basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX
, nY
, nX
+nWidth
, nY
+nHeight
) );
394 ensureClip(); // FIXME: for ...
395 if( m_bUseFillColor
)
397 basegfx::B2DPolyPolygon
aPolyPoly( aRect
);
398 m_aDevice
->fillPolyPolygon( aPolyPoly
, m_aFillColor
, m_aDrawMode
, m_aClipMap
);
400 if( m_bUseLineColor
)
401 m_aDevice
->drawPolygon( aRect
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
406 void SvpSalGraphics::drawPolyLine( sal_uLong nPoints
, const SalPoint
* pPtAry
)
408 if( m_bUseLineColor
&& nPoints
)
410 basegfx::B2DPolygon aPoly
;
411 aPoly
.append( basegfx::B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
412 for( sal_uLong i
= 1; i
< nPoints
; i
++ )
413 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
414 aPoly
.setClosed( false );
415 ensureClip(); // FIXME: for ...
416 m_aDevice
->drawPolygon( aPoly
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
421 void SvpSalGraphics::drawPolygon( sal_uLong nPoints
, const SalPoint
* pPtAry
)
423 if( ( m_bUseLineColor
|| m_bUseFillColor
) && nPoints
)
425 basegfx::B2DPolygon aPoly
;
426 aPoly
.append( basegfx::B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
427 for( sal_uLong i
= 1; i
< nPoints
; i
++ )
428 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
429 ensureClip(); // FIXME: for ...
430 if( m_bUseFillColor
)
432 aPoly
.setClosed( true );
433 m_aDevice
->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly
), m_aFillColor
, m_aDrawMode
, m_aClipMap
);
435 if( m_bUseLineColor
)
437 aPoly
.setClosed( false );
438 m_aDevice
->drawPolygon( aPoly
, m_aLineColor
, m_aDrawMode
, m_aClipMap
);
444 void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly
,
445 const sal_uInt32
* pPointCounts
,
446 PCONSTSALPOINT
* pPtAry
)
448 if( ( m_bUseLineColor
|| m_bUseFillColor
) && nPoly
)
450 basegfx::B2DPolyPolygon aPolyPoly
;
451 for( sal_uInt32 nPolygon
= 0; nPolygon
< nPoly
; nPolygon
++ )
453 sal_uInt32 nPoints
= pPointCounts
[nPolygon
];
456 PCONSTSALPOINT pPoints
= pPtAry
[nPolygon
];
457 basegfx::B2DPolygon aPoly
;
458 aPoly
.append( basegfx::B2DPoint( pPoints
->mnX
, pPoints
->mnY
), nPoints
);
459 for( sal_uInt32 i
= 1; i
< nPoints
; i
++ )
460 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPoints
[i
].mnX
, pPoints
[i
].mnY
) );
462 aPolyPoly
.append( aPoly
);
465 ensureClip(); // FIXME: for ...
466 if( m_bUseFillColor
)
468 aPolyPoly
.setClosed( true );
469 m_aDevice
->fillPolyPolygon( aPolyPoly
, m_aFillColor
, m_aDrawMode
, m_aClipMap
);
471 if( m_bUseLineColor
)
473 aPolyPoly
.setClosed( false );
474 nPoly
= aPolyPoly
.count();
475 for( sal_uInt32 i
= 0; i
< nPoly
; i
++ )
476 m_aDevice
->drawPolygon( aPolyPoly
.getB2DPolygon(i
), m_aLineColor
, m_aDrawMode
, m_aClipMap
);
482 bool SvpSalGraphics::drawPolyLine(
483 const ::basegfx::B2DPolygon
&,
484 double /*fTransparency*/,
485 const ::basegfx::B2DVector
& /*rLineWidths*/,
486 basegfx::B2DLineJoin
/*eJoin*/,
487 com::sun::star::drawing::LineCap
/*eLineCap*/)
489 // TODO: implement and advertise OutDevSupport_B2DDraw support
493 sal_Bool
SvpSalGraphics::drawPolyLineBezier( sal_uLong
,
500 sal_Bool
SvpSalGraphics::drawPolygonBezier( sal_uLong
,
507 sal_Bool
SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32
,
509 const SalPoint
* const*,
510 const sal_uInt8
* const* )
515 bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon
&, double /*fTransparency*/ )
517 // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
521 void SvpSalGraphics::copyArea( long nDestX
,
527 sal_uInt16
/*nFlags*/ )
529 basegfx::B2IBox
aSrcRect( nSrcX
, nSrcY
, nSrcX
+nSrcWidth
, nSrcY
+nSrcHeight
);
530 basegfx::B2IBox
aDestRect( nDestX
, nDestY
, nDestX
+nSrcWidth
, nDestY
+nSrcHeight
);
531 // fprintf( stderr, "copyArea %ld pixels - clip region %d\n",
532 // (long)(nSrcWidth * nSrcHeight), m_aClipMap.get() != NULL );
533 SvpSalGraphics::ClipUndoHandle
aUndo( this );
534 if( !isClippedSetup( aDestRect
, aUndo
) )
535 m_aDevice
->drawBitmap( m_aOrigDevice
, aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
539 void SvpSalGraphics::copyBits( const SalTwoRect
* pPosAry
,
540 SalGraphics
* pSrcGraphics
)
542 SvpSalGraphics
* pSrc
= pSrcGraphics
?
543 static_cast<SvpSalGraphics
*>(pSrcGraphics
) : this;
544 basegfx::B2IBox
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
545 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
546 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
547 basegfx::B2IBox
aDestRect( pPosAry
->mnDestX
, pPosAry
->mnDestY
,
548 pPosAry
->mnDestX
+pPosAry
->mnDestWidth
,
549 pPosAry
->mnDestY
+pPosAry
->mnDestHeight
);
551 SvpSalGraphics::ClipUndoHandle
aUndo( this );
552 if( !isClippedSetup( aDestRect
, aUndo
) )
553 m_aDevice
->drawBitmap( pSrc
->m_aOrigDevice
, aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
557 void SvpSalGraphics::drawBitmap( const SalTwoRect
* pPosAry
,
558 const SalBitmap
& rSalBitmap
)
560 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
561 basegfx::B2IBox
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
562 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
563 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
564 basegfx::B2IBox
aDestRect( pPosAry
->mnDestX
, pPosAry
->mnDestY
,
565 pPosAry
->mnDestX
+pPosAry
->mnDestWidth
,
566 pPosAry
->mnDestY
+pPosAry
->mnDestHeight
);
568 SvpSalGraphics::ClipUndoHandle
aUndo( this );
569 if( !isClippedSetup( aDestRect
, aUndo
) )
570 m_aDevice
->drawBitmap( rSrc
.getBitmap(), aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
574 void SvpSalGraphics::drawBitmap( const SalTwoRect
*,
578 // SNI, as in X11 plugin
581 void SvpSalGraphics::drawBitmap( const SalTwoRect
* pPosAry
,
582 const SalBitmap
& rSalBitmap
,
583 const SalBitmap
& rTransparentBitmap
)
585 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
586 const SvpSalBitmap
& rSrcTrans
= static_cast<const SvpSalBitmap
&>(rTransparentBitmap
);
587 basegfx::B2IBox
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
588 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
589 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
590 basegfx::B2IBox
aDestRect( pPosAry
->mnDestX
, pPosAry
->mnDestY
,
591 pPosAry
->mnDestX
+pPosAry
->mnDestWidth
,
592 pPosAry
->mnDestY
+pPosAry
->mnDestHeight
);
593 SvpSalGraphics::ClipUndoHandle
aUndo( this );
594 if( !isClippedSetup( aDestRect
, aUndo
) )
595 m_aDevice
->drawMaskedBitmap( rSrc
.getBitmap(), rSrcTrans
.getBitmap(),
596 aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
, m_aClipMap
);
600 void SvpSalGraphics::drawMask( const SalTwoRect
* pPosAry
,
601 const SalBitmap
& rSalBitmap
,
602 SalColor nMaskColor
)
604 const SvpSalBitmap
& rSrc
= static_cast<const SvpSalBitmap
&>(rSalBitmap
);
605 basegfx::B2IBox
aSrcRect( pPosAry
->mnSrcX
, pPosAry
->mnSrcY
,
606 pPosAry
->mnSrcX
+pPosAry
->mnSrcWidth
,
607 pPosAry
->mnSrcY
+pPosAry
->mnSrcHeight
);
608 basegfx::B2IPoint
aDestPoint( pPosAry
->mnDestX
, pPosAry
->mnDestY
);
610 // BitmapDevice::drawMaskedColor works with 0==transparent,
611 // 255==opaque. drawMask() semantic is the other way
612 // around. Therefore, invert mask.
613 basebmp::BitmapDeviceSharedPtr aCopy
=
614 cloneBitmapDevice( basegfx::B2IVector( pPosAry
->mnSrcWidth
, pPosAry
->mnSrcHeight
),
616 basebmp::Color
aBgColor( COL_WHITE
);
617 aCopy
->clear(aBgColor
);
618 basebmp::Color
aFgColor( COL_BLACK
);
619 aCopy
->drawMaskedColor( aFgColor
, rSrc
.getBitmap(), aSrcRect
, basegfx::B2IPoint() );
621 basebmp::Color
aColor( nMaskColor
);
622 basegfx::B2IBox
aSrcRect2( 0, 0, pPosAry
->mnSrcWidth
, pPosAry
->mnSrcHeight
);
623 const basegfx::B2IBox
aClipRect( aDestPoint
, basegfx::B2ITuple( aSrcRect
.getWidth(), aSrcRect
.getHeight() ) );
625 SvpSalGraphics::ClipUndoHandle
aUndo( this );
626 if( !isClippedSetup( aClipRect
, aUndo
) )
627 m_aDevice
->drawMaskedColor( aColor
, aCopy
, aSrcRect
, aDestPoint
, m_aClipMap
);
631 SalBitmap
* SvpSalGraphics::getBitmap( long nX
, long nY
, long nWidth
, long nHeight
)
633 basebmp::BitmapDeviceSharedPtr aCopy
=
634 cloneBitmapDevice( basegfx::B2IVector( nWidth
, nHeight
),
636 basegfx::B2IBox
aSrcRect( nX
, nY
, nX
+nWidth
, nY
+nHeight
);
637 basegfx::B2IBox
aDestRect( 0, 0, nWidth
, nHeight
);
639 SvpSalGraphics::ClipUndoHandle
aUndo( this );
640 if( !isClippedSetup( aDestRect
, aUndo
) )
641 aCopy
->drawBitmap( m_aOrigDevice
, aSrcRect
, aDestRect
, basebmp::DrawMode_PAINT
);
643 SvpSalBitmap
* pBitmap
= new SvpSalBitmap();
644 pBitmap
->setBitmap( aCopy
);
648 SalColor
SvpSalGraphics::getPixel( long nX
, long nY
)
650 basebmp::Color
aColor( m_aOrigDevice
->getPixel( basegfx::B2IPoint( nX
, nY
) ) );
651 return aColor
.toInt32();
654 void SvpSalGraphics::invert( long nX
, long nY
, long nWidth
, long nHeight
, SalInvert
/*nFlags*/ )
656 // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
657 basegfx::B2DPolygon aRect
= basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX
, nY
, nX
+nWidth
, nY
+nHeight
) );
658 basegfx::B2DPolyPolygon
aPolyPoly( aRect
);
659 basegfx::B2IBox
aDestRange( nX
, nY
, nX
+ nWidth
, nY
+ nHeight
);
661 SvpSalGraphics::ClipUndoHandle
aUndo( this );
662 if( !isClippedSetup( aDestRange
, aUndo
) )
663 m_aDevice
->fillPolyPolygon( aPolyPoly
, basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR
, m_aClipMap
);
667 void SvpSalGraphics::invert( sal_uLong nPoints
, const SalPoint
* pPtAry
, SalInvert
/*nFlags*/ )
669 // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
670 basegfx::B2DPolygon aPoly
;
671 aPoly
.append( basegfx::B2DPoint( pPtAry
->mnX
, pPtAry
->mnY
), nPoints
);
672 for( sal_uLong i
= 1; i
< nPoints
; i
++ )
673 aPoly
.setB2DPoint( i
, basegfx::B2DPoint( pPtAry
[i
].mnX
, pPtAry
[i
].mnY
) );
674 aPoly
.setClosed( true );
675 ensureClip(); // FIXME for ...
676 m_aDevice
->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly
), basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR
, m_aClipMap
);
680 sal_Bool
SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong
)
685 SystemFontData
SvpSalGraphics::GetSysFontData( int nFallbacklevel
) const
687 SystemFontData aSysFontData
;
689 if (nFallbacklevel
>= MAX_FALLBACK
) nFallbacklevel
= MAX_FALLBACK
- 1;
690 if (nFallbacklevel
< 0 ) nFallbacklevel
= 0;
692 aSysFontData
.nSize
= sizeof( SystemFontData
);
693 aSysFontData
.nFontId
= 0;
694 aSysFontData
.nFontFlags
= 0;
695 aSysFontData
.bFakeBold
= false;
696 aSysFontData
.bFakeItalic
= false;
697 aSysFontData
.bAntialias
= true;
701 SystemGraphicsData
SvpSalGraphics::GetGraphicsData() const
703 return SystemGraphicsData();
706 bool SvpSalGraphics::supportsOperation( OutDevSupportType
) const
711 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */