/src/libreoffice/svx/source/xoutdev/xattrbmp.cxx
Line | Count | Source |
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 | | |
23 | | #include <comphelper/propertyvalue.hxx> |
24 | | #include <tools/debug.hxx> |
25 | | #include <vcl/virdev.hxx> |
26 | | #include <vcl/bitmap.hxx> |
27 | | #include <svl/style.hxx> |
28 | | #include <editeng/memberids.h> |
29 | | #include <svx/strings.hrc> |
30 | | #include <svx/xtable.hxx> |
31 | | #include <svx/xdef.hxx> |
32 | | #include <svx/unomid.hxx> |
33 | | #include <svx/unoapi.hxx> |
34 | | #include <svx/svdmodel.hxx> |
35 | | #include <svx/xbitmap.hxx> |
36 | | #include <svx/xbtmpit.hxx> |
37 | | #include <com/sun/star/beans/PropertyValue.hpp> |
38 | | #include <vcl/BitmapTools.hxx> |
39 | | #include <vcl/GraphicLoader.hxx> |
40 | | |
41 | | #include <libxml/xmlwriter.h> |
42 | | #include <tools/XmlWriter.hxx> |
43 | | |
44 | | using namespace ::com::sun::star; |
45 | | |
46 | | XOBitmap::XOBitmap( const Bitmap& rBmp ) : |
47 | 6.39k | m_xGraphicObject (new GraphicObject(rBmp)), |
48 | 6.39k | m_bGraphicDirty ( false ) |
49 | 6.39k | { |
50 | 6.39k | } |
51 | | |
52 | | XOBitmap::~XOBitmap() |
53 | 6.39k | { |
54 | 6.39k | } |
55 | | |
56 | | Bitmap XOBitmap::GetBitmap() const |
57 | 12.7k | { |
58 | 12.7k | return GetGraphicObject().GetGraphic().GetBitmap(); |
59 | 12.7k | } |
60 | | |
61 | | const GraphicObject& XOBitmap::GetGraphicObject() const |
62 | 12.7k | { |
63 | 12.7k | if( m_bGraphicDirty ) |
64 | 0 | const_cast<XOBitmap*>(this)->Array2Bitmap(); |
65 | | |
66 | 12.7k | return *m_xGraphicObject; |
67 | 12.7k | } |
68 | | |
69 | | void XOBitmap::Bitmap2Array() |
70 | 6.39k | { |
71 | 6.39k | ScopedVclPtrInstance< VirtualDevice > pVDev; |
72 | 6.39k | bool bPixelColor = false; |
73 | 6.39k | const Bitmap aBitmap( GetBitmap() ); |
74 | 6.39k | const sal_Int32 nLines = 8; // type dependent |
75 | | |
76 | 6.39k | if( !m_pPixelArray ) |
77 | 6.38k | m_pPixelArray.reset( new sal_uInt16[ nLines * nLines ] ); |
78 | | |
79 | 6.39k | pVDev->SetOutputSizePixel( aBitmap.GetSizePixel() ); |
80 | 6.39k | pVDev->DrawBitmap( Point(), aBitmap ); |
81 | 6.39k | m_aPixelColor = m_aBckgrColor = pVDev->GetPixel( Point() ); |
82 | | |
83 | | // create array and determine foreground and background color |
84 | 57.4k | for (sal_Int32 i = 0; i < nLines; ++i) |
85 | 51.0k | { |
86 | 459k | for (sal_Int32 j = 0; j < nLines; ++j) |
87 | 408k | { |
88 | 408k | if ( pVDev->GetPixel( Point( j, i ) ) == m_aBckgrColor ) |
89 | 378k | m_pPixelArray[ j + i * nLines ] = 0; |
90 | 29.7k | else |
91 | 29.7k | { |
92 | 29.7k | m_pPixelArray[ j + i * nLines ] = 1; |
93 | 29.7k | if( !bPixelColor ) |
94 | 6.38k | { |
95 | 6.38k | m_aPixelColor = pVDev->GetPixel( Point( j, i ) ); |
96 | 6.38k | bPixelColor = true; |
97 | 6.38k | } |
98 | 29.7k | } |
99 | 408k | } |
100 | 51.0k | } |
101 | 6.39k | } |
102 | | |
103 | | /// convert array, fore- and background color into a bitmap |
104 | | void XOBitmap::Array2Bitmap() |
105 | 6.38k | { |
106 | 6.38k | if (!m_pPixelArray) |
107 | 0 | return; |
108 | | |
109 | 6.38k | ScopedVclPtrInstance< VirtualDevice > pVDev; |
110 | 6.38k | const sal_Int32 nLines = 8; // type dependent |
111 | | |
112 | 6.38k | pVDev->SetOutputSizePixel( Size( nLines, nLines ) ); |
113 | | |
114 | | // create bitmap |
115 | 57.4k | for (sal_Int32 i = 0; i < nLines; ++i) |
116 | 51.0k | { |
117 | 459k | for (sal_Int32 j = 0; j < nLines; ++j) |
118 | 408k | { |
119 | 408k | if( m_pPixelArray[ j + i * nLines ] == 0 ) |
120 | 378k | pVDev->DrawPixel( Point( j, i ), m_aBckgrColor ); |
121 | 29.7k | else |
122 | 29.7k | pVDev->DrawPixel( Point( j, i ), m_aPixelColor ); |
123 | 408k | } |
124 | 51.0k | } |
125 | | |
126 | 6.38k | m_xGraphicObject.reset(new GraphicObject(pVDev->GetBitmap(Point(), Size(nLines, nLines)))); |
127 | 6.38k | m_bGraphicDirty = false; |
128 | 6.38k | } |
129 | | |
130 | | |
131 | 0 | SfxPoolItem* XFillBitmapItem::CreateDefault() { return new XFillBitmapItem; } |
132 | | |
133 | | XFillBitmapItem::XFillBitmapItem(const OUString& rName, const GraphicObject& rGraphicObject) |
134 | 18.7k | : NameOrIndex(XATTR_FILLBITMAP, rName), |
135 | 18.7k | maGraphicObject(rGraphicObject) |
136 | 18.7k | { |
137 | 18.7k | } |
138 | | |
139 | | XFillBitmapItem::XFillBitmapItem(const XFillBitmapItem& rItem) |
140 | 32.6k | : NameOrIndex(rItem), |
141 | 32.6k | maGraphicObject(rItem.maGraphicObject) |
142 | 32.6k | { |
143 | 32.6k | } |
144 | | |
145 | | XFillBitmapItem::XFillBitmapItem(const GraphicObject& rGraphicObject) |
146 | 181k | : NameOrIndex(XATTR_FILLBITMAP, -1) |
147 | 181k | , maGraphicObject(rGraphicObject) |
148 | 181k | { |
149 | 181k | } |
150 | | |
151 | | XFillBitmapItem* XFillBitmapItem::Clone(SfxItemPool* /*pPool*/) const |
152 | 32.6k | { |
153 | 32.6k | return new XFillBitmapItem(*this); |
154 | 32.6k | } |
155 | | |
156 | | bool XFillBitmapItem::operator==(const SfxPoolItem& rItem) const |
157 | 20.1k | { |
158 | 20.1k | return (NameOrIndex::operator==(rItem) |
159 | 11.2k | && maGraphicObject == static_cast<const XFillBitmapItem&>(rItem).maGraphicObject); |
160 | 20.1k | } |
161 | | |
162 | | |
163 | | bool XFillBitmapItem::isPattern() const |
164 | 46.8k | { |
165 | 46.8k | Color aBack, aFront; |
166 | 46.8k | return vcl::bitmap::isHistorical8x8(GetGraphicObject().GetGraphic().GetBitmap(), aBack, aFront); |
167 | 46.8k | } |
168 | | |
169 | | bool XFillBitmapItem::GetPresentation( |
170 | | SfxItemPresentation /*ePres*/, |
171 | | MapUnit /*eCoreUnit*/, |
172 | | MapUnit /*ePresUnit*/, |
173 | | OUString& rText, |
174 | | const IntlWrapper&) const |
175 | 0 | { |
176 | 0 | rText += GetName(); |
177 | 0 | return true; |
178 | 0 | } |
179 | | |
180 | | bool XFillBitmapItem::QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId) const |
181 | 1.44k | { |
182 | 1.44k | nMemberId &= ~CONVERT_TWIPS; |
183 | | |
184 | | // needed for MID_NAME |
185 | 1.44k | OUString aApiName; |
186 | | // needed for complete item (MID 0) |
187 | 1.44k | OUString aInternalName; |
188 | | |
189 | 1.44k | css::uno::Reference< css::awt::XBitmap > xBmp; |
190 | | |
191 | 1.44k | if( nMemberId == MID_NAME ) |
192 | 62 | { |
193 | 62 | aApiName = SvxUnogetApiNameForItem(Which(), GetName()); |
194 | 62 | } |
195 | 1.38k | else if( nMemberId == 0 ) |
196 | 0 | { |
197 | 0 | aInternalName = GetName(); |
198 | 0 | } |
199 | | |
200 | 1.44k | if (nMemberId == MID_BITMAP || |
201 | 62 | nMemberId == 0) |
202 | 1.38k | { |
203 | 1.38k | xBmp.set(GetGraphicObject().GetGraphic().GetXGraphic(), uno::UNO_QUERY); |
204 | 1.38k | } |
205 | | |
206 | 1.44k | if( nMemberId == MID_NAME ) |
207 | 62 | rVal <<= aApiName; |
208 | 1.38k | else if( nMemberId == MID_BITMAP ) |
209 | 1.38k | rVal <<= xBmp; |
210 | 0 | else |
211 | 0 | { |
212 | | // member-id 0 => complete item (e.g. for toolbars) |
213 | 0 | DBG_ASSERT( nMemberId == 0, "invalid member-id" ); |
214 | 0 | uno::Sequence< beans::PropertyValue > aPropSeq{ |
215 | 0 | comphelper::makePropertyValue(u"Name"_ustr, aInternalName), |
216 | 0 | comphelper::makePropertyValue(u"Bitmap"_ustr, xBmp) |
217 | 0 | }; |
218 | |
|
219 | 0 | rVal <<= aPropSeq; |
220 | 0 | } |
221 | | |
222 | 1.44k | return true; |
223 | 1.44k | } |
224 | | |
225 | | bool XFillBitmapItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) |
226 | 796 | { |
227 | 796 | nMemberId &= ~CONVERT_TWIPS; |
228 | | |
229 | 796 | OUString aName; |
230 | 796 | OUString aURL; |
231 | 796 | css::uno::Reference< css::awt::XBitmap > xBmp; |
232 | 796 | css::uno::Reference< css::graphic::XGraphic > xGraphic; |
233 | | |
234 | 796 | bool bSetURL = false; |
235 | 796 | bool bSetName = false; |
236 | 796 | bool bSetBitmap = false; |
237 | | |
238 | 796 | if( nMemberId == MID_NAME ) |
239 | 0 | bSetName = (rVal >>= aName); |
240 | 796 | else if( nMemberId == MID_BITMAP ) |
241 | 796 | { |
242 | 796 | if (rVal.has<OUString>()) |
243 | 0 | { |
244 | 0 | bSetURL = true; |
245 | 0 | aURL = rVal.get<OUString>(); |
246 | 0 | } |
247 | 796 | else if (rVal.has<uno::Reference<awt::XBitmap>>()) |
248 | 796 | { |
249 | 796 | bSetBitmap = true; |
250 | 796 | xBmp = rVal.get<uno::Reference<awt::XBitmap>>(); |
251 | 796 | } |
252 | 0 | else if (rVal.has<uno::Reference<graphic::XGraphic>>()) |
253 | 0 | { |
254 | 0 | bSetBitmap = true; |
255 | 0 | xGraphic = rVal.get<uno::Reference<graphic::XGraphic>>(); |
256 | 0 | } |
257 | 796 | } |
258 | 0 | else |
259 | 0 | { |
260 | 0 | DBG_ASSERT( nMemberId == 0, "invalid member-id" ); |
261 | 0 | uno::Sequence< beans::PropertyValue > aPropSeq; |
262 | 0 | if( rVal >>= aPropSeq ) |
263 | 0 | { |
264 | 0 | for (const auto& rProp : aPropSeq) |
265 | 0 | { |
266 | 0 | if ( rProp.Name == "Name" ) |
267 | 0 | bSetName = (rProp.Value >>= aName); |
268 | 0 | else if ( rProp.Name == "Bitmap" ) |
269 | 0 | bSetBitmap = (rProp.Value >>= xBmp); |
270 | 0 | else if ( rProp.Name == "FillBitmapURL" ) |
271 | 0 | bSetURL = (rProp.Value >>= aURL); |
272 | 0 | } |
273 | 0 | } |
274 | 0 | } |
275 | | |
276 | 796 | if( bSetName ) |
277 | 0 | { |
278 | 0 | SetName( aName ); |
279 | 0 | } |
280 | 796 | if (bSetURL && !aURL.isEmpty()) |
281 | 0 | { |
282 | 0 | Graphic aGraphic = vcl::graphic::loadFromURL(aURL); |
283 | 0 | if (!aGraphic.IsNone()) |
284 | 0 | { |
285 | 0 | maGraphicObject.SetGraphic(aGraphic.GetXGraphic()); |
286 | 0 | } |
287 | 0 | } |
288 | 796 | else if( bSetBitmap ) |
289 | 796 | { |
290 | 796 | if (xBmp.is()) |
291 | 50 | { |
292 | 50 | xGraphic.set(xBmp, uno::UNO_QUERY); |
293 | 50 | } |
294 | 796 | if (xGraphic.is()) |
295 | 50 | { |
296 | 50 | maGraphicObject.SetGraphic(xGraphic); |
297 | 50 | } |
298 | 796 | } |
299 | | |
300 | 796 | return (bSetURL || bSetName || bSetBitmap); |
301 | 796 | } |
302 | | |
303 | | bool XFillBitmapItem::CompareValueFunc( const NameOrIndex* p1, const NameOrIndex* p2 ) |
304 | 34.8k | { |
305 | 34.8k | const GraphicObject& aGraphicObjectA(static_cast<const XFillBitmapItem*>(p1)->GetGraphicObject()); |
306 | 34.8k | const GraphicObject& aGraphicObjectB(static_cast<const XFillBitmapItem*>(p2)->GetGraphicObject()); |
307 | | |
308 | 34.8k | return aGraphicObjectA == aGraphicObjectB; |
309 | 34.8k | } |
310 | | |
311 | | std::unique_ptr<XFillBitmapItem> XFillBitmapItem::checkForUniqueItem( SdrModel& rModel ) const |
312 | 46.8k | { |
313 | 46.8k | XPropertyListType aListType = XPropertyListType::Bitmap; |
314 | 46.8k | if(isPattern()) |
315 | 6.50k | aListType = XPropertyListType::Pattern; |
316 | 46.8k | const OUString aUniqueName(CheckNamedItem( |
317 | 46.8k | XATTR_FILLBITMAP, &rModel.GetItemPool(), |
318 | 46.8k | XFillBitmapItem::CompareValueFunc, RID_SVXSTR_BMP21, |
319 | 46.8k | rModel.GetPropertyList(aListType))); |
320 | | |
321 | | // if the given name is not valid, replace it! |
322 | 46.8k | if( aUniqueName != GetName() ) |
323 | 8.87k | { |
324 | 8.87k | return std::make_unique<XFillBitmapItem>(aUniqueName, maGraphicObject); |
325 | 8.87k | } |
326 | | |
327 | 37.9k | return nullptr; |
328 | 46.8k | } |
329 | | |
330 | | void XFillBitmapItem::dumpAsXml(xmlTextWriterPtr pWriter) const |
331 | 0 | { |
332 | 0 | tools::XmlWriter aWriter(pWriter); |
333 | 0 | aWriter.startElement("XFillBitmapItem"); |
334 | 0 | aWriter.attribute("whichId", Which()); |
335 | 0 | NameOrIndex::dumpAsXml(pWriter); |
336 | 0 | aWriter.endElement(); |
337 | 0 | } |
338 | | |
339 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |