/src/libreoffice/svx/source/sdr/primitive2d/sdrattributecreator.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 <sdr/primitive2d/sdrattributecreator.hxx> |
21 | | #include <svl/itemset.hxx> |
22 | | #include <svx/sdmetitm.hxx> |
23 | | #include <svx/sdooitm.hxx> |
24 | | #include <svx/sdprcitm.hxx> |
25 | | #include <svx/xdef.hxx> |
26 | | #include <basegfx/polygon/b2dpolygon.hxx> |
27 | | #include <svx/xlineit0.hxx> |
28 | | #include <svx/xfillit0.hxx> |
29 | | #include <svx/xflbmpit.hxx> |
30 | | #include <svx/xlntrit.hxx> |
31 | | #include <svx/xlnwtit.hxx> |
32 | | #include <svx/xlinjoit.hxx> |
33 | | #include <svx/xlncapit.hxx> |
34 | | #include <svx/xlnclit.hxx> |
35 | | #include <svx/xlnstwit.hxx> |
36 | | #include <svx/xlnedwit.hxx> |
37 | | #include <svx/xlnstit.hxx> |
38 | | #include <svx/xlnstcit.hxx> |
39 | | #include <svx/xlnedit.hxx> |
40 | | #include <svx/xlnedcit.hxx> |
41 | | #include <svx/xdash.hxx> |
42 | | #include <svx/xlndsit.hxx> |
43 | | #include <svx/xfilluseslidebackgrounditem.hxx> |
44 | | #include <svx/xfltrit.hxx> |
45 | | #include <svx/xflftrit.hxx> |
46 | | #include <svx/xflclit.hxx> |
47 | | #include <svx/xgrscit.hxx> |
48 | | #include <svx/xflhtit.hxx> |
49 | | #include <svx/xflbckit.hxx> |
50 | | #include <svx/xflbmsxy.hxx> |
51 | | #include <svx/xflbtoxy.hxx> |
52 | | #include <svx/xflboxy.hxx> |
53 | | #include <svx/xflbmtit.hxx> |
54 | | #include <svx/xflbstit.hxx> |
55 | | #include <svx/xtextit0.hxx> |
56 | | #include <RectangleAlignmentItem.hxx> |
57 | | #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx> |
58 | | #include <svx/svdotext.hxx> |
59 | | #include <sdr/attribute/sdrtextattribute.hxx> |
60 | | #include <svx/xbtmpit.hxx> |
61 | | #include <svl/itempool.hxx> |
62 | | #include <vcl/svapp.hxx> |
63 | | #include <vcl/GraphicLoader.hxx> |
64 | | #include <sfx2/objsh.hxx> |
65 | | #include <basegfx/range/b2drange.hxx> |
66 | | #include <svx/svx3ditems.hxx> |
67 | | #include <com/sun/star/drawing/ProjectionMode.hpp> |
68 | | #include <com/sun/star/drawing/ShadeMode.hpp> |
69 | | #include <drawinglayer/attribute/sdrallattribute3d.hxx> |
70 | | #include <svx/rectenum.hxx> |
71 | | #include <svx/sdtfchim.hxx> |
72 | | #include <svx/svdoutl.hxx> |
73 | | #include <svx/svdmodel.hxx> |
74 | | #include <svx/xflbmsli.hxx> |
75 | | #include <editeng/editstat.hxx> |
76 | | #include <editeng/eeitem.hxx> |
77 | | #include <editeng/fhgtitem.hxx> |
78 | | #include <editeng/editobj.hxx> |
79 | | #include <o3tl/test_info.hxx> |
80 | | #include <osl/diagnose.h> |
81 | | #include <drawinglayer/attribute/fillhatchattribute.hxx> |
82 | | #include <drawinglayer/attribute/fillgradientattribute.hxx> |
83 | | #include <sdr/attribute/sdreffectstextattribute.hxx> |
84 | | #include <sdr/attribute/sdrlineeffectstextattribute.hxx> |
85 | | #include <sdr/attribute/sdrformtextattribute.hxx> |
86 | | #include <sdr/attribute/sdrlinefilleffectstextattribute.hxx> |
87 | | #include <drawinglayer/attribute/sdrglowattribute.hxx> |
88 | | #include <drawinglayer/attribute/sdrglowtextattribute.hxx> |
89 | | #include <drawinglayer/attribute/sdrsceneattribute3d.hxx> |
90 | | #include <drawinglayer/attribute/sdrlightingattribute3d.hxx> |
91 | | #include <drawinglayer/attribute/sdrlightattribute3d.hxx> |
92 | | #include <sdr/attribute/sdrfilltextattribute.hxx> |
93 | | #include <com/sun/star/drawing/LineCap.hpp> |
94 | | |
95 | | #include <math.h> |
96 | | |
97 | | using namespace com::sun::star; |
98 | | |
99 | | namespace drawinglayer |
100 | | { |
101 | | namespace |
102 | | { |
103 | | attribute::HatchStyle XHatchStyleToHatchStyle(css::drawing::HatchStyle eStyle) |
104 | 0 | { |
105 | 0 | switch(eStyle) |
106 | 0 | { |
107 | 0 | case css::drawing::HatchStyle_SINGLE : |
108 | 0 | { |
109 | 0 | return attribute::HatchStyle::Single; |
110 | 0 | } |
111 | 0 | case css::drawing::HatchStyle_DOUBLE : |
112 | 0 | { |
113 | 0 | return attribute::HatchStyle::Double; |
114 | 0 | } |
115 | 0 | default : |
116 | 0 | { |
117 | 0 | return attribute::HatchStyle::Triple; // css::drawing::HatchStyle_TRIPLE |
118 | 0 | } |
119 | 0 | } |
120 | 0 | } |
121 | | |
122 | | basegfx::B2DLineJoin LineJointToB2DLineJoin(css::drawing::LineJoint eLineJoint) |
123 | 1.92k | { |
124 | 1.92k | switch(eLineJoint) |
125 | 1.92k | { |
126 | 0 | case css::drawing::LineJoint_BEVEL : |
127 | 0 | { |
128 | 0 | return basegfx::B2DLineJoin::Bevel; |
129 | 0 | } |
130 | 0 | case css::drawing::LineJoint_MIDDLE : |
131 | 1.33k | case css::drawing::LineJoint_MITER : |
132 | 1.33k | { |
133 | 1.33k | return basegfx::B2DLineJoin::Miter; |
134 | 0 | } |
135 | 589 | case css::drawing::LineJoint_ROUND : |
136 | 589 | { |
137 | 589 | return basegfx::B2DLineJoin::Round; |
138 | 0 | } |
139 | 0 | default : // css::drawing::LineJoint_NONE |
140 | 0 | { |
141 | 0 | return basegfx::B2DLineJoin::NONE; |
142 | 0 | } |
143 | 1.92k | } |
144 | 1.92k | } |
145 | | |
146 | | basegfx::B2DVector RectPointToB2DVector(RectPoint eRectPoint) |
147 | 0 | { |
148 | 0 | basegfx::B2DVector aRetval(0.0, 0.0); |
149 | | |
150 | | // position changes X |
151 | 0 | switch(eRectPoint) |
152 | 0 | { |
153 | 0 | case RectPoint::LT: case RectPoint::LM: case RectPoint::LB: |
154 | 0 | { |
155 | 0 | aRetval.setX(-1.0); |
156 | 0 | break; |
157 | 0 | } |
158 | | |
159 | 0 | case RectPoint::RT: case RectPoint::RM: case RectPoint::RB: |
160 | 0 | { |
161 | 0 | aRetval.setX(1.0); |
162 | 0 | break; |
163 | 0 | } |
164 | | |
165 | 0 | default : |
166 | 0 | { |
167 | 0 | break; |
168 | 0 | } |
169 | 0 | } |
170 | | |
171 | | // position changes Y |
172 | 0 | switch(eRectPoint) |
173 | 0 | { |
174 | 0 | case RectPoint::LT: case RectPoint::MT: case RectPoint::RT: |
175 | 0 | { |
176 | 0 | aRetval.setY(-1.0); |
177 | 0 | break; |
178 | 0 | } |
179 | | |
180 | 0 | case RectPoint::LB: case RectPoint::MB: case RectPoint::RB: |
181 | 0 | { |
182 | 0 | aRetval.setY(1.0); |
183 | 0 | break; |
184 | 0 | } |
185 | | |
186 | 0 | default : |
187 | 0 | { |
188 | 0 | break; |
189 | 0 | } |
190 | 0 | } |
191 | | |
192 | 0 | return aRetval; |
193 | 0 | } |
194 | | |
195 | | attribute::SdrGlowAttribute createNewSdrGlowAttribute(const SfxItemSet& rSet) |
196 | 1.99k | { |
197 | 1.99k | sal_Int32 nRadius = rSet.Get(SDRATTR_GLOW_RADIUS).GetValue(); |
198 | | |
199 | 1.99k | if (!nRadius) |
200 | 1.99k | return attribute::SdrGlowAttribute(); |
201 | | |
202 | 0 | Color aColor(rSet.Get(SDRATTR_GLOW_COLOR).GetColorValue()); |
203 | |
|
204 | 0 | sal_uInt16 nTransparency(rSet.Get(SDRATTR_GLOW_TRANSPARENCY).GetValue()); |
205 | 0 | if (nTransparency) |
206 | 0 | aColor.SetAlpha(255 - std::round(nTransparency / 100.0 * 255.0)); |
207 | |
|
208 | 0 | attribute::SdrGlowAttribute glowAttr{ nRadius, aColor }; |
209 | 0 | return glowAttr; |
210 | 1.99k | } |
211 | | |
212 | | attribute::SdrGlowTextAttribute createNewSdrGlowTextAttribute(const SfxItemSet& rSet, const OutlinerParaObject* pOutliner) |
213 | 1.99k | { |
214 | 1.99k | sal_Int32 nTextRadius = rSet.Get(SDRATTR_GLOW_TEXT_RADIUS).GetValue(); |
215 | | |
216 | 1.99k | if (!nTextRadius) |
217 | 1.99k | return attribute::SdrGlowTextAttribute(); |
218 | | |
219 | 0 | Color aTextColor(rSet.Get(SDRATTR_GLOW_TEXT_COLOR).GetColorValue()); |
220 | |
|
221 | 0 | sal_uInt16 nTextTransparency(rSet.Get(SDRATTR_GLOW_TEXT_TRANSPARENCY).GetValue()); |
222 | 0 | if (nTextTransparency) |
223 | 0 | aTextColor.SetAlpha(255 - std::round(nTextTransparency / 100.0 * 255.0)); |
224 | | |
225 | | // calculate rendering text glow radius from biggest Char size for the full text in shape |
226 | 0 | double nRadius = 0.0; |
227 | 0 | sal_uInt32 nFontSize = 0; |
228 | 0 | if (const SvxFontHeightItem* pItem = rSet.GetItemIfSet(EE_CHAR_FONTHEIGHT)) |
229 | 0 | nFontSize = pItem->GetHeight(); |
230 | |
|
231 | 0 | if (pOutliner) |
232 | 0 | { |
233 | 0 | const EditTextObject& aEdit = pOutliner->GetTextObject(); |
234 | 0 | for (sal_Int32 i = 0; i < aEdit.GetParagraphCount(); i++) |
235 | 0 | { |
236 | 0 | std::vector<EECharAttrib> aAttribs; |
237 | 0 | aEdit.GetCharAttribs(i, aAttribs); |
238 | 0 | for (const auto& attrib : aAttribs) |
239 | 0 | { |
240 | 0 | if (const SvxFontHeightItem* pFontHeight = dynamic_cast<const SvxFontHeightItem*>(attrib.pAttr)) |
241 | 0 | { |
242 | 0 | if (nFontSize < pFontHeight->GetHeight()) |
243 | 0 | nFontSize = pFontHeight->GetHeight(); |
244 | 0 | } |
245 | 0 | } |
246 | 0 | } |
247 | 0 | } |
248 | |
|
249 | 0 | if (nFontSize) |
250 | 0 | { |
251 | | // Rendering_glow_size = Original_glow_size / (154.39 * FontSize ^ -0,575) |
252 | | // This is an approximate calculation similar to MSO text glow size which is |
253 | | // depending on font size |
254 | 0 | nRadius = nTextRadius / (154.39 * pow(nFontSize, -0.575)); |
255 | 0 | nTextRadius = std::round(nRadius); |
256 | 0 | } |
257 | |
|
258 | 0 | attribute::SdrGlowTextAttribute glowTextAttr{ nTextRadius, aTextColor }; |
259 | 0 | return glowTextAttr; |
260 | 1.99k | } |
261 | | |
262 | | sal_Int32 getSoftEdgeRadius(const SfxItemSet& rSet) |
263 | 1.99k | { |
264 | 1.99k | return rSet.Get(SDRATTR_SOFTEDGE_RADIUS).GetValue(); |
265 | 1.99k | } |
266 | | } // end of anonymous namespace |
267 | | } // end of namespace drawinglayer |
268 | | |
269 | | |
270 | | namespace drawinglayer::primitive2d |
271 | | { |
272 | | attribute::SdrLineAttribute createNewSdrLineAttribute(const SfxItemSet& rSet) |
273 | 2.21k | { |
274 | 2.21k | const css::drawing::LineStyle eStyle(rSet.Get(XATTR_LINESTYLE).GetValue()); |
275 | | |
276 | 2.21k | if(drawing::LineStyle_NONE != eStyle) |
277 | 1.93k | { |
278 | 1.93k | sal_uInt16 nTransparence(rSet.Get(XATTR_LINETRANSPARENCE).GetValue()); |
279 | | |
280 | 1.93k | if(nTransparence > 100) |
281 | 7 | { |
282 | 7 | nTransparence = 100; |
283 | 7 | } |
284 | | |
285 | 1.93k | if(100 != nTransparence) |
286 | 1.92k | { |
287 | 1.92k | const sal_uInt32 nWidth(rSet.Get(XATTR_LINEWIDTH).GetValue()); |
288 | 1.92k | const Color aColor(rSet.Get(XATTR_LINECOLOR).GetColorValue()); |
289 | 1.92k | const css::drawing::LineJoint eJoint(rSet.Get(XATTR_LINEJOINT).GetValue()); |
290 | 1.92k | const css::drawing::LineCap eCap(rSet.Get(XATTR_LINECAP).GetValue()); |
291 | 1.92k | ::std::vector< double > aDotDashArray; |
292 | 1.92k | double fFullDotDashLen(0.0); |
293 | | |
294 | 1.92k | if(drawing::LineStyle_DASH == eStyle) |
295 | 6 | { |
296 | 6 | const XDash& rDash = rSet.Get(XATTR_LINEDASH).GetDashValue(); |
297 | | |
298 | 6 | if(rDash.GetDots() || rDash.GetDashes()) |
299 | 6 | { |
300 | 6 | fFullDotDashLen = rDash.CreateDotDashArray(aDotDashArray, static_cast<double>(nWidth)); |
301 | 6 | } |
302 | 6 | } |
303 | | |
304 | 1.92k | return attribute::SdrLineAttribute( |
305 | 1.92k | LineJointToB2DLineJoin(eJoint), |
306 | 1.92k | static_cast<double>(nWidth), |
307 | 1.92k | static_cast<double>(nTransparence) * 0.01, |
308 | 1.92k | aColor.getBColor(), |
309 | 1.92k | eCap, |
310 | 1.92k | std::move(aDotDashArray), |
311 | 1.92k | fFullDotDashLen); |
312 | 1.92k | } |
313 | 1.93k | } |
314 | | |
315 | 296 | return attribute::SdrLineAttribute(); |
316 | 2.21k | } |
317 | | |
318 | | attribute::SdrLineStartEndAttribute createNewSdrLineStartEndAttribute( |
319 | | const SfxItemSet& rSet, |
320 | | double fWidth) |
321 | 613 | { |
322 | 613 | const sal_Int32 nTempStartWidth(rSet.Get(XATTR_LINESTARTWIDTH).GetValue()); |
323 | 613 | const sal_Int32 nTempEndWidth(rSet.Get(XATTR_LINEENDWIDTH).GetValue()); |
324 | 613 | basegfx::B2DPolyPolygon aStartPolyPolygon; |
325 | 613 | basegfx::B2DPolyPolygon aEndPolyPolygon; |
326 | 613 | double fStartWidth(0.0); |
327 | 613 | double fEndWidth(0.0); |
328 | 613 | bool bStartActive(false); |
329 | 613 | bool bEndActive(false); |
330 | 613 | bool bStartCentered(true); |
331 | 613 | bool bEndCentered(true); |
332 | | |
333 | 613 | if(nTempStartWidth) |
334 | 613 | { |
335 | 613 | if(nTempStartWidth < 0) |
336 | 0 | { |
337 | 0 | fStartWidth = (static_cast<double>(-nTempStartWidth) * fWidth) * 0.01; |
338 | 0 | } |
339 | 613 | else |
340 | 613 | { |
341 | 613 | fStartWidth = static_cast<double>(nTempStartWidth); |
342 | 613 | } |
343 | | |
344 | 613 | if(0.0 != fStartWidth) |
345 | 613 | { |
346 | 613 | aStartPolyPolygon = rSet.Get(XATTR_LINESTART).GetLineStartValue(); |
347 | | |
348 | 613 | if(aStartPolyPolygon.count() && aStartPolyPolygon.getB2DPolygon(0).count()) |
349 | 0 | { |
350 | 0 | bStartActive = true; |
351 | 0 | bStartCentered = rSet.Get(XATTR_LINESTARTCENTER).GetValue(); |
352 | 0 | } |
353 | 613 | } |
354 | 613 | } |
355 | | |
356 | 613 | if(nTempEndWidth) |
357 | 613 | { |
358 | 613 | if(nTempEndWidth < 0) |
359 | 0 | { |
360 | 0 | fEndWidth = (static_cast<double>(-nTempEndWidth) * fWidth) * 0.01; |
361 | 0 | } |
362 | 613 | else |
363 | 613 | { |
364 | 613 | fEndWidth = static_cast<double>(nTempEndWidth); |
365 | 613 | } |
366 | | |
367 | 613 | if(0.0 != fEndWidth) |
368 | 613 | { |
369 | 613 | aEndPolyPolygon = rSet.Get(XATTR_LINEEND).GetLineEndValue(); |
370 | | |
371 | 613 | if(aEndPolyPolygon.count() && aEndPolyPolygon.getB2DPolygon(0).count()) |
372 | 0 | { |
373 | 0 | bEndActive = true; |
374 | 0 | bEndCentered = rSet.Get(XATTR_LINEENDCENTER).GetValue(); |
375 | 0 | } |
376 | 613 | } |
377 | 613 | } |
378 | | |
379 | 613 | if(bStartActive || bEndActive) |
380 | 0 | { |
381 | 0 | return attribute::SdrLineStartEndAttribute( |
382 | 0 | aStartPolyPolygon, aEndPolyPolygon, fStartWidth, fEndWidth, |
383 | 0 | bStartActive, bEndActive, bStartCentered, bEndCentered); |
384 | 0 | } |
385 | | |
386 | 613 | return attribute::SdrLineStartEndAttribute(); |
387 | 613 | } |
388 | | |
389 | | attribute::SdrShadowAttribute createNewSdrShadowAttribute(const SfxItemSet& rSet) |
390 | 1.99k | { |
391 | 1.99k | const bool bShadow(rSet.Get(SDRATTR_SHADOW).GetValue()); |
392 | | |
393 | 1.99k | if(bShadow) |
394 | 0 | { |
395 | 0 | sal_uInt16 nTransparence(rSet.Get(SDRATTR_SHADOWTRANSPARENCE).GetValue()); |
396 | |
|
397 | 0 | if(nTransparence > 100) |
398 | 0 | { |
399 | 0 | nTransparence = 100; |
400 | 0 | } |
401 | |
|
402 | 0 | if(nTransparence) |
403 | 0 | { |
404 | 0 | sal_uInt16 nFillTransparence(rSet.Get(XATTR_FILLTRANSPARENCE).GetValue()); |
405 | |
|
406 | 0 | if(nFillTransparence > 100) |
407 | 0 | { |
408 | 0 | nFillTransparence = 100; |
409 | 0 | } |
410 | |
|
411 | 0 | if(nTransparence == nFillTransparence) |
412 | 0 | { |
413 | | // shadow does not really have an own transparence, but the application |
414 | | // sets the shadow transparence equal to the object transparence for |
415 | | // convenience. This is not useful for primitive creation, so take |
416 | | // this as no shadow transparence |
417 | 0 | nTransparence = 0; |
418 | 0 | } |
419 | 0 | } |
420 | |
|
421 | 0 | if(100 != nTransparence) |
422 | 0 | { |
423 | 0 | const basegfx::B2DVector aOffset( |
424 | 0 | static_cast<double>(rSet.Get(SDRATTR_SHADOWXDIST).GetValue()), |
425 | 0 | static_cast<double>(rSet.Get(SDRATTR_SHADOWYDIST).GetValue())); |
426 | |
|
427 | 0 | const basegfx::B2DVector aSize( |
428 | 0 | static_cast<double>(rSet.Get(SDRATTR_SHADOWSIZEX).GetValue()), |
429 | 0 | static_cast<double>(rSet.Get(SDRATTR_SHADOWSIZEY).GetValue())); |
430 | |
|
431 | 0 | const Color aColor(rSet.Get(SDRATTR_SHADOWCOLOR).GetColorValue()); |
432 | |
|
433 | 0 | sal_Int32 nBlur(rSet.Get(SDRATTR_SHADOWBLUR).GetValue()); |
434 | |
|
435 | 0 | model::RectangleAlignment eAlignment{rSet.Get(SDRATTR_SHADOWALIGNMENT).GetValue()}; |
436 | |
|
437 | 0 | return attribute::SdrShadowAttribute(aOffset, aSize, static_cast<double>(nTransparence) * 0.01, nBlur, eAlignment, aColor.getBColor()); |
438 | 0 | } |
439 | 0 | } |
440 | | |
441 | 1.99k | return attribute::SdrShadowAttribute(); |
442 | 1.99k | } |
443 | | |
444 | | attribute::SdrFillAttribute createNewSdrFillAttribute(const SfxItemSet& rSet) |
445 | 119k | { |
446 | 119k | const drawing::FillStyle eStyle(rSet.Get(XATTR_FILLSTYLE).GetValue()); |
447 | | |
448 | 119k | sal_uInt16 nTransparence(rSet.Get(XATTR_FILLTRANSPARENCE).GetValue()); |
449 | | |
450 | 119k | if(nTransparence > 100) |
451 | 0 | { |
452 | 0 | nTransparence = 100; |
453 | 0 | } |
454 | | |
455 | 119k | if(drawing::FillStyle_NONE == eStyle) |
456 | 117k | { |
457 | 117k | const XFillUseSlideBackgroundItem& aBckItem(rSet.Get(XATTR_FILLUSESLIDEBACKGROUND)); |
458 | 117k | const bool bSlideBackgroundFill(aBckItem.GetValue()); |
459 | | |
460 | 117k | if(bSlideBackgroundFill) |
461 | 0 | { |
462 | | // we have SlideBackgroundFill mode, create a |
463 | | // SdrFillAttribute accordingly |
464 | 0 | return attribute::SdrFillAttribute(true); |
465 | 0 | } |
466 | 117k | } |
467 | | |
468 | 119k | if(drawing::FillStyle_NONE != eStyle) |
469 | 2.62k | { |
470 | 2.62k | if(100 != nTransparence) |
471 | 1.14k | { |
472 | | // need to check XFillFloatTransparence, object fill may still be completely transparent |
473 | 1.14k | const XFillFloatTransparenceItem* pGradientItem; |
474 | | |
475 | 1.14k | if((pGradientItem = rSet.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE, true)) |
476 | 0 | && pGradientItem->IsEnabled()) |
477 | 0 | { |
478 | 0 | const basegfx::BGradient& rGradient = pGradientItem->GetGradientValue(); |
479 | 0 | basegfx::BColor aSingleColor; |
480 | 0 | const bool bSingleColor(rGradient.GetColorStops().isSingleColor(aSingleColor)); |
481 | 0 | const bool bCompletelyTransparent(bSingleColor && basegfx::fTools::equal(aSingleColor.luminance(), 1.0)); |
482 | |
|
483 | 0 | if(bCompletelyTransparent) |
484 | 0 | { |
485 | 0 | nTransparence = 100; |
486 | 0 | } |
487 | 0 | } |
488 | 1.14k | } |
489 | | |
490 | 2.62k | if(100 != nTransparence) |
491 | 1.14k | { |
492 | 1.14k | const Color aColor(rSet.Get(XATTR_FILLCOLOR).GetColorValue()); |
493 | 1.14k | attribute::FillGradientAttribute aGradient; |
494 | 1.14k | attribute::FillHatchAttribute aHatch; |
495 | 1.14k | attribute::SdrFillGraphicAttribute aFillGraphic; |
496 | | |
497 | 1.14k | switch(eStyle) |
498 | 1.14k | { |
499 | 1.14k | default: |
500 | 1.14k | { |
501 | | // nothing to do, color is defined |
502 | 1.14k | break; |
503 | 0 | } |
504 | 0 | case drawing::FillStyle_GRADIENT : |
505 | 0 | { |
506 | 0 | basegfx::BGradient aBGradient(rSet.Get(XATTR_FILLGRADIENT).GetGradientValue()); |
507 | 0 | basegfx::BColorStops aColorStops(aBGradient.GetColorStops()); |
508 | | |
509 | |
|
510 | 0 | if (aBGradient.GetStartIntens() != 100 || aBGradient.GetEndIntens() != 100) |
511 | 0 | { |
512 | | // Need to do the (old, crazy) blend against black for a |
513 | | // used intensity, but now for all ColorStops relative to their |
514 | | // offsets, where 0 means black and 100 means original color |
515 | 0 | aColorStops.blendToIntensity( |
516 | 0 | aBGradient.GetStartIntens() * 0.01, |
517 | 0 | aBGradient.GetEndIntens() * 0.01, |
518 | 0 | basegfx::BColor()); // COL_BLACK |
519 | 0 | } |
520 | |
|
521 | 0 | aGradient = attribute::FillGradientAttribute( |
522 | 0 | aBGradient.GetGradientStyle(), |
523 | 0 | static_cast<double>(aBGradient.GetBorder()) * 0.01, |
524 | 0 | static_cast<double>(aBGradient.GetXOffset()) * 0.01, |
525 | 0 | static_cast<double>(aBGradient.GetYOffset()) * 0.01, |
526 | 0 | toRadians(aBGradient.GetAngle()), |
527 | 0 | aColorStops, |
528 | 0 | rSet.Get(XATTR_GRADIENTSTEPCOUNT).GetValue()); |
529 | |
|
530 | 0 | break; |
531 | 0 | } |
532 | 0 | case drawing::FillStyle_HATCH : |
533 | 0 | { |
534 | 0 | const XHatch& rHatch(rSet.Get(XATTR_FILLHATCH).GetHatchValue()); |
535 | 0 | const Color aColorB(rHatch.GetColor()); |
536 | |
|
537 | 0 | aHatch = attribute::FillHatchAttribute( |
538 | 0 | XHatchStyleToHatchStyle(rHatch.GetHatchStyle()), |
539 | 0 | static_cast<double>(rHatch.GetDistance()), |
540 | 0 | toRadians(rHatch.GetAngle()), |
541 | 0 | aColorB.getBColor(), |
542 | 0 | 3, // same default as VCL, a minimum of three discrete units (pixels) offset |
543 | 0 | rSet.Get(XATTR_FILLBACKGROUND).GetValue()); |
544 | |
|
545 | 0 | break; |
546 | 0 | } |
547 | 0 | case drawing::FillStyle_BITMAP : |
548 | 0 | { |
549 | 0 | aFillGraphic = createNewSdrFillGraphicAttribute(rSet); |
550 | 0 | break; |
551 | 0 | } |
552 | 1.14k | } |
553 | | |
554 | 1.14k | return attribute::SdrFillAttribute( |
555 | 1.14k | static_cast<double>(nTransparence) * 0.01, |
556 | 1.14k | aColor.getBColor(), |
557 | 1.14k | aGradient, |
558 | 1.14k | aHatch, |
559 | 1.14k | aFillGraphic); |
560 | 1.14k | } |
561 | 2.62k | } |
562 | | |
563 | 118k | if(nTransparence == 100) |
564 | 1.47k | { |
565 | 1.47k | attribute::FillGradientAttribute aGradient; |
566 | 1.47k | attribute::FillHatchAttribute aHatch; |
567 | 1.47k | attribute::SdrFillGraphicAttribute aFillGraphic; |
568 | 1.47k | return attribute::SdrFillAttribute( |
569 | 1.47k | 1, |
570 | 1.47k | basegfx::BColor( 0, 0, 0 ), |
571 | 1.47k | aGradient, |
572 | 1.47k | aHatch, |
573 | 1.47k | aFillGraphic); |
574 | 1.47k | } |
575 | | |
576 | 117k | return attribute::SdrFillAttribute(); |
577 | 118k | } |
578 | | |
579 | | // #i101508# Support handing over given text-to-border distances |
580 | | attribute::SdrTextAttribute createNewSdrTextAttribute( |
581 | | const SfxItemSet& rSet, |
582 | | const SdrText& rText, |
583 | | const sal_Int32* pLeft, |
584 | | const sal_Int32* pUpper, |
585 | | const sal_Int32* pRight, |
586 | | const sal_Int32* pLower) |
587 | 3.40k | { |
588 | 3.40k | const SdrTextObj& rTextObj = rText.GetObject(); |
589 | | |
590 | | // Save chaining attributes |
591 | 3.40k | bool bChainable = rTextObj.IsChainable(); |
592 | | |
593 | | // get OutlinerParaObject |
594 | 3.40k | std::optional<OutlinerParaObject> aOutlinerParaObject; |
595 | | |
596 | | // 1st try to get from rText |
597 | 3.40k | if(rText.GetOutlinerParaObject()) |
598 | 663 | { |
599 | 663 | aOutlinerParaObject.emplace(*rText.GetOutlinerParaObject()); |
600 | 663 | } |
601 | | |
602 | | // added TextEdit text suppression - check if rText is in EditMode |
603 | 3.40k | bool bInEditMode(false); |
604 | | |
605 | 3.40k | if(rText.GetObject().getTextCount() > 1) |
606 | 0 | { |
607 | 0 | bInEditMode = rTextObj.IsInEditMode() && rText.GetObject().getActiveText() == &rText; |
608 | 0 | } |
609 | 3.40k | else |
610 | 3.40k | { |
611 | 3.40k | bInEditMode = rTextObj.IsInEditMode(); |
612 | 3.40k | } |
613 | | |
614 | 3.40k | if(bInEditMode) |
615 | 0 | { |
616 | | // if yes, try to get OutlinerParaObject from active TextEdit |
617 | 0 | std::optional<OutlinerParaObject> aTextEditOutlinerParaObject(rTextObj.CreateEditOutlinerParaObject()); |
618 | |
|
619 | 0 | if (aTextEditOutlinerParaObject) |
620 | 0 | { |
621 | | // if we got one, prefer text from active TextEdit |
622 | 0 | aOutlinerParaObject = std::move(aTextEditOutlinerParaObject); |
623 | 0 | } |
624 | 0 | } |
625 | | |
626 | 3.40k | if(aOutlinerParaObject) |
627 | 663 | { |
628 | 663 | const SdrTextAniKind eAniKind(rTextObj.GetTextAniKind()); |
629 | | |
630 | | // #i107346# |
631 | 663 | const SdrOutliner& rDrawTextOutliner(rText.GetObject().getSdrModelFromSdrObject().GetDrawOutliner(&rTextObj)); |
632 | 663 | const bool bWrongSpell(rDrawTextOutliner.GetControlWord() & EEControlBits::ONLINESPELLING); |
633 | | |
634 | 663 | return attribute::SdrTextAttribute( |
635 | 663 | rText, |
636 | 663 | *aOutlinerParaObject, |
637 | 663 | rSet.Get(XATTR_FORMTXTSTYLE).GetValue(), |
638 | 663 | pLeft ? *pLeft : rTextObj.GetTextLeftDistance(), |
639 | 663 | pUpper ? *pUpper : rTextObj.GetTextUpperDistance(), |
640 | 663 | pRight ? *pRight : rTextObj.GetTextRightDistance(), |
641 | 663 | pLower ? *pLower : rTextObj.GetTextLowerDistance(), |
642 | 663 | rTextObj.GetTextHorizontalAdjust(rSet), |
643 | 663 | rTextObj.GetTextVerticalAdjust(rSet), |
644 | 663 | rSet.Get(SDRATTR_TEXT_CONTOURFRAME).GetValue(), |
645 | 663 | rTextObj.IsFitToSize(), |
646 | 663 | rTextObj.IsAutoFit(), |
647 | 663 | rSet.Get(XATTR_FORMTXTHIDEFORM).GetValue(), |
648 | 663 | SdrTextAniKind::Blink == eAniKind, |
649 | 663 | SdrTextAniKind::Scroll == eAniKind || SdrTextAniKind::Alternate == eAniKind || SdrTextAniKind::Slide == eAniKind, |
650 | 663 | bInEditMode, |
651 | 663 | rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT).GetValue(), |
652 | 663 | bWrongSpell, |
653 | 663 | bChainable); |
654 | 663 | } |
655 | | |
656 | 2.73k | return attribute::SdrTextAttribute(); |
657 | 3.40k | } |
658 | | |
659 | | attribute::FillGradientAttribute createNewTransparenceGradientAttribute(const SfxItemSet& rSet) |
660 | 119k | { |
661 | 119k | const XFillFloatTransparenceItem* pGradientItem; |
662 | | |
663 | 119k | if((pGradientItem = rSet.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE)) |
664 | 147 | && pGradientItem->IsEnabled()) |
665 | 0 | { |
666 | | // test if float transparency is completely transparent |
667 | 0 | const basegfx::BGradient& rGradient(pGradientItem->GetGradientValue()); |
668 | 0 | basegfx::BColor aSingleColor; |
669 | 0 | const bool bSingleColor(rGradient.GetColorStops().isSingleColor(aSingleColor)); |
670 | 0 | const bool bCompletelyTransparent(bSingleColor && basegfx::fTools::equal(aSingleColor.luminance(), 1.0)); |
671 | 0 | const bool bNotTransparent(bSingleColor && basegfx::fTools::equalZero(aSingleColor.luminance())); |
672 | | |
673 | | // create nothing when completely transparent: This case is already checked for the |
674 | | // normal fill attributes, XFILL_NONE will be used. |
675 | | // create nothing when not transparent: use normal fill, no need t create a FillGradientAttribute. |
676 | | // Both cases are optimizations, always creating FillGradientAttribute will work, too |
677 | 0 | if (!bNotTransparent && !bCompletelyTransparent) |
678 | 0 | { |
679 | 0 | basegfx::BColorStops aColorStops(rGradient.GetColorStops()); |
680 | |
|
681 | 0 | if (rGradient.GetStartIntens() != 100 || rGradient.GetEndIntens() != 100) |
682 | 0 | { |
683 | | // tdf#155913 Start/EndIntens is not used for transparency gradient, |
684 | | // so might even get asserted (?) |
685 | | // this may also be set for transparence, so need to take care of it |
686 | 0 | aColorStops.blendToIntensity( |
687 | 0 | rGradient.GetStartIntens() * 0.01, |
688 | 0 | rGradient.GetEndIntens() * 0.01, |
689 | 0 | basegfx::BColor()); // COL_BLACK |
690 | 0 | } |
691 | | |
692 | | // tdf#155913 GradientStepCount is not used for transparency gradient |
693 | 0 | return attribute::FillGradientAttribute( |
694 | 0 | rGradient.GetGradientStyle(), |
695 | 0 | static_cast<double>(rGradient.GetBorder()) * 0.01, |
696 | 0 | static_cast<double>(rGradient.GetXOffset()) * 0.01, |
697 | 0 | static_cast<double>(rGradient.GetYOffset()) * 0.01, |
698 | 0 | toRadians(rGradient.GetAngle()), |
699 | 0 | aColorStops); |
700 | 0 | } |
701 | 0 | } |
702 | | |
703 | 119k | return attribute::FillGradientAttribute(); |
704 | 119k | } |
705 | | |
706 | | attribute::SdrFillGraphicAttribute createNewSdrFillGraphicAttribute(const SfxItemSet& rSet) |
707 | 0 | { |
708 | 0 | Graphic aGraphic(rSet.Get(XATTR_FILLBITMAP).GetGraphicObject().GetGraphic()); |
709 | |
|
710 | 0 | OUString aOriginURL = aGraphic.getOriginURL(); |
711 | 0 | if (aGraphic.GetType() == GraphicType::Default && !aOriginURL.isEmpty()) |
712 | 0 | { |
713 | 0 | SfxObjectShell* pSh = SfxObjectShell::Current(); |
714 | 0 | if (pSh && pSh->GetEmbeddedObjectContainer().getUserAllowsLinkUpdate()) |
715 | 0 | { |
716 | 0 | assert(!o3tl::IsRunningUnitTest() |
717 | 0 | && "createNewSdrFillGraphicAttribute: unexpected remote graphic" |
718 | 0 | " fetch during unit test"); |
719 | 0 | aGraphic = vcl::graphic::loadFromURL(aGraphic.getOriginURL()); |
720 | 0 | aGraphic.setOriginURL(aOriginURL); |
721 | 0 | } |
722 | 0 | } |
723 | |
|
724 | 0 | if(GraphicType::Bitmap != aGraphic.GetType() && GraphicType::GdiMetafile != aGraphic.GetType()) |
725 | 0 | { |
726 | | // no content if not bitmap or metafile |
727 | 0 | OSL_ENSURE(false, "No fill graphic in SfxItemSet (!)"); |
728 | 0 | return attribute::SdrFillGraphicAttribute(); |
729 | 0 | } |
730 | | |
731 | 0 | Size aPrefSize(aGraphic.GetPrefSize()); |
732 | |
|
733 | 0 | if(!aPrefSize.Width() || !aPrefSize.Height()) |
734 | 0 | { |
735 | | // if there is no logical size, create a size from pixel size and set MapMode accordingly |
736 | 0 | if(GraphicType::Bitmap == aGraphic.GetType()) |
737 | 0 | { |
738 | 0 | aGraphic.SetPrefSize(aGraphic.GetBitmap().GetSizePixel()); |
739 | 0 | aGraphic.SetPrefMapMode(MapMode(MapUnit::MapPixel)); |
740 | 0 | aPrefSize = aGraphic.GetPrefSize(); |
741 | 0 | } |
742 | 0 | } |
743 | |
|
744 | 0 | if(!aPrefSize.Width() || !aPrefSize.Height()) |
745 | 0 | { |
746 | | // no content if no size |
747 | 0 | OSL_ENSURE(false, "Graphic has no size in SfxItemSet (!)"); |
748 | 0 | return attribute::SdrFillGraphicAttribute(); |
749 | 0 | } |
750 | | |
751 | | // convert size and MapMode to destination logical size and MapMode |
752 | 0 | const MapUnit aDestinationMapUnit(rSet.GetPool()->GetMetric(0)); |
753 | 0 | basegfx::B2DVector aGraphicLogicSize(aGraphic.GetPrefSize().Width(), aGraphic.GetPrefSize().Height()); |
754 | |
|
755 | 0 | if (aGraphic.GetPrefMapMode().GetMapUnit() != aDestinationMapUnit) |
756 | 0 | { |
757 | | // #i100360# for MapUnit::MapPixel, LogicToLogic will not work properly, |
758 | | // so fallback to Application::GetDefaultDevice() |
759 | 0 | Size aNewSize(0, 0); |
760 | |
|
761 | 0 | if(MapUnit::MapPixel == aGraphic.GetPrefMapMode().GetMapUnit()) |
762 | 0 | { |
763 | 0 | aNewSize = Application::GetDefaultDevice()->PixelToLogic( |
764 | 0 | aGraphic.GetPrefSize(), |
765 | 0 | MapMode(aDestinationMapUnit)); |
766 | 0 | } |
767 | 0 | else |
768 | 0 | { |
769 | 0 | aNewSize = OutputDevice::LogicToLogic( |
770 | 0 | aGraphic.GetPrefSize(), |
771 | 0 | aGraphic.GetPrefMapMode(), |
772 | 0 | MapMode(aDestinationMapUnit)); |
773 | 0 | } |
774 | | |
775 | | // #i124002# do not set new size using SetPrefSize at the graphic, this will lead to problems. |
776 | | // Instead, adapt the GraphicLogicSize which will be used for further decompositions |
777 | 0 | aGraphicLogicSize = basegfx::B2DVector(aNewSize.Width(), aNewSize.Height()); |
778 | 0 | } |
779 | | |
780 | | // get size |
781 | 0 | const basegfx::B2DVector aSize( |
782 | 0 | static_cast<double>(rSet.Get(XATTR_FILLBMP_SIZEX).GetValue()), |
783 | 0 | static_cast<double>(rSet.Get(XATTR_FILLBMP_SIZEY).GetValue())); |
784 | 0 | const basegfx::B2DVector aOffset( |
785 | 0 | static_cast<double>(rSet.Get(XATTR_FILLBMP_TILEOFFSETX).GetValue()), |
786 | 0 | static_cast<double>(rSet.Get(XATTR_FILLBMP_TILEOFFSETY).GetValue())); |
787 | 0 | const basegfx::B2DVector aOffsetPosition( |
788 | 0 | static_cast<double>(rSet.Get(XATTR_FILLBMP_POSOFFSETX).GetValue()), |
789 | 0 | static_cast<double>(rSet.Get(XATTR_FILLBMP_POSOFFSETY).GetValue())); |
790 | |
|
791 | 0 | return attribute::SdrFillGraphicAttribute( |
792 | 0 | aGraphic, |
793 | 0 | aGraphicLogicSize, |
794 | 0 | aSize, |
795 | 0 | aOffset, |
796 | 0 | aOffsetPosition, |
797 | 0 | RectPointToB2DVector(rSet.GetItem<XFillBmpPosItem>(XATTR_FILLBMP_POS)->GetValue()), |
798 | 0 | rSet.Get(XATTR_FILLBMP_TILE).GetValue(), |
799 | 0 | rSet.Get(XATTR_FILLBMP_STRETCH).GetValue(), |
800 | 0 | rSet.Get(XATTR_FILLBMP_SIZELOG).GetValue()); |
801 | 0 | } |
802 | | |
803 | | attribute::SdrEffectsTextAttribute createNewSdrEffectsTextAttribute( |
804 | | const SfxItemSet& rSet, |
805 | | const SdrText* pText, |
806 | | bool bSuppressText) |
807 | 1.28k | { |
808 | 1.28k | attribute::SdrTextAttribute aText; |
809 | | |
810 | | // #i98072# added option to suppress text |
811 | | // look for text first |
812 | 1.28k | if(!bSuppressText && pText) |
813 | 1.28k | { |
814 | 1.28k | aText = createNewSdrTextAttribute(rSet, *pText); |
815 | 1.28k | } |
816 | | |
817 | | // try shadow |
818 | 1.28k | const attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet)); |
819 | 1.28k | const attribute::SdrGlowAttribute aGlow(createNewSdrGlowAttribute(rSet)); |
820 | 1.28k | const OutlinerParaObject* pOutliner = pText ? pText->GetObject().GetOutlinerParaObject() : nullptr; |
821 | 1.28k | const attribute::SdrGlowTextAttribute aGlowText(createNewSdrGlowTextAttribute(rSet, pOutliner)); |
822 | 1.28k | const sal_Int32 nSoftEdgeRadius(getSoftEdgeRadius(rSet)); |
823 | | |
824 | 1.28k | return attribute::SdrEffectsTextAttribute(aShadow, std::move(aText), |
825 | 1.28k | aGlow, aGlowText, nSoftEdgeRadius); |
826 | 1.28k | } |
827 | | |
828 | | attribute::SdrLineEffectsTextAttribute createNewSdrLineEffectsTextAttribute( |
829 | | const SfxItemSet& rSet, |
830 | | const SdrText* pText) |
831 | 0 | { |
832 | 0 | attribute::SdrLineAttribute aLine; |
833 | 0 | attribute::SdrLineStartEndAttribute aLineStartEnd; |
834 | 0 | attribute::SdrTextAttribute aText; |
835 | 0 | bool bFontworkHideContour(false); |
836 | | |
837 | | // look for text first |
838 | 0 | if(pText) |
839 | 0 | { |
840 | 0 | aText = createNewSdrTextAttribute(rSet, *pText); |
841 | | |
842 | | // when object has text and text is fontwork and hide contour is set for fontwork, force |
843 | | // line and fill style to empty |
844 | 0 | if(!aText.isDefault() |
845 | 0 | && !aText.getSdrFormTextAttribute().isDefault() |
846 | 0 | && aText.isHideContour()) |
847 | 0 | { |
848 | 0 | bFontworkHideContour = true; |
849 | 0 | } |
850 | 0 | } |
851 | | |
852 | | // try line style |
853 | 0 | if(!bFontworkHideContour) |
854 | 0 | { |
855 | 0 | aLine = createNewSdrLineAttribute(rSet); |
856 | |
|
857 | 0 | if(!aLine.isDefault()) |
858 | 0 | { |
859 | | // try LineStartEnd |
860 | 0 | aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth()); |
861 | 0 | } |
862 | 0 | } |
863 | |
|
864 | 0 | if(!aLine.isDefault() || !aText.isDefault()) |
865 | 0 | { |
866 | | // try shadow |
867 | 0 | attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet)); |
868 | 0 | attribute::SdrGlowAttribute aGlow = createNewSdrGlowAttribute(rSet); |
869 | 0 | const OutlinerParaObject* pOutliner = pText ? pText->GetObject().GetOutlinerParaObject() : nullptr; |
870 | 0 | attribute::SdrGlowTextAttribute aGlowText = createNewSdrGlowTextAttribute(rSet, pOutliner); |
871 | 0 | const sal_Int32 nSoftEdgeRadius(getSoftEdgeRadius(rSet)); |
872 | |
|
873 | 0 | return attribute::SdrLineEffectsTextAttribute(std::move(aLine), |
874 | 0 | std::move(aLineStartEnd), |
875 | 0 | std::move(aShadow), |
876 | 0 | std::move(aText), |
877 | 0 | std::move(aGlow), |
878 | 0 | std::move(aGlowText), nSoftEdgeRadius); |
879 | 0 | } |
880 | | |
881 | 0 | return attribute::SdrLineEffectsTextAttribute(); |
882 | 0 | } |
883 | | |
884 | | attribute::SdrLineFillEffectsTextAttribute createNewSdrLineFillEffectsTextAttribute( |
885 | | const SfxItemSet& rSet, |
886 | | const SdrText* pText, |
887 | | bool bHasContent, |
888 | | bool bSuppressShadow) |
889 | 717 | { |
890 | 717 | attribute::SdrLineAttribute aLine; |
891 | 717 | attribute::SdrFillAttribute aFill; |
892 | 717 | attribute::SdrLineStartEndAttribute aLineStartEnd; |
893 | 717 | attribute::FillGradientAttribute aFillFloatTransGradient; |
894 | 717 | attribute::SdrTextAttribute aText; |
895 | 717 | bool bFontworkHideContour(false); |
896 | | |
897 | | // look for text first |
898 | 717 | if(pText) |
899 | 717 | { |
900 | 717 | aText = createNewSdrTextAttribute(rSet, *pText); |
901 | | |
902 | | // when object has text and text is fontwork and hide contour is set for fontwork, force |
903 | | // line and fill style to empty |
904 | 717 | if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour()) |
905 | 0 | { |
906 | 0 | bFontworkHideContour = true; |
907 | 0 | } |
908 | 717 | } |
909 | | |
910 | 717 | if(!bFontworkHideContour) |
911 | 717 | { |
912 | | // try line style |
913 | 717 | aLine = createNewSdrLineAttribute(rSet); |
914 | | |
915 | 717 | if(!aLine.isDefault()) |
916 | 603 | { |
917 | | // try LineStartEnd |
918 | 603 | aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth()); |
919 | 603 | } |
920 | | |
921 | | // try fill style |
922 | 717 | aFill = createNewSdrFillAttribute(rSet); |
923 | | |
924 | 717 | if(!aFill.isDefault()) |
925 | 477 | { |
926 | | // try fillfloattransparence |
927 | 477 | aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet); |
928 | 477 | } |
929 | 717 | } |
930 | | |
931 | | // bHasContent is used from OLE and graphic objects. Normally a possible shadow |
932 | | // depends on line, fill or text to be set, but for these objects it is possible |
933 | | // to have none of these, but still content which needs to have a shadow (if set), |
934 | | // so shadow needs to be tried |
935 | 717 | if(bHasContent || !aLine.isDefault() || !aFill.isDefault() || !aText.isDefault()) |
936 | 717 | { |
937 | | // try shadow |
938 | 717 | const attribute::SdrShadowAttribute aShadow = !bSuppressShadow ? |
939 | 717 | createNewSdrShadowAttribute(rSet) : attribute::SdrShadowAttribute(); |
940 | | |
941 | | // glow |
942 | 717 | const attribute::SdrGlowAttribute aGlow = createNewSdrGlowAttribute(rSet); |
943 | | |
944 | | // text glow |
945 | 717 | const OutlinerParaObject* pOutliner = pText ? pText->GetObject().GetOutlinerParaObject() : nullptr; |
946 | 717 | const attribute::SdrGlowTextAttribute aGlowText = createNewSdrGlowTextAttribute(rSet, pOutliner); |
947 | | |
948 | 717 | const sal_Int32 nSoftEdgeRadius(getSoftEdgeRadius(rSet)); |
949 | | |
950 | 717 | return attribute::SdrLineFillEffectsTextAttribute(aLine, std::move(aFill), aLineStartEnd, |
951 | 717 | aShadow, std::move(aFillFloatTransGradient), |
952 | 717 | aText, aGlow, aGlowText, nSoftEdgeRadius); |
953 | 717 | } |
954 | | |
955 | 0 | return attribute::SdrLineFillEffectsTextAttribute(); |
956 | 717 | } |
957 | | |
958 | | attribute::SdrLineFillShadowAttribute3D createNewSdrLineFillShadowAttribute(const SfxItemSet& rSet, bool bSuppressFill) |
959 | 0 | { |
960 | 0 | attribute::SdrFillAttribute aFill; |
961 | 0 | attribute::SdrLineStartEndAttribute aLineStartEnd; |
962 | 0 | attribute::SdrShadowAttribute aShadow; |
963 | 0 | attribute::FillGradientAttribute aFillFloatTransGradient; |
964 | | |
965 | | // try line style |
966 | 0 | attribute::SdrLineAttribute aLine(createNewSdrLineAttribute(rSet)); |
967 | |
|
968 | 0 | if(!aLine.isDefault()) |
969 | 0 | { |
970 | | // try LineStartEnd |
971 | 0 | aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth()); |
972 | 0 | } |
973 | | |
974 | | // try fill style |
975 | 0 | if(!bSuppressFill) |
976 | 0 | { |
977 | 0 | aFill = createNewSdrFillAttribute(rSet); |
978 | |
|
979 | 0 | if(!aFill.isDefault()) |
980 | 0 | { |
981 | | // try fillfloattransparence |
982 | 0 | aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet); |
983 | 0 | } |
984 | 0 | } |
985 | |
|
986 | 0 | if(!aLine.isDefault() || !aFill.isDefault()) |
987 | 0 | { |
988 | | // try shadow |
989 | 0 | aShadow = createNewSdrShadowAttribute(rSet); |
990 | |
|
991 | 0 | return attribute::SdrLineFillShadowAttribute3D( |
992 | 0 | std::move(aLine), std::move(aFill), std::move(aLineStartEnd), |
993 | 0 | std::move(aShadow), std::move(aFillFloatTransGradient)); |
994 | 0 | } |
995 | | |
996 | 0 | return attribute::SdrLineFillShadowAttribute3D(); |
997 | 0 | } |
998 | | |
999 | | attribute::SdrSceneAttribute createNewSdrSceneAttribute(const SfxItemSet& rSet) |
1000 | 0 | { |
1001 | | // get perspective |
1002 | 0 | css::drawing::ProjectionMode aProjectionMode(css::drawing::ProjectionMode_PARALLEL); |
1003 | 0 | const sal_uInt16 nProjectionValue(rSet.Get(SDRATTR_3DSCENE_PERSPECTIVE).GetValue()); |
1004 | |
|
1005 | 0 | if(1 == nProjectionValue) |
1006 | 0 | { |
1007 | 0 | aProjectionMode = css::drawing::ProjectionMode_PERSPECTIVE; |
1008 | 0 | } |
1009 | | |
1010 | | // get distance |
1011 | 0 | const double fDistance(rSet.Get(SDRATTR_3DSCENE_DISTANCE).GetValue()); |
1012 | | |
1013 | | // get shadow slant |
1014 | 0 | const double fShadowSlant( |
1015 | 0 | basegfx::deg2rad(rSet.Get(SDRATTR_3DSCENE_SHADOW_SLANT).GetValue())); |
1016 | | |
1017 | | // get shade mode |
1018 | 0 | css::drawing::ShadeMode aShadeMode(css::drawing::ShadeMode_FLAT); |
1019 | 0 | const sal_uInt16 nShadeValue(rSet.Get(SDRATTR_3DSCENE_SHADE_MODE).GetValue()); |
1020 | |
|
1021 | 0 | if(1 == nShadeValue) |
1022 | 0 | { |
1023 | 0 | aShadeMode = css::drawing::ShadeMode_PHONG; |
1024 | 0 | } |
1025 | 0 | else if(2 == nShadeValue) |
1026 | 0 | { |
1027 | 0 | aShadeMode = css::drawing::ShadeMode_SMOOTH; |
1028 | 0 | } |
1029 | 0 | else if(3 == nShadeValue) |
1030 | 0 | { |
1031 | 0 | aShadeMode = css::drawing::ShadeMode_DRAFT; |
1032 | 0 | } |
1033 | | |
1034 | | // get two sided lighting |
1035 | 0 | const bool bTwoSidedLighting(rSet.Get(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING).GetValue()); |
1036 | |
|
1037 | 0 | return attribute::SdrSceneAttribute(fDistance, fShadowSlant, aProjectionMode, aShadeMode, bTwoSidedLighting); |
1038 | 0 | } |
1039 | | |
1040 | | attribute::SdrLightingAttribute createNewSdrLightingAttribute(const SfxItemSet& rSet) |
1041 | 0 | { |
1042 | | // extract lights from given SfxItemSet (from scene) |
1043 | 0 | ::std::vector< attribute::Sdr3DLightAttribute > aLightVector; |
1044 | |
|
1045 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_1).GetValue()) |
1046 | 0 | { |
1047 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1).GetValue().getBColor()); |
1048 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1).GetValue()); |
1049 | 0 | aLightVector.emplace_back(aColor, aDirection, true); |
1050 | 0 | } |
1051 | |
|
1052 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_2).GetValue()) |
1053 | 0 | { |
1054 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2).GetValue().getBColor()); |
1055 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2).GetValue()); |
1056 | 0 | aLightVector.emplace_back(aColor, aDirection, false); |
1057 | 0 | } |
1058 | |
|
1059 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_3).GetValue()) |
1060 | 0 | { |
1061 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3).GetValue().getBColor()); |
1062 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3).GetValue()); |
1063 | 0 | aLightVector.emplace_back(aColor, aDirection, false); |
1064 | 0 | } |
1065 | |
|
1066 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_4).GetValue()) |
1067 | 0 | { |
1068 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4).GetValue().getBColor()); |
1069 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4).GetValue()); |
1070 | 0 | aLightVector.emplace_back(aColor, aDirection, false); |
1071 | 0 | } |
1072 | |
|
1073 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_5).GetValue()) |
1074 | 0 | { |
1075 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5).GetValue().getBColor()); |
1076 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5).GetValue()); |
1077 | 0 | aLightVector.emplace_back(aColor, aDirection, false); |
1078 | 0 | } |
1079 | |
|
1080 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_6).GetValue()) |
1081 | 0 | { |
1082 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6).GetValue().getBColor()); |
1083 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6).GetValue()); |
1084 | 0 | aLightVector.emplace_back(aColor, aDirection, false); |
1085 | 0 | } |
1086 | |
|
1087 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_7).GetValue()) |
1088 | 0 | { |
1089 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7).GetValue().getBColor()); |
1090 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7).GetValue()); |
1091 | 0 | aLightVector.emplace_back(aColor, aDirection, false); |
1092 | 0 | } |
1093 | |
|
1094 | 0 | if(rSet.Get(SDRATTR_3DSCENE_LIGHTON_8).GetValue()) |
1095 | 0 | { |
1096 | 0 | const basegfx::BColor aColor(rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8).GetValue().getBColor()); |
1097 | 0 | const basegfx::B3DVector aDirection(rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8).GetValue()); |
1098 | 0 | aLightVector.emplace_back(aColor, aDirection, false); |
1099 | 0 | } |
1100 | | |
1101 | | // get ambient color |
1102 | 0 | const Color aAmbientValue(rSet.Get(SDRATTR_3DSCENE_AMBIENTCOLOR).GetValue()); |
1103 | 0 | const basegfx::BColor aAmbientLight(aAmbientValue.getBColor()); |
1104 | |
|
1105 | 0 | return attribute::SdrLightingAttribute(aAmbientLight, std::move(aLightVector)); |
1106 | 0 | } |
1107 | | |
1108 | | void calculateRelativeCornerRadius(sal_Int32 nRadius, const basegfx::B2DRange& rObjectRange, double& rfCornerRadiusX, double& rfCornerRadiusY) |
1109 | 126 | { |
1110 | 126 | rfCornerRadiusX = rfCornerRadiusY = static_cast<double>(nRadius); |
1111 | | |
1112 | 126 | if(0.0 != rfCornerRadiusX) |
1113 | 0 | { |
1114 | 0 | const double fHalfObjectWidth(rObjectRange.getWidth() * 0.5); |
1115 | |
|
1116 | 0 | if(0.0 != fHalfObjectWidth) |
1117 | 0 | { |
1118 | 0 | if(rfCornerRadiusX < 0.0) |
1119 | 0 | { |
1120 | 0 | rfCornerRadiusX = 0.0; |
1121 | 0 | } |
1122 | |
|
1123 | 0 | if(rfCornerRadiusX > fHalfObjectWidth) |
1124 | 0 | { |
1125 | 0 | rfCornerRadiusX = fHalfObjectWidth; |
1126 | 0 | } |
1127 | |
|
1128 | 0 | rfCornerRadiusX /= fHalfObjectWidth; |
1129 | 0 | } |
1130 | 0 | else |
1131 | 0 | { |
1132 | 0 | rfCornerRadiusX = 0.0; |
1133 | 0 | } |
1134 | 0 | } |
1135 | | |
1136 | 126 | if(0.0 == rfCornerRadiusY) |
1137 | 126 | return; |
1138 | | |
1139 | 0 | const double fHalfObjectHeight(rObjectRange.getHeight() * 0.5); |
1140 | |
|
1141 | 0 | if(0.0 != fHalfObjectHeight) |
1142 | 0 | { |
1143 | 0 | if(rfCornerRadiusY < 0.0) |
1144 | 0 | { |
1145 | 0 | rfCornerRadiusY = 0.0; |
1146 | 0 | } |
1147 | |
|
1148 | 0 | if(rfCornerRadiusY > fHalfObjectHeight) |
1149 | 0 | { |
1150 | 0 | rfCornerRadiusY = fHalfObjectHeight; |
1151 | 0 | } |
1152 | |
|
1153 | 0 | rfCornerRadiusY /= fHalfObjectHeight; |
1154 | 0 | } |
1155 | 0 | else |
1156 | 0 | { |
1157 | 0 | rfCornerRadiusY = 0.0; |
1158 | 0 | } |
1159 | 0 | } |
1160 | | |
1161 | | // #i101508# Support handing over given text-to-border distances |
1162 | | attribute::SdrFillTextAttribute createNewSdrFillTextAttribute( |
1163 | | const SfxItemSet& rSet, |
1164 | | const SdrText* pText, |
1165 | | const sal_Int32* pLeft, |
1166 | | const sal_Int32* pUpper, |
1167 | | const sal_Int32* pRight, |
1168 | | const sal_Int32* pLower) |
1169 | 0 | { |
1170 | 0 | attribute::SdrFillAttribute aFill; |
1171 | 0 | attribute::FillGradientAttribute aFillFloatTransGradient; |
1172 | 0 | attribute::SdrTextAttribute aText; |
1173 | 0 | bool bFontworkHideContour(false); |
1174 | | |
1175 | | // look for text first |
1176 | 0 | if(pText) |
1177 | 0 | { |
1178 | 0 | aText = createNewSdrTextAttribute(rSet, *pText, pLeft, pUpper, pRight, pLower); |
1179 | | |
1180 | | // when object has text and text is fontwork and hide contour is set for fontwork, force |
1181 | | // fill style to empty |
1182 | 0 | if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour()) |
1183 | 0 | { |
1184 | 0 | bFontworkHideContour = true; |
1185 | 0 | } |
1186 | 0 | } |
1187 | |
|
1188 | 0 | if(!bFontworkHideContour) |
1189 | 0 | { |
1190 | | // try fill style |
1191 | 0 | aFill = createNewSdrFillAttribute(rSet); |
1192 | |
|
1193 | 0 | if(!aFill.isDefault()) |
1194 | 0 | { |
1195 | | // try fillfloattransparence |
1196 | 0 | aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet); |
1197 | 0 | } |
1198 | 0 | } |
1199 | |
|
1200 | 0 | if (!aFill.isDefault() || !aText.isDefault()) |
1201 | 0 | { |
1202 | 0 | return attribute::SdrFillTextAttribute(std::move(aFill), |
1203 | 0 | std::move(aFillFloatTransGradient), |
1204 | 0 | std::move(aText)); |
1205 | 0 | } |
1206 | | |
1207 | 0 | return attribute::SdrFillTextAttribute(); |
1208 | 0 | } |
1209 | | |
1210 | | } // end of namespace |
1211 | | |
1212 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |