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 // #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 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 215 XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/, const GraphicObject& rGraphicObject) 216 : NameOrIndex( XATTR_FILLBITMAP, -1), 217 maGraphicObject(rGraphicObject) 218 { 219 } 220 221 ////////////////////////////////////////////////////////////////////////////// 222 223 XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/) 224 : NameOrIndex(XATTR_FILLBITMAP, -1), 225 maGraphicObject() 226 { 227 } 228 229 ////////////////////////////////////////////////////////////////////////////// 230 231 SfxPoolItem* XFillBitmapItem::Clone(SfxItemPool* /*pPool*/) const 232 { 233 return new XFillBitmapItem(*this); 234 } 235 236 ////////////////////////////////////////////////////////////////////////////// 237 238 int XFillBitmapItem::operator==(const SfxPoolItem& rItem) const 239 { 240 return (NameOrIndex::operator==(rItem) 241 && maGraphicObject == ((const XFillBitmapItem&)rItem).maGraphicObject); 242 } 243 244 ////////////////////////////////////////////////////////////////////////////// 245 246 SfxPoolItem* XFillBitmapItem::Create(SvStream& rIn, sal_uInt16 nVer) const 247 { 248 return new XFillBitmapItem( rIn, nVer ); 249 } 250 251 ////////////////////////////////////////////////////////////////////////////// 252 253 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 267 const GraphicObject& XFillBitmapItem::GetGraphicObject() const 268 { 269 return maGraphicObject; 270 } 271 272 ////////////////////////////////////////////////////////////////////////////// 273 274 void XFillBitmapItem::SetGraphicObject(const GraphicObject& rGraphicObject) 275 { 276 maGraphicObject = rGraphicObject; 277 } 278 279 ////////////////////////////////////////////////////////////////////////////// 280 281 sal_uInt16 XFillBitmapItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const 282 { 283 // version three 284 return(2); 285 } 286 287 ////////////////////////////////////////////////////////////////////////////// 288 289 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 312 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 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 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 454 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