xref: /aoo41x/main/svx/source/xoutdev/xattrbmp.cxx (revision 3e407bd8)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svx.hxx"
24 
25 #include <com/sun/star/awt/XBitmap.hpp>
26 #include <com/sun/star/graphic/XGraphic.hpp>
27 #include <tools/stream.hxx>
28 #include <vcl/window.hxx>
29 #include <vcl/virdev.hxx>
30 #include <vcl/bitmapex.hxx>
31 #include <toolkit/unohlp.hxx>
32 #include <svl/style.hxx>
33 #include <editeng/memberids.hrc>
34 #include <svx/dialogs.hrc>
35 #include "svx/xattr.hxx"
36 #include <svx/xtable.hxx>
37 #include <svx/xdef.hxx>
38 #include <svx/unomid.hxx>
39 #include <editeng/unoprnms.hxx>
40 #include <svx/unoapi.hxx>
41 #include <svx/svdmodel.hxx>
42 #include <com/sun/star/beans/PropertyValue.hpp>
43 #include <vcl/salbtype.hxx>
44 #include <vcl/bmpacc.hxx>
45 #include <vcl/dibtools.hxx>
46 
47 using namespace ::com::sun::star;
48 
49 // -----------------------
50 // class XFillBitmapItem
51 // -----------------------
52 TYPEINIT1_AUTOFACTORY(XFillBitmapItem, NameOrIndex);
53 
54 //////////////////////////////////////////////////////////////////////////////
55 
56 XFillBitmapItem::XFillBitmapItem(long nIndex, const GraphicObject& rGraphicObject)
57 :   NameOrIndex(XATTR_FILLBITMAP, nIndex),
58 	maGraphicObject(rGraphicObject)
59 {
60 }
61 
62 //////////////////////////////////////////////////////////////////////////////
63 
64 XFillBitmapItem::XFillBitmapItem(const XubString& rName, const GraphicObject& rGraphicObject)
65 :   NameOrIndex(XATTR_FILLBITMAP, rName),
66 	maGraphicObject(rGraphicObject)
67 {
68 }
69 
70 //////////////////////////////////////////////////////////////////////////////
71 
72 XFillBitmapItem::XFillBitmapItem(const XFillBitmapItem& rItem)
73 :   NameOrIndex(rItem),
74 	maGraphicObject(rItem.maGraphicObject)
75 {
76 }
77 
78 //////////////////////////////////////////////////////////////////////////////
79 
80 Bitmap createHistorical8x8FromArray(const sal_uInt16* pArray, Color aColorPix, Color aColorBack)
81 {
82     BitmapPalette aPalette(2);
83 
84     aPalette[0] = BitmapColor(aColorBack);
85     aPalette[1] = BitmapColor(aColorPix);
86 
87     Bitmap aBitmap(Size(8, 8), 1, &aPalette);
88 	BitmapWriteAccess* pContent = aBitmap.AcquireWriteAccess();
89 
90     if(pContent)
91     {
92         for(sal_uInt16 a(0); a < 8; a++)
93         {
94             for(sal_uInt16 b(0); b < 8; b++)
95             {
96                 if(pArray[(a * 8) + b])
97                 {
98                     pContent->SetPixelIndex(a, b, 1);
99                 }
100                 else
101                 {
102                     pContent->SetPixelIndex(a, b, 0);
103                 }
104             }
105         }
106 
107         aBitmap.ReleaseAccess(pContent);
108     }
109 
110     return aBitmap;
111 }
112 
113 //////////////////////////////////////////////////////////////////////////////
114 
115 bool SVX_DLLPUBLIC isHistorical8x8(const BitmapEx& rBitmapEx, BitmapColor& o_rBack, BitmapColor& o_rFront)
116 {
117     if(!rBitmapEx.IsTransparent())
118     {
119         Bitmap aBitmap(rBitmapEx.GetBitmap());
120 
121         if(8 == aBitmap.GetSizePixel().Width() && 8 == aBitmap.GetSizePixel().Height())
122         {
123             if(2 == aBitmap.GetColorCount())
124             {
125                 BitmapReadAccess* pRead = aBitmap.AcquireReadAccess();
126 
127                 if(pRead)
128                 {
129                     if(pRead->HasPalette() && 2 == pRead->GetPaletteEntryCount())
130                     {
131                         const BitmapPalette& rPalette = pRead->GetPalette();
132 
133                         o_rBack = rPalette[1];
134                         o_rFront = rPalette[0];
135 
136                         return true;
137                     }
138                 }
139             }
140         }
141     }
142 
143     return false;
144 }
145 
146 //////////////////////////////////////////////////////////////////////////////
147 
148 XFillBitmapItem::XFillBitmapItem(SvStream& rIn, sal_uInt16 nVer)
149 :   NameOrIndex(XATTR_FILLBITMAP, rIn)
150 {
151 	if (!IsIndex())
152 	{
153 	    if(0 == nVer)
154 	    {
155 		    // Behandlung der alten Bitmaps
156 		    Bitmap aBmp;
157 
158             ReadDIB(aBmp, rIn, true);
159             maGraphicObject = Graphic(aBmp);
160 	    }
161 	    else if(1 == nVer)
162 	    {
163             enum XBitmapType
164             {
165                 XBITMAP_IMPORT,
166                 XBITMAP_8X8
167             };
168 
169             sal_Int16 iTmp;
170 
171             rIn >> iTmp; // former XBitmapStyle
172 		    rIn >> iTmp; // former XBitmapType
173 
174 		    if(XBITMAP_IMPORT == iTmp)
175 		    {
176 			    Bitmap aBmp;
177 
178                 ReadDIB(aBmp, rIn, true);
179                 maGraphicObject = Graphic(aBmp);
180 		    }
181 		    else if(XBITMAP_8X8 == iTmp)
182 		    {
183                 sal_uInt16 aArray[64];
184 
185 			    for(sal_uInt16 i(0); i < 64; i++)
186                 {
187 				    rIn >> aArray[i];
188                 }
189 
190 			    Color aColorPix;
191 			    Color aColorBack;
192 
193                 rIn >> aColorPix;
194 			    rIn >> aColorBack;
195 
196                 const Bitmap aBitmap(createHistorical8x8FromArray(aArray, aColorPix, aColorBack));
197 
198                 maGraphicObject = Graphic(aBitmap);
199             }
200 	    }
201         else if(2 == nVer)
202         {
203 		    BitmapEx aBmpEx;
204 
205             ReadDIBBitmapEx(aBmpEx, rIn);
206             maGraphicObject = Graphic(aBmpEx);
207         }
208     }
209 }
210 
211 //////////////////////////////////////////////////////////////////////////////
212 
213 XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/, const GraphicObject& rGraphicObject)
214 : 	NameOrIndex( XATTR_FILLBITMAP, -1),
215 	maGraphicObject(rGraphicObject)
216 {
217 }
218 
219 //////////////////////////////////////////////////////////////////////////////
220 
221 XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/)
222 :   NameOrIndex(XATTR_FILLBITMAP, -1),
223     maGraphicObject()
224 {
225 }
226 
227 //////////////////////////////////////////////////////////////////////////////
228 
229 SfxPoolItem* XFillBitmapItem::Clone(SfxItemPool* /*pPool*/) const
230 {
231 	return new XFillBitmapItem(*this);
232 }
233 
234 //////////////////////////////////////////////////////////////////////////////
235 
236 int XFillBitmapItem::operator==(const SfxPoolItem& rItem) const
237 {
238 	return (NameOrIndex::operator==(rItem)
239         && maGraphicObject == ((const XFillBitmapItem&)rItem).maGraphicObject);
240 }
241 
242 //////////////////////////////////////////////////////////////////////////////
243 
244 SfxPoolItem* XFillBitmapItem::Create(SvStream& rIn, sal_uInt16 nVer) const
245 {
246 	return new XFillBitmapItem( rIn, nVer );
247 }
248 
249 //////////////////////////////////////////////////////////////////////////////
250 
251 SvStream& XFillBitmapItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
252 {
253 	NameOrIndex::Store(rOut, nItemVersion);
254 
255 	if(!IsIndex())
256 	{
257         WriteDIBBitmapEx(maGraphicObject.GetGraphic().GetBitmapEx(), rOut);
258 	}
259 
260 	return rOut;
261 }
262 
263 //////////////////////////////////////////////////////////////////////////////
264 
265 const GraphicObject& XFillBitmapItem::GetGraphicObject() const
266 {
267     return maGraphicObject;
268 }
269 
270 //////////////////////////////////////////////////////////////////////////////
271 
272 void XFillBitmapItem::SetGraphicObject(const GraphicObject& rGraphicObject)
273 {
274     maGraphicObject = rGraphicObject;
275 }
276 
277 //////////////////////////////////////////////////////////////////////////////
278 
279 sal_uInt16 XFillBitmapItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const
280 {
281 	// version three
282 	return(2);
283 }
284 
285 //////////////////////////////////////////////////////////////////////////////
286 
287 SfxItemPresentation XFillBitmapItem::GetPresentation(
288 	SfxItemPresentation ePres,
289 	SfxMapUnit /*eCoreUnit*/,
290 	SfxMapUnit /*ePresUnit*/,
291     XubString& rText,
292     const IntlWrapper*) const
293 {
294 	switch (ePres)
295 	{
296 		case SFX_ITEM_PRESENTATION_NONE:
297 			rText.Erase();
298 			return ePres;
299 		case SFX_ITEM_PRESENTATION_NAMELESS:
300 		case SFX_ITEM_PRESENTATION_COMPLETE:
301 			rText += GetName();
302 			return ePres;
303 		default:
304 			return SFX_ITEM_PRESENTATION_NONE;
305 	}
306 }
307 
308 //////////////////////////////////////////////////////////////////////////////
309 
310 sal_Bool XFillBitmapItem::QueryValue(::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId) const
311 {
312     nMemberId &= ~CONVERT_TWIPS;
313 
314     // needed for MID_NAME
315     ::rtl::OUString aApiName;
316     // needed for complete item (MID 0)
317     ::rtl::OUString aInternalName;
318 
319     ::rtl::OUString aURL;
320     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
321 
322 	if( nMemberId == MID_NAME )
323 	{
324  		SvxUnogetApiNameForItem( Which(), GetName(), aApiName );
325 	}
326     else if( nMemberId == 0  )
327     {
328         aInternalName = GetName();
329     }
330 
331     if( nMemberId == MID_GRAFURL ||
332         nMemberId == 0 )
333 	{
334         aURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
335 		aURL += ::rtl::OUString::createFromAscii(GetGraphicObject().GetUniqueID().GetBuffer() );
336 	}
337     if( nMemberId == MID_BITMAP ||
338         nMemberId == 0  )
339 	{
340 		xBmp.set(VCLUnoHelper::CreateBitmap(GetGraphicObject().GetGraphic().GetBitmapEx()));
341 	}
342 
343     if( nMemberId == MID_NAME )
344 		rVal <<= aApiName;
345 	else if( nMemberId == MID_GRAFURL )
346 		rVal <<= aURL;
347 	else if( nMemberId == MID_BITMAP )
348 		rVal <<= xBmp;
349     else
350     {
351         // member-id 0 => complete item (e.g. for toolbars)
352         DBG_ASSERT( nMemberId == 0, "invalid member-id" );
353         uno::Sequence< beans::PropertyValue > aPropSeq( 3 );
354 
355         aPropSeq[0].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ));
356         aPropSeq[0].Value = uno::makeAny( aInternalName );
357         aPropSeq[1].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ));
358         aPropSeq[1].Value = uno::makeAny( aURL );
359         aPropSeq[2].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ));
360         aPropSeq[2].Value = uno::makeAny( xBmp );
361 
362         rVal <<= aPropSeq;
363     }
364 
365 	return sal_True;
366 }
367 
368 //////////////////////////////////////////////////////////////////////////////
369 
370 sal_Bool XFillBitmapItem::PutValue( const ::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId )
371 {
372     nMemberId &= ~CONVERT_TWIPS;
373 
374     ::rtl::OUString aName;
375     ::rtl::OUString aURL;
376     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
377     ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > xGraphic;
378 
379     bool bSetName   = false;
380     bool bSetURL    = false;
381     bool bSetBitmap = false;
382 
383     if( nMemberId == MID_NAME )
384 		bSetName = (rVal >>= aName);
385     else if( nMemberId == MID_GRAFURL )
386 		bSetURL = (rVal >>= aURL);
387 	else if( nMemberId == MID_BITMAP )
388 	{
389         bSetBitmap = (rVal >>= xBmp);
390 		if ( !bSetBitmap )
391 			bSetBitmap = (rVal >>= xGraphic );
392 	}
393     else
394     {
395         DBG_ASSERT( nMemberId == 0, "invalid member-id" );
396         uno::Sequence< beans::PropertyValue >   aPropSeq;
397         if( rVal >>= aPropSeq )
398         {
399             for ( sal_Int32 n = 0; n < aPropSeq.getLength(); n++ )
400             {
401                 if( aPropSeq[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Name" )))
402                     bSetName = (aPropSeq[n].Value >>= aName);
403                 else if( aPropSeq[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FillBitmapURL" )))
404                     bSetURL = (aPropSeq[n].Value >>= aURL);
405                 else if( aPropSeq[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Bitmap" )))
406                     bSetBitmap = (aPropSeq[n].Value >>= xBmp);
407             }
408         }
409     }
410 
411     if( bSetName )
412     {
413         SetName( aName );
414     }
415     if( bSetURL )
416     {
417         maGraphicObject  = GraphicObject::CreateGraphicObjectFromURL(aURL);
418 
419         // #121194# Prefer GraphicObject over bitmap object if both are provided
420         if(bSetBitmap && GRAPHIC_NONE != maGraphicObject.GetType())
421         {
422             bSetBitmap = false;
423         }
424     }
425     if( bSetBitmap )
426     {
427 		if(xBmp.is())
428 		{
429             maGraphicObject = Graphic(VCLUnoHelper::GetBitmap(xBmp));
430 		}
431 		else if(xGraphic.is())
432 		{
433 			maGraphicObject = Graphic(xGraphic);
434 		}
435     }
436 
437 	return (bSetName || bSetURL || bSetBitmap);
438 }
439 
440 //////////////////////////////////////////////////////////////////////////////
441 
442 sal_Bool XFillBitmapItem::CompareValueFunc( const NameOrIndex* p1, const NameOrIndex* p2 )
443 {
444     const GraphicObject& aGraphicObjectA(((XFillBitmapItem*)p1)->GetGraphicObject());
445     const GraphicObject& aGraphicObjectB(((XFillBitmapItem*)p2)->GetGraphicObject());
446 
447 	return aGraphicObjectA == aGraphicObjectB;
448 }
449 
450 //////////////////////////////////////////////////////////////////////////////
451 
452 XFillBitmapItem* XFillBitmapItem::checkForUniqueItem( SdrModel* pModel ) const
453 {
454 	if( pModel )
455 	{
456 		const String aUniqueName = NameOrIndex::CheckNamedItem(	this,
457 																XATTR_FILLBITMAP,
458 																&pModel->GetItemPool(),
459 																pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : NULL,
460 																XFillBitmapItem::CompareValueFunc,
461 																RID_SVXSTR_BMP21,
462 																pModel->GetBitmapListFromSdrModel().get() );
463 
464 		// if the given name is not valid, replace it!
465 		if( aUniqueName != GetName() )
466 		{
467 			return new XFillBitmapItem(aUniqueName, maGraphicObject);
468 		}
469 	}
470 
471 	return (XFillBitmapItem*)this;
472 }
473 
474 //////////////////////////////////////////////////////////////////////////////
475 // eof
476