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