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 .
22 #include <awt/vclxgraphics.hxx>
23 #include <toolkit/awt/vclxdevice.hxx>
24 #include <toolkit/helper/vclunohelper.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/outdev.hxx>
28 #include <vcl/image.hxx>
29 #include <vcl/kernarray.hxx>
30 #include <vcl/gradient.hxx>
31 #include <vcl/metric.hxx>
32 #include <vcl/unohelp.hxx>
33 #include <tools/debug.hxx>
35 using namespace com::sun::star
;
39 VCLXGraphics::VCLXGraphics()
40 : mpOutputDevice(nullptr)
41 , meRasterOp(RasterOp::OverPaint
)
45 VCLXGraphics::~VCLXGraphics()
47 std::vector
< VCLXGraphics
* > *pLst
= mpOutputDevice
? mpOutputDevice
->GetUnoGraphicsList() : nullptr;
50 auto it
= std::find(pLst
->begin(), pLst
->end(), this);
51 if (it
!= pLst
->end())
58 mpOutputDevice
.reset();
61 void VCLXGraphics::SetOutputDevice( OutputDevice
* pOutDev
)
63 mpOutputDevice
= pOutDev
;
68 void VCLXGraphics::Init( OutputDevice
* pOutDev
)
70 DBG_ASSERT( !mpOutputDevice
, "VCLXGraphics::Init already has pOutDev !" );
71 mpOutputDevice
= pOutDev
;
74 mpClipRegion
= nullptr;
76 // Register at OutputDevice
77 std::vector
< VCLXGraphics
* > *pLst
= mpOutputDevice
->GetUnoGraphicsList();
79 pLst
= mpOutputDevice
->CreateUnoGraphicsList();
80 pLst
->push_back( this );
83 void VCLXGraphics::initAttrs()
85 if ( !mpOutputDevice
)
88 maFont
= mpOutputDevice
->GetFont();
89 maTextColor
= mpOutputDevice
->GetTextColor(); /* COL_BLACK */
90 maTextFillColor
= mpOutputDevice
->GetTextFillColor(); /* COL_TRANSPARENT */
91 maLineColor
= mpOutputDevice
->GetLineColor(); /* COL_BLACK */
92 maFillColor
= mpOutputDevice
->GetFillColor(); /* COL_WHITE */
93 meRasterOp
= mpOutputDevice
->GetRasterOp(); /* RasterOp::OverPaint */
96 void VCLXGraphics::InitOutputDevice( InitOutDevFlags nFlags
)
101 SolarMutexGuard aVclGuard
;
103 if ( nFlags
& InitOutDevFlags::FONT
)
105 mpOutputDevice
->SetFont( maFont
);
106 mpOutputDevice
->SetTextColor( maTextColor
);
107 mpOutputDevice
->SetTextFillColor( maTextFillColor
);
110 if ( nFlags
& InitOutDevFlags::COLORS
)
112 mpOutputDevice
->SetLineColor( maLineColor
);
113 mpOutputDevice
->SetFillColor( maFillColor
);
116 mpOutputDevice
->SetRasterOp( meRasterOp
);
119 mpOutputDevice
->SetClipRegion( *mpClipRegion
);
121 mpOutputDevice
->SetClipRegion();
124 uno::Reference
< awt::XDevice
> VCLXGraphics::getDevice()
126 SolarMutexGuard aGuard
;
128 if( !mxDevice
.is() && mpOutputDevice
)
130 rtl::Reference
<VCLXDevice
> xDev
= new VCLXDevice
;
131 xDev
->SetOutputDevice( mpOutputDevice
);
132 mxDevice
= std::move(xDev
);
137 awt::SimpleFontMetric
VCLXGraphics::getFontMetric()
139 SolarMutexGuard aGuard
;
141 awt::SimpleFontMetric aM
;
144 mpOutputDevice
->SetFont( maFont
);
145 aM
= VCLUnoHelper::CreateFontMetric( mpOutputDevice
->GetFontMetric() );
150 void VCLXGraphics::setFont( const uno::Reference
< awt::XFont
>& rxFont
)
152 SolarMutexGuard aGuard
;
154 maFont
= VCLUnoHelper::CreateFont( rxFont
);
157 void VCLXGraphics::selectFont( const awt::FontDescriptor
& rDescription
)
159 SolarMutexGuard aGuard
;
161 maFont
= VCLUnoHelper::CreateFont( rDescription
, vcl::Font() );
164 void VCLXGraphics::setTextColor( sal_Int32 nColor
)
166 SolarMutexGuard aGuard
;
168 maTextColor
= Color( ColorTransparency
, nColor
);
171 void VCLXGraphics::setTextFillColor( sal_Int32 nColor
)
173 SolarMutexGuard aGuard
;
175 maTextFillColor
= Color( ColorTransparency
, nColor
);
178 void VCLXGraphics::setLineColor( sal_Int32 nColor
)
180 SolarMutexGuard aGuard
;
182 maLineColor
= Color( ColorTransparency
, nColor
);
185 void VCLXGraphics::setFillColor( sal_Int32 nColor
)
187 SolarMutexGuard aGuard
;
189 maFillColor
= Color( ColorTransparency
, nColor
);
192 void VCLXGraphics::setRasterOp( awt::RasterOperation eROP
)
194 SolarMutexGuard aGuard
;
196 meRasterOp
= static_cast<RasterOp
>(eROP
);
199 void VCLXGraphics::setClipRegion( const uno::Reference
< awt::XRegion
>& rxRegion
)
201 SolarMutexGuard aGuard
;
204 mpClipRegion
.reset( new vcl::Region( VCLUnoHelper::GetRegion( rxRegion
) ) );
206 mpClipRegion
.reset();
209 void VCLXGraphics::intersectClipRegion( const uno::Reference
< awt::XRegion
>& rxRegion
)
211 SolarMutexGuard aGuard
;
215 vcl::Region
aRegion( VCLUnoHelper::GetRegion( rxRegion
) );
217 mpClipRegion
.reset( new vcl::Region(std::move(aRegion
)) );
219 mpClipRegion
->Intersect( aRegion
);
223 void VCLXGraphics::push( )
225 SolarMutexGuard aGuard
;
229 mpOutputDevice
->Push();
232 void VCLXGraphics::pop( )
234 SolarMutexGuard aGuard
;
238 mpOutputDevice
->Pop();
241 void VCLXGraphics::clear(
242 const awt::Rectangle
& aRect
)
244 SolarMutexGuard aGuard
;
248 const ::tools::Rectangle aVCLRect
= vcl::unohelper::ConvertToVCLRect( aRect
);
249 mpOutputDevice
->Erase( aVCLRect
);
253 void VCLXGraphics::copy( const uno::Reference
< awt::XDevice
>& rxSource
, sal_Int32 nSourceX
, sal_Int32 nSourceY
, sal_Int32 nSourceWidth
, sal_Int32 nSourceHeight
, sal_Int32 nDestX
, sal_Int32 nDestY
, sal_Int32 nDestWidth
, sal_Int32 nDestHeight
)
255 SolarMutexGuard aGuard
;
257 if ( mpOutputDevice
)
259 VCLXDevice
* pFromDev
= dynamic_cast<VCLXDevice
*>( rxSource
.get() );
260 DBG_ASSERT( pFromDev
, "VCLXGraphics::copy - invalid device" );
263 InitOutputDevice( InitOutDevFlags::NONE
);
264 mpOutputDevice
->DrawOutDev( Point( nDestX
, nDestY
), Size( nDestWidth
, nDestHeight
),
265 Point( nSourceX
, nSourceY
), Size( nSourceWidth
, nSourceHeight
), *pFromDev
->GetOutputDevice() );
270 void VCLXGraphics::draw( const uno::Reference
< awt::XDisplayBitmap
>& rxBitmapHandle
, sal_Int32 nSourceX
, sal_Int32 nSourceY
, sal_Int32 nSourceWidth
, sal_Int32 nSourceHeight
, sal_Int32 nDestX
, sal_Int32 nDestY
, sal_Int32 nDestWidth
, sal_Int32 nDestHeight
)
272 SolarMutexGuard aGuard
;
274 if( !mpOutputDevice
)
277 InitOutputDevice( InitOutDevFlags::NONE
);
278 uno::Reference
< awt::XBitmap
> xBitmap( rxBitmapHandle
, uno::UNO_QUERY
);
279 BitmapEx aBmpEx
= VCLUnoHelper::GetBitmap( xBitmap
);
281 Point
aPos(nDestX
- nSourceX
, nDestY
- nSourceY
);
282 Size aSz
= aBmpEx
.GetSizePixel();
284 if(nDestWidth
!= nSourceWidth
)
286 float zoomX
= static_cast<float>(nDestWidth
) / static_cast<float>(nSourceWidth
);
287 aSz
.setWidth( static_cast<tools::Long
>(static_cast<float>(aSz
.Width()) * zoomX
) );
290 if(nDestHeight
!= nSourceHeight
)
292 float zoomY
= static_cast<float>(nDestHeight
) / static_cast<float>(nSourceHeight
);
293 aSz
.setHeight( static_cast<tools::Long
>(static_cast<float>(aSz
.Height()) * zoomY
) );
296 if(nSourceX
|| nSourceY
|| aSz
.Width() != nSourceWidth
|| aSz
.Height() != nSourceHeight
)
297 mpOutputDevice
->IntersectClipRegion(vcl::Region(tools::Rectangle(nDestX
, nDestY
, nDestX
+ nDestWidth
- 1, nDestY
+ nDestHeight
- 1)));
299 mpOutputDevice
->DrawBitmapEx( aPos
, aSz
, aBmpEx
);
302 void VCLXGraphics::drawPixel( sal_Int32 x
, sal_Int32 y
)
304 SolarMutexGuard aGuard
;
308 InitOutputDevice( InitOutDevFlags::COLORS
);
309 mpOutputDevice
->DrawPixel( Point( x
, y
) );
313 void VCLXGraphics::drawLine( sal_Int32 x1
, sal_Int32 y1
, sal_Int32 x2
, sal_Int32 y2
)
315 SolarMutexGuard aGuard
;
319 InitOutputDevice( InitOutDevFlags::COLORS
);
320 mpOutputDevice
->DrawLine( Point( x1
, y1
), Point( x2
, y2
) );
324 void VCLXGraphics::drawRect( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
)
326 SolarMutexGuard aGuard
;
330 InitOutputDevice( InitOutDevFlags::COLORS
);
331 mpOutputDevice
->DrawRect( tools::Rectangle( Point( x
, y
), Size( width
, height
) ) );
335 void VCLXGraphics::drawRoundedRect( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
, sal_Int32 nHorzRound
, sal_Int32 nVertRound
)
337 SolarMutexGuard aGuard
;
341 InitOutputDevice( InitOutDevFlags::COLORS
);
342 mpOutputDevice
->DrawRect( tools::Rectangle( Point( x
, y
), Size( width
, height
) ), nHorzRound
, nVertRound
);
346 void VCLXGraphics::drawPolyLine( const uno::Sequence
< sal_Int32
>& DataX
, const uno::Sequence
< sal_Int32
>& DataY
)
348 SolarMutexGuard aGuard
;
352 InitOutputDevice( InitOutDevFlags::COLORS
);
353 mpOutputDevice
->DrawPolyLine( VCLUnoHelper::CreatePolygon( DataX
, DataY
) );
357 void VCLXGraphics::drawPolygon( const uno::Sequence
< sal_Int32
>& DataX
, const uno::Sequence
< sal_Int32
>& DataY
)
359 SolarMutexGuard aGuard
;
363 InitOutputDevice( InitOutDevFlags::COLORS
);
364 mpOutputDevice
->DrawPolygon( VCLUnoHelper::CreatePolygon( DataX
, DataY
) );
368 void VCLXGraphics::drawPolyPolygon( const uno::Sequence
< uno::Sequence
< sal_Int32
> >& DataX
, const uno::Sequence
< uno::Sequence
< sal_Int32
> >& DataY
)
370 SolarMutexGuard aGuard
;
374 InitOutputDevice( InitOutDevFlags::COLORS
);
375 sal_uInt16 nPolys
= static_cast<sal_uInt16
>(DataX
.getLength());
376 tools::PolyPolygon
aPolyPoly( nPolys
);
377 for ( sal_uInt16 n
= 0; n
< nPolys
; n
++ )
378 aPolyPoly
[n
] = VCLUnoHelper::CreatePolygon( DataX
.getConstArray()[n
], DataY
.getConstArray()[n
] );
380 mpOutputDevice
->DrawPolyPolygon( aPolyPoly
);
384 void VCLXGraphics::drawEllipse( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
)
386 SolarMutexGuard aGuard
;
390 InitOutputDevice( InitOutDevFlags::COLORS
);
391 mpOutputDevice
->DrawEllipse( tools::Rectangle( Point( x
, y
), Size( width
, height
) ) );
395 void VCLXGraphics::drawArc( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
, sal_Int32 x1
, sal_Int32 y1
, sal_Int32 x2
, sal_Int32 y2
)
397 SolarMutexGuard aGuard
;
401 InitOutputDevice( InitOutDevFlags::COLORS
);
402 mpOutputDevice
->DrawArc( tools::Rectangle( Point( x
, y
), Size( width
, height
) ), Point( x1
, y1
), Point( x2
, y2
) );
406 void VCLXGraphics::drawPie( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
, sal_Int32 x1
, sal_Int32 y1
, sal_Int32 x2
, sal_Int32 y2
)
408 SolarMutexGuard aGuard
;
412 InitOutputDevice( InitOutDevFlags::COLORS
);
413 mpOutputDevice
->DrawPie( tools::Rectangle( Point( x
, y
), Size( width
, height
) ), Point( x1
, y1
), Point( x2
, y2
) );
417 void VCLXGraphics::drawChord( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
, sal_Int32 x1
, sal_Int32 y1
, sal_Int32 x2
, sal_Int32 y2
)
419 SolarMutexGuard aGuard
;
423 InitOutputDevice( InitOutDevFlags::COLORS
);
424 mpOutputDevice
->DrawChord( tools::Rectangle( Point( x
, y
), Size( width
, height
) ), Point( x1
, y1
), Point( x2
, y2
) );
428 void VCLXGraphics::drawGradient( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
, const awt::Gradient
& rGradient
)
430 SolarMutexGuard aGuard
;
432 if( !mpOutputDevice
)
435 InitOutputDevice( InitOutDevFlags::COLORS
);
436 Gradient
aGradient(rGradient
.Style
, Color(ColorTransparency
, rGradient
.StartColor
), Color(ColorTransparency
, rGradient
.EndColor
));
437 aGradient
.SetAngle(Degree10(rGradient
.Angle
));
438 aGradient
.SetBorder(rGradient
.Border
);
439 aGradient
.SetOfsX(rGradient
.XOffset
);
440 aGradient
.SetOfsY(rGradient
.YOffset
);
441 aGradient
.SetStartIntensity(rGradient
.StartIntensity
);
442 aGradient
.SetEndIntensity(rGradient
.EndIntensity
);
443 aGradient
.SetSteps(rGradient
.StepCount
);
444 mpOutputDevice
->DrawGradient( tools::Rectangle( Point( x
, y
), Size( width
, height
) ), aGradient
);
447 void VCLXGraphics::drawText( sal_Int32 x
, sal_Int32 y
, const OUString
& rText
)
449 SolarMutexGuard aGuard
;
453 InitOutputDevice( InitOutDevFlags::COLORS
|InitOutDevFlags::FONT
);
454 mpOutputDevice
->DrawText( Point( x
, y
), rText
);
458 void VCLXGraphics::drawTextArray( sal_Int32 x
, sal_Int32 y
, const OUString
& rText
, const uno::Sequence
< sal_Int32
>& rLongs
)
460 SolarMutexGuard aGuard
;
464 InitOutputDevice( InitOutDevFlags::COLORS
|InitOutDevFlags::FONT
);
466 aDXA
.reserve(rText
.getLength());
467 for(int i
= 0; i
< rText
.getLength(); ++i
)
468 aDXA
.push_back(rLongs
[i
]);
469 mpOutputDevice
->DrawTextArray( Point( x
, y
), rText
, aDXA
, {}, 0, rText
.getLength());
474 void VCLXGraphics::drawImage( sal_Int32 x
, sal_Int32 y
, sal_Int32 width
, sal_Int32 height
, sal_Int16 nStyle
, const uno::Reference
< graphic::XGraphic
>& xGraphic
)
476 SolarMutexGuard aGuard
;
478 if( mpOutputDevice
&& xGraphic
.is() )
480 Image
aImage( xGraphic
);
483 InitOutputDevice( InitOutDevFlags::COLORS
);
484 mpOutputDevice
->DrawImage( Point( x
, y
), Size( width
, height
), aImage
, static_cast<DrawImageFlags
>(nStyle
) );
488 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */