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 : // class XFillBitmapItem
201 :
202 0 : TYPEINIT1_AUTOFACTORY(XFillBitmapItem, NameOrIndex);
203 :
204 0 : XFillBitmapItem::XFillBitmapItem(const OUString& rName, const GraphicObject& rGraphicObject)
205 : : NameOrIndex(XATTR_FILLBITMAP, rName),
206 0 : maGraphicObject(rGraphicObject)
207 : {
208 0 : }
209 :
210 0 : XFillBitmapItem::XFillBitmapItem(const XFillBitmapItem& rItem)
211 : : NameOrIndex(rItem),
212 0 : maGraphicObject(rItem.maGraphicObject)
213 : {
214 0 : }
215 :
216 0 : Bitmap createHistorical8x8FromArray(const sal_uInt16* pArray, Color aColorPix, Color aColorBack)
217 : {
218 0 : BitmapPalette aPalette(2);
219 :
220 0 : aPalette[0] = BitmapColor(aColorBack);
221 0 : aPalette[1] = BitmapColor(aColorPix);
222 :
223 0 : Bitmap aBitmap(Size(8, 8), 1, &aPalette);
224 0 : BitmapWriteAccess* pContent = aBitmap.AcquireWriteAccess();
225 :
226 0 : if(pContent)
227 : {
228 0 : for(sal_uInt16 a(0); a < 8; a++)
229 : {
230 0 : for(sal_uInt16 b(0); b < 8; b++)
231 : {
232 0 : if(pArray[(a * 8) + b])
233 : {
234 0 : pContent->SetPixelIndex(a, b, 1);
235 : }
236 : else
237 : {
238 0 : pContent->SetPixelIndex(a, b, 0);
239 : }
240 : }
241 : }
242 :
243 0 : aBitmap.ReleaseAccess(pContent);
244 : }
245 :
246 0 : return aBitmap;
247 : }
248 :
249 0 : bool SVX_DLLPUBLIC isHistorical8x8(const BitmapEx& rBitmapEx, BitmapColor& o_rBack, BitmapColor& o_rFront)
250 : {
251 0 : if(!rBitmapEx.IsTransparent())
252 : {
253 0 : Bitmap aBitmap(rBitmapEx.GetBitmap());
254 :
255 0 : if(8 == aBitmap.GetSizePixel().Width() && 8 == aBitmap.GetSizePixel().Height())
256 : {
257 0 : if(2 == aBitmap.GetColorCount())
258 : {
259 0 : BitmapReadAccess* pRead = aBitmap.AcquireReadAccess();
260 :
261 0 : if(pRead)
262 : {
263 0 : if(pRead->HasPalette() && 2 == pRead->GetPaletteEntryCount())
264 : {
265 0 : const BitmapPalette& rPalette = pRead->GetPalette();
266 :
267 : // #i123564# bachground and foregrund were exchanged; of course
268 : // rPalette[0] is the background color
269 0 : o_rFront = rPalette[1];
270 0 : o_rBack = rPalette[0];
271 :
272 0 : return true;
273 : }
274 : }
275 : }
276 0 : }
277 : }
278 :
279 0 : return false;
280 : }
281 :
282 0 : XFillBitmapItem::XFillBitmapItem(SvStream& rIn, sal_uInt16 nVer)
283 0 : : NameOrIndex(XATTR_FILLBITMAP, rIn)
284 : {
285 0 : if (!IsIndex())
286 : {
287 0 : if(0 == nVer)
288 : {
289 : // work with the old bitmap
290 0 : Bitmap aBmp;
291 :
292 0 : ReadDIB(aBmp, rIn, true);
293 0 : maGraphicObject = Graphic(aBmp);
294 : }
295 0 : else if(1 == nVer)
296 : {
297 : sal_Int16 iTmp;
298 :
299 0 : rIn.ReadInt16( iTmp ); // former XBitmapStyle
300 0 : rIn.ReadInt16( iTmp ); // former XBitmapType
301 :
302 0 : if(XBITMAP_IMPORT == iTmp)
303 : {
304 0 : Bitmap aBmp;
305 :
306 0 : ReadDIB(aBmp, rIn, true);
307 0 : maGraphicObject = Graphic(aBmp);
308 : }
309 0 : else if(XBITMAP_8X8 == iTmp)
310 : {
311 : sal_uInt16 aArray[64];
312 :
313 0 : for(sal_uInt16 i(0); i < 64; i++)
314 : {
315 0 : rIn.ReadUInt16( aArray[i] );
316 : }
317 :
318 0 : Color aColorPix;
319 0 : Color aColorBack;
320 :
321 0 : ReadColor( rIn, aColorPix );
322 0 : ReadColor( rIn, aColorBack );
323 :
324 0 : const Bitmap aBitmap(createHistorical8x8FromArray(aArray, aColorPix, aColorBack));
325 :
326 0 : maGraphicObject = Graphic(aBitmap);
327 : }
328 : }
329 0 : else if(2 == nVer)
330 : {
331 0 : BitmapEx aBmpEx;
332 :
333 0 : ReadDIBBitmapEx(aBmpEx, rIn);
334 0 : maGraphicObject = Graphic(aBmpEx);
335 : }
336 : }
337 0 : }
338 :
339 0 : XFillBitmapItem::XFillBitmapItem(SfxItemPool* /*pPool*/, const GraphicObject& rGraphicObject)
340 : : NameOrIndex( XATTR_FILLBITMAP, -1),
341 0 : maGraphicObject(rGraphicObject)
342 : {
343 0 : }
344 :
345 0 : SfxPoolItem* XFillBitmapItem::Clone(SfxItemPool* /*pPool*/) const
346 : {
347 0 : return new XFillBitmapItem(*this);
348 : }
349 :
350 0 : bool XFillBitmapItem::operator==(const SfxPoolItem& rItem) const
351 : {
352 0 : return (NameOrIndex::operator==(rItem)
353 0 : && maGraphicObject == ((const XFillBitmapItem&)rItem).maGraphicObject);
354 : }
355 :
356 0 : SfxPoolItem* XFillBitmapItem::Create(SvStream& rIn, sal_uInt16 nVer) const
357 : {
358 0 : return new XFillBitmapItem( rIn, nVer );
359 : }
360 :
361 0 : SvStream& XFillBitmapItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
362 : {
363 0 : NameOrIndex::Store(rOut, nItemVersion);
364 :
365 0 : if(!IsIndex())
366 : {
367 0 : WriteDIBBitmapEx(maGraphicObject.GetGraphic().GetBitmapEx(), rOut);
368 : }
369 :
370 0 : return rOut;
371 : }
372 :
373 0 : const GraphicObject& XFillBitmapItem::GetGraphicObject() const
374 : {
375 0 : return maGraphicObject;
376 : }
377 :
378 0 : void XFillBitmapItem::SetGraphicObject(const GraphicObject& rGraphicObject)
379 : {
380 0 : maGraphicObject = rGraphicObject;
381 0 : }
382 :
383 0 : sal_uInt16 XFillBitmapItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const
384 : {
385 0 : return(2);
386 : }
387 :
388 0 : SfxItemPresentation XFillBitmapItem::GetPresentation(
389 : SfxItemPresentation ePres,
390 : SfxMapUnit /*eCoreUnit*/,
391 : SfxMapUnit /*ePresUnit*/,
392 : OUString& rText,
393 : const IntlWrapper*) const
394 : {
395 0 : switch (ePres)
396 : {
397 : case SFX_ITEM_PRESENTATION_NONE:
398 0 : rText = OUString();
399 0 : return ePres;
400 : case SFX_ITEM_PRESENTATION_NAMELESS:
401 : case SFX_ITEM_PRESENTATION_COMPLETE:
402 0 : rText += GetName();
403 0 : return ePres;
404 : default:
405 0 : return SFX_ITEM_PRESENTATION_NONE;
406 : }
407 : }
408 :
409 0 : bool XFillBitmapItem::QueryValue(::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId) const
410 : {
411 0 : nMemberId &= ~CONVERT_TWIPS;
412 :
413 : // needed for MID_NAME
414 0 : OUString aApiName;
415 : // needed for complete item (MID 0)
416 0 : OUString aInternalName;
417 :
418 0 : OUString aURL;
419 0 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
420 :
421 0 : if( nMemberId == MID_NAME )
422 : {
423 0 : aApiName = SvxUnogetApiNameForItem(Which(), GetName());
424 : }
425 0 : else if( nMemberId == 0 )
426 : {
427 0 : aInternalName = GetName();
428 : }
429 :
430 0 : if( nMemberId == MID_GRAFURL ||
431 : nMemberId == 0 )
432 : {
433 0 : aURL = UNO_NAME_GRAPHOBJ_URLPREFIX;
434 0 : aURL += OStringToOUString(
435 0 : GetGraphicObject().GetUniqueID(),
436 0 : RTL_TEXTENCODING_ASCII_US);
437 : }
438 0 : if( nMemberId == MID_BITMAP ||
439 : nMemberId == 0 )
440 : {
441 0 : xBmp.set(VCLUnoHelper::CreateBitmap(GetGraphicObject().GetGraphic().GetBitmapEx()));
442 : }
443 :
444 0 : if( nMemberId == MID_NAME )
445 0 : rVal <<= aApiName;
446 0 : else if( nMemberId == MID_GRAFURL )
447 0 : rVal <<= aURL;
448 0 : else if( nMemberId == MID_BITMAP )
449 0 : rVal <<= xBmp;
450 : else
451 : {
452 : // member-id 0 => complete item (e.g. for toolbars)
453 : DBG_ASSERT( nMemberId == 0, "invalid member-id" );
454 0 : uno::Sequence< beans::PropertyValue > aPropSeq( 3 );
455 :
456 0 : aPropSeq[0].Name = "Name";
457 0 : aPropSeq[0].Value = uno::makeAny( aInternalName );
458 0 : aPropSeq[1].Name = "FillBitmapURL";
459 0 : aPropSeq[1].Value = uno::makeAny( aURL );
460 0 : aPropSeq[2].Name = "Bitmap";
461 0 : aPropSeq[2].Value = uno::makeAny( xBmp );
462 :
463 0 : rVal <<= aPropSeq;
464 : }
465 :
466 0 : return true;
467 : }
468 :
469 0 : bool XFillBitmapItem::PutValue( const ::com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId )
470 : {
471 0 : nMemberId &= ~CONVERT_TWIPS;
472 :
473 0 : OUString aName;
474 0 : OUString aURL;
475 0 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
476 0 : ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > xGraphic;
477 :
478 0 : bool bSetName = false;
479 0 : bool bSetURL = false;
480 0 : bool bSetBitmap = false;
481 :
482 0 : if( nMemberId == MID_NAME )
483 0 : bSetName = (rVal >>= aName);
484 0 : else if( nMemberId == MID_GRAFURL )
485 0 : bSetURL = (rVal >>= aURL);
486 0 : else if( nMemberId == MID_BITMAP )
487 : {
488 0 : bSetBitmap = (rVal >>= xBmp);
489 0 : if ( !bSetBitmap )
490 0 : bSetBitmap = (rVal >>= xGraphic );
491 : }
492 : else
493 : {
494 : DBG_ASSERT( nMemberId == 0, "invalid member-id" );
495 0 : uno::Sequence< beans::PropertyValue > aPropSeq;
496 0 : if( rVal >>= aPropSeq )
497 : {
498 0 : for ( sal_Int32 n = 0; n < aPropSeq.getLength(); n++ )
499 : {
500 0 : if ( aPropSeq[n].Name == "Name" )
501 0 : bSetName = (aPropSeq[n].Value >>= aName);
502 0 : else if ( aPropSeq[n].Name == "FillBitmapURL" )
503 0 : bSetURL = (aPropSeq[n].Value >>= aURL);
504 0 : else if ( aPropSeq[n].Name == "Bitmap" )
505 0 : bSetBitmap = (aPropSeq[n].Value >>= xBmp);
506 : }
507 0 : }
508 : }
509 :
510 0 : if( bSetName )
511 : {
512 0 : SetName( aName );
513 : }
514 0 : if( bSetURL )
515 : {
516 0 : GraphicObject aGraphicObject = GraphicObject::CreateGraphicObjectFromURL(aURL);
517 0 : if( aGraphicObject.GetType() != GRAPHIC_NONE )
518 0 : maGraphicObject = aGraphicObject;
519 :
520 : // #121194# Prefer GraphicObject over bitmap object if both are provided
521 0 : if(bSetBitmap && GRAPHIC_NONE != maGraphicObject.GetType())
522 : {
523 0 : bSetBitmap = false;
524 0 : }
525 : }
526 0 : if( bSetBitmap )
527 : {
528 0 : if(xBmp.is())
529 : {
530 0 : maGraphicObject = Graphic(VCLUnoHelper::GetBitmap(xBmp));
531 : }
532 0 : else if(xGraphic.is())
533 : {
534 0 : maGraphicObject = Graphic(xGraphic);
535 : }
536 : }
537 :
538 0 : return (bSetName || bSetURL || bSetBitmap);
539 : }
540 :
541 0 : bool XFillBitmapItem::CompareValueFunc( const NameOrIndex* p1, const NameOrIndex* p2 )
542 : {
543 0 : const GraphicObject& aGraphicObjectA(((XFillBitmapItem*)p1)->GetGraphicObject());
544 0 : const GraphicObject& aGraphicObjectB(((XFillBitmapItem*)p2)->GetGraphicObject());
545 :
546 0 : return aGraphicObjectA == aGraphicObjectB;
547 : }
548 :
549 0 : XFillBitmapItem* XFillBitmapItem::checkForUniqueItem( SdrModel* pModel ) const
550 : {
551 0 : if( pModel )
552 : {
553 : const OUString aUniqueName = NameOrIndex::CheckNamedItem(
554 0 : this, XATTR_FILLBITMAP, &pModel->GetItemPool(),
555 0 : pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : NULL,
556 : XFillBitmapItem::CompareValueFunc, RID_SVXSTR_BMP21,
557 0 : pModel->GetPropertyList( XBITMAP_LIST ) );
558 :
559 : // if the given name is not valid, replace it!
560 0 : if( aUniqueName != GetName() )
561 : {
562 0 : return new XFillBitmapItem(aUniqueName, maGraphicObject);
563 0 : }
564 : }
565 :
566 0 : return (XFillBitmapItem*)this;
567 : }
568 :
569 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|