1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_toolkit.hxx"
26 
27 #include <toolkit/awt/vclxgraphics.hxx>
28 #include <toolkit/awt/vclxdevice.hxx>
29 #include <toolkit/helper/macros.hxx>
30 #include <toolkit/helper/vclunohelper.hxx>
31 #include <cppuhelper/typeprovider.hxx>
32 #include <rtl/memory.h>
33 #include <rtl/uuid.h>
34 
35 #include <vcl/svapp.hxx>
36 #include <vcl/outdev.hxx>
37 #include <vcl/gradient.hxx>
38 #include <tools/debug.hxx>
39 
40 
41 //	----------------------------------------------------
42 //	class VCLXGraphics
43 //	----------------------------------------------------
44 
45 // ::com::sun::star::uno::XInterface
46 ::com::sun::star::uno::Any VCLXGraphics::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
47 {
48 	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
49 										SAL_STATIC_CAST( ::com::sun::star::awt::XGraphics*, this ),
50 										SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ),
51 										SAL_STATIC_CAST( ::com::sun::star::lang::XUnoTunnel*, this ) );
52 	return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
53 }
54 
55 // ::com::sun::star::lang::XUnoTunnel
56 IMPL_XUNOTUNNEL( VCLXGraphics )
57 
58 // ::com::sun::star::lang::XTypeProvider
59 IMPL_XTYPEPROVIDER_START( VCLXGraphics )
60 	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics>* ) NULL )
61 IMPL_XTYPEPROVIDER_END
62 
63 VCLXGraphics::VCLXGraphics() : mrMutex( Application::GetSolarMutex() )
64 {
65 	mpOutputDevice = NULL;
66 	mpClipRegion = NULL;
67 }
68 
69 VCLXGraphics::~VCLXGraphics()
70 {
71 	List* pLst = mpOutputDevice ? mpOutputDevice->GetUnoGraphicsList() : NULL;
72 	if ( pLst )
73 		pLst->Remove( this );
74 
75 	delete mpClipRegion;
76 }
77 
78 void VCLXGraphics::SetOutputDevice( OutputDevice* pOutDev )
79 {
80 	mpOutputDevice = pOutDev;
81 	mxDevice = NULL;
82 }
83 
84 void VCLXGraphics::Init( OutputDevice* pOutDev )
85 {
86 	DBG_ASSERT( !mpOutputDevice, "VCLXGraphics::Init allready has pOutDev !" );
87 	mpOutputDevice 	= pOutDev;
88 
89 	maFont 			= mpOutputDevice->GetFont();
90 	maTextColor 	= COL_BLACK;
91 	maTextFillColor = COL_TRANSPARENT;
92 	maLineColor 	= COL_BLACK;
93 	maFillColor 	= COL_WHITE;
94 	meRasterOp 		= ROP_OVERPAINT;
95 	mpClipRegion 	= NULL;
96 
97 	// Register at OutputDevice
98 	List* pLst = mpOutputDevice->GetUnoGraphicsList();
99 	if ( !pLst )
100 		pLst = mpOutputDevice->CreateUnoGraphicsList();
101 	pLst->Insert( this, LIST_APPEND );
102 }
103 
104 void VCLXGraphics::InitOutputDevice( sal_uInt16 nFlags )
105 {
106 	if(mpOutputDevice)
107 	{
108 		vos::OGuard aVclGuard( Application::GetSolarMutex()  );
109 
110 		if ( nFlags & INITOUTDEV_FONT )
111 		{
112 			mpOutputDevice->SetFont( maFont );
113 			mpOutputDevice->SetTextColor( maTextColor );
114 			mpOutputDevice->SetTextFillColor( maTextFillColor );
115 		}
116 
117 		if ( nFlags & INITOUTDEV_COLORS )
118 		{
119 			mpOutputDevice->SetLineColor( maLineColor );
120 			mpOutputDevice->SetFillColor( maFillColor );
121 		}
122 
123 		if ( nFlags & INITOUTDEV_RASTEROP )
124 		{
125 			mpOutputDevice->SetRasterOp( meRasterOp );
126 		}
127 
128 		if ( nFlags & INITOUTDEV_CLIPREGION )
129 		{
130 			if( mpClipRegion )
131 				mpOutputDevice->SetClipRegion( *mpClipRegion );
132 			else
133 				mpOutputDevice->SetClipRegion();
134 		}
135 	}
136 }
137 
138 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > VCLXGraphics::getDevice() throw(::com::sun::star::uno::RuntimeException)
139 {
140 	::vos::OGuard aGuard( GetMutex() );
141 
142 	if( !mxDevice.is() && mpOutputDevice )
143 	{
144 		VCLXDevice* pDev = new VCLXDevice;
145 		pDev->SetOutputDevice( mpOutputDevice );
146 		mxDevice = pDev;
147 	}
148 	return mxDevice;
149 }
150 
151 ::com::sun::star::awt::SimpleFontMetric VCLXGraphics::getFontMetric() throw(::com::sun::star::uno::RuntimeException)
152 {
153 	::vos::OGuard aGuard( GetMutex() );
154 
155 	::com::sun::star::awt::SimpleFontMetric aM;
156 	if( mpOutputDevice )
157 	{
158 		mpOutputDevice->SetFont( maFont );
159 		aM = VCLUnoHelper::CreateFontMetric( mpOutputDevice->GetFontMetric() );
160 	}
161 	return aM;
162 }
163 
164 void VCLXGraphics::setFont( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont >& rxFont ) throw(::com::sun::star::uno::RuntimeException)
165 {
166 	::vos::OGuard aGuard( GetMutex() );
167 
168 	maFont = VCLUnoHelper::CreateFont( rxFont );
169 }
170 
171 void VCLXGraphics::selectFont( const ::com::sun::star::awt::FontDescriptor& rDescription ) throw(::com::sun::star::uno::RuntimeException)
172 {
173 	::vos::OGuard aGuard( GetMutex() );
174 
175 	maFont = VCLUnoHelper::CreateFont( rDescription, Font() );
176 }
177 
178 void VCLXGraphics::setTextColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
179 {
180 	::vos::OGuard aGuard( GetMutex() );
181 
182 	maTextColor = Color( (sal_uInt32)nColor );
183 }
184 
185 void VCLXGraphics::setTextFillColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
186 {
187 	::vos::OGuard aGuard( GetMutex() );
188 
189 	maTextFillColor = Color( (sal_uInt32)nColor );
190 }
191 
192 void VCLXGraphics::setLineColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
193 {
194 	::vos::OGuard aGuard( GetMutex() );
195 
196 	maLineColor = Color( (sal_uInt32)nColor );
197 }
198 
199 void VCLXGraphics::setFillColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
200 {
201 	::vos::OGuard aGuard( GetMutex() );
202 
203 	maFillColor = Color( (sal_uInt32)nColor );
204 }
205 
206 void VCLXGraphics::setRasterOp( ::com::sun::star::awt::RasterOperation eROP ) throw(::com::sun::star::uno::RuntimeException)
207 {
208 	::vos::OGuard aGuard( GetMutex() );
209 
210 	meRasterOp = (RasterOp)eROP;
211 }
212 
213 void VCLXGraphics::setClipRegion( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XRegion >& rxRegion ) throw(::com::sun::star::uno::RuntimeException)
214 {
215 	::vos::OGuard aGuard( GetMutex() );
216 
217 	delete mpClipRegion;
218 	if ( rxRegion.is() )
219 		mpClipRegion = new Region( VCLUnoHelper::GetRegion( rxRegion ) );
220 	else
221 		mpClipRegion = NULL;
222 }
223 
224 void VCLXGraphics::intersectClipRegion( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XRegion >& rxRegion ) throw(::com::sun::star::uno::RuntimeException)
225 {
226 	::vos::OGuard aGuard( GetMutex() );
227 
228 	if ( rxRegion.is() )
229 	{
230 		Region aRegion( VCLUnoHelper::GetRegion( rxRegion ) );
231 		if ( !mpClipRegion )
232 			mpClipRegion = new Region( aRegion );
233 		else
234 			mpClipRegion->Intersect( aRegion );
235 	}
236 }
237 
238 void VCLXGraphics::push(  ) throw(::com::sun::star::uno::RuntimeException)
239 {
240 	::vos::OGuard aGuard( GetMutex() );
241 
242 
243 	if( mpOutputDevice )
244 		mpOutputDevice->Push();
245 }
246 
247 void VCLXGraphics::pop(  ) throw(::com::sun::star::uno::RuntimeException)
248 {
249 	::vos::OGuard aGuard( GetMutex() );
250 
251 
252 	if( mpOutputDevice )
253 		mpOutputDevice->Pop();
254 }
255 
256 void VCLXGraphics::copy( const ::com::sun::star::uno::Reference< ::com::sun::star::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 ) throw(::com::sun::star::uno::RuntimeException)
257 {
258 	::vos::OGuard aGuard( GetMutex() );
259 
260 	if ( mpOutputDevice )
261 	{
262 		VCLXDevice* pFromDev = VCLXDevice::GetImplementation( rxSource );
263 		DBG_ASSERT( pFromDev, "VCLXGraphics::copy - invalid device" );
264 		if ( pFromDev )
265 		{
266 			InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP );
267 			mpOutputDevice->DrawOutDev( Point( nDestX, nDestY ), Size( nDestWidth, nDestHeight ),
268 									Point( nSourceX, nSourceY ), Size( nSourceWidth, nSourceHeight ), *pFromDev->GetOutputDevice() );
269 		}
270 	}
271 }
272 
273 void VCLXGraphics::draw( const ::com::sun::star::uno::Reference< ::com::sun::star::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 ) throw(::com::sun::star::uno::RuntimeException)
274 {
275 	::vos::OGuard aGuard( GetMutex() );
276 
277 	if( mpOutputDevice )
278 	{
279 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP);
280 		::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBitmap( rxBitmapHandle, ::com::sun::star::uno::UNO_QUERY );
281 		BitmapEx aBmpEx = VCLUnoHelper::GetBitmap( xBitmap );
282 
283 		Point aPos(nDestX - nSourceX, nDestY - nSourceY);
284   		Size aSz = aBmpEx.GetSizePixel();
285 
286 		if(nDestWidth != nSourceWidth)
287 		{
288 			float zoomX = (float)nDestWidth / (float)nSourceWidth;
289 			aSz.Width() = (long) ((float)aSz.Width() * zoomX);
290 		}
291 
292 		if(nDestHeight != nSourceHeight)
293 		{
294 			float zoomY = (float)nDestHeight / (float)nSourceHeight;
295 			aSz.Height() = (long) ((float)aSz.Height() * zoomY);
296 		}
297 
298 		if(nSourceX || nSourceY || aSz.Width() != nSourceWidth || aSz.Height() != nSourceHeight)
299 			mpOutputDevice->IntersectClipRegion(Region(Rectangle(nDestX, nDestY, nDestX + nDestWidth - 1, nDestY + nDestHeight - 1)));
300 
301 		mpOutputDevice->DrawBitmapEx( aPos, aSz, aBmpEx );
302 	}
303 }
304 
305 void VCLXGraphics::drawPixel( sal_Int32 x, sal_Int32 y ) throw(::com::sun::star::uno::RuntimeException)
306 {
307 	::vos::OGuard aGuard( GetMutex() );
308 
309 	if( mpOutputDevice )
310 	{
311 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
312 		mpOutputDevice->DrawPixel( Point( x, y ) );
313 	}
314 }
315 
316 void VCLXGraphics::drawLine( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) throw(::com::sun::star::uno::RuntimeException)
317 {
318 	::vos::OGuard aGuard( GetMutex() );
319 
320 	if( mpOutputDevice )
321 	{
322 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
323 		mpOutputDevice->DrawLine( Point( x1, y1 ), Point( x2, y2 ) );
324 	}
325 }
326 
327 void VCLXGraphics::drawRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) throw(::com::sun::star::uno::RuntimeException)
328 {
329 	::vos::OGuard aGuard( GetMutex() );
330 
331 	if( mpOutputDevice )
332 	{
333 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
334 		mpOutputDevice->DrawRect( Rectangle( Point( x, y ), Size( width, height ) ) );
335 	}
336 }
337 
338 void VCLXGraphics::drawRoundedRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 nHorzRound, sal_Int32 nVertRound ) throw(::com::sun::star::uno::RuntimeException)
339 {
340 	::vos::OGuard aGuard( GetMutex() );
341 
342 	if( mpOutputDevice )
343 	{
344 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
345 		mpOutputDevice->DrawRect( Rectangle( Point( x, y ), Size( width, height ) ), nHorzRound, nVertRound );
346 	}
347 }
348 
349 void VCLXGraphics::drawPolyLine( const ::com::sun::star::uno::Sequence< sal_Int32 >& DataX, const ::com::sun::star::uno::Sequence< sal_Int32 >& DataY ) throw(::com::sun::star::uno::RuntimeException)
350 {
351 	::vos::OGuard aGuard( GetMutex() );
352 
353 	if( mpOutputDevice )
354 	{
355 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
356 		mpOutputDevice->DrawPolyLine( VCLUnoHelper::CreatePolygon( DataX, DataY ) );
357 	}
358 }
359 
360 void VCLXGraphics::drawPolygon( const ::com::sun::star::uno::Sequence< sal_Int32 >& DataX, const ::com::sun::star::uno::Sequence< sal_Int32 >& DataY ) throw(::com::sun::star::uno::RuntimeException)
361 {
362 	::vos::OGuard aGuard( GetMutex() );
363 
364 	if( mpOutputDevice )
365 	{
366 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
367 		mpOutputDevice->DrawPolygon( VCLUnoHelper::CreatePolygon( DataX, DataY ) );
368 	}
369 }
370 
371 void VCLXGraphics::drawPolyPolygon( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int32 > >& DataX, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int32 > >& DataY ) throw(::com::sun::star::uno::RuntimeException)
372 {
373 	::vos::OGuard aGuard( GetMutex() );
374 
375 	if( mpOutputDevice )
376 	{
377 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
378 		sal_uInt16 nPolys = (sal_uInt16) DataX.getLength();
379 		PolyPolygon aPolyPoly( nPolys );
380 		for ( sal_uInt16 n = 0; n < nPolys; n++ )
381 			aPolyPoly[n] = VCLUnoHelper::CreatePolygon( DataX.getConstArray()[n], DataY.getConstArray()[n] );
382 
383 		mpOutputDevice->DrawPolyPolygon( aPolyPoly );
384 	}
385 }
386 
387 void VCLXGraphics::drawEllipse( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) throw(::com::sun::star::uno::RuntimeException)
388 {
389 	::vos::OGuard aGuard( GetMutex() );
390 
391 	if( mpOutputDevice )
392 	{
393 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
394 		mpOutputDevice->DrawEllipse( Rectangle( Point( x, y ), Size( width, height ) ) );
395 	}
396 }
397 
398 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 ) throw(::com::sun::star::uno::RuntimeException)
399 {
400 	::vos::OGuard aGuard( GetMutex() );
401 
402 	if( mpOutputDevice )
403 	{
404 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
405 		mpOutputDevice->DrawArc( Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) );
406 	}
407 }
408 
409 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 ) throw(::com::sun::star::uno::RuntimeException)
410 {
411 	::vos::OGuard aGuard( GetMutex() );
412 
413 	if( mpOutputDevice )
414 	{
415 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
416 		mpOutputDevice->DrawPie( Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) );
417 	}
418 }
419 
420 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 ) throw(::com::sun::star::uno::RuntimeException)
421 {
422 	::vos::OGuard aGuard( GetMutex() );
423 
424 	if( mpOutputDevice )
425 	{
426 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
427 		mpOutputDevice->DrawChord( Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) );
428 	}
429 }
430 
431 void VCLXGraphics::drawGradient( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, const ::com::sun::star::awt::Gradient& rGradient ) throw(::com::sun::star::uno::RuntimeException)
432 {
433 	::vos::OGuard aGuard( GetMutex() );
434 
435 	if( mpOutputDevice )
436 	{
437 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS );
438 		Gradient aGradient((GradientStyle)rGradient.Style, rGradient.StartColor, rGradient.EndColor);
439 		aGradient.SetAngle(rGradient.Angle);
440 		aGradient.SetBorder(rGradient.Border);
441 		aGradient.SetOfsX(rGradient.XOffset);
442 		aGradient.SetOfsY(rGradient.YOffset);
443 		aGradient.SetStartIntensity(rGradient.StartIntensity);
444 		aGradient.SetEndIntensity(rGradient.EndIntensity);
445 		aGradient.SetSteps(rGradient.StepCount);
446 		mpOutputDevice->DrawGradient( Rectangle( Point( x, y ), Size( width, height ) ), aGradient );
447 	}
448 }
449 
450 void VCLXGraphics::drawText( sal_Int32 x, sal_Int32 y, const ::rtl::OUString& rText ) throw(::com::sun::star::uno::RuntimeException)
451 {
452 	::vos::OGuard aGuard( GetMutex() );
453 
454 	if( mpOutputDevice )
455 	{
456 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS |INITOUTDEV_FONT);
457 		mpOutputDevice->DrawText( Point( x, y ), rText );
458 	}
459 }
460 
461 void VCLXGraphics::drawTextArray( sal_Int32 x, sal_Int32 y, const ::rtl::OUString& rText, const ::com::sun::star::uno::Sequence< sal_Int32 >& rLongs ) throw(::com::sun::star::uno::RuntimeException)
462 {
463 	::vos::OGuard aGuard( GetMutex() );
464 
465 	if( mpOutputDevice )
466 	{
467 		InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS|INITOUTDEV_FONT );
468 		mpOutputDevice->DrawTextArray( Point( x, y ), rText, rLongs.getConstArray() );
469 	}
470 }
471 
472 
473 
474 
475