1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 #include "descriptor.hxx"
32 
33 #include <rtl/uuid.h>
34 #include <vos/mutex.hxx>
35 #include <unotools/ucbstreamhelper.hxx>
36 #include <svtools/filter.hxx>
37 #include <svl/itemprop.hxx>
38 
39 #include <com/sun/star/beans/PropertyState.hpp>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/awt/Size.hpp>
42 #include <com/sun/star/graphic/GraphicType.hpp>
43 
44 #include "vcl/graph.hxx"
45 #include "vcl/svapp.hxx"
46 
47 #define UNOGRAPHIC_GRAPHICTYPE 	1
48 #define UNOGRAPHIC_MIMETYPE		2
49 #define UNOGRAPHIC_SIZEPIXEL	3
50 #define UNOGRAPHIC_SIZE100THMM	4
51 #define UNOGRAPHIC_BITSPERPIXEL	5
52 #define UNOGRAPHIC_TRANSPARENT	6
53 #define UNOGRAPHIC_ALPHA		7
54 #define UNOGRAPHIC_ANIMATED		8
55 
56 using namespace ::com::sun::star;
57 
58 namespace unographic {
59 
60 // ---------------------
61 // - GraphicDescriptor -
62 // ---------------------
63 
64 GraphicDescriptor::GraphicDescriptor() :
65 	::comphelper::PropertySetHelper( createPropertySetInfo(), SAL_NO_ACQUIRE ),
66 	mpGraphic( NULL ),
67 	meType( GRAPHIC_NONE ),
68 	mnBitsPerPixel ( 0 ),
69 	mbTransparent ( false ),
70 	mbAlpha( false ),
71 	mbAnimated( false )
72 {
73 }
74 
75 // ------------------------------------------------------------------------------
76 
77 GraphicDescriptor::~GraphicDescriptor()
78 	throw()
79 {
80 }
81 
82 // ------------------------------------------------------------------------------
83 
84 void GraphicDescriptor::init( const ::Graphic& rGraphic )
85 	throw()
86 {
87 	mpGraphic = &rGraphic;
88 }
89 
90 // ------------------------------------------------------------------------------
91 
92 void GraphicDescriptor::init( const ::rtl::OUString& rURL )
93 	throw()
94 {
95 	SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rURL, STREAM_READ );
96 
97 	if( pIStm )
98 	{
99 		implCreate( *pIStm, &rURL );
100 		delete pIStm;
101 	}
102 }
103 
104 // ------------------------------------------------------------------------------
105 
106 void GraphicDescriptor::init( const uno::Reference< io::XInputStream >& rxIStm, const ::rtl::OUString& rURL )
107 	throw()
108 {
109 	SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rxIStm );
110 
111 	if( pIStm )
112 	{
113 		implCreate( *pIStm, &rURL );
114 		delete pIStm;
115 	}
116 }
117 
118 // ------------------------------------------------------------------------------
119 
120 bool GraphicDescriptor::isValid() const
121 {
122 	return( mpGraphic ? ( mpGraphic->GetType() != GRAPHIC_NONE ) : ( meType != GRAPHIC_NONE ) );
123 }
124 
125 // ------------------------------------------------------------------------------
126 
127 void GraphicDescriptor::implCreate( SvStream& rIStm, const ::rtl::OUString* pURL )
128 {
129 	String aURL;
130 	if( pURL )
131 		aURL = *pURL;
132 	::GraphicDescriptor aDescriptor( rIStm, &aURL );
133 
134 	mpGraphic = NULL;
135 	maMimeType = ::rtl::OUString();
136 	meType = GRAPHIC_NONE;
137 	mnBitsPerPixel = 0;
138 	mbTransparent = false;
139 
140 	if( aDescriptor.Detect( true ) && aDescriptor.GetFileFormat() != GFF_NOT )
141 	{
142 		const char* 			pMimeType = NULL;
143 		sal_uInt8 				cType = graphic::GraphicType::EMPTY;
144 
145 		switch( aDescriptor.GetFileFormat() )
146 		{
147 			case( GFF_BMP ): pMimeType = MIMETYPE_BMP; cType = graphic::GraphicType::PIXEL; break;
148 			case( GFF_GIF ): pMimeType = MIMETYPE_GIF; cType = graphic::GraphicType::PIXEL; break;
149 			case( GFF_JPG ): pMimeType = MIMETYPE_JPG; cType = graphic::GraphicType::PIXEL; break;
150 			case( GFF_PCD ): pMimeType = MIMETYPE_PCD; cType = graphic::GraphicType::PIXEL; break;
151 			case( GFF_PCX ): pMimeType = MIMETYPE_PCX; cType = graphic::GraphicType::PIXEL; break;
152 			case( GFF_PNG ): pMimeType = MIMETYPE_PNG; cType = graphic::GraphicType::PIXEL; break;
153 			case( GFF_TIF ): pMimeType = MIMETYPE_TIF; cType = graphic::GraphicType::PIXEL; break;
154 			case( GFF_XBM ): pMimeType = MIMETYPE_XBM; cType = graphic::GraphicType::PIXEL; break;
155 			case( GFF_XPM ): pMimeType = MIMETYPE_XPM; cType = graphic::GraphicType::PIXEL; break;
156 			case( GFF_PBM ): pMimeType = MIMETYPE_PBM; cType = graphic::GraphicType::PIXEL; break;
157 			case( GFF_PGM ): pMimeType = MIMETYPE_PGM; cType = graphic::GraphicType::PIXEL; break;
158 			case( GFF_PPM ): pMimeType = MIMETYPE_PPM; cType = graphic::GraphicType::PIXEL; break;
159 			case( GFF_RAS ): pMimeType = MIMETYPE_RAS; cType = graphic::GraphicType::PIXEL; break;
160 			case( GFF_TGA ): pMimeType = MIMETYPE_TGA; cType = graphic::GraphicType::PIXEL; break;
161 			case( GFF_PSD ): pMimeType = MIMETYPE_PSD; cType = graphic::GraphicType::PIXEL; break;
162 
163 			case( GFF_EPS ): pMimeType = MIMETYPE_EPS; cType = graphic::GraphicType::VECTOR; break;
164 			case( GFF_DXF ): pMimeType = MIMETYPE_DXF; cType = graphic::GraphicType::VECTOR; break;
165 			case( GFF_MET ): pMimeType = MIMETYPE_MET; cType = graphic::GraphicType::VECTOR; break;
166 			case( GFF_PCT ): pMimeType = MIMETYPE_PCT; cType = graphic::GraphicType::VECTOR; break;
167 			case( GFF_SGF ): pMimeType = MIMETYPE_SGF; cType = graphic::GraphicType::VECTOR; break;
168 			case( GFF_SVM ): pMimeType = MIMETYPE_SVM; cType = graphic::GraphicType::VECTOR; break;
169 			case( GFF_WMF ): pMimeType = MIMETYPE_WMF; cType = graphic::GraphicType::VECTOR; break;
170 			case( GFF_SGV ): pMimeType = MIMETYPE_SGV; cType = graphic::GraphicType::VECTOR; break;
171 			case( GFF_EMF ): pMimeType = MIMETYPE_EMF; cType = graphic::GraphicType::VECTOR; break;
172 			case( GFF_SVG ): pMimeType = MIMETYPE_SVG; cType = graphic::GraphicType::VECTOR; break;
173 
174 			default:
175 			break;
176 		}
177 
178 		if( graphic::GraphicType::EMPTY != cType )
179 		{
180 			meType = ( ( graphic::GraphicType::PIXEL == cType ) ? GRAPHIC_BITMAP : GRAPHIC_GDIMETAFILE );
181 			maMimeType = String( pMimeType, RTL_TEXTENCODING_ASCII_US );
182 			maSizePixel = aDescriptor.GetSizePixel();
183 			maSize100thMM = aDescriptor.GetSize_100TH_MM();
184 			mnBitsPerPixel = aDescriptor.GetBitsPerPixel();
185 			mbTransparent = ( graphic::GraphicType::VECTOR == cType );
186 			mbAlpha = mbAnimated = false;
187 		}
188 	}
189 }
190 
191 // ------------------------------------------------------------------------------
192 
193 ::rtl::OUString GraphicDescriptor::getImplementationName_Static()
194 	throw()
195 {
196 	return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.GraphicDescriptor" ) );
197 }
198 
199 // ------------------------------------------------------------------------------
200 
201 uno::Sequence< ::rtl::OUString > GraphicDescriptor::getSupportedServiceNames_Static()
202 	throw(	)
203 {
204 	uno::Sequence< ::rtl::OUString > aSeq( 1 );
205 
206 	aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicDescriptor" ) );
207 
208 	return aSeq;
209 }
210 
211 // ------------------------------------------------------------------------------
212 
213 uno::Any SAL_CALL GraphicDescriptor::queryAggregation( const uno::Type & rType )
214 	throw( uno::RuntimeException )
215 {
216 	uno::Any aAny;
217 
218 	if( rType == ::getCppuType((const uno::Reference< lang::XServiceInfo >*)0) )
219 		aAny <<= uno::Reference< lang::XServiceInfo >(this);
220 	else if( rType == ::getCppuType((const uno::Reference< lang::XTypeProvider >*)0) )
221 		aAny <<= uno::Reference< lang::XTypeProvider >(this);
222 	else if( rType == ::getCppuType((const uno::Reference< beans::XPropertySet >*)0) )
223 		aAny <<= uno::Reference< beans::XPropertySet >(this);
224 	else if( rType == ::getCppuType((const uno::Reference< beans::XPropertyState >*)0) )
225 		aAny <<= uno::Reference< beans::XPropertyState >(this);
226 	else if( rType == ::getCppuType((const uno::Reference< beans::XMultiPropertySet >*)0) )
227 		aAny <<= uno::Reference< beans::XMultiPropertySet >(this);
228 	else
229 		aAny <<= OWeakAggObject::queryAggregation( rType );
230 
231 	return aAny;
232 }
233 
234 // ------------------------------------------------------------------------------
235 
236 uno::Any SAL_CALL GraphicDescriptor::queryInterface( const uno::Type & rType )
237 	throw( uno::RuntimeException )
238 {
239 	return OWeakAggObject::queryInterface( rType );
240 }
241 
242 // ------------------------------------------------------------------------------
243 
244 void SAL_CALL GraphicDescriptor::acquire()
245 	throw()
246 {
247 	OWeakAggObject::acquire();
248 }
249 
250 // ------------------------------------------------------------------------------
251 
252 void SAL_CALL GraphicDescriptor::release()
253 	throw()
254 {
255 	OWeakAggObject::release();
256 }
257 
258 // ------------------------------------------------------------------------------
259 
260 ::rtl::OUString SAL_CALL GraphicDescriptor::getImplementationName()
261 	throw( uno::RuntimeException )
262 {
263 	return getImplementationName_Static();
264 }
265 
266 // ------------------------------------------------------------------------------
267 
268 sal_Bool SAL_CALL GraphicDescriptor::supportsService( const rtl::OUString& ServiceName )
269 	throw( uno::RuntimeException )
270 {
271     uno::Sequence< ::rtl::OUString >	aSNL( getSupportedServiceNames() );
272     const ::rtl::OUString*				pArray = aSNL.getConstArray();
273 
274     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
275         if( pArray[i] == ServiceName )
276             return true;
277 
278     return false;
279 }
280 
281 // ------------------------------------------------------------------------------
282 
283 uno::Sequence< rtl::OUString > SAL_CALL GraphicDescriptor::getSupportedServiceNames()
284 	throw( uno::RuntimeException )
285 {
286 	return getSupportedServiceNames_Static();
287 }
288 
289 // ------------------------------------------------------------------------------
290 
291 uno::Sequence< uno::Type > SAL_CALL GraphicDescriptor::getTypes()
292 	throw( uno::RuntimeException )
293 {
294 	uno::Sequence< uno::Type >	aTypes( 6 );
295 	uno::Type* 					pTypes = aTypes.getArray();
296 
297 	*pTypes++ = ::getCppuType((const uno::Reference< uno::XAggregation>*)0);
298 	*pTypes++ = ::getCppuType((const uno::Reference< lang::XServiceInfo>*)0);
299 	*pTypes++ = ::getCppuType((const uno::Reference< lang::XTypeProvider>*)0);
300 	*pTypes++ = ::getCppuType((const uno::Reference< beans::XPropertySet>*)0);
301 	*pTypes++ = ::getCppuType((const uno::Reference< beans::XPropertyState>*)0);
302 	*pTypes++ = ::getCppuType((const uno::Reference< beans::XMultiPropertySet>*)0);
303 
304 	return aTypes;
305 }
306 
307 // ------------------------------------------------------------------------------
308 
309 uno::Sequence< sal_Int8 > SAL_CALL GraphicDescriptor::getImplementationId()
310 	throw( uno::RuntimeException )
311 {
312 	vos::OGuard 						aGuard( Application::GetSolarMutex() );
313 	static uno::Sequence< sal_Int8 >	aId;
314 
315 	if( aId.getLength() == 0 )
316 	{
317 		aId.realloc( 16 );
318 		rtl_createUuid( reinterpret_cast< sal_uInt8* >( aId.getArray() ), 0, sal_True );
319 	}
320 
321 	return aId;
322 }
323 
324 // ------------------------------------------------------------------------------
325 
326 ::comphelper::PropertySetInfo* GraphicDescriptor::createPropertySetInfo()
327 {
328 	vos::OGuard 					aGuard( Application::GetSolarMutex() );
329 	::comphelper::PropertySetInfo*	pRet = new ::comphelper::PropertySetInfo();
330 
331 	static ::comphelper::PropertyMapEntry aEntries[] =
332 	{
333 		{ MAP_CHAR_LEN( "GraphicType" ), UNOGRAPHIC_GRAPHICTYPE, &::getCppuType( (const sal_Int8*)(0)), beans::PropertyAttribute::READONLY, 0 },
334 		{ MAP_CHAR_LEN( "MimeType" ), UNOGRAPHIC_MIMETYPE, &::getCppuType( (const ::rtl::OUString*)(0)), beans::PropertyAttribute::READONLY, 0 },
335 		{ MAP_CHAR_LEN( "SizePixel" ), UNOGRAPHIC_SIZEPIXEL, &::getCppuType( (const awt::Size*)(0)), beans::PropertyAttribute::READONLY, 0 },
336 		{ MAP_CHAR_LEN( "Size100thMM" ), UNOGRAPHIC_SIZE100THMM,	&::getCppuType( (const awt::Size*)(0)), beans::PropertyAttribute::READONLY, 0 },
337 		{ MAP_CHAR_LEN( "BitsPerPixel" ), UNOGRAPHIC_BITSPERPIXEL, &::getCppuType( (const sal_uInt8*)(0)), beans::PropertyAttribute::READONLY, 0 },
338 		{ MAP_CHAR_LEN( "Transparent" ), UNOGRAPHIC_TRANSPARENT, &::getCppuType( (const sal_Bool*)(0)), beans::PropertyAttribute::READONLY, 0 },
339 		{ MAP_CHAR_LEN( "Alpha" ), UNOGRAPHIC_ALPHA, &::getCppuType( (const sal_Bool*)(0)), beans::PropertyAttribute::READONLY, 0 },
340 		{ MAP_CHAR_LEN( "Animated" ), UNOGRAPHIC_ANIMATED, &::getCppuType( (const sal_Bool*)(0)), beans::PropertyAttribute::READONLY, 0 },
341 
342 		{ 0,0,0,0,0,0 }
343 	};
344 
345 	pRet->acquire();
346 	pRet->add( aEntries );
347 
348 	return pRet;
349 }
350 
351 // ------------------------------------------------------------------------------
352 
353 void GraphicDescriptor::_setPropertyValues( const comphelper::PropertyMapEntry** /*ppEntries*/, const uno::Any* /*pValues*/ )
354 	throw( beans::UnknownPropertyException,
355 		   beans::PropertyVetoException,
356 		   lang::IllegalArgumentException,
357 	   	   lang::WrappedTargetException )
358 {
359 	// we only have readonly attributes
360 }
361 
362 // ------------------------------------------------------------------------------
363 
364 void GraphicDescriptor::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, uno::Any* pValues )
365 	throw( beans::UnknownPropertyException, lang::WrappedTargetException )
366 {
367 	::vos::OGuard aGuard( Application::GetSolarMutex() );
368 
369 	while( *ppEntries )
370 	{
371 		switch( (*ppEntries)->mnHandle )
372 		{
373 			case( UNOGRAPHIC_GRAPHICTYPE ):
374 			{
375 				const GraphicType eType( mpGraphic ? mpGraphic->GetType() : meType );
376 
377 				*pValues <<= ( ( eType == GRAPHIC_BITMAP ? graphic::GraphicType::PIXEL :
378 								( eType == GRAPHIC_GDIMETAFILE ? graphic::GraphicType::VECTOR :
379 								graphic::GraphicType::EMPTY ) ) );
380 			}
381 			break;
382 
383 			case( UNOGRAPHIC_MIMETYPE ):
384 			{
385 				::rtl::OUString aMimeType;
386 
387 				if( mpGraphic )
388 				{
389 					if( mpGraphic->IsLink() )
390 					{
391 						const char* pMimeType;
392 
393 						switch( const_cast< Graphic* >( mpGraphic )->GetLink().GetType() )
394 						{
395 							case( GFX_LINK_TYPE_NATIVE_GIF ): pMimeType = MIMETYPE_GIF; break;
396 							case( GFX_LINK_TYPE_NATIVE_JPG ): pMimeType = MIMETYPE_JPG; break;
397 							case( GFX_LINK_TYPE_NATIVE_PNG ): pMimeType = MIMETYPE_PNG; break;
398 							case( GFX_LINK_TYPE_NATIVE_WMF ): pMimeType = MIMETYPE_WMF; break;
399 							case( GFX_LINK_TYPE_NATIVE_MET ): pMimeType = MIMETYPE_MET; break;
400 							case( GFX_LINK_TYPE_NATIVE_PCT ): pMimeType = MIMETYPE_PCT ; break;
401 
402 							default:
403 								pMimeType = NULL;
404 							break;
405 						}
406 
407 						if( pMimeType )
408 							aMimeType = ::rtl::OUString::createFromAscii( pMimeType );
409 					}
410 
411 					if( !aMimeType.getLength() && ( mpGraphic->GetType() != GRAPHIC_NONE ) )
412 						aMimeType = ::rtl::OUString::createFromAscii( MIMETYPE_VCLGRAPHIC );
413 				}
414 				else
415 					aMimeType = maMimeType;
416 
417  				*pValues <<= aMimeType;
418 			}
419 			break;
420 
421 			case( UNOGRAPHIC_SIZEPIXEL ):
422 			{
423 				awt::Size aAWTSize( 0, 0 );
424 
425 				if( mpGraphic )
426 				{
427 					if( mpGraphic->GetType() == GRAPHIC_BITMAP )
428 					{
429 						const Size aSizePix( mpGraphic->GetBitmapEx().GetSizePixel() );
430 						aAWTSize = awt::Size( aSizePix.Width(), aSizePix.Height() );
431 					}
432 				}
433 				else
434 					aAWTSize = awt::Size( maSizePixel.Width(), maSizePixel.Height() );
435 
436 				*pValues <<= aAWTSize;
437 			}
438 			break;
439 
440 			case( UNOGRAPHIC_SIZE100THMM ):
441 			{
442 				awt::Size aAWTSize( 0, 0 );
443 
444 				if( mpGraphic )
445 				{
446 					if( mpGraphic->GetPrefMapMode().GetMapUnit() != MAP_PIXEL )
447 					{
448 						const Size aSizeLog( OutputDevice::LogicToLogic( mpGraphic->GetPrefSize(), mpGraphic->GetPrefMapMode(), MAP_100TH_MM ) );
449 						aAWTSize = awt::Size( aSizeLog.Width(), aSizeLog.Height() );
450 					}
451 				}
452 				else
453 					aAWTSize = awt::Size( maSize100thMM.Width(), maSize100thMM.Height() );
454 
455 				*pValues <<= aAWTSize;
456 			}
457 			break;
458 
459 			case( UNOGRAPHIC_BITSPERPIXEL ):
460 			{
461 				sal_uInt16 nBitsPerPixel = 0;
462 
463 				if( mpGraphic )
464 				{
465 					if( mpGraphic->GetType() == GRAPHIC_BITMAP )
466 						nBitsPerPixel = mpGraphic->GetBitmapEx().GetBitmap().GetBitCount();
467 				}
468 				else
469 					nBitsPerPixel = mnBitsPerPixel;
470 
471 				*pValues <<= sal::static_int_cast< sal_Int8 >(nBitsPerPixel);
472 			}
473 			break;
474 
475 			case( UNOGRAPHIC_TRANSPARENT ):
476 			{
477 				*pValues <<= static_cast< sal_Bool >( mpGraphic ? mpGraphic->IsTransparent() : mbTransparent );
478 			}
479 			break;
480 
481 			case( UNOGRAPHIC_ALPHA ):
482 			{
483 				*pValues <<= static_cast< sal_Bool >( mpGraphic ? mpGraphic->IsAlpha() : mbAlpha );
484 			}
485 			break;
486 
487 			case( UNOGRAPHIC_ANIMATED ):
488 			{
489 				*pValues <<= static_cast< sal_Bool >( mpGraphic ? mpGraphic->IsAnimated() : mbAnimated );
490 			}
491 			break;
492 		}
493 
494 		++ppEntries;
495 		++pValues;
496 	}
497 }
498 
499 }
500