xref: /trunk/main/svx/source/xoutdev/xattrbmp.cxx (revision b63233d8)
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/helper/vclunohelper.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 
XFillBitmapItem(long nIndex,const GraphicObject & rGraphicObject)56 XFillBitmapItem::XFillBitmapItem(long nIndex, const GraphicObject& rGraphicObject)
57 :   NameOrIndex(XATTR_FILLBITMAP, nIndex),
58 	maGraphicObject(rGraphicObject)
59 {
60 }
61 
62 //////////////////////////////////////////////////////////////////////////////
63 
XFillBitmapItem(const XubString & rName,const GraphicObject & rGraphicObject)64 XFillBitmapItem::XFillBitmapItem(const XubString& rName, const GraphicObject& rGraphicObject)
65 :   NameOrIndex(XATTR_FILLBITMAP, rName),
66 	maGraphicObject(rGraphicObject)
67 {
68 }
69 
70 //////////////////////////////////////////////////////////////////////////////
71 
XFillBitmapItem(const XFillBitmapItem & rItem)72 XFillBitmapItem::XFillBitmapItem(const XFillBitmapItem& rItem)
73 :   NameOrIndex(rItem),
74 	maGraphicObject(rItem.maGraphicObject)
75 {
76 }
77 
78 //////////////////////////////////////////////////////////////////////////////
79 
createHistorical8x8FromArray(const sal_uInt16 * pArray,Color aColorPix,Color aColorBack)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 
isHistorical8x8(const BitmapEx & rBitmapEx,BitmapColor & o_rBack,BitmapColor & o_rFront)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                         // #123564# bachground and foregrund were exchanged; of course
134                         // rPalette[0] is the background color
135                         o_rFront = rPalette[1];
136                         o_rBack = rPalette[0];
137 
138                         return true;
139                     }
140                 }
141             }
142         }
143     }
144 
145     return false;
146 }
147 
148 //////////////////////////////////////////////////////////////////////////////
149 
XFillBitmapItem(SvStream & rIn,sal_uInt16 nVer)150 XFillBitmapItem::XFillBitmapItem(SvStream& rIn, sal_uInt16 nVer)
151 :   NameOrIndex(XATTR_FILLBITMAP, rIn)
152 {
153 	if (!IsIndex())
154 	{
155 	    if(0 == nVer)
156 	    {
157 		    // Behandlung der alten Bitmaps
158 		    Bitmap aBmp;
159 
160             ReadDIB(aBmp, rIn, true);
161             maGraphicObject = Graphic(aBmp);
162 	    }
163 	    else if(1 == nVer)
164 	    {
165             enum XBitmapType
166             {
167                 XBITMAP_IMPORT,
168                 XBITMAP_8X8
169             };
170 
171             sal_Int16 iTmp;
172 
173             rIn >> iTmp; // former XBitmapStyle
174 		    rIn >> iTmp; // former XBitmapType
175 
176 		    if(XBITMAP_IMPORT == iTmp)
177 		    {
178 			    Bitmap aBmp;
179 
180                 ReadDIB(aBmp, rIn, true);
181                 maGraphicObject = Graphic(aBmp);
182 		    }
183 		    else if(XBITMAP_8X8 == iTmp)
184 		    {
185                 sal_uInt16 aArray[64];
186 
187 			    for(sal_uInt16 i(0); i < 64; i++)
188                 {
189 				    rIn >> aArray[i];
190                 }
191 
192 			    Color aColorPix;
193 			    Color aColorBack;
194 
195                 rIn >> aColorPix;
196 			    rIn >> aColorBack;
197 
198                 const Bitmap aBitmap(createHistorical8x8FromArray(aArray, aColorPix, aColorBack));
199 
200                 maGraphicObject = Graphic(aBitmap);
201             }
202 	    }
203         else if(2 == nVer)
204         {
205 		    BitmapEx aBmpEx;
206 
207             ReadDIBBitmapEx(aBmpEx, rIn);
208             maGraphicObject = Graphic(aBmpEx);
209         }
210     }
211 }
212 
213 //////////////////////////////////////////////////////////////////////////////
214 
XFillBitmapItem(SfxItemPool *,const GraphicObject & rGraphicObject)215 XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/, const GraphicObject& rGraphicObject)
216 : 	NameOrIndex( XATTR_FILLBITMAP, -1),
217 	maGraphicObject(rGraphicObject)
218 {
219 }
220 
221 //////////////////////////////////////////////////////////////////////////////
222 
XFillBitmapItem(SfxItemPool *)223 XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/)
224 :   NameOrIndex(XATTR_FILLBITMAP, -1),
225     maGraphicObject()
226 {
227 }
228 
229 //////////////////////////////////////////////////////////////////////////////
230 
Clone(SfxItemPool *) const231 SfxPoolItem* XFillBitmapItem::Clone(SfxItemPool* /*pPool*/) const
232 {
233 	return new XFillBitmapItem(*this);
234 }
235 
236 //////////////////////////////////////////////////////////////////////////////
237 
operator ==(const SfxPoolItem & rItem) const238 int XFillBitmapItem::operator==(const SfxPoolItem& rItem) const
239 {
240 	return (NameOrIndex::operator==(rItem)
241         && maGraphicObject == ((const XFillBitmapItem&)rItem).maGraphicObject);
242 }
243 
244 //////////////////////////////////////////////////////////////////////////////
245 
Create(SvStream & rIn,sal_uInt16 nVer) const246 SfxPoolItem* XFillBitmapItem::Create(SvStream& rIn, sal_uInt16 nVer) const
247 {
248 	return new XFillBitmapItem( rIn, nVer );
249 }
250 
251 //////////////////////////////////////////////////////////////////////////////
252 
Store(SvStream & rOut,sal_uInt16 nItemVersion) const253 SvStream& XFillBitmapItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
254 {
255 	NameOrIndex::Store(rOut, nItemVersion);
256 
257 	if(!IsIndex())
258 	{
259         WriteDIBBitmapEx(maGraphicObject.GetGraphic().GetBitmapEx(), rOut);
260 	}
261 
262 	return rOut;
263 }
264 
265 //////////////////////////////////////////////////////////////////////////////
266 
GetGraphicObject() const267 const GraphicObject& XFillBitmapItem::GetGraphicObject() const
268 {
269     return maGraphicObject;
270 }
271 
272 //////////////////////////////////////////////////////////////////////////////
273 
SetGraphicObject(const GraphicObject & rGraphicObject)274 void XFillBitmapItem::SetGraphicObject(const GraphicObject& rGraphicObject)
275 {
276     maGraphicObject = rGraphicObject;
277 }
278 
279 //////////////////////////////////////////////////////////////////////////////
280 
GetVersion(sal_uInt16) const281 sal_uInt16 XFillBitmapItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const
282 {
283 	// version three
284 	return(2);
285 }
286 
287 //////////////////////////////////////////////////////////////////////////////
288 
GetPresentation(SfxItemPresentation ePres,SfxMapUnit,SfxMapUnit,XubString & rText,const IntlWrapper *) const289 SfxItemPresentation XFillBitmapItem::GetPresentation(
290 	SfxItemPresentation ePres,
291 	SfxMapUnit /*eCoreUnit*/,
292 	SfxMapUnit /*ePresUnit*/,
293     XubString& rText,
294     const IntlWrapper*) const
295 {
296 	switch (ePres)
297 	{
298 		case SFX_ITEM_PRESENTATION_NONE:
299 			rText.Erase();
300 			return ePres;
301 		case SFX_ITEM_PRESENTATION_NAMELESS:
302 		case SFX_ITEM_PRESENTATION_COMPLETE:
303 			rText += GetName();
304 			return ePres;
305 		default:
306 			return SFX_ITEM_PRESENTATION_NONE;
307 	}
308 }
309 
310 //////////////////////////////////////////////////////////////////////////////
311 
QueryValue(::com::sun::star::uno::Any & rVal,sal_uInt8 nMemberId) const312 sal_Bool XFillBitmapItem::QueryValue(::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId) const
313 {
314     nMemberId &= ~CONVERT_TWIPS;
315 
316     // needed for MID_NAME
317     ::rtl::OUString aApiName;
318     // needed for complete item (MID 0)
319     ::rtl::OUString aInternalName;
320 
321     ::rtl::OUString aURL;
322     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
323 
324 	if( nMemberId == MID_NAME )
325 	{
326  		SvxUnogetApiNameForItem( Which(), GetName(), aApiName );
327 	}
328     else if( nMemberId == 0  )
329     {
330         aInternalName = GetName();
331     }
332 
333     if( nMemberId == MID_GRAFURL ||
334         nMemberId == 0 )
335 	{
336         aURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
337 		aURL += ::rtl::OUString::createFromAscii(GetGraphicObject().GetUniqueID().GetBuffer() );
338 	}
339     if( nMemberId == MID_BITMAP ||
340         nMemberId == 0  )
341 	{
342 		xBmp.set(VCLUnoHelper::CreateBitmap(GetGraphicObject().GetGraphic().GetBitmapEx()));
343 	}
344 
345     if( nMemberId == MID_NAME )
346 		rVal <<= aApiName;
347 	else if( nMemberId == MID_GRAFURL )
348 		rVal <<= aURL;
349 	else if( nMemberId == MID_BITMAP )
350 		rVal <<= xBmp;
351     else
352     {
353         // member-id 0 => complete item (e.g. for toolbars)
354         DBG_ASSERT( nMemberId == 0, "invalid member-id" );
355         uno::Sequence< beans::PropertyValue > aPropSeq( 3 );
356 
357         aPropSeq[0].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ));
358         aPropSeq[0].Value = uno::makeAny( aInternalName );
359         aPropSeq[1].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ));
360         aPropSeq[1].Value = uno::makeAny( aURL );
361         aPropSeq[2].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ));
362         aPropSeq[2].Value = uno::makeAny( xBmp );
363 
364         rVal <<= aPropSeq;
365     }
366 
367 	return sal_True;
368 }
369 
370 //////////////////////////////////////////////////////////////////////////////
371 
PutValue(const::com::sun::star::uno::Any & rVal,sal_uInt8 nMemberId)372 sal_Bool XFillBitmapItem::PutValue( const ::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId )
373 {
374     nMemberId &= ~CONVERT_TWIPS;
375 
376     ::rtl::OUString aName;
377     ::rtl::OUString aURL;
378     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
379     ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > xGraphic;
380 
381     bool bSetName   = false;
382     bool bSetURL    = false;
383     bool bSetBitmap = false;
384 
385     if( nMemberId == MID_NAME )
386 		bSetName = (rVal >>= aName);
387     else if( nMemberId == MID_GRAFURL )
388 		bSetURL = (rVal >>= aURL);
389 	else if( nMemberId == MID_BITMAP )
390 	{
391         bSetBitmap = (rVal >>= xBmp);
392 		if ( !bSetBitmap )
393 			bSetBitmap = (rVal >>= xGraphic );
394 	}
395     else
396     {
397         DBG_ASSERT( nMemberId == 0, "invalid member-id" );
398         uno::Sequence< beans::PropertyValue >   aPropSeq;
399         if( rVal >>= aPropSeq )
400         {
401             for ( sal_Int32 n = 0; n < aPropSeq.getLength(); n++ )
402             {
403                 if( aPropSeq[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Name" )))
404                     bSetName = (aPropSeq[n].Value >>= aName);
405                 else if( aPropSeq[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FillBitmapURL" )))
406                     bSetURL = (aPropSeq[n].Value >>= aURL);
407                 else if( aPropSeq[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Bitmap" )))
408                     bSetBitmap = (aPropSeq[n].Value >>= xBmp);
409             }
410         }
411     }
412 
413     if( bSetName )
414     {
415         SetName( aName );
416     }
417     if( bSetURL )
418     {
419         maGraphicObject  = GraphicObject::CreateGraphicObjectFromURL(aURL);
420 
421         // #121194# Prefer GraphicObject over bitmap object if both are provided
422         if(bSetBitmap && GRAPHIC_NONE != maGraphicObject.GetType())
423         {
424             bSetBitmap = false;
425         }
426     }
427     if( bSetBitmap )
428     {
429 		if(xBmp.is())
430 		{
431             maGraphicObject = Graphic(VCLUnoHelper::GetBitmap(xBmp));
432 		}
433 		else if(xGraphic.is())
434 		{
435 			maGraphicObject = Graphic(xGraphic);
436 		}
437     }
438 
439 	return (bSetName || bSetURL || bSetBitmap);
440 }
441 
442 //////////////////////////////////////////////////////////////////////////////
443 
CompareValueFunc(const NameOrIndex * p1,const NameOrIndex * p2)444 sal_Bool XFillBitmapItem::CompareValueFunc( const NameOrIndex* p1, const NameOrIndex* p2 )
445 {
446     const GraphicObject& aGraphicObjectA(((XFillBitmapItem*)p1)->GetGraphicObject());
447     const GraphicObject& aGraphicObjectB(((XFillBitmapItem*)p2)->GetGraphicObject());
448 
449 	return aGraphicObjectA == aGraphicObjectB;
450 }
451 
452 //////////////////////////////////////////////////////////////////////////////
453 
checkForUniqueItem(SdrModel * pModel) const454 XFillBitmapItem* XFillBitmapItem::checkForUniqueItem( SdrModel* pModel ) const
455 {
456 	if( pModel )
457 	{
458 		const String aUniqueName = NameOrIndex::CheckNamedItem(	this,
459 																XATTR_FILLBITMAP,
460 																&pModel->GetItemPool(),
461 																pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : NULL,
462 																XFillBitmapItem::CompareValueFunc,
463 																RID_SVXSTR_BMP21,
464 																pModel->GetBitmapListFromSdrModel().get() );
465 
466 		// if the given name is not valid, replace it!
467 		if( aUniqueName != GetName() )
468 		{
469 			return new XFillBitmapItem(aUniqueName, maGraphicObject);
470 		}
471 	}
472 
473 	return (XFillBitmapItem*)this;
474 }
475 
476 //////////////////////////////////////////////////////////////////////////////
477 // eof
478