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