1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_svx.hxx"
25 #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
26 #include <svl/itemset.hxx>
27 #include <svx/xdef.hxx>
28 #include <basegfx/polygon/b2dpolygon.hxx>
29 #include <svx/xlineit0.hxx>
30 #include <svx/xfillit0.hxx>
31 #include <svx/xlntrit.hxx>
32 #include <svx/xlnwtit.hxx>
33 #include <svx/xlinjoit.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/xfltrit.hxx>
44 #include <svx/xflftrit.hxx>
45 #include <svx/xflclit.hxx>
46 #include <svx/xgrscit.hxx>
47 #include <svx/xflhtit.hxx>
48 #include <svx/xflbckit.hxx>
49 #include <svx/sdshitm.hxx>
50 #include <svx/sdsxyitm.hxx>
51 #include <svx/sdshcitm.hxx>
52 #include <svx/sdshtitm.hxx>
53 #include <drawinglayer/attribute/sdrfillbitmapattribute.hxx>
54 #include <basegfx/polygon/b2dlinegeometry.hxx>
55 #include <svx/svdotext.hxx>
56 #include <drawinglayer/attribute/fillbitmapattribute.hxx>
57 #include <svx/sdr/attribute/sdrtextattribute.hxx>
58 #include <svx/xbtmpit.hxx>
59 #include <svl/itempool.hxx>
60 #include <vcl/svapp.hxx>
61 #include <basegfx/range/b2drange.hxx>
62 #include <svx/svx3ditems.hxx>
63 #include <com/sun/star/drawing/ProjectionMode.hpp>
64 #include <com/sun/star/drawing/ShadeMode.hpp>
65 #include <drawinglayer/attribute/sdrallattribute3d.hxx>
66 #include <svx/rectenum.hxx>
67 #include <svx/sdtfchim.hxx>
68 #include <svx/svdoutl.hxx>
69 #include <svx/svdmodel.hxx>
70 #include <editeng/editstat.hxx>
71 #include <drawinglayer/attribute/fillhatchattribute.hxx>
72 #include <drawinglayer/attribute/fillgradientattribute.hxx>
73 #include <svx/sdr/attribute/sdrshadowtextattribute.hxx>
74 #include <svx/sdr/attribute/sdrlineshadowtextattribute.hxx>
75 #include <svx/sdr/attribute/sdrformtextattribute.hxx>
76 #include <svx/sdr/attribute/sdrlinefillshadowtextattribute.hxx>
77 #include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
78 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
79 #include <drawinglayer/attribute/sdrlightattribute3d.hxx>
80 #include <svx/sdr/attribute/sdrfilltextattribute.hxx>
81 
82 //////////////////////////////////////////////////////////////////////////////
83 
84 namespace drawinglayer
85 {
86 	namespace
87 	{
88 		attribute::GradientStyle XGradientStyleToGradientStyle(XGradientStyle eStyle)
89 		{
90 			switch(eStyle)
91 			{
92 				case XGRAD_LINEAR :
93 				{
94 					return attribute::GRADIENTSTYLE_LINEAR;
95 				}
96 				case XGRAD_AXIAL :
97 				{
98 					return attribute::GRADIENTSTYLE_AXIAL;
99 				}
100 				case XGRAD_RADIAL :
101 				{
102 					return attribute::GRADIENTSTYLE_RADIAL;
103 				}
104 				case XGRAD_ELLIPTICAL :
105 				{
106 					return attribute::GRADIENTSTYLE_ELLIPTICAL;
107 				}
108 				case XGRAD_SQUARE :
109 				{
110 					return attribute::GRADIENTSTYLE_SQUARE;
111 				}
112 				default :
113 				{
114 					return attribute::GRADIENTSTYLE_RECT; // XGRAD_RECT
115 				}
116 			}
117 		}
118 
119 		attribute::HatchStyle XHatchStyleToHatchStyle(XHatchStyle eStyle)
120 		{
121 			switch(eStyle)
122 			{
123 				case XHATCH_SINGLE :
124 				{
125 					return attribute::HATCHSTYLE_SINGLE;
126 				}
127 				case XHATCH_DOUBLE :
128 				{
129 					return attribute::HATCHSTYLE_DOUBLE;
130 				}
131 				default :
132 				{
133 					return attribute::HATCHSTYLE_TRIPLE; // XHATCH_TRIPLE
134 				}
135 			}
136 		}
137 
138 		basegfx::B2DLineJoin XLineJointtoB2DLineJoin(XLineJoint eLineJoint)
139 		{
140 			switch(eLineJoint)
141 			{
142 				case XLINEJOINT_MIDDLE :
143 				{
144 					return basegfx::B2DLINEJOIN_MIDDLE;
145 				}
146 				case XLINEJOINT_BEVEL :
147 				{
148 					return basegfx::B2DLINEJOIN_BEVEL;
149 				}
150 				case XLINEJOINT_MITER :
151 				{
152 					return basegfx::B2DLINEJOIN_MITER;
153 				}
154 				case XLINEJOINT_ROUND :
155 				{
156 					return basegfx::B2DLINEJOIN_ROUND;
157 				}
158 				default :
159 				{
160 					return basegfx::B2DLINEJOIN_NONE; // XLINEJOINT_NONE
161 				}
162 			}
163 		}
164 
165 		basegfx::B2DVector RectPointToB2DVector(RECT_POINT eRectPoint)
166 		{
167 			basegfx::B2DVector aRetval(0.0, 0.0);
168 
169 			// position changes X
170 			switch(eRectPoint)
171 			{
172 				case RP_LT: case RP_LM: case RP_LB:
173 				{
174 					aRetval.setX(-1.0);
175 					break;
176 				}
177 
178 				case RP_RT: case RP_RM: case RP_RB:
179 				{
180 					aRetval.setX(1.0);
181 					break;
182 				}
183 
184 				default :
185 				{
186 					break;
187 				}
188 			}
189 
190 			// position changes Y
191 			switch(eRectPoint)
192 			{
193 				case RP_LT: case RP_MT: case RP_RT:
194 				{
195 					aRetval.setY(-1.0);
196 					break;
197 				}
198 
199 				case RP_LB: case RP_MB: case RP_RB:
200 				{
201 					aRetval.setY(1.0);
202 					break;
203 				}
204 
205 				default :
206 				{
207 					break;
208 				}
209 			}
210 
211 			return aRetval;
212 		}
213 	} // end of anonymous namespace
214 } // end of namespace drawinglayer
215 
216 //////////////////////////////////////////////////////////////////////////////
217 
218 namespace drawinglayer
219 {
220 	namespace primitive2d
221 	{
222 		attribute::SdrLineAttribute createNewSdrLineAttribute(const SfxItemSet& rSet)
223 		{
224 			const XLineStyle eStyle(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue());
225 
226 			if(XLINE_NONE != eStyle)
227 			{
228 				sal_uInt16 nTransparence(((const XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue());
229 
230 				if(nTransparence > 100)
231 				{
232 					nTransparence = 100;
233 				}
234 
235 				if(100 != nTransparence)
236 				{
237 					const sal_uInt32 nWidth(((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue());
238 					const Color aColor(((const XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetColorValue());
239 					const XLineJoint eJoint(((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue());
240 					::std::vector< double > aDotDashArray;
241 					double fFullDotDashLen(0.0);
242 
243 					if(XLINE_DASH == eStyle)
244 					{
245 						const XDash& rDash = ((const XLineDashItem&)(rSet.Get(XATTR_LINEDASH))).GetDashValue();
246 
247 						if(rDash.GetDots() || rDash.GetDashes())
248 						{
249 							fFullDotDashLen = rDash.CreateDotDashArray(aDotDashArray, (double)nWidth);
250 						}
251 					}
252 
253 					return attribute::SdrLineAttribute(
254 						XLineJointtoB2DLineJoin(eJoint),
255 						(double)nWidth,
256 						(double)nTransparence * 0.01,
257 						aColor.getBColor(),
258 						aDotDashArray,
259 						fFullDotDashLen);
260 				}
261 			}
262 
263 			return attribute::SdrLineAttribute();
264 		}
265 
266 		attribute::SdrLineStartEndAttribute createNewSdrLineStartEndAttribute(
267 			const SfxItemSet& rSet,
268 			double fWidth)
269 		{
270 			const sal_Int32 nTempStartWidth(((const XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue());
271 			const sal_Int32 nTempEndWidth(((const XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue());
272 			basegfx::B2DPolyPolygon aStartPolyPolygon;
273 			basegfx::B2DPolyPolygon aEndPolyPolygon;
274 			double fStartWidth(0.0);
275 			double fEndWidth(0.0);
276 			bool bStartActive(false);
277 			bool bEndActive(false);
278 			bool bStartCentered(true);
279 			bool bEndCentered(true);
280 
281 			if(nTempStartWidth)
282 			{
283 				if(nTempStartWidth < 0L)
284 				{
285 					fStartWidth = ((double)(-nTempStartWidth) * fWidth) * 0.01;
286 				}
287 				else
288 				{
289 					fStartWidth = (double)nTempStartWidth;
290 				}
291 
292 				if(0.0 != fStartWidth)
293 				{
294 					aStartPolyPolygon = basegfx::B2DPolyPolygon(((const XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue());
295 
296 					if(aStartPolyPolygon.count() && aStartPolyPolygon.getB2DPolygon(0L).count())
297 					{
298 						bStartActive = true;
299 						bStartCentered = ((const XLineStartCenterItem&)(rSet.Get(XATTR_LINESTARTCENTER))).GetValue();
300 					}
301 				}
302 			}
303 
304 			if(nTempEndWidth)
305 			{
306 				if(nTempEndWidth < 0L)
307 				{
308 					fEndWidth = ((double)(-nTempEndWidth) * fWidth) * 0.01;
309 				}
310 				else
311 				{
312 					fEndWidth = (double)nTempEndWidth;
313 				}
314 
315 				if(0.0 != fEndWidth)
316 				{
317 					aEndPolyPolygon = basegfx::B2DPolyPolygon(((const XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue());
318 
319 					if(aEndPolyPolygon.count() && aEndPolyPolygon.getB2DPolygon(0L).count())
320 					{
321 						bEndActive = true;
322 						bEndCentered = ((const XLineEndCenterItem&)(rSet.Get(XATTR_LINEENDCENTER))).GetValue();
323 					}
324 				}
325 			}
326 
327 			if(bStartActive || bEndActive)
328 			{
329 				return attribute::SdrLineStartEndAttribute(
330 					aStartPolyPolygon, aEndPolyPolygon, fStartWidth, fEndWidth,
331 					bStartActive, bEndActive, bStartCentered, bEndCentered);
332 			}
333 
334 			return attribute::SdrLineStartEndAttribute();
335 		}
336 
337 		attribute::SdrShadowAttribute createNewSdrShadowAttribute(const SfxItemSet& rSet)
338 		{
339 			const bool bShadow(((SdrShadowItem&)rSet.Get(SDRATTR_SHADOW)).GetValue());
340 
341 			if(bShadow)
342 			{
343 				sal_uInt16 nTransparence(((SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue());
344 
345 				if(nTransparence > 100)
346 				{
347 					nTransparence = 100;
348 				}
349 
350 				if(nTransparence)
351 				{
352 					sal_uInt16 nFillTransparence(((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue());
353 
354 					if(nFillTransparence > 100)
355 					{
356 						nFillTransparence = 100;
357 					}
358 
359 					if(nTransparence == nFillTransparence)
360 					{
361 						// shadow does not really have an own transparence, but the application
362 						// sets the shadow transparence equal to the object transparence for
363 						// convenience. This is not useful for primitive creation, so take
364 						// this as no shadow transparence
365 						nTransparence = 0;
366 					}
367 				}
368 
369 				if(100 != nTransparence)
370 				{
371 					const basegfx::B2DVector aOffset(
372 						(double)((SdrShadowXDistItem&)(rSet.Get(SDRATTR_SHADOWXDIST))).GetValue(),
373 						(double)((SdrShadowYDistItem&)(rSet.Get(SDRATTR_SHADOWYDIST))).GetValue());
374 					const Color aColor(((SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
375 
376 					return attribute::SdrShadowAttribute(aOffset, (double)nTransparence * 0.01, aColor.getBColor());
377 				}
378 			}
379 
380 			return attribute::SdrShadowAttribute();
381 		}
382 
383 		attribute::SdrFillAttribute createNewSdrFillAttribute(const SfxItemSet& rSet)
384 		{
385 			const XFillStyle eStyle(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue());
386 
387 			if(XFILL_NONE != eStyle)
388 			{
389 				sal_uInt16 nTransparence(((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue());
390 
391 				if(nTransparence > 100)
392 				{
393 					nTransparence = 100;
394 				}
395 
396 				if(100 != nTransparence)
397 				{
398 					const Color aColor(((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue());
399 					attribute::FillGradientAttribute aGradient;
400 					attribute::FillHatchAttribute aHatch;
401 					attribute::SdrFillBitmapAttribute aBitmap;
402 
403 					switch(eStyle)
404 					{
405 						case XFILL_NONE : // for warnings
406 						case XFILL_SOLID :
407 						{
408 							// nothing to do, color is defined
409 							break;
410 						}
411 						case XFILL_GRADIENT :
412 						{
413 							XGradient aXGradient(((XFillGradientItem&)(rSet.Get(XATTR_FILLGRADIENT))).GetGradientValue());
414 
415 							const Color aStartColor(aXGradient.GetStartColor());
416 							const sal_uInt16 nStartIntens(aXGradient.GetStartIntens());
417 							basegfx::BColor aStart(aStartColor.getBColor());
418 
419 							if(nStartIntens != 100)
420 							{
421 								const basegfx::BColor aBlack;
422 								aStart = interpolate(aBlack, aStart, (double)nStartIntens * 0.01);
423 							}
424 
425 							const Color aEndColor(aXGradient.GetEndColor());
426 							const sal_uInt16 nEndIntens(aXGradient.GetEndIntens());
427 							basegfx::BColor aEnd(aEndColor.getBColor());
428 
429 							if(nEndIntens != 100)
430 							{
431 								const basegfx::BColor aBlack;
432 								aEnd = interpolate(aBlack, aEnd, (double)nEndIntens * 0.01);
433 							}
434 
435 							aGradient = attribute::FillGradientAttribute(
436 								XGradientStyleToGradientStyle(aXGradient.GetGradientStyle()),
437 								(double)aXGradient.GetBorder() * 0.01,
438 								(double)aXGradient.GetXOffset() * 0.01,
439 								(double)aXGradient.GetYOffset() * 0.01,
440 								(double)aXGradient.GetAngle() * F_PI1800,
441 								aStart,
442 								aEnd,
443 								((const XGradientStepCountItem&)rSet.Get(XATTR_GRADIENTSTEPCOUNT)).GetValue());
444 
445 							break;
446 						}
447 						case XFILL_HATCH :
448 						{
449 							const XHatch& rHatch(((XFillHatchItem&)(rSet.Get(XATTR_FILLHATCH))).GetHatchValue());
450 							const Color aColorB(rHatch.GetColor());
451 
452 							aHatch = attribute::FillHatchAttribute(
453 								XHatchStyleToHatchStyle(rHatch.GetHatchStyle()),
454 								(double)rHatch.GetDistance(),
455 								(double)rHatch.GetAngle() * F_PI1800,
456 								aColorB.getBColor(),
457 								((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue());
458 
459 							break;
460 						}
461 						case XFILL_BITMAP :
462 						{
463 							aBitmap = createNewSdrFillBitmapAttribute(rSet);
464 							break;
465 						}
466 					}
467 
468 					return attribute::SdrFillAttribute(
469 						(double)nTransparence * 0.01,
470 						aColor.getBColor(),
471 						aGradient,
472 						aHatch,
473 						aBitmap);
474 				}
475 			}
476 
477 			return attribute::SdrFillAttribute();
478 		}
479 
480 		// #i101508# Support handing over given text-to-border distances
481 		attribute::SdrTextAttribute createNewSdrTextAttribute(
482 			const SfxItemSet& rSet,
483 			const SdrText& rText,
484 			const sal_Int32* pLeft,
485 			const sal_Int32* pUpper,
486 			const sal_Int32* pRight,
487 			const sal_Int32* pLower)
488 		{
489 			const SdrTextObj& rTextObj = rText.GetObject();
490 
491 			if(rText.GetOutlinerParaObject() && rText.GetModel())
492 			{
493 				// added TextEdit text suppression
494 				bool bInEditMode(false);
495 
496 				if(rText.GetObject().getTextCount() > 1)
497 				{
498 					bInEditMode = rTextObj.IsInEditMode() && rText.GetObject().getActiveText() == &rText;
499 				}
500 				else
501 				{
502 					bInEditMode = rTextObj.IsInEditMode();
503 				}
504 
505                 OutlinerParaObject aOutlinerParaObject(*rText.GetOutlinerParaObject());
506 
507                 if(bInEditMode)
508                 {
509                     OutlinerParaObject* pTempObj = rTextObj.GetEditOutlinerParaObject();
510 
511                     if(pTempObj)
512                     {
513                         aOutlinerParaObject = *pTempObj;
514                         delete pTempObj;
515                     }
516                     else
517                     {
518                         // #i100537#
519                         // GetEditOutlinerParaObject() returning no object does not mean that
520                         // text edit mode is not active. Do not reset the flag here
521                         // bInEditMode = false;
522                     }
523                 }
524 
525 			    const SdrFitToSizeType eFit(rTextObj.GetFitToSize());
526 			    const SdrTextAniKind eAniKind(rTextObj.GetTextAniKind());
527 
528 				// #i107346#
529 				const SdrOutliner& rDrawTextOutliner = rText.GetModel()->GetDrawOutliner(&rTextObj);
530 				const bool bWrongSpell(rDrawTextOutliner.GetControlWord() & EE_CNTRL_ONLINESPELLING);
531 
532 			    return attribute::SdrTextAttribute(
533 				    rText,
534                     aOutlinerParaObject,
535 				    ((const XFormTextStyleItem&)rSet.Get(XATTR_FORMTXTSTYLE)).GetValue(),
536 					pLeft ? *pLeft : rTextObj.GetTextLeftDistance(),
537 					pUpper ? *pUpper : rTextObj.GetTextUpperDistance(),
538 					pRight ? *pRight : rTextObj.GetTextRightDistance(),
539 					pLower ? *pLower : rTextObj.GetTextLowerDistance(),
540                     rTextObj.GetTextHorizontalAdjust(rSet),
541                     rTextObj.GetTextVerticalAdjust(rSet),
542 				    ((const SdrTextContourFrameItem&)rSet.Get(SDRATTR_TEXT_CONTOURFRAME)).GetValue(),
543 				    (SDRTEXTFIT_PROPORTIONAL == eFit || SDRTEXTFIT_ALLLINES == eFit),
544 				    ((const XFormTextHideFormItem&)rSet.Get(XATTR_FORMTXTHIDEFORM)).GetValue(),
545 				    SDRTEXTANI_BLINK == eAniKind,
546 				    SDRTEXTANI_SCROLL == eAniKind || SDRTEXTANI_ALTERNATE == eAniKind || SDRTEXTANI_SLIDE == eAniKind,
547                     bInEditMode,
548                     ((const SdrTextFixedCellHeightItem&)rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue(),
549 					bWrongSpell);
550 			}
551 
552 			return attribute::SdrTextAttribute();
553 		}
554 
555 		attribute::FillGradientAttribute createNewTransparenceGradientAttribute(const SfxItemSet& rSet)
556 		{
557 			const SfxPoolItem* pGradientItem;
558 
559 			if(SFX_ITEM_SET == rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, sal_True, &pGradientItem)
560 				&& ((XFillFloatTransparenceItem*)pGradientItem)->IsEnabled())
561 			{
562 				// test if float transparence is completely transparent
563 				const XGradient& rGradient = ((XFillFloatTransparenceItem*)pGradientItem)->GetGradientValue();
564 				const sal_uInt8 nStartLuminance(rGradient.GetStartColor().GetLuminance());
565 				const sal_uInt8 nEndLuminance(rGradient.GetEndColor().GetLuminance());
566 				const bool bCompletelyTransparent(0xff == nStartLuminance && 0xff == nEndLuminance);
567 
568 				if(!bCompletelyTransparent)
569 				{
570 					const double fStartLum(nStartLuminance / 255.0);
571 					const double fEndLum(nEndLuminance / 255.0);
572 
573 					return attribute::FillGradientAttribute(
574 						XGradientStyleToGradientStyle(rGradient.GetGradientStyle()),
575 						(double)rGradient.GetBorder() * 0.01,
576 						(double)rGradient.GetXOffset() * 0.01,
577 						(double)rGradient.GetYOffset() * 0.01,
578 						(double)rGradient.GetAngle() * F_PI1800,
579 						basegfx::BColor(fStartLum, fStartLum, fStartLum),
580 						basegfx::BColor(fEndLum, fEndLum, fEndLum),
581 						0);
582 				}
583 			}
584 
585 			return attribute::FillGradientAttribute();
586 		}
587 
588 		attribute::SdrFillBitmapAttribute createNewSdrFillBitmapAttribute(const SfxItemSet& rSet)
589 		{
590 			Bitmap aBitmap((((const XFillBitmapItem&)(rSet.Get(XATTR_FILLBITMAP))).GetBitmapValue()).GetBitmap());
591 
592 			// make sure it's not empty, use default instead
593 			if(aBitmap.IsEmpty())
594 			{
595                 // #i118485# Add PrefMapMode and PrefSize to avoid mini-tiling and
596                 // expensive primitive processing in this case. Use 10x10 cm
597 				aBitmap = Bitmap(Size(4,4), 8);
598                 aBitmap.SetPrefMapMode(MapMode(MAP_100TH_MM));
599                 aBitmap.SetPrefSize(Size(10000.0, 10000.0));
600 			}
601 
602 			// if there is no logical size, create a size from pixel size and set MapMode accordingly
603 			if(0L == aBitmap.GetPrefSize().Width() || 0L == aBitmap.GetPrefSize().Height())
604 			{
605 				aBitmap.SetPrefSize(aBitmap.GetSizePixel());
606 				aBitmap.SetPrefMapMode(MAP_PIXEL);
607 			}
608 
609 			// convert size and MapMode to destination logical size and MapMode. The created
610 			// bitmap must have a valid logical size (PrefSize)
611 			const MapUnit aDestinationMapUnit((MapUnit)rSet.GetPool()->GetMetric(0));
612 
613 			if(aBitmap.GetPrefMapMode() != aDestinationMapUnit)
614 			{
615 				// #i100360# for MAP_PIXEL, LogicToLogic will not work properly,
616                 // so fallback to Application::GetDefaultDevice()
617     			if(MAP_PIXEL == aBitmap.GetPrefMapMode().GetMapUnit())
618                 {
619     				aBitmap.SetPrefSize(Application::GetDefaultDevice()->PixelToLogic(
620 	    				aBitmap.GetPrefSize(), aDestinationMapUnit));
621                 }
622                 else
623                 {
624                     aBitmap.SetPrefSize(OutputDevice::LogicToLogic(
625 	    				aBitmap.GetPrefSize(), aBitmap.GetPrefMapMode(), aDestinationMapUnit));
626                 }
627 			}
628 
629 			// get size
630 			const basegfx::B2DVector aSize(
631 				(double)((const SfxMetricItem&)(rSet.Get(XATTR_FILLBMP_SIZEX))).GetValue(),
632 				(double)((const SfxMetricItem&)(rSet.Get(XATTR_FILLBMP_SIZEY))).GetValue());
633 			const basegfx::B2DVector aOffset(
634 				(double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_TILEOFFSETX))).GetValue(),
635 				(double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_TILEOFFSETY))).GetValue());
636 			const basegfx::B2DVector aOffsetPosition(
637 				(double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETX))).GetValue(),
638 				(double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETY))).GetValue());
639 
640 			return attribute::SdrFillBitmapAttribute(
641 				aBitmap,
642 				aSize,
643 				aOffset,
644 				aOffsetPosition,
645 				RectPointToB2DVector((RECT_POINT)((const SfxEnumItem&)(rSet.Get(XATTR_FILLBMP_POS))).GetValue()),
646 				((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_TILE))).GetValue(),
647 				((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_STRETCH))).GetValue(),
648 				((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_SIZELOG))).GetValue());
649 		}
650 
651 		attribute::SdrShadowTextAttribute createNewSdrShadowTextAttribute(
652             const SfxItemSet& rSet,
653             const SdrText* pText,
654             bool bSuppressText)
655 		{
656 			attribute::SdrTextAttribute aText;
657 
658 			// #i98072# added option to suppress text
659             // look for text first
660             if(!bSuppressText && pText)
661             {
662     			aText = createNewSdrTextAttribute(rSet, *pText);
663             }
664 
665 			// try shadow
666 			const attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet));
667 
668 			return attribute::SdrShadowTextAttribute(aShadow, aText);
669 		}
670 
671 		attribute::SdrLineShadowTextAttribute createNewSdrLineShadowTextAttribute(
672             const SfxItemSet& rSet,
673             const SdrText* pText)
674 		{
675 			attribute::SdrLineAttribute aLine;
676 			attribute::SdrLineStartEndAttribute aLineStartEnd;
677 			attribute::SdrTextAttribute aText;
678 			bool bFontworkHideContour(false);
679 
680 			// look for text first
681             if(pText)
682             {
683     			aText = createNewSdrTextAttribute(rSet, *pText);
684 
685 			    // when object has text and text is fontwork and hide contour is set for fontwork, force
686 			    // line and fill style to empty
687 			    if(!aText.isDefault()
688                     && !aText.getSdrFormTextAttribute().isDefault()
689                     && aText.isHideContour())
690 			    {
691 				    bFontworkHideContour = true;
692 			    }
693 			}
694 
695 			// try line style
696 			if(!bFontworkHideContour)
697 			{
698 				aLine = createNewSdrLineAttribute(rSet);
699 
700 				if(!aLine.isDefault())
701 				{
702 					// try LineStartEnd
703 					aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth());
704 				}
705 			}
706 
707 			if(!aLine.isDefault() || !aText.isDefault())
708 			{
709 				// try shadow
710 				const attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet));
711 
712 				return attribute::SdrLineShadowTextAttribute(aLine, aLineStartEnd, aShadow, aText);
713 			}
714 
715 			return attribute::SdrLineShadowTextAttribute();
716 		}
717 
718 		attribute::SdrLineFillShadowTextAttribute createNewSdrLineFillShadowTextAttribute(
719             const SfxItemSet& rSet,
720             const SdrText* pText)
721 		{
722 			attribute::SdrLineAttribute aLine;
723 			attribute::SdrFillAttribute aFill;
724 			attribute::SdrLineStartEndAttribute aLineStartEnd;
725 			attribute::SdrShadowAttribute aShadow;
726 			attribute::FillGradientAttribute aFillFloatTransGradient;
727 			attribute::SdrTextAttribute aText;
728 			bool bFontworkHideContour(false);
729 
730 			// look for text first
731             if(pText)
732             {
733     			aText = createNewSdrTextAttribute(rSet, *pText);
734 
735 			    // when object has text and text is fontwork and hide contour is set for fontwork, force
736 			    // line and fill style to empty
737 			    if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour())
738 			    {
739 				    bFontworkHideContour = true;
740 			    }
741             }
742 
743 			if(!bFontworkHideContour)
744 			{
745 				// try line style
746 				aLine = createNewSdrLineAttribute(rSet);
747 
748 				if(!aLine.isDefault())
749 				{
750 					// try LineStartEnd
751 					aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth());
752 				}
753 
754 				// try fill style
755 				aFill = createNewSdrFillAttribute(rSet);
756 
757 				if(!aFill.isDefault())
758 				{
759 					// try fillfloattransparence
760 					aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet);
761 				}
762 			}
763 
764 			if(!aLine.isDefault() || !aFill.isDefault() || !aText.isDefault())
765 			{
766 				// try shadow
767 				aShadow = createNewSdrShadowAttribute(rSet);
768 
769 				return attribute::SdrLineFillShadowTextAttribute(
770 					aLine, aFill, aLineStartEnd, aShadow, aFillFloatTransGradient, aText);
771 			}
772 
773 			return attribute::SdrLineFillShadowTextAttribute();
774 		}
775 
776 		attribute::SdrLineFillShadowAttribute3D createNewSdrLineFillShadowAttribute(const SfxItemSet& rSet, bool bSuppressFill)
777 		{
778 			attribute::SdrFillAttribute aFill;
779 			attribute::SdrLineStartEndAttribute aLineStartEnd;
780 			attribute::SdrShadowAttribute aShadow;
781 			attribute::FillGradientAttribute aFillFloatTransGradient;
782 
783 			// try line style
784 			const attribute::SdrLineAttribute aLine(createNewSdrLineAttribute(rSet));
785 
786 			if(!aLine.isDefault())
787 			{
788 				// try LineStartEnd
789 				aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth());
790 			}
791 
792 			// try fill style
793 			if(!bSuppressFill)
794 			{
795 				aFill = createNewSdrFillAttribute(rSet);
796 
797 				if(!aFill.isDefault())
798 				{
799 					// try fillfloattransparence
800 					aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet);
801 				}
802 			}
803 
804 			if(!aLine.isDefault() || !aFill.isDefault())
805 			{
806 				// try shadow
807 				aShadow = createNewSdrShadowAttribute(rSet);
808 
809 				return attribute::SdrLineFillShadowAttribute3D(
810 					aLine, aFill, aLineStartEnd, aShadow, aFillFloatTransGradient);
811 			}
812 
813 			return attribute::SdrLineFillShadowAttribute3D();
814 		}
815 
816 		attribute::SdrSceneAttribute createNewSdrSceneAttribute(const SfxItemSet& rSet)
817 		{
818 			// get perspective
819 			::com::sun::star::drawing::ProjectionMode aProjectionMode(::com::sun::star::drawing::ProjectionMode_PARALLEL);
820 			const sal_uInt16 nProjectionValue(((const Svx3DPerspectiveItem&)rSet.Get(SDRATTR_3DSCENE_PERSPECTIVE)).GetValue());
821 
822 			if(1L == nProjectionValue)
823 			{
824 				aProjectionMode = ::com::sun::star::drawing::ProjectionMode_PERSPECTIVE;
825 			}
826 
827 			// get distance
828 			const double fDistance(((const Svx3DDistanceItem&)rSet.Get(SDRATTR_3DSCENE_DISTANCE)).GetValue());
829 
830 			// get shadow slant
831 			const double fShadowSlant(F_PI180 * ((const Svx3DShadowSlantItem&)rSet.Get(SDRATTR_3DSCENE_SHADOW_SLANT)).GetValue());
832 
833 			// get shade mode
834 			::com::sun::star::drawing::ShadeMode aShadeMode(::com::sun::star::drawing::ShadeMode_FLAT);
835 			const sal_uInt16 nShadeValue(((const Svx3DShadeModeItem&)rSet.Get(SDRATTR_3DSCENE_SHADE_MODE)).GetValue());
836 
837 			if(1L == nShadeValue)
838 			{
839 				aShadeMode = ::com::sun::star::drawing::ShadeMode_PHONG;
840 			}
841 			else if(2L == nShadeValue)
842 			{
843 				aShadeMode = ::com::sun::star::drawing::ShadeMode_SMOOTH;
844 			}
845 			else if(3L == nShadeValue)
846 			{
847 				aShadeMode = ::com::sun::star::drawing::ShadeMode_DRAFT;
848 			}
849 
850 			// get two sided lighting
851 			const bool bTwoSidedLighting(((const Svx3DTwoSidedLightingItem&)rSet.Get(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING)).GetValue());
852 
853 			return attribute::SdrSceneAttribute(fDistance, fShadowSlant, aProjectionMode, aShadeMode, bTwoSidedLighting);
854 		}
855 
856 		attribute::SdrLightingAttribute createNewSdrLightingAttribute(const SfxItemSet& rSet)
857 		{
858 			// extract lights from given SfxItemSet (from scene)
859 			::std::vector< attribute::Sdr3DLightAttribute > aLightVector;
860 
861             if(((const Svx3DLightOnOff1Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_1)).GetValue())
862             {
863 				const basegfx::BColor aColor(((const Svx3DLightcolor1Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1)).GetValue().getBColor());
864 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection1Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1)).GetValue());
865 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, true));
866             }
867 
868             if(((const Svx3DLightOnOff2Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_2)).GetValue())
869             {
870 				const basegfx::BColor aColor(((const Svx3DLightcolor2Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2)).GetValue().getBColor());
871 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection2Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2)).GetValue());
872 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false));
873             }
874 
875             if(((const Svx3DLightOnOff3Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_3)).GetValue())
876             {
877 				const basegfx::BColor aColor(((const Svx3DLightcolor3Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3)).GetValue().getBColor());
878 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection3Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3)).GetValue());
879 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false));
880             }
881 
882             if(((const Svx3DLightOnOff4Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_4)).GetValue())
883             {
884 				const basegfx::BColor aColor(((const Svx3DLightcolor4Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4)).GetValue().getBColor());
885 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection4Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4)).GetValue());
886 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false));
887             }
888 
889             if(((const Svx3DLightOnOff5Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_5)).GetValue())
890             {
891 				const basegfx::BColor aColor(((const Svx3DLightcolor5Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5)).GetValue().getBColor());
892 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection5Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5)).GetValue());
893 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false));
894             }
895 
896             if(((const Svx3DLightOnOff6Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_6)).GetValue())
897             {
898 				const basegfx::BColor aColor(((const Svx3DLightcolor6Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6)).GetValue().getBColor());
899 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection6Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6)).GetValue());
900 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false));
901             }
902 
903             if(((const Svx3DLightOnOff7Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_7)).GetValue())
904             {
905 				const basegfx::BColor aColor(((const Svx3DLightcolor7Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7)).GetValue().getBColor());
906 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection7Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7)).GetValue());
907 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false));
908             }
909 
910             if(((const Svx3DLightOnOff8Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_8)).GetValue())
911             {
912 				const basegfx::BColor aColor(((const Svx3DLightcolor8Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8)).GetValue().getBColor());
913 				const basegfx::B3DVector aDirection(((const Svx3DLightDirection8Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8)).GetValue());
914 				aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false));
915             }
916 
917             // get ambient color
918 			const Color aAmbientValue(((const Svx3DAmbientcolorItem&)rSet.Get(SDRATTR_3DSCENE_AMBIENTCOLOR)).GetValue());
919 			const basegfx::BColor aAmbientLight(aAmbientValue.getBColor());
920 
921             return attribute::SdrLightingAttribute(aAmbientLight, aLightVector);
922 		}
923 
924 		void calculateRelativeCornerRadius(sal_Int32 nRadius, const basegfx::B2DRange& rObjectRange, double& rfCornerRadiusX, double& rfCornerRadiusY)
925 		{
926 			rfCornerRadiusX = rfCornerRadiusY = (double)nRadius;
927 
928 			if(0.0 != rfCornerRadiusX)
929 			{
930 				const double fHalfObjectWidth(rObjectRange.getWidth() * 0.5);
931 
932 				if(0.0 != fHalfObjectWidth)
933 				{
934 					if(rfCornerRadiusX < 0.0)
935 					{
936 						rfCornerRadiusX = 0.0;
937 					}
938 
939 					if(rfCornerRadiusX > fHalfObjectWidth)
940 					{
941 						rfCornerRadiusX = fHalfObjectWidth;
942 					}
943 
944 					rfCornerRadiusX /= fHalfObjectWidth;
945 				}
946 				else
947 				{
948 					rfCornerRadiusX = 0.0;
949 				}
950 			}
951 
952 			if(0.0 != rfCornerRadiusY)
953 			{
954 				const double fHalfObjectHeight(rObjectRange.getHeight() * 0.5);
955 
956 				if(0.0 != fHalfObjectHeight)
957 				{
958 					if(rfCornerRadiusY < 0.0)
959 					{
960 						rfCornerRadiusY = 0.0;
961 					}
962 
963 					if(rfCornerRadiusY > fHalfObjectHeight)
964 					{
965 						rfCornerRadiusY = fHalfObjectHeight;
966 					}
967 
968 					rfCornerRadiusY /= fHalfObjectHeight;
969 				}
970 				else
971 				{
972 					rfCornerRadiusY = 0.0;
973 				}
974 			}
975 		}
976 
977 		// #i101508# Support handing over given text-to-border distances
978 		attribute::SdrFillTextAttribute createNewSdrFillTextAttribute(
979 			const SfxItemSet& rSet,
980 			const SdrText* pText,
981 			const sal_Int32* pLeft,
982 			const sal_Int32* pUpper,
983 			const sal_Int32* pRight,
984 			const sal_Int32* pLower)
985 		{
986 			attribute::SdrFillAttribute aFill;
987 			attribute::FillGradientAttribute aFillFloatTransGradient;
988 			attribute::SdrTextAttribute aText;
989 			bool bFontworkHideContour(false);
990 
991 			// look for text first
992             if(pText)
993             {
994     			aText = createNewSdrTextAttribute(rSet, *pText, pLeft, pUpper, pRight, pLower);
995 
996 			    // when object has text and text is fontwork and hide contour is set for fontwork, force
997 			    // fill style to empty
998 			    if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour())
999 			    {
1000 				    bFontworkHideContour = true;
1001 			    }
1002             }
1003 
1004 			if(!bFontworkHideContour)
1005 			{
1006 				// try fill style
1007 				aFill = createNewSdrFillAttribute(rSet);
1008 
1009 				if(!aFill.isDefault())
1010 				{
1011 					// try fillfloattransparence
1012 					aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet);
1013 				}
1014 			}
1015 
1016 			if(!aFill.isDefault() || !aText.isDefault())
1017 			{
1018 				return attribute::SdrFillTextAttribute(aFill, aFillFloatTransGradient, aText);
1019 			}
1020 
1021 			return attribute::SdrFillTextAttribute();
1022 		}
1023 
1024 	} // end of namespace primitive2d
1025 } // end of namespace drawinglayer
1026 
1027 //////////////////////////////////////////////////////////////////////////////
1028 // eof
1029