xref: /AOO41X/main/svx/source/xoutdev/xattrbmp.cxx (revision 5980243063f6840bf3a2e60b2243db5da5e78fa6)
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(b, a, 1);
99                 }
100                 else
101                 {
102                     pContent->SetPixelIndex(b, a, 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->GetBitmapList() );
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