1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/awt/XBitmap.hpp>
21 #include <com/sun/star/graphic/XGraphic.hpp>
22 #include <tools/debug.hxx>
23 #include <vcl/virdev.hxx>
24 #include <vcl/bitmapex.hxx>
25 #include <svl/style.hxx>
26 #include <editeng/memberids.h>
27 #include <svx/strings.hrc>
28 #include <svx/xtable.hxx>
29 #include <svx/xdef.hxx>
30 #include <svx/unomid.hxx>
31 #include <svx/unoapi.hxx>
32 #include <svx/svdmodel.hxx>
33 #include <svx/xbitmap.hxx>
34 #include <svx/xbtmpit.hxx>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <vcl/BitmapTools.hxx>
37 #include <vcl/GraphicLoader.hxx>
39 #include <libxml/xmlwriter.h>
41 using namespace ::com::sun::star
;
43 XOBitmap::XOBitmap( const BitmapEx
& rBmp
) :
44 xGraphicObject (new GraphicObject(rBmp
)),
45 bGraphicDirty ( false )
53 BitmapEx
XOBitmap::GetBitmap() const
55 return GetGraphicObject().GetGraphic().GetBitmapEx();
58 const GraphicObject
& XOBitmap::GetGraphicObject() const
61 const_cast<XOBitmap
*>(this)->Array2Bitmap();
63 return *xGraphicObject
;
66 void XOBitmap::Bitmap2Array()
68 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
69 bool bPixelColor
= false;
70 const BitmapEx
aBitmap( GetBitmap() );
71 const sal_Int32 nLines
= 8; // type dependent
74 pPixelArray
.reset( new sal_uInt16
[ nLines
* nLines
] );
76 pVDev
->SetOutputSizePixel( aBitmap
.GetSizePixel() );
77 pVDev
->DrawBitmapEx( Point(), aBitmap
);
78 aPixelColor
= aBckgrColor
= pVDev
->GetPixel( Point() );
80 // create array and determine foreground and background color
81 for (sal_Int32 i
= 0; i
< nLines
; ++i
)
83 for (sal_Int32 j
= 0; j
< nLines
; ++j
)
85 if ( pVDev
->GetPixel( Point( j
, i
) ) == aBckgrColor
)
86 pPixelArray
[ j
+ i
* nLines
] = 0;
89 pPixelArray
[ j
+ i
* nLines
] = 1;
92 aPixelColor
= pVDev
->GetPixel( Point( j
, i
) );
100 /// convert array, fore- and background color into a bitmap
101 void XOBitmap::Array2Bitmap()
106 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
107 const sal_Int32 nLines
= 8; // type dependent
109 pVDev
->SetOutputSizePixel( Size( nLines
, nLines
) );
112 for (sal_Int32 i
= 0; i
< nLines
; ++i
)
114 for (sal_Int32 j
= 0; j
< nLines
; ++j
)
116 if( pPixelArray
[ j
+ i
* nLines
] == 0 )
117 pVDev
->DrawPixel( Point( j
, i
), aBckgrColor
);
119 pVDev
->DrawPixel( Point( j
, i
), aPixelColor
);
123 xGraphicObject
.reset(new GraphicObject(pVDev
->GetBitmapEx(Point(), Size(nLines
, nLines
))));
124 bGraphicDirty
= false;
128 SfxPoolItem
* XFillBitmapItem::CreateDefault() { return new XFillBitmapItem
; }
130 XFillBitmapItem::XFillBitmapItem(const OUString
& rName
, const GraphicObject
& rGraphicObject
)
131 : NameOrIndex(XATTR_FILLBITMAP
, rName
),
132 maGraphicObject(rGraphicObject
)
136 XFillBitmapItem::XFillBitmapItem(const XFillBitmapItem
& rItem
)
137 : NameOrIndex(rItem
),
138 maGraphicObject(rItem
.maGraphicObject
)
142 XFillBitmapItem::XFillBitmapItem(const GraphicObject
& rGraphicObject
)
143 : NameOrIndex(XATTR_FILLBITMAP
, -1)
144 , maGraphicObject(rGraphicObject
)
148 XFillBitmapItem
* XFillBitmapItem::Clone(SfxItemPool
* /*pPool*/) const
150 return new XFillBitmapItem(*this);
153 bool XFillBitmapItem::operator==(const SfxPoolItem
& rItem
) const
155 return (NameOrIndex::operator==(rItem
)
156 && maGraphicObject
== static_cast<const XFillBitmapItem
&>(rItem
).maGraphicObject
);
160 bool XFillBitmapItem::isPattern() const
163 return vcl::bitmap::isHistorical8x8(GetGraphicObject().GetGraphic().GetBitmapEx(), aBack
, aFront
);
166 bool XFillBitmapItem::GetPresentation(
167 SfxItemPresentation
/*ePres*/,
168 MapUnit
/*eCoreUnit*/,
169 MapUnit
/*ePresUnit*/,
171 const IntlWrapper
&) const
177 bool XFillBitmapItem::QueryValue(css::uno::Any
& rVal
, sal_uInt8 nMemberId
) const
179 nMemberId
&= ~CONVERT_TWIPS
;
181 // needed for MID_NAME
183 // needed for complete item (MID 0)
184 OUString aInternalName
;
186 css::uno::Reference
< css::awt::XBitmap
> xBmp
;
188 if( nMemberId
== MID_NAME
)
190 aApiName
= SvxUnogetApiNameForItem(Which(), GetName());
192 else if( nMemberId
== 0 )
194 aInternalName
= GetName();
197 if (nMemberId
== MID_BITMAP
||
200 xBmp
.set(GetGraphicObject().GetGraphic().GetXGraphic(), uno::UNO_QUERY
);
203 if( nMemberId
== MID_NAME
)
205 else if( nMemberId
== MID_BITMAP
)
209 // member-id 0 => complete item (e.g. for toolbars)
210 DBG_ASSERT( nMemberId
== 0, "invalid member-id" );
211 uno::Sequence
< beans::PropertyValue
> aPropSeq( 2 );
213 aPropSeq
[0].Name
= "Name";
214 aPropSeq
[0].Value
<<= aInternalName
;
215 aPropSeq
[1].Name
= "Bitmap";
216 aPropSeq
[1].Value
<<= xBmp
;
224 bool XFillBitmapItem::PutValue( const css::uno::Any
& rVal
, sal_uInt8 nMemberId
)
226 nMemberId
&= ~CONVERT_TWIPS
;
230 css::uno::Reference
< css::awt::XBitmap
> xBmp
;
231 css::uno::Reference
< css::graphic::XGraphic
> xGraphic
;
233 bool bSetURL
= false;
234 bool bSetName
= false;
235 bool bSetBitmap
= false;
237 if( nMemberId
== MID_NAME
)
238 bSetName
= (rVal
>>= aName
);
239 else if( nMemberId
== MID_BITMAP
)
241 if (rVal
.has
<OUString
>())
244 aURL
= rVal
.get
<OUString
>();
246 else if (rVal
.has
<uno::Reference
<awt::XBitmap
>>())
249 xBmp
= rVal
.get
<uno::Reference
<awt::XBitmap
>>();
251 else if (rVal
.has
<uno::Reference
<graphic::XGraphic
>>())
254 xGraphic
= rVal
.get
<uno::Reference
<graphic::XGraphic
>>();
259 DBG_ASSERT( nMemberId
== 0, "invalid member-id" );
260 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
261 if( rVal
>>= aPropSeq
)
263 for ( const auto& rProp
: std::as_const(aPropSeq
) )
265 if ( rProp
.Name
== "Name" )
266 bSetName
= (rProp
.Value
>>= aName
);
267 else if ( rProp
.Name
== "Bitmap" )
268 bSetBitmap
= (rProp
.Value
>>= xBmp
);
269 else if ( rProp
.Name
== "FillBitmapURL" )
270 bSetURL
= (rProp
.Value
>>= aURL
);
279 if (bSetURL
&& !aURL
.isEmpty())
281 Graphic aGraphic
= vcl::graphic::loadFromURL(aURL
);
282 if (!aGraphic
.IsNone())
284 maGraphicObject
.SetGraphic(aGraphic
.GetXGraphic());
287 else if( bSetBitmap
)
291 xGraphic
.set(xBmp
, uno::UNO_QUERY
);
295 maGraphicObject
.SetGraphic(xGraphic
);
299 return (bSetURL
|| bSetName
|| bSetBitmap
);
302 bool XFillBitmapItem::CompareValueFunc( const NameOrIndex
* p1
, const NameOrIndex
* p2
)
304 const GraphicObject
& aGraphicObjectA(static_cast<const XFillBitmapItem
*>(p1
)->GetGraphicObject());
305 const GraphicObject
& aGraphicObjectB(static_cast<const XFillBitmapItem
*>(p2
)->GetGraphicObject());
307 return aGraphicObjectA
== aGraphicObjectB
;
310 std::unique_ptr
<XFillBitmapItem
> XFillBitmapItem::checkForUniqueItem( SdrModel
* pModel
) const
314 XPropertyListType aListType
= XPropertyListType::Bitmap
;
316 aListType
= XPropertyListType::Pattern
;
317 const OUString aUniqueName
= NameOrIndex::CheckNamedItem(
318 this, XATTR_FILLBITMAP
, &pModel
->GetItemPool(),
319 XFillBitmapItem::CompareValueFunc
, RID_SVXSTR_BMP21
,
320 pModel
->GetPropertyList( aListType
) );
322 // if the given name is not valid, replace it!
323 if( aUniqueName
!= GetName() )
325 return std::make_unique
<XFillBitmapItem
>(aUniqueName
, maGraphicObject
);
332 void XFillBitmapItem::dumpAsXml(xmlTextWriterPtr pWriter
) const
334 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("XFillBitmapItem"));
335 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
337 NameOrIndex::dumpAsXml(pWriter
);
339 (void)xmlTextWriterEndElement(pWriter
);
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */