1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "precompiled_svx.hxx"
29 #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
30 #include <svl/itemset.hxx>
31 #include <svx/xdef.hxx>
32 #include <basegfx/polygon/b2dpolygon.hxx>
33 #include <svx/xlineit0.hxx>
34 #include <svx/xfillit0.hxx>
35 #include <svx/xlntrit.hxx>
36 #include <svx/xlnwtit.hxx>
37 #include <svx/xlinjoit.hxx>
38 #include <svx/xlnclit.hxx>
39 #include <svx/xlnstwit.hxx>
40 #include <svx/xlnedwit.hxx>
41 #include <svx/xlnstit.hxx>
42 #include <svx/xlnstcit.hxx>
43 #include <svx/xlnedit.hxx>
44 #include <svx/xlnedcit.hxx>
45 #include <svx/xdash.hxx>
46 #include <svx/xlndsit.hxx>
47 #include <svx/xfltrit.hxx>
48 #include <svx/xflftrit.hxx>
49 #include <svx/xflclit.hxx>
50 #include <svx/xgrscit.hxx>
51 #include <svx/xflhtit.hxx>
52 #include <svx/xflbckit.hxx>
53 #include <svx/sdshitm.hxx>
54 #include <svx/sdsxyitm.hxx>
55 #include <svx/sdshcitm.hxx>
56 #include <svx/sdshtitm.hxx>
57 #include <drawinglayer/attribute/sdrfillbitmapattribute.hxx>
58 #include <basegfx/polygon/b2dlinegeometry.hxx>
59 #include <svx/svdotext.hxx>
60 #include <drawinglayer/attribute/fillbitmapattribute.hxx>
61 #include <svx/sdr/attribute/sdrtextattribute.hxx>
62 #include <svx/xbtmpit.hxx>
63 #include <svl/itempool.hxx>
64 #include <vcl/svapp.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 <editeng/editstat.hxx>
75 #include <drawinglayer/attribute/fillhatchattribute.hxx>
76 #include <drawinglayer/attribute/fillgradientattribute.hxx>
77 #include <svx/sdr/attribute/sdrshadowtextattribute.hxx>
78 #include <svx/sdr/attribute/sdrlineshadowtextattribute.hxx>
79 #include <svx/sdr/attribute/sdrformtextattribute.hxx>
80 #include <svx/sdr/attribute/sdrlinefillshadowtextattribute.hxx>
81 #include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
82 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
83 #include <drawinglayer/attribute/sdrlightattribute3d.hxx>
84 #include <svx/sdr/attribute/sdrfilltextattribute.hxx>
85 
86 //////////////////////////////////////////////////////////////////////////////
87 
88 namespace drawinglayer
89 {
90 	namespace
91 	{
92 		attribute::GradientStyle XGradientStyleToGradientStyle(XGradientStyle eStyle)
93 		{
94 			switch(eStyle)
95 			{
96 				case XGRAD_LINEAR :
97 				{
98 					return attribute::GRADIENTSTYLE_LINEAR;
99 				}
100 				case XGRAD_AXIAL :
101 				{
102 					return attribute::GRADIENTSTYLE_AXIAL;
103 				}
104 				case XGRAD_RADIAL :
105 				{
106 					return attribute::GRADIENTSTYLE_RADIAL;
107 				}
108 				case XGRAD_ELLIPTICAL :
109 				{
110 					return attribute::GRADIENTSTYLE_ELLIPTICAL;
111 				}
112 				case XGRAD_SQUARE :
113 				{
114 					return attribute::GRADIENTSTYLE_SQUARE;
115 				}
116 				default :
117 				{
118 					return attribute::GRADIENTSTYLE_RECT; // XGRAD_RECT
119 				}
120 			}
121 		}
122 
123 		attribute::HatchStyle XHatchStyleToHatchStyle(XHatchStyle eStyle)
124 		{
125 			switch(eStyle)
126 			{
127 				case XHATCH_SINGLE :
128 				{
129 					return attribute::HATCHSTYLE_SINGLE;
130 				}
131 				case XHATCH_DOUBLE :
132 				{
133 					return attribute::HATCHSTYLE_DOUBLE;
134 				}
135 				default :
136 				{
137 					return attribute::HATCHSTYLE_TRIPLE; // XHATCH_TRIPLE
138 				}
139 			}
140 		}
141 
142 		basegfx::B2DLineJoin XLineJointtoB2DLineJoin(XLineJoint eLineJoint)
143 		{
144 			switch(eLineJoint)
145 			{
146 				case XLINEJOINT_MIDDLE :
147 				{
148 					return basegfx::B2DLINEJOIN_MIDDLE;
149 				}
150 				case XLINEJOINT_BEVEL :
151 				{
152 					return basegfx::B2DLINEJOIN_BEVEL;
153 				}
154 				case XLINEJOINT_MITER :
155 				{
156 					return basegfx::B2DLINEJOIN_MITER;
157 				}
158 				case XLINEJOINT_ROUND :
159 				{
160 					return basegfx::B2DLINEJOIN_ROUND;
161 				}
162 				default :
163 				{
164 					return basegfx::B2DLINEJOIN_NONE; // XLINEJOINT_NONE
165 				}
166 			}
167 		}
168 
169 		basegfx::B2DVector RectPointToB2DVector(RECT_POINT eRectPoint)
170 		{
171 			basegfx::B2DVector aRetval(0.0, 0.0);
172 
173 			// position changes X
174 			switch(eRectPoint)
175 			{
176 				case RP_LT: case RP_LM: case RP_LB:
177 				{
178 					aRetval.setX(-1.0);
179 					break;
180 				}
181 
182 				case RP_RT: case RP_RM: case RP_RB:
183 				{
184 					aRetval.setX(1.0);
185 					break;
186 				}
187 
188 				default :
189 				{
190 					break;
191 				}
192 			}
193 
194 			// position changes Y
195 			switch(eRectPoint)
196 			{
197 				case RP_LT: case RP_MT: case RP_RT:
198 				{
199 					aRetval.setY(-1.0);
200 					break;
201 				}
202 
203 				case RP_LB: case RP_MB: case RP_RB:
204 				{
205 					aRetval.setY(1.0);
206 					break;
207 				}
208 
209 				default :
210 				{
211 					break;
212 				}
213 			}
214 
215 			return aRetval;
216 		}
217 	} // end of anonymous namespace
218 } // end of namespace drawinglayer
219 
220 //////////////////////////////////////////////////////////////////////////////
221 
222 namespace drawinglayer
223 {
224 	namespace primitive2d
225 	{
226 		attribute::SdrLineAttribute createNewSdrLineAttribute(const SfxItemSet& rSet)
227 		{
228 			const XLineStyle eStyle(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue());
229 
230 			if(XLINE_NONE != eStyle)
231 			{
232 				sal_uInt16 nTransparence(((const XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue());
233 
234 				if(nTransparence > 100)
235 				{
236 					nTransparence = 100;
237 				}
238 
239 				if(100 != nTransparence)
240 				{
241 					const sal_uInt32 nWidth(((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue());
242 					const Color aColor(((const XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetColorValue());
243 					const XLineJoint eJoint(((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue());
244 					::std::vector< double > aDotDashArray;
245 					double fFullDotDashLen(0.0);
246 
247 					if(XLINE_DASH == eStyle)
248 					{
249 						const XDash& rDash = ((const XLineDashItem&)(rSet.Get(XATTR_LINEDASH))).GetDashValue();
250 
251 						if(rDash.GetDots() || rDash.GetDashes())
252 						{
253 							fFullDotDashLen = rDash.CreateDotDashArray(aDotDashArray, (double)nWidth);
254 						}
255 					}
256 
257 					return attribute::SdrLineAttribute(
258 						XLineJointtoB2DLineJoin(eJoint),
259 						(double)nWidth,
260 						(double)nTransparence * 0.01,
261 						aColor.getBColor(),
262 						aDotDashArray,
263 						fFullDotDashLen);
264 				}
265 			}
266 
267 			return attribute::SdrLineAttribute();
268 		}
269 
270 		attribute::SdrLineStartEndAttribute createNewSdrLineStartEndAttribute(
271 			const SfxItemSet& rSet,
272 			double fWidth)
273 		{
274 			const sal_Int32 nTempStartWidth(((const XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue());
275 			const sal_Int32 nTempEndWidth(((const XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue());
276 			basegfx::B2DPolyPolygon aStartPolyPolygon;
277 			basegfx::B2DPolyPolygon aEndPolyPolygon;
278 			double fStartWidth(0.0);
279 			double fEndWidth(0.0);
280 			bool bStartActive(false);
281 			bool bEndActive(false);
282 			bool bStartCentered(true);
283 			bool bEndCentered(true);
284 
285 			if(nTempStartWidth)
286 			{
287 				if(nTempStartWidth < 0L)
288 				{
289 					fStartWidth = ((double)(-nTempStartWidth) * fWidth) * 0.01;
290 				}
291 				else
292 				{
293 					fStartWidth = (double)nTempStartWidth;
294 				}
295 
296 				if(0.0 != fStartWidth)
297 				{
298 					aStartPolyPolygon = basegfx::B2DPolyPolygon(((const XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue());
299 
300 					if(aStartPolyPolygon.count() && aStartPolyPolygon.getB2DPolygon(0L).count())
301 					{
302 						bStartActive = true;
303 						bStartCentered = ((const XLineStartCenterItem&)(rSet.Get(XATTR_LINESTARTCENTER))).GetValue();
304 					}
305 				}
306 			}
307 
308 			if(nTempEndWidth)
309 			{
310 				if(nTempEndWidth < 0L)
311 				{
312 					fEndWidth = ((double)(-nTempEndWidth) * fWidth) * 0.01;
313 				}
314 				else
315 				{
316 					fEndWidth = (double)nTempEndWidth;
317 				}
318 
319 				if(0.0 != fEndWidth)
320 				{
321 					aEndPolyPolygon = basegfx::B2DPolyPolygon(((const XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue());
322 
323 					if(aEndPolyPolygon.count() && aEndPolyPolygon.getB2DPolygon(0L).count())
324 					{
325 						bEndActive = true;
326 						bEndCentered = ((const XLineEndCenterItem&)(rSet.Get(XATTR_LINEENDCENTER))).GetValue();
327 					}
328 				}
329 			}
330 
331 			if(bStartActive || bEndActive)
332 			{
333 				return attribute::SdrLineStartEndAttribute(
334 					aStartPolyPolygon, aEndPolyPolygon, fStartWidth, fEndWidth,
335 					bStartActive, bEndActive, bStartCentered, bEndCentered);
336 			}
337 
338 			return attribute::SdrLineStartEndAttribute();
339 		}
340 
341 		attribute::SdrShadowAttribute createNewSdrShadowAttribute(const SfxItemSet& rSet)
342 		{
343 			const bool bShadow(((SdrShadowItem&)rSet.Get(SDRATTR_SHADOW)).GetValue());
344 
345 			if(bShadow)
346 			{
347 				sal_uInt16 nTransparence(((SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue());
348 
349 				if(nTransparence > 100)
350 				{
351 					nTransparence = 100;
352 				}
353 
354 				if(nTransparence)
355 				{
356 					sal_uInt16 nFillTransparence(((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue());
357 
358 					if(nFillTransparence > 100)
359 					{
360 						nFillTransparence = 100;
361 					}
362 
363 					if(nTransparence == nFillTransparence)
364 					{
365 						// shadow does not really have an own transparence, but the application
366 						// sets the shadow transparence equal to the object transparence for
367 						// convenience. This is not useful for primitive creation, so take
368 						// this as no shadow transparence
369 						nTransparence = 0;
370 					}
371 				}
372 
373 				if(100 != nTransparence)
374 				{
375 					const basegfx::B2DVector aOffset(
376 						(double)((SdrShadowXDistItem&)(rSet.Get(SDRATTR_SHADOWXDIST))).GetValue(),
377 						(double)((SdrShadowYDistItem&)(rSet.Get(SDRATTR_SHADOWYDIST))).GetValue());
378 					const Color aColor(((SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
379 
380 					return attribute::SdrShadowAttribute(aOffset, (double)nTransparence * 0.01, aColor.getBColor());
381 				}
382 			}
383 
384 			return attribute::SdrShadowAttribute();
385 		}
386 
387 		attribute::SdrFillAttribute createNewSdrFillAttribute(const SfxItemSet& rSet)
388 		{
389 			const XFillStyle eStyle(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue());
390 
391 			if(XFILL_NONE != eStyle)
392 			{
393 				sal_uInt16 nTransparence(((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue());
394 
395 				if(nTransparence > 100)
396 				{
397 					nTransparence = 100;
398 				}
399 
400 				if(100 != nTransparence)
401 				{
402 					const Color aColor(((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue());
403 					attribute::FillGradientAttribute aGradient;
404 					attribute::FillHatchAttribute aHatch;
405 					attribute::SdrFillBitmapAttribute aBitmap;
406 
407 					switch(eStyle)
408 					{
409 						case XFILL_NONE : // for warnings
410 						case XFILL_SOLID :
411 						{
412 							// nothing to do, color is defined
413 							break;
414 						}
415 						case XFILL_GRADIENT :
416 						{
417 							XGradient aXGradient(((XFillGradientItem&)(rSet.Get(XATTR_FILLGRADIENT))).GetGradientValue());
418 
419 							const Color aStartColor(aXGradient.GetStartColor());
420 							const sal_uInt16 nStartIntens(aXGradient.GetStartIntens());
421 							basegfx::BColor aStart(aStartColor.getBColor());
422 
423 							if(nStartIntens != 100)
424 							{
425 								const basegfx::BColor aBlack;
426 								aStart = interpolate(aBlack, aStart, (double)nStartIntens * 0.01);
427 							}
428 
429 							const Color aEndColor(aXGradient.GetEndColor());
430 							const sal_uInt16 nEndIntens(aXGradient.GetEndIntens());
431 							basegfx::BColor aEnd(aEndColor.getBColor());
432 
433 							if(nEndIntens != 100)
434 							{
435 								const basegfx::BColor aBlack;
436 								aEnd = interpolate(aBlack, aEnd, (double)nEndIntens * 0.01);
437 							}
438 
439 							aGradient = attribute::FillGradientAttribute(
440 								XGradientStyleToGradientStyle(aXGradient.GetGradientStyle()),
441 								(double)aXGradient.GetBorder() * 0.01,
442 								(double)aXGradient.GetXOffset() * 0.01,
443 								(double)aXGradient.GetYOffset() * 0.01,
444 								(double)aXGradient.GetAngle() * F_PI1800,
445 								aStart,
446 								aEnd,
447 								((const XGradientStepCountItem&)rSet.Get(XATTR_GRADIENTSTEPCOUNT)).GetValue());
448 
449 							break;
450 						}
451 						case XFILL_HATCH :
452 						{
453 							const XHatch& rHatch(((XFillHatchItem&)(rSet.Get(XATTR_FILLHATCH))).GetHatchValue());
454 							const Color aColorB(rHatch.GetColor());
455 
456 							aHatch = attribute::FillHatchAttribute(
457 								XHatchStyleToHatchStyle(rHatch.GetHatchStyle()),
458 								(double)rHatch.GetDistance(),
459 								(double)rHatch.GetAngle() * F_PI1800,
460 								aColorB.getBColor(),
461 								((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue());
462 
463 							break;
464 						}
465 						case XFILL_BITMAP :
466 						{
467 							aBitmap = createNewSdrFillBitmapAttribute(rSet);
468 							break;
469 						}
470 					}
471 
472 					return attribute::SdrFillAttribute(
473 						(double)nTransparence * 0.01,
474 						aColor.getBColor(),
475 						aGradient,
476 						aHatch,
477 						aBitmap);
478 				}
479 			}
480 
481 			return attribute::SdrFillAttribute();
482 		}
483 
484 		// #i101508# Support handing over given text-to-border distances
485 		attribute::SdrTextAttribute createNewSdrTextAttribute(
486 			const SfxItemSet& rSet,
487 			const SdrText& rText,
488 			const sal_Int32* pLeft,
489 			const sal_Int32* pUpper,
490 			const sal_Int32* pRight,
491 			const sal_Int32* pLower)
492 		{
493 			const SdrTextObj& rTextObj = rText.GetObject();
494 
495 			if(rText.GetOutlinerParaObject() && rText.GetModel())
496 			{
497 				// added TextEdit text suppression
498 				bool bInEditMode(false);
499 
500 				if(rText.GetObject().getTextCount() > 1)
501 				{
502 					bInEditMode = rTextObj.IsInEditMode() && rText.GetObject().getActiveText() == &rText;
503 				}
504 				else
505 				{
506 					bInEditMode = rTextObj.IsInEditMode();
507 				}
508 
509                 OutlinerParaObject aOutlinerParaObject(*rText.GetOutlinerParaObject());
510 
511                 if(bInEditMode)
512                 {
513                     OutlinerParaObject* pTempObj = rTextObj.GetEditOutlinerParaObject();
514 
515                     if(pTempObj)
516                     {
517                         aOutlinerParaObject = *pTempObj;
518                         delete pTempObj;
519                     }
520                     else
521                     {
522                         // #i100537#
523                         // GetEditOutlinerParaObject() returning no object does not mean that
524                         // text edit mode is not active. Do not reset the flag here
525                         // bInEditMode = false;
526                     }
527                 }
528 
529 			    const SdrFitToSizeType eFit(rTextObj.GetFitToSize());
530 			    const SdrTextAniKind eAniKind(rTextObj.GetTextAniKind());
531 
532 				// #i107346#
533 				const SdrOutliner& rDrawTextOutliner = rText.GetModel()->GetDrawOutliner(&rTextObj);
534 				const bool bWrongSpell(rDrawTextOutliner.GetControlWord() & EE_CNTRL_ONLINESPELLING);
535 
536 			    return attribute::SdrTextAttribute(
537 				    rText,
538                     aOutlinerParaObject,
539 				    ((const XFormTextStyleItem&)rSet.Get(XATTR_FORMTXTSTYLE)).GetValue(),
540 					pLeft ? *pLeft : rTextObj.GetTextLeftDistance(),
541 					pUpper ? *pUpper : rTextObj.GetTextUpperDistance(),
542 					pRight ? *pRight : rTextObj.GetTextRightDistance(),
543 					pLower ? *pLower : rTextObj.GetTextLowerDistance(),
544                     rTextObj.GetTextHorizontalAdjust(rSet),
545                     rTextObj.GetTextVerticalAdjust(rSet),
546 				    ((const SdrTextContourFrameItem&)rSet.Get(SDRATTR_TEXT_CONTOURFRAME)).GetValue(),
547 				    (SDRTEXTFIT_PROPORTIONAL == eFit || SDRTEXTFIT_ALLLINES == eFit),
548 				    ((const XFormTextHideFormItem&)rSet.Get(XATTR_FORMTXTHIDEFORM)).GetValue(),
549 				    SDRTEXTANI_BLINK == eAniKind,
550 				    SDRTEXTANI_SCROLL == eAniKind || SDRTEXTANI_ALTERNATE == eAniKind || SDRTEXTANI_SLIDE == eAniKind,
551                     bInEditMode,
552                     ((const SdrTextFixedCellHeightItem&)rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue(),
553 					bWrongSpell);
554 			}
555 
556 			return attribute::SdrTextAttribute();
557 		}
558 
559 		attribute::FillGradientAttribute createNewTransparenceGradientAttribute(const SfxItemSet& rSet)
560 		{
561 			const SfxPoolItem* pGradientItem;
562 
563 			if(SFX_ITEM_SET == rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, sal_True, &pGradientItem)
564 				&& ((XFillFloatTransparenceItem*)pGradientItem)->IsEnabled())
565 			{
566 				// test if float transparence is completely transparent
567 				const XGradient& rGradient = ((XFillFloatTransparenceItem*)pGradientItem)->GetGradientValue();
568 				const sal_uInt8 nStartLuminance(rGradient.GetStartColor().GetLuminance());
569 				const sal_uInt8 nEndLuminance(rGradient.GetEndColor().GetLuminance());
570 				const bool bCompletelyTransparent(0xff == nStartLuminance && 0xff == nEndLuminance);
571 
572 				if(!bCompletelyTransparent)
573 				{
574 					const double fStartLum(nStartLuminance / 255.0);
575 					const double fEndLum(nEndLuminance / 255.0);
576 
577 					return attribute::FillGradientAttribute(
578 						XGradientStyleToGradientStyle(rGradient.GetGradientStyle()),
579 						(double)rGradient.GetBorder() * 0.01,
580 						(double)rGradient.GetXOffset() * 0.01,
581 						(double)rGradient.GetYOffset() * 0.01,
582 						(double)rGradient.GetAngle() * F_PI1800,
583 						basegfx::BColor(fStartLum, fStartLum, fStartLum),
584 						basegfx::BColor(fEndLum, fEndLum, fEndLum),
585 						0);
586 				}
587 			}
588 
589 			return attribute::FillGradientAttribute();
590 		}
591 
592 		attribute::SdrFillBitmapAttribute createNewSdrFillBitmapAttribute(const SfxItemSet& rSet)
593 		{
594 			Bitmap aBitmap((((const XFillBitmapItem&)(rSet.Get(XATTR_FILLBITMAP))).GetBitmapValue()).GetBitmap());
595 
596 			// make sure it's not empty, use default instead
597 			if(aBitmap.IsEmpty())
598 			{
599 				aBitmap = Bitmap(Size(4,4), 8);
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