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