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
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