LibreOffice Module toolkit (master) 1
vclxgraphics.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include <memory>
22#include <awt/vclxgraphics.hxx>
25
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 <tools/debug.hxx>
33
34using namespace com::sun::star;
35
36
37
39 : mpOutputDevice(nullptr)
40 , meRasterOp(RasterOp::OverPaint)
41{
42}
43
45{
46 std::vector< VCLXGraphics* > *pLst = mpOutputDevice ? mpOutputDevice->GetUnoGraphicsList() : nullptr;
47 if ( pLst )
48 {
49 auto it = std::find(pLst->begin(), pLst->end(), this);
50 if (it != pLst->end())
51 pLst->erase( it );
52 }
53
54 mpClipRegion.reset();
55
58}
59
61{
62 mpOutputDevice = pOutDev;
63 mxDevice = nullptr;
64 initAttrs();
65}
66
68{
69 DBG_ASSERT( !mpOutputDevice, "VCLXGraphics::Init already has pOutDev !" );
70 mpOutputDevice = pOutDev;
71
72 initAttrs();
73 mpClipRegion = nullptr;
74
75 // Register at OutputDevice
76 std::vector< VCLXGraphics* > *pLst = mpOutputDevice->GetUnoGraphicsList();
77 if ( !pLst )
78 pLst = mpOutputDevice->CreateUnoGraphicsList();
79 pLst->push_back( this );
80}
81
83{
84 if ( !mpOutputDevice )
85 return;
86
87 maFont = mpOutputDevice->GetFont();
88 maTextColor = mpOutputDevice->GetTextColor(); /* COL_BLACK */
89 maTextFillColor = mpOutputDevice->GetTextFillColor(); /* COL_TRANSPARENT */
90 maLineColor = mpOutputDevice->GetLineColor(); /* COL_BLACK */
91 maFillColor = mpOutputDevice->GetFillColor(); /* COL_WHITE */
92 meRasterOp = mpOutputDevice->GetRasterOp(); /* RasterOp::OverPaint */
93}
94
96{
98 return;
99
100 SolarMutexGuard aVclGuard;
101
102 if ( nFlags & InitOutDevFlags::FONT )
103 {
104 mpOutputDevice->SetFont( maFont );
105 mpOutputDevice->SetTextColor( maTextColor );
106 mpOutputDevice->SetTextFillColor( maTextFillColor );
107 }
108
109 if ( nFlags & InitOutDevFlags::COLORS )
110 {
111 mpOutputDevice->SetLineColor( maLineColor );
112 mpOutputDevice->SetFillColor( maFillColor );
113 }
114
115 mpOutputDevice->SetRasterOp( meRasterOp );
116
117 if( mpClipRegion )
118 mpOutputDevice->SetClipRegion( *mpClipRegion );
119 else
120 mpOutputDevice->SetClipRegion();
121}
122
123uno::Reference< awt::XDevice > VCLXGraphics::getDevice()
124{
125 SolarMutexGuard aGuard;
126
127 if( !mxDevice.is() && mpOutputDevice )
128 {
130 pDev->SetOutputDevice( mpOutputDevice );
131 mxDevice = pDev;
132 }
133 return mxDevice;
134}
135
136awt::SimpleFontMetric VCLXGraphics::getFontMetric()
137{
138 SolarMutexGuard aGuard;
139
140 awt::SimpleFontMetric aM;
141 if( mpOutputDevice )
142 {
143 mpOutputDevice->SetFont( maFont );
144 aM = VCLUnoHelper::CreateFontMetric( mpOutputDevice->GetFontMetric() );
145 }
146 return aM;
147}
148
149void VCLXGraphics::setFont( const uno::Reference< awt::XFont >& rxFont )
150{
151 SolarMutexGuard aGuard;
152
154}
155
156void VCLXGraphics::selectFont( const awt::FontDescriptor& rDescription )
157{
158 SolarMutexGuard aGuard;
159
160 maFont = VCLUnoHelper::CreateFont( rDescription, vcl::Font() );
161}
162
163void VCLXGraphics::setTextColor( sal_Int32 nColor )
164{
165 SolarMutexGuard aGuard;
166
168}
169
170void VCLXGraphics::setTextFillColor( sal_Int32 nColor )
171{
172 SolarMutexGuard aGuard;
173
175}
176
177void VCLXGraphics::setLineColor( sal_Int32 nColor )
178{
179 SolarMutexGuard aGuard;
180
182}
183
184void VCLXGraphics::setFillColor( sal_Int32 nColor )
185{
186 SolarMutexGuard aGuard;
187
189}
190
191void VCLXGraphics::setRasterOp( awt::RasterOperation eROP )
192{
193 SolarMutexGuard aGuard;
194
195 meRasterOp = static_cast<RasterOp>(eROP);
196}
197
198void VCLXGraphics::setClipRegion( const uno::Reference< awt::XRegion >& rxRegion )
199{
200 SolarMutexGuard aGuard;
201
202 if ( rxRegion.is() )
203 mpClipRegion.reset( new vcl::Region( VCLUnoHelper::GetRegion( rxRegion ) ) );
204 else
205 mpClipRegion.reset();
206}
207
208void VCLXGraphics::intersectClipRegion( const uno::Reference< awt::XRegion >& rxRegion )
209{
210 SolarMutexGuard aGuard;
211
212 if ( rxRegion.is() )
213 {
214 vcl::Region aRegion( VCLUnoHelper::GetRegion( rxRegion ) );
215 if ( !mpClipRegion )
216 mpClipRegion.reset( new vcl::Region( aRegion ) );
217 else
218 mpClipRegion->Intersect( aRegion );
219 }
220}
221
223{
224 SolarMutexGuard aGuard;
225
226
227 if( mpOutputDevice )
228 mpOutputDevice->Push();
229}
230
232{
233 SolarMutexGuard aGuard;
234
235
236 if( mpOutputDevice )
237 mpOutputDevice->Pop();
238}
239
241 const awt::Rectangle& aRect )
242{
243 SolarMutexGuard aGuard;
244
245 if( mpOutputDevice )
246 {
247 const ::tools::Rectangle aVCLRect = VCLUnoHelper::ConvertToVCLRect( aRect );
248 mpOutputDevice->Erase( aVCLRect );
249 }
250}
251
252void 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 )
253{
254 SolarMutexGuard aGuard;
255
256 if ( mpOutputDevice )
257 {
258 VCLXDevice* pFromDev = dynamic_cast<VCLXDevice*>( rxSource.get() );
259 DBG_ASSERT( pFromDev, "VCLXGraphics::copy - invalid device" );
260 if ( pFromDev )
261 {
263 mpOutputDevice->DrawOutDev( Point( nDestX, nDestY ), Size( nDestWidth, nDestHeight ),
264 Point( nSourceX, nSourceY ), Size( nSourceWidth, nSourceHeight ), *pFromDev->GetOutputDevice() );
265 }
266 }
267}
268
269void 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 )
270{
271 SolarMutexGuard aGuard;
272
273 if( !mpOutputDevice )
274 return;
275
277 uno::Reference< awt::XBitmap > xBitmap( rxBitmapHandle, uno::UNO_QUERY );
278 BitmapEx aBmpEx = VCLUnoHelper::GetBitmap( xBitmap );
279
280 Point aPos(nDestX - nSourceX, nDestY - nSourceY);
281 Size aSz = aBmpEx.GetSizePixel();
282
283 if(nDestWidth != nSourceWidth)
284 {
285 float zoomX = static_cast<float>(nDestWidth) / static_cast<float>(nSourceWidth);
286 aSz.setWidth( static_cast<tools::Long>(static_cast<float>(aSz.Width()) * zoomX) );
287 }
288
289 if(nDestHeight != nSourceHeight)
290 {
291 float zoomY = static_cast<float>(nDestHeight) / static_cast<float>(nSourceHeight);
292 aSz.setHeight( static_cast<tools::Long>(static_cast<float>(aSz.Height()) * zoomY) );
293 }
294
295 if(nSourceX || nSourceY || aSz.Width() != nSourceWidth || aSz.Height() != nSourceHeight)
296 mpOutputDevice->IntersectClipRegion(vcl::Region(tools::Rectangle(nDestX, nDestY, nDestX + nDestWidth - 1, nDestY + nDestHeight - 1)));
297
298 mpOutputDevice->DrawBitmapEx( aPos, aSz, aBmpEx );
299}
300
301void VCLXGraphics::drawPixel( sal_Int32 x, sal_Int32 y )
302{
303 SolarMutexGuard aGuard;
304
305 if( mpOutputDevice )
306 {
308 mpOutputDevice->DrawPixel( Point( x, y ) );
309 }
310}
311
312void VCLXGraphics::drawLine( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 )
313{
314 SolarMutexGuard aGuard;
315
316 if( mpOutputDevice )
317 {
319 mpOutputDevice->DrawLine( Point( x1, y1 ), Point( x2, y2 ) );
320 }
321}
322
323void VCLXGraphics::drawRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height )
324{
325 SolarMutexGuard aGuard;
326
327 if( mpOutputDevice )
328 {
330 mpOutputDevice->DrawRect( tools::Rectangle( Point( x, y ), Size( width, height ) ) );
331 }
332}
333
334void VCLXGraphics::drawRoundedRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 nHorzRound, sal_Int32 nVertRound )
335{
336 SolarMutexGuard aGuard;
337
338 if( mpOutputDevice )
339 {
341 mpOutputDevice->DrawRect( tools::Rectangle( Point( x, y ), Size( width, height ) ), nHorzRound, nVertRound );
342 }
343}
344
345void VCLXGraphics::drawPolyLine( const uno::Sequence< sal_Int32 >& DataX, const uno::Sequence< sal_Int32 >& DataY )
346{
347 SolarMutexGuard aGuard;
348
349 if( mpOutputDevice )
350 {
352 mpOutputDevice->DrawPolyLine( VCLUnoHelper::CreatePolygon( DataX, DataY ) );
353 }
354}
355
356void VCLXGraphics::drawPolygon( const uno::Sequence< sal_Int32 >& DataX, const uno::Sequence< sal_Int32 >& DataY )
357{
358 SolarMutexGuard aGuard;
359
360 if( mpOutputDevice )
361 {
363 mpOutputDevice->DrawPolygon( VCLUnoHelper::CreatePolygon( DataX, DataY ) );
364 }
365}
366
367void VCLXGraphics::drawPolyPolygon( const uno::Sequence< uno::Sequence< sal_Int32 > >& DataX, const uno::Sequence< uno::Sequence< sal_Int32 > >& DataY )
368{
369 SolarMutexGuard aGuard;
370
371 if( mpOutputDevice )
372 {
374 sal_uInt16 nPolys = static_cast<sal_uInt16>(DataX.getLength());
375 tools::PolyPolygon aPolyPoly( nPolys );
376 for ( sal_uInt16 n = 0; n < nPolys; n++ )
377 aPolyPoly[n] = VCLUnoHelper::CreatePolygon( DataX.getConstArray()[n], DataY.getConstArray()[n] );
378
379 mpOutputDevice->DrawPolyPolygon( aPolyPoly );
380 }
381}
382
383void VCLXGraphics::drawEllipse( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height )
384{
385 SolarMutexGuard aGuard;
386
387 if( mpOutputDevice )
388 {
390 mpOutputDevice->DrawEllipse( tools::Rectangle( Point( x, y ), Size( width, height ) ) );
391 }
392}
393
394void 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 )
395{
396 SolarMutexGuard aGuard;
397
398 if( mpOutputDevice )
399 {
401 mpOutputDevice->DrawArc( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) );
402 }
403}
404
405void 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 )
406{
407 SolarMutexGuard aGuard;
408
409 if( mpOutputDevice )
410 {
412 mpOutputDevice->DrawPie( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) );
413 }
414}
415
416void 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 )
417{
418 SolarMutexGuard aGuard;
419
420 if( mpOutputDevice )
421 {
423 mpOutputDevice->DrawChord( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) );
424 }
425}
426
427void VCLXGraphics::drawGradient( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, const awt::Gradient& rGradient )
428{
429 SolarMutexGuard aGuard;
430
431 if( !mpOutputDevice )
432 return;
433
435 Gradient aGradient(rGradient.Style, Color(ColorTransparency, rGradient.StartColor), Color(ColorTransparency, rGradient.EndColor));
436 aGradient.SetAngle(Degree10(rGradient.Angle));
437 aGradient.SetBorder(rGradient.Border);
438 aGradient.SetOfsX(rGradient.XOffset);
439 aGradient.SetOfsY(rGradient.YOffset);
440 aGradient.SetStartIntensity(rGradient.StartIntensity);
441 aGradient.SetEndIntensity(rGradient.EndIntensity);
442 aGradient.SetSteps(rGradient.StepCount);
443 mpOutputDevice->DrawGradient( tools::Rectangle( Point( x, y ), Size( width, height ) ), aGradient );
444}
445
446void VCLXGraphics::drawText( sal_Int32 x, sal_Int32 y, const OUString& rText )
447{
448 SolarMutexGuard aGuard;
449
450 if( mpOutputDevice )
451 {
453 mpOutputDevice->DrawText( Point( x, y ), rText );
454 }
455}
456
457void VCLXGraphics::drawTextArray( sal_Int32 x, sal_Int32 y, const OUString& rText, const uno::Sequence< sal_Int32 >& rLongs )
458{
459 SolarMutexGuard aGuard;
460
461 if( mpOutputDevice )
462 {
464 KernArray aDXA;
465 aDXA.reserve(rText.getLength());
466 for(int i = 0; i < rText.getLength(); ++i)
467 aDXA.push_back(rLongs[i]);
468 mpOutputDevice->DrawTextArray( Point( x, y ), rText, aDXA, {}, 0, rText.getLength());
469 }
470}
471
472
473void VCLXGraphics::drawImage( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int16 nStyle, const uno::Reference< graphic::XGraphic >& xGraphic )
474{
475 SolarMutexGuard aGuard;
476
477 if( mpOutputDevice && xGraphic.is() )
478 {
479 Image aImage( xGraphic );
480 if ( !!aImage )
481 {
483 mpOutputDevice->DrawImage( Point( x, y ), Size( width, height ), aImage, static_cast<DrawImageFlags>(nStyle) );
484 }
485 }
486}
487/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawImageFlags
RasterOp
const Size & GetSizePixel() const
void SetOfsX(sal_uInt16 nOfsX)
void SetStartIntensity(sal_uInt16 nIntens)
void SetBorder(sal_uInt16 nBorder)
void SetSteps(sal_uInt16 nSteps)
void SetOfsY(sal_uInt16 nOfsY)
void SetAngle(Degree10 nAngle)
void SetEndIntensity(sal_uInt16 nIntens)
void reserve(size_t nCapacity)
void push_back(sal_Int32 nUnit)
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
static css::awt::SimpleFontMetric CreateFontMetric(const FontMetric &rFontMetric)
static vcl::Region GetRegion(const css::uno::Reference< css::awt::XRegion > &rxRegion)
static BitmapEx GetBitmap(const css::uno::Reference< css::awt::XBitmap > &rxBitmap)
static tools::Polygon CreatePolygon(const css::uno::Sequence< sal_Int32 > &DataX, const css::uno::Sequence< sal_Int32 > &DataY)
::tools::Rectangle ConvertToVCLRect(css::awt::Rectangle const &_rRect)
static vcl::Font CreateFont(const css::awt::FontDescriptor &rDescr, const vcl::Font &rInitFont)
A UNO wrapper for the VCL OutputDevice.
Definition: vclxdevice.hxx:37
const VclPtr< OutputDevice > & GetOutputDevice() const
Definition: vclxdevice.hxx:49
virtual void SAL_CALL drawGradient(::sal_Int32 nX, ::sal_Int32 nY, ::sal_Int32 nWidth, ::sal_Int32 Height, const css::awt::Gradient &aGradient) override
virtual void SAL_CALL setTextColor(::sal_Int32 _textcolor) override
virtual void SAL_CALL selectFont(const css::awt::FontDescriptor &aDescription) override
virtual void SAL_CALL setRasterOp(css::awt::RasterOperation _rasterop) override
virtual void SAL_CALL drawText(::sal_Int32 X, ::sal_Int32 Y, const OUString &Text) override
vcl::Font maFont
virtual void SAL_CALL 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) override
RasterOp meRasterOp
virtual void SAL_CALL drawChord(::sal_Int32 nX, ::sal_Int32 nY, ::sal_Int32 nWidth, ::sal_Int32 nHeight, ::sal_Int32 nX1, ::sal_Int32 nY1, ::sal_Int32 nX2, ::sal_Int32 nY2) override
virtual void SAL_CALL setTextFillColor(::sal_Int32 _textfillcolor) override
virtual void SAL_CALL drawEllipse(::sal_Int32 X, ::sal_Int32 Y, ::sal_Int32 Width, ::sal_Int32 Height) override
void initAttrs()
std::unique_ptr< vcl::Region > mpClipRegion
virtual ~VCLXGraphics() override
virtual void SAL_CALL drawPixel(::sal_Int32 X, ::sal_Int32 Y) override
virtual void SAL_CALL drawPolyLine(const css::uno::Sequence< ::sal_Int32 > &DataX, const css::uno::Sequence< ::sal_Int32 > &DataY) override
Color maTextFillColor
virtual void SAL_CALL draw(const css::uno::Reference< css::awt::XDisplayBitmap > &xBitmapHandle, ::sal_Int32 SourceX, ::sal_Int32 SourceY, ::sal_Int32 SourceWidth, ::sal_Int32 SourceHeight, ::sal_Int32 DestX, ::sal_Int32 DestY, ::sal_Int32 DestWidth, ::sal_Int32 DestHeight) override
virtual css::awt::SimpleFontMetric SAL_CALL getFontMetric() override
virtual void SAL_CALL drawPolyPolygon(const css::uno::Sequence< css::uno::Sequence< ::sal_Int32 > > &DataX, const css::uno::Sequence< css::uno::Sequence< ::sal_Int32 > > &DataY) override
virtual void SAL_CALL setFont(const css::uno::Reference< css::awt::XFont > &_font) override
virtual css::uno::Reference< css::awt::XDevice > SAL_CALL getDevice() override
virtual void SAL_CALL setFillColor(::sal_Int32 _fillcolor) override
void SetOutputDevice(OutputDevice *pOutDev)
void Init(OutputDevice *pOutDev)
VclPtr< OutputDevice > mpOutputDevice
virtual void SAL_CALL drawTextArray(::sal_Int32 X, ::sal_Int32 Y, const OUString &Text, const css::uno::Sequence< ::sal_Int32 > &Longs) override
virtual void SAL_CALL drawRoundedRect(::sal_Int32 X, ::sal_Int32 Y, ::sal_Int32 Width, ::sal_Int32 Height, ::sal_Int32 nHorzRound, ::sal_Int32 nVertRound) override
virtual void SAL_CALL setClipRegion(const css::uno::Reference< css::awt::XRegion > &Clipping) override
void InitOutputDevice(InitOutDevFlags nFlags)
virtual void SAL_CALL 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) override
virtual void SAL_CALL intersectClipRegion(const css::uno::Reference< css::awt::XRegion > &xClipping) override
virtual void SAL_CALL drawRect(::sal_Int32 X, ::sal_Int32 Y, ::sal_Int32 Width, ::sal_Int32 Height) override
virtual void SAL_CALL push() override
virtual void SAL_CALL drawImage(::sal_Int32 nX, ::sal_Int32 nY, ::sal_Int32 nWidth, ::sal_Int32 nHeight, ::sal_Int16 nStyle, const css::uno::Reference< css::graphic::XGraphic > &aGraphic) override
virtual void SAL_CALL setLineColor(::sal_Int32 _linecolor) override
virtual void SAL_CALL drawLine(::sal_Int32 X1, ::sal_Int32 Y1, ::sal_Int32 X2, ::sal_Int32 Y2) override
virtual void SAL_CALL clear(const css::awt::Rectangle &aRect) override
virtual void SAL_CALL pop() override
virtual void SAL_CALL copy(const css::uno::Reference< css::awt::XDevice > &xSource, ::sal_Int32 nSourceX, ::sal_Int32 nSourceY, ::sal_Int32 nSourceWidth, ::sal_Int32 nSourceHeight, ::sal_Int32 nDestX, ::sal_Int32 nDestY, ::sal_Int32 nDestWidth, ::sal_Int32 nDestHeight) override
virtual void SAL_CALL drawPolygon(const css::uno::Sequence< ::sal_Int32 > &DataX, const css::uno::Sequence< ::sal_Int32 > &DataY) override
css::uno::Reference< css::awt::XDevice > mxDevice
void reset(reference_type *pBody)
ColorTransparency
#define DBG_ASSERT(sCon, aError)
float y
float x
sal_Int64 n
int i
long Long
InitOutDevFlags