Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/awt/XBitmap.hpp>
21 : #include <com/sun/star/graphic/XGraphic.hpp>
22 : #include <tools/stream.hxx>
23 : #include <vcl/window.hxx>
24 : #include <vcl/virdev.hxx>
25 : #include <vcl/bitmapex.hxx>
26 : #include <toolkit/helper/vclunohelper.hxx>
27 : #include <svl/style.hxx>
28 : #include <editeng/memberids.hrc>
29 : #include <svx/dialogs.hrc>
30 : #include "svx/xattr.hxx"
31 : #include <svx/xtable.hxx>
32 : #include <svx/xdef.hxx>
33 : #include <svx/unomid.hxx>
34 : #include <editeng/unoprnms.hxx>
35 : #include <svx/unoapi.hxx>
36 : #include <svx/svdmodel.hxx>
37 : #include <svx/xbitmap.hxx>
38 : #include <com/sun/star/beans/PropertyValue.hpp>
39 : #include <vcl/salbtype.hxx>
40 : #include <vcl/bmpacc.hxx>
41 : #include <vcl/dibtools.hxx>
42 :
43 : using namespace ::com::sun::star;
44 :
45 0 : XOBitmap::XOBitmap( const Bitmap& rBmp ) :
46 : eType ( XBITMAP_IMPORT ),
47 : aGraphicObject ( rBmp ),
48 : pPixelArray ( NULL ),
49 0 : bGraphicDirty ( false )
50 : {
51 0 : }
52 :
53 0 : XOBitmap::XOBitmap( const XOBitmap& rXBmp ) :
54 0 : pPixelArray ( NULL )
55 : {
56 0 : eType = rXBmp.eType;
57 0 : aGraphicObject = rXBmp.aGraphicObject;
58 0 : aArraySize = rXBmp.aArraySize;
59 0 : aPixelColor = rXBmp.aPixelColor;
60 0 : aBckgrColor = rXBmp.aBckgrColor;
61 0 : bGraphicDirty = rXBmp.bGraphicDirty;
62 :
63 0 : if( rXBmp.pPixelArray )
64 : {
65 0 : if( eType == XBITMAP_8X8 )
66 : {
67 0 : pPixelArray = new sal_uInt16[ 64 ];
68 :
69 0 : for( sal_uInt16 i = 0; i < 64; i++ )
70 0 : *( pPixelArray + i ) = *( rXBmp.pPixelArray + i );
71 : }
72 : }
73 0 : }
74 :
75 0 : XOBitmap::~XOBitmap()
76 : {
77 0 : delete [] pPixelArray;
78 0 : }
79 :
80 0 : XOBitmap& XOBitmap::operator=( const XOBitmap& rXBmp )
81 : {
82 0 : eType = rXBmp.eType;
83 0 : aGraphicObject = rXBmp.aGraphicObject;
84 0 : aArraySize = rXBmp.aArraySize;
85 0 : aPixelColor = rXBmp.aPixelColor;
86 0 : aBckgrColor = rXBmp.aBckgrColor;
87 0 : bGraphicDirty = rXBmp.bGraphicDirty;
88 :
89 0 : if( rXBmp.pPixelArray )
90 : {
91 0 : if( eType == XBITMAP_8X8 )
92 : {
93 0 : pPixelArray = new sal_uInt16[ 64 ];
94 :
95 0 : for( sal_uInt16 i = 0; i < 64; i++ )
96 0 : *( pPixelArray + i ) = *( rXBmp.pPixelArray + i );
97 : }
98 : }
99 0 : return( *this );
100 : }
101 :
102 0 : int XOBitmap::operator==( const XOBitmap& rXOBitmap ) const
103 : {
104 0 : if( eType != rXOBitmap.eType ||
105 0 : aGraphicObject != rXOBitmap.aGraphicObject ||
106 0 : aArraySize != rXOBitmap.aArraySize ||
107 0 : aPixelColor != rXOBitmap.aPixelColor ||
108 0 : aBckgrColor != rXOBitmap.aBckgrColor ||
109 0 : bGraphicDirty != rXOBitmap.bGraphicDirty )
110 : {
111 0 : return( sal_False );
112 : }
113 :
114 0 : if( pPixelArray && rXOBitmap.pPixelArray )
115 : {
116 0 : sal_uInt16 nCount = (sal_uInt16) ( aArraySize.Width() * aArraySize.Height() );
117 0 : for( sal_uInt16 i = 0; i < nCount; i++ )
118 : {
119 0 : if( *( pPixelArray + i ) != *( rXOBitmap.pPixelArray + i ) )
120 0 : return( sal_False );
121 : }
122 : }
123 0 : return( sal_True );
124 : }
125 :
126 0 : Bitmap XOBitmap::GetBitmap() const
127 : {
128 0 : return GetGraphicObject().GetGraphic().GetBitmap();
129 : }
130 :
131 0 : const GraphicObject& XOBitmap::GetGraphicObject() const
132 : {
133 0 : if( bGraphicDirty )
134 0 : ( (XOBitmap*) this )->Array2Bitmap();
135 :
136 0 : return aGraphicObject;
137 : }
138 :
139 0 : void XOBitmap::Bitmap2Array()
140 : {
141 0 : VirtualDevice aVD;
142 0 : bool bPixelColor = false;
143 0 : const Bitmap aBitmap( GetBitmap() );
144 0 : const sal_uInt16 nLines = 8; // type dependent
145 :
146 0 : if( !pPixelArray )
147 0 : pPixelArray = new sal_uInt16[ nLines * nLines ];
148 :
149 0 : aVD.SetOutputSizePixel( aBitmap.GetSizePixel() );
150 0 : aVD.DrawBitmap( Point(), aBitmap );
151 0 : aPixelColor = aBckgrColor = aVD.GetPixel( Point() );
152 :
153 : // create array and determine foreground and background color
154 0 : for( sal_uInt16 i = 0; i < nLines; i++ )
155 : {
156 0 : for( sal_uInt16 j = 0; j < nLines; j++ )
157 : {
158 0 : if ( aVD.GetPixel( Point( j, i ) ) == aBckgrColor )
159 0 : *( pPixelArray + j + i * nLines ) = 0;
160 : else
161 : {
162 0 : *( pPixelArray + j + i * nLines ) = 1;
163 0 : if( !bPixelColor )
164 : {
165 0 : aPixelColor = aVD.GetPixel( Point( j, i ) );
166 0 : bPixelColor = true;
167 : }
168 : }
169 : }
170 0 : }
171 0 : }
172 :
173 : /// convert array, fore- and background color into a bitmap
174 0 : void XOBitmap::Array2Bitmap()
175 : {
176 0 : VirtualDevice aVD;
177 0 : sal_uInt16 nLines = 8; // type dependent
178 :
179 0 : if( !pPixelArray )
180 0 : return;
181 :
182 0 : aVD.SetOutputSizePixel( Size( nLines, nLines ) );
183 :
184 : // create bitmap
185 0 : for( sal_uInt16 i = 0; i < nLines; i++ )
186 : {
187 0 : for( sal_uInt16 j = 0; j < nLines; j++ )
188 : {
189 0 : if( *( pPixelArray + j + i * nLines ) == 0 )
190 0 : aVD.DrawPixel( Point( j, i ), aBckgrColor );
191 : else
192 0 : aVD.DrawPixel( Point( j, i ), aPixelColor );
193 : }
194 : }
195 :
196 0 : aGraphicObject = GraphicObject( aVD.GetBitmap( Point(), Size( nLines, nLines ) ) );
197 0 : bGraphicDirty = false;
198 : }
199 :
200 27344 : TYPEINIT1_AUTOFACTORY(XFillBitmapItem, NameOrIndex);
201 :
202 26 : XFillBitmapItem::XFillBitmapItem(const OUString& rName, const GraphicObject& rGraphicObject)
203 : : NameOrIndex(XATTR_FILLBITMAP, rName),
204 26 : maGraphicObject(rGraphicObject)
205 : {
206 26 : }
207 :
208 953 : XFillBitmapItem::XFillBitmapItem(const XFillBitmapItem& rItem)
209 : : NameOrIndex(rItem),
210 953 : maGraphicObject(rItem.maGraphicObject)
211 : {
212 953 : }
213 :
214 16 : Bitmap createHistorical8x8FromArray(const sal_uInt16* pArray, Color aColorPix, Color aColorBack)
215 : {
216 16 : BitmapPalette aPalette(2);
217 :
218 16 : aPalette[0] = BitmapColor(aColorBack);
219 16 : aPalette[1] = BitmapColor(aColorPix);
220 :
221 16 : Bitmap aBitmap(Size(8, 8), 1, &aPalette);
222 16 : BitmapWriteAccess* pContent = aBitmap.AcquireWriteAccess();
223 :
224 16 : if(pContent)
225 : {
226 144 : for(sal_uInt16 a(0); a < 8; a++)
227 : {
228 1152 : for(sal_uInt16 b(0); b < 8; b++)
229 : {
230 1024 : if(pArray[(a * 8) + b])
231 : {
232 184 : pContent->SetPixelIndex(a, b, 1);
233 : }
234 : else
235 : {
236 840 : pContent->SetPixelIndex(a, b, 0);
237 : }
238 : }
239 : }
240 :
241 16 : aBitmap.ReleaseAccess(pContent);
242 : }
243 :
244 16 : return aBitmap;
245 : }
246 :
247 0 : bool SVX_DLLPUBLIC isHistorical8x8(const BitmapEx& rBitmapEx, BitmapColor& o_rBack, BitmapColor& o_rFront)
248 : {
249 0 : if(!rBitmapEx.IsTransparent())
250 : {
251 0 : Bitmap aBitmap(rBitmapEx.GetBitmap());
252 :
253 0 : if(8 == aBitmap.GetSizePixel().Width() && 8 == aBitmap.GetSizePixel().Height())
254 : {
255 0 : if(2 == aBitmap.GetColorCount())
256 : {
257 0 : BitmapReadAccess* pRead = aBitmap.AcquireReadAccess();
258 :
259 0 : if(pRead)
260 : {
261 0 : if(pRead->HasPalette() && 2 == pRead->GetPaletteEntryCount())
262 : {
263 0 : const BitmapPalette& rPalette = pRead->GetPalette();
264 :
265 : // #i123564# bachground and foregrund were exchanged; of course
266 : // rPalette[0] is the background color
267 0 : o_rFront = rPalette[1];
268 0 : o_rBack = rPalette[0];
269 :
270 0 : return true;
271 : }
272 : }
273 : }
274 0 : }
275 : }
276 :
277 0 : return false;
278 : }
279 :
280 0 : XFillBitmapItem::XFillBitmapItem(SvStream& rIn, sal_uInt16 nVer)
281 0 : : NameOrIndex(XATTR_FILLBITMAP, rIn)
282 : {
283 0 : if (!IsIndex())
284 : {
285 0 : if(0 == nVer)
286 : {
287 : // work with the old bitmap
288 0 : Bitmap aBmp;
289 :
290 0 : ReadDIB(aBmp, rIn, true);
291 0 : maGraphicObject = Graphic(aBmp);
292 : }
293 0 : else if(1 == nVer)
294 : {
295 : sal_Int16 iTmp;
296 :
297 0 : rIn.ReadInt16( iTmp ); // former XBitmapStyle
298 0 : rIn.ReadInt16( iTmp ); // former XBitmapType
299 :
300 0 : if(XBITMAP_IMPORT == iTmp)
301 : {
302 0 : Bitmap aBmp;
303 :
304 0 : ReadDIB(aBmp, rIn, true);
305 0 : maGraphicObject = Graphic(aBmp);
306 : }
307 0 : else if(XBITMAP_8X8 == iTmp)
308 : {
309 : sal_uInt16 aArray[64];
310 :
311 0 : for(sal_uInt16 i(0); i < 64; i++)
312 : {
313 0 : rIn.ReadUInt16( aArray[i] );
314 : }
315 :
316 0 : Color aColorPix;
317 0 : Color aColorBack;
318 :
319 0 : ReadColor( rIn, aColorPix );
320 0 : ReadColor( rIn, aColorBack );
321 :
322 0 : const Bitmap aBitmap(createHistorical8x8FromArray(aArray, aColorPix, aColorBack));
323 :
324 0 : maGraphicObject = Graphic(aBitmap);
325 : }
326 : }
327 0 : else if(2 == nVer)
328 : {
329 0 : BitmapEx aBmpEx;
330 :
331 0 : ReadDIBBitmapEx(aBmpEx, rIn);
332 0 : maGraphicObject = Graphic(aBmpEx);
333 : }
334 : }
335 0 : }
336 :
337 8152 : XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/, const GraphicObject& rGraphicObject)
338 : : NameOrIndex( XATTR_FILLBITMAP, -1),
339 8152 : maGraphicObject(rGraphicObject)
340 : {
341 8152 : }
342 :
343 953 : SfxPoolItem* XFillBitmapItem::Clone(SfxItemPool* /*pPool*/) const
344 : {
345 953 : return new XFillBitmapItem(*this);
346 : }
347 :
348 2100 : bool XFillBitmapItem::operator==(const SfxPoolItem& rItem) const
349 : {
350 2100 : return (NameOrIndex::operator==(rItem)
351 2100 : && maGraphicObject == static_cast<const XFillBitmapItem&>(rItem).maGraphicObject);
352 : }
353 :
354 0 : SfxPoolItem* XFillBitmapItem::Create(SvStream& rIn, sal_uInt16 nVer) const
355 : {
356 0 : return new XFillBitmapItem( rIn, nVer );
357 : }
358 :
359 0 : SvStream& XFillBitmapItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
360 : {
361 0 : NameOrIndex::Store(rOut, nItemVersion);
362 :
363 0 : if(!IsIndex())
364 : {
365 0 : WriteDIBBitmapEx(maGraphicObject.GetGraphic().GetBitmapEx(), rOut);
366 : }
367 :
368 0 : return rOut;
369 : }
370 :
371 :
372 0 : void XFillBitmapItem::SetGraphicObject(const GraphicObject& rGraphicObject)
373 : {
374 0 : maGraphicObject = rGraphicObject;
375 0 : }
376 :
377 0 : sal_uInt16 XFillBitmapItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const
378 : {
379 0 : return(2);
380 : }
381 :
382 0 : bool XFillBitmapItem::GetPresentation(
383 : SfxItemPresentation /*ePres*/,
384 : SfxMapUnit /*eCoreUnit*/,
385 : SfxMapUnit /*ePresUnit*/,
386 : OUString& rText,
387 : const IntlWrapper*) const
388 : {
389 0 : rText += GetName();
390 0 : return true;
391 : }
392 :
393 1614 : bool XFillBitmapItem::QueryValue(::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId) const
394 : {
395 1614 : nMemberId &= ~CONVERT_TWIPS;
396 :
397 : // needed for MID_NAME
398 1614 : OUString aApiName;
399 : // needed for complete item (MID 0)
400 3228 : OUString aInternalName;
401 :
402 3228 : OUString aURL;
403 3228 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
404 :
405 1614 : if( nMemberId == MID_NAME )
406 : {
407 508 : aApiName = SvxUnogetApiNameForItem(Which(), GetName());
408 : }
409 1106 : else if( nMemberId == 0 )
410 : {
411 66 : aInternalName = GetName();
412 : }
413 :
414 1614 : if( nMemberId == MID_GRAFURL ||
415 : nMemberId == 0 )
416 : {
417 602 : aURL = UNO_NAME_GRAPHOBJ_URLPREFIX;
418 1204 : aURL += OStringToOUString(
419 602 : GetGraphicObject().GetUniqueID(),
420 602 : RTL_TEXTENCODING_ASCII_US);
421 : }
422 1614 : if( nMemberId == MID_BITMAP ||
423 : nMemberId == 0 )
424 : {
425 570 : xBmp.set(VCLUnoHelper::CreateBitmap(GetGraphicObject().GetGraphic().GetBitmapEx()));
426 : }
427 :
428 1614 : if( nMemberId == MID_NAME )
429 508 : rVal <<= aApiName;
430 1106 : else if( nMemberId == MID_GRAFURL )
431 536 : rVal <<= aURL;
432 570 : else if( nMemberId == MID_BITMAP )
433 504 : rVal <<= xBmp;
434 : else
435 : {
436 : // member-id 0 => complete item (e.g. for toolbars)
437 : DBG_ASSERT( nMemberId == 0, "invalid member-id" );
438 66 : uno::Sequence< beans::PropertyValue > aPropSeq( 3 );
439 :
440 66 : aPropSeq[0].Name = "Name";
441 66 : aPropSeq[0].Value = uno::makeAny( aInternalName );
442 66 : aPropSeq[1].Name = "FillBitmapURL";
443 66 : aPropSeq[1].Value = uno::makeAny( aURL );
444 66 : aPropSeq[2].Name = "Bitmap";
445 66 : aPropSeq[2].Value = uno::makeAny( xBmp );
446 :
447 66 : rVal <<= aPropSeq;
448 : }
449 :
450 3228 : return true;
451 : }
452 :
453 326 : bool XFillBitmapItem::PutValue( const ::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId )
454 : {
455 326 : nMemberId &= ~CONVERT_TWIPS;
456 :
457 326 : OUString aName;
458 652 : OUString aURL;
459 652 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
460 652 : ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > xGraphic;
461 :
462 326 : bool bSetName = false;
463 326 : bool bSetURL = false;
464 326 : bool bSetBitmap = false;
465 :
466 326 : if( nMemberId == MID_NAME )
467 0 : bSetName = (rVal >>= aName);
468 326 : else if( nMemberId == MID_GRAFURL )
469 260 : bSetURL = (rVal >>= aURL);
470 66 : else if( nMemberId == MID_BITMAP )
471 : {
472 0 : bSetBitmap = (rVal >>= xBmp);
473 0 : if ( !bSetBitmap )
474 0 : bSetBitmap = (rVal >>= xGraphic );
475 : }
476 : else
477 : {
478 : DBG_ASSERT( nMemberId == 0, "invalid member-id" );
479 66 : uno::Sequence< beans::PropertyValue > aPropSeq;
480 66 : if( rVal >>= aPropSeq )
481 : {
482 264 : for ( sal_Int32 n = 0; n < aPropSeq.getLength(); n++ )
483 : {
484 198 : if ( aPropSeq[n].Name == "Name" )
485 66 : bSetName = (aPropSeq[n].Value >>= aName);
486 132 : else if ( aPropSeq[n].Name == "FillBitmapURL" )
487 66 : bSetURL = (aPropSeq[n].Value >>= aURL);
488 66 : else if ( aPropSeq[n].Name == "Bitmap" )
489 66 : bSetBitmap = (aPropSeq[n].Value >>= xBmp);
490 : }
491 66 : }
492 : }
493 :
494 326 : if( bSetName )
495 : {
496 66 : SetName( aName );
497 : }
498 326 : if( bSetURL )
499 : {
500 326 : GraphicObject aGraphicObject = GraphicObject::CreateGraphicObjectFromURL(aURL);
501 326 : if( aGraphicObject.GetType() != GRAPHIC_NONE )
502 314 : maGraphicObject = aGraphicObject;
503 :
504 : // #121194# Prefer GraphicObject over bitmap object if both are provided
505 326 : if(bSetBitmap && GRAPHIC_NONE != maGraphicObject.GetType())
506 : {
507 66 : bSetBitmap = false;
508 326 : }
509 : }
510 326 : if( bSetBitmap )
511 : {
512 0 : if(xBmp.is())
513 : {
514 0 : maGraphicObject = Graphic(VCLUnoHelper::GetBitmap(xBmp));
515 : }
516 0 : else if(xGraphic.is())
517 : {
518 0 : maGraphicObject = Graphic(xGraphic);
519 : }
520 : }
521 :
522 652 : return (bSetName || bSetURL || bSetBitmap);
523 : }
524 :
525 899 : bool XFillBitmapItem::CompareValueFunc( const NameOrIndex* p1, const NameOrIndex* p2 )
526 : {
527 899 : const GraphicObject& aGraphicObjectA(static_cast<const XFillBitmapItem*>(p1)->GetGraphicObject());
528 899 : const GraphicObject& aGraphicObjectB(static_cast<const XFillBitmapItem*>(p2)->GetGraphicObject());
529 :
530 899 : return aGraphicObjectA == aGraphicObjectB;
531 : }
532 :
533 1107 : XFillBitmapItem* XFillBitmapItem::checkForUniqueItem( SdrModel* pModel ) const
534 : {
535 1107 : if( pModel )
536 : {
537 : const OUString aUniqueName = NameOrIndex::CheckNamedItem(
538 899 : this, XATTR_FILLBITMAP, &pModel->GetItemPool(),
539 1023 : pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : NULL,
540 : XFillBitmapItem::CompareValueFunc, RID_SVXSTR_BMP21,
541 2821 : pModel->GetPropertyList( XBITMAP_LIST ) );
542 :
543 : // if the given name is not valid, replace it!
544 899 : if( aUniqueName != GetName() )
545 : {
546 6 : return new XFillBitmapItem(aUniqueName, maGraphicObject);
547 893 : }
548 : }
549 :
550 1101 : return NULL;
551 651 : }
552 :
553 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|