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 
30 #include <svx/sdr/attribute/sdrformtextattribute.hxx>
31 #include <basegfx/vector/b2enums.hxx>
32 #include <svl/itemset.hxx>
33 #include <svx/xftdiit.hxx>
34 #include <svx/xftstit.hxx>
35 #include <svx/xftshxy.hxx>
36 #include <svx/xftshtit.hxx>
37 #include <svx/xtextit0.hxx>
38 #include <svx/xftadit.hxx>
39 #include <svx/xftshit.hxx>
40 #include <svx/xftshcit.hxx>
41 #include <svx/xftmrit.hxx>
42 #include <svx/xftouit.hxx>
43 #include <svx/sdshtitm.hxx>
44 #include <svx/xlntrit.hxx>
45 #include <svx/sdshcitm.hxx>
46 #include <svx/xlnclit.hxx>
47 #include <svx/xlnwtit.hxx>
48 #include <svx/xlinjoit.hxx>
49 #include <svx/xlineit0.hxx>
50 #include <svx/xdash.hxx>
51 #include <svx/xlndsit.hxx>
52 #include <drawinglayer/attribute/lineattribute.hxx>
53 #include <drawinglayer/attribute/strokeattribute.hxx>
54 #include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx>
55 
56 //////////////////////////////////////////////////////////////////////////////
57 // helper to get line, stroke and transparence attributes from SfxItemSet
58 
59 namespace
60 {
61 	basegfx::B2DLineJoin impGetB2DLineJoin(XLineJoint eLineJoint)
62 	{
63 		switch(eLineJoint)
64 		{
65 			case XLINEJOINT_MIDDLE	:
66 			{
67 				return basegfx::B2DLINEJOIN_MIDDLE;
68 			}
69 			case XLINEJOINT_BEVEL	:
70 			{
71 				return basegfx::B2DLINEJOIN_BEVEL;
72 			}
73 			case XLINEJOINT_MITER	:
74 			{
75 				return basegfx::B2DLINEJOIN_MITER;
76 			}
77 			case XLINEJOINT_ROUND	:
78 			{
79 				return basegfx::B2DLINEJOIN_ROUND;
80 			}
81 			default :
82 			{
83 				return basegfx::B2DLINEJOIN_NONE; // XLINEJOINT_NONE
84 			}
85 		}
86 	}
87 
88     sal_uInt8 impGetStrokeTransparence(bool bShadow, const SfxItemSet& rSet)
89 	{
90 		sal_uInt8 nRetval;
91 
92 		if(bShadow)
93 		{
94 			nRetval = (sal_uInt8)((((SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue() * 255) / 100);
95 		}
96 		else
97 		{
98 			nRetval = (sal_uInt8)((((XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue() * 255) / 100);
99 		}
100 
101 		return nRetval;
102 	}
103 
104 	drawinglayer::attribute::LineAttribute impGetLineAttribute(bool bShadow, const SfxItemSet& rSet)
105 	{
106 		basegfx::BColor aColorAttribute;
107 
108 		if(bShadow)
109 		{
110 			const Color aShadowColor(((SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
111 			aColorAttribute = aShadowColor.getBColor();
112 		}
113 		else
114 		{
115 			const Color aLineColor(((XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetColorValue());
116 			aColorAttribute = aLineColor.getBColor();
117 		}
118 
119 		const sal_uInt32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
120 		const XLineJoint eLineJoint = ((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue();
121 
122 		return drawinglayer::attribute::LineAttribute(aColorAttribute, (double)nLineWidth, impGetB2DLineJoin(eLineJoint));
123 	}
124 
125     drawinglayer::attribute::StrokeAttribute impGetStrokeAttribute(const SfxItemSet& rSet)
126 	{
127 		const XLineStyle eLineStyle = ((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue();
128 		double fFullDotDashLen(0.0);
129 		::std::vector< double > aDotDashArray;
130 
131 		if(XLINE_DASH == eLineStyle)
132 		{
133 			const XDash& rDash = ((const XLineDashItem&)(rSet.Get(XATTR_LINEDASH))).GetDashValue();
134 
135 			if(rDash.GetDots() || rDash.GetDashes())
136 			{
137         		const sal_uInt32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
138 				fFullDotDashLen = rDash.CreateDotDashArray(aDotDashArray, (double)nLineWidth);
139 			}
140 		}
141 
142 		return drawinglayer::attribute::StrokeAttribute(aDotDashArray, fFullDotDashLen);
143 	}
144 } // end of anonymous namespace
145 
146 //////////////////////////////////////////////////////////////////////////////
147 
148 namespace drawinglayer
149 {
150 	namespace attribute
151 	{
152 	    class ImpSdrFormTextAttribute
153 	    {
154 		public:
155 			// refcounter
156 			sal_uInt32								mnRefCount;
157 
158             // FormText (FontWork) Attributes
159 		    sal_Int32								mnFormTextDistance;		// distance from line in upright direction
160 		    sal_Int32								mnFormTextStart;		// shift from polygon start
161 		    sal_Int32								mnFormTextShdwXVal;		// shadow distance or 10th degrees
162 		    sal_Int32								mnFormTextShdwYVal;		// shadow distance or scaling
163 		    sal_uInt16								mnFormTextShdwTransp;	// shadow transparence
164 		    XFormTextStyle							meFormTextStyle;		// on/off and char orientation
165 		    XFormTextAdjust							meFormTextAdjust;		// adjustment (left/right/center) and scale
166 		    XFormTextShadow							meFormTextShadow;		// shadow mode
167 		    Color									maFormTextShdwColor;	// shadow color
168 
169             // outline attributes; used when getFormTextOutline() is true and (for
170             // shadow) when getFormTextShadow() != XFTSHADOW_NONE
171             SdrFormTextOutlineAttribute				maOutline;
172             SdrFormTextOutlineAttribute				maShadowOutline;
173 
174 		    // bitfield
175 		    unsigned								mbFormTextMirror : 1;	// change orientation
176 		    unsigned								mbFormTextOutline : 1;	// show contour of objects
177 
178 		    ImpSdrFormTextAttribute(const SfxItemSet& rSet)
179 			:	mnRefCount(0),
180 				mnFormTextDistance(((const XFormTextDistanceItem&)rSet.Get(XATTR_FORMTXTDISTANCE)).GetValue()),
181 				mnFormTextStart(((const XFormTextStartItem&)rSet.Get(XATTR_FORMTXTSTART)).GetValue()),
182 				mnFormTextShdwXVal(((const XFormTextShadowXValItem&)rSet.Get(XATTR_FORMTXTSHDWXVAL)).GetValue()),
183 				mnFormTextShdwYVal(((const XFormTextShadowYValItem&)rSet.Get(XATTR_FORMTXTSHDWYVAL)).GetValue()),
184 				mnFormTextShdwTransp(((const XFormTextShadowTranspItem&)rSet.Get(XATTR_FORMTXTSHDWTRANSP)).GetValue()),
185 				meFormTextStyle(((const XFormTextStyleItem&)rSet.Get(XATTR_FORMTXTSTYLE)).GetValue()),
186 				meFormTextAdjust(((const XFormTextAdjustItem&)rSet.Get(XATTR_FORMTXTADJUST)).GetValue()),
187 				meFormTextShadow(((const XFormTextShadowItem&)rSet.Get(XATTR_FORMTXTSHADOW)).GetValue()),
188 				maFormTextShdwColor(((const XFormTextShadowColorItem&)rSet.Get(XATTR_FORMTXTSHDWCOLOR)).GetColorValue()),
189 				maOutline(),
190 				maShadowOutline(),
191 				mbFormTextMirror(((const XFormTextMirrorItem&)rSet.Get(XATTR_FORMTXTMIRROR)).GetValue()),
192 				mbFormTextOutline(((const XFormTextOutlineItem&)rSet.Get(XATTR_FORMTXTOUTLINE)).GetValue())
193 			{
194 				if(getFormTextOutline())
195 				{
196 					const StrokeAttribute aStrokeAttribute(impGetStrokeAttribute(rSet));
197 
198 					// also need to prepare attributes for outlines
199 					{
200 						const LineAttribute aLineAttribute(impGetLineAttribute(false, rSet));
201 						const sal_uInt8 nTransparence(impGetStrokeTransparence(false, rSet));
202 
203 						maOutline = SdrFormTextOutlineAttribute(
204 							aLineAttribute, aStrokeAttribute, nTransparence);
205 					}
206 
207 					if(XFTSHADOW_NONE != getFormTextShadow())
208 					{
209 						// also need to prepare attributes for shadow outlines
210 						const LineAttribute aLineAttribute(impGetLineAttribute(true, rSet));
211 						const sal_uInt8 nTransparence(impGetStrokeTransparence(true, rSet));
212 
213 						maShadowOutline = SdrFormTextOutlineAttribute(
214 							aLineAttribute, aStrokeAttribute, nTransparence);
215 					}
216 				}
217 			}
218 
219 			ImpSdrFormTextAttribute()
220 			:	mnRefCount(0),
221 				mnFormTextDistance(0),
222 				mnFormTextStart(0),
223 				mnFormTextShdwXVal(0),
224 				mnFormTextShdwYVal(0),
225 				mnFormTextShdwTransp(0),
226 				meFormTextStyle(XFT_NONE),
227 				meFormTextAdjust(XFT_CENTER),
228 				meFormTextShadow(XFTSHADOW_NONE),
229 				maFormTextShdwColor(),
230 				maOutline(),
231 				maShadowOutline(),
232 				mbFormTextMirror(false),
233 				mbFormTextOutline(false)
234 			{
235 			}
236 
237 		    // data read access
238 		    sal_Int32 getFormTextDistance() const { return mnFormTextDistance; }
239 		    sal_Int32 getFormTextStart() const { return mnFormTextStart; }
240 		    sal_Int32 getFormTextShdwXVal() const { return mnFormTextShdwXVal; }
241 		    sal_Int32 getFormTextShdwYVal() const { return mnFormTextShdwYVal; }
242 		    sal_uInt16 getFormTextShdwTransp() const { return mnFormTextShdwTransp; }
243 		    XFormTextStyle getFormTextStyle() const { return meFormTextStyle; }
244 		    XFormTextAdjust getFormTextAdjust() const { return meFormTextAdjust; }
245 		    XFormTextShadow getFormTextShadow() const { return meFormTextShadow; }
246 		    Color getFormTextShdwColor() const { return maFormTextShdwColor; }
247             const SdrFormTextOutlineAttribute& getOutline() const { return maOutline; }
248             const SdrFormTextOutlineAttribute& getShadowOutline() const { return maShadowOutline; }
249             bool getFormTextMirror() const { return mbFormTextMirror; }
250 		    bool getFormTextOutline() const { return mbFormTextOutline; }
251 
252             // compare operator
253 			bool operator==(const ImpSdrFormTextAttribute& rCandidate) const
254 			{
255 				return (getFormTextDistance() == rCandidate.getFormTextDistance()
256 					&& getFormTextStart() == rCandidate.getFormTextStart()
257 					&& getFormTextShdwXVal() == rCandidate.getFormTextShdwXVal()
258 					&& getFormTextShdwYVal() == rCandidate.getFormTextShdwYVal()
259 					&& getFormTextShdwTransp() == rCandidate.getFormTextShdwTransp()
260 					&& getFormTextStyle() == rCandidate.getFormTextStyle()
261 					&& getFormTextAdjust() == rCandidate.getFormTextAdjust()
262 					&& getFormTextShadow() == rCandidate.getFormTextShadow()
263 					&& getFormTextShdwColor() == rCandidate.getFormTextShdwColor()
264 					&& getOutline() == rCandidate.getOutline()
265 					&& getShadowOutline() == rCandidate.getShadowOutline()
266 					&& getFormTextMirror() == rCandidate.getFormTextMirror()
267 					&& getFormTextOutline() == rCandidate.getFormTextOutline());
268 			}
269 
270             static ImpSdrFormTextAttribute* get_global_default()
271             {
272                 static ImpSdrFormTextAttribute* pDefault = 0;
273 
274                 if(!pDefault)
275                 {
276                     pDefault = new ImpSdrFormTextAttribute();
277 
278                     // never delete; start with RefCount 1, not 0
279     			    pDefault->mnRefCount++;
280                 }
281 
282                 return pDefault;
283             }
284 	    };
285 
286         SdrFormTextAttribute::SdrFormTextAttribute(const SfxItemSet& rSet)
287 		:	mpSdrFormTextAttribute(new ImpSdrFormTextAttribute(rSet))
288 		{
289 		}
290 
291 		SdrFormTextAttribute::SdrFormTextAttribute()
292         :	mpSdrFormTextAttribute(ImpSdrFormTextAttribute::get_global_default())
293 		{
294 			mpSdrFormTextAttribute->mnRefCount++;
295 		}
296 
297         SdrFormTextAttribute::SdrFormTextAttribute(const SdrFormTextAttribute& rCandidate)
298 		:	mpSdrFormTextAttribute(rCandidate.mpSdrFormTextAttribute)
299 		{
300 			mpSdrFormTextAttribute->mnRefCount++;
301 		}
302 
303 		SdrFormTextAttribute::~SdrFormTextAttribute()
304 		{
305 			if(mpSdrFormTextAttribute->mnRefCount)
306 			{
307 				mpSdrFormTextAttribute->mnRefCount--;
308 			}
309 			else
310 			{
311 				delete mpSdrFormTextAttribute;
312 			}
313 		}
314 
315         bool SdrFormTextAttribute::isDefault() const
316         {
317             return mpSdrFormTextAttribute == ImpSdrFormTextAttribute::get_global_default();
318         }
319 
320         SdrFormTextAttribute& SdrFormTextAttribute::operator=(const SdrFormTextAttribute& rCandidate)
321 		{
322 			if(rCandidate.mpSdrFormTextAttribute != mpSdrFormTextAttribute)
323 			{
324 				if(mpSdrFormTextAttribute->mnRefCount)
325 				{
326 					mpSdrFormTextAttribute->mnRefCount--;
327 				}
328 				else
329 				{
330 					delete mpSdrFormTextAttribute;
331 				}
332 
333 				mpSdrFormTextAttribute = rCandidate.mpSdrFormTextAttribute;
334 				mpSdrFormTextAttribute->mnRefCount++;
335 			}
336 
337 			return *this;
338 		}
339 
340 		bool SdrFormTextAttribute::operator==(const SdrFormTextAttribute& rCandidate) const
341 		{
342 			if(rCandidate.mpSdrFormTextAttribute == mpSdrFormTextAttribute)
343 			{
344 				return true;
345 			}
346 
347 			if(rCandidate.isDefault() != isDefault())
348 			{
349 				return false;
350 			}
351 
352 			return (*rCandidate.mpSdrFormTextAttribute == *mpSdrFormTextAttribute);
353 		}
354 
355 	    sal_Int32 SdrFormTextAttribute::getFormTextDistance() const
356 		{
357 			return mpSdrFormTextAttribute->getFormTextDistance();
358 		}
359 
360 		sal_Int32 SdrFormTextAttribute::getFormTextStart() const
361 		{
362 			return mpSdrFormTextAttribute->getFormTextStart();
363 		}
364 
365 		sal_Int32 SdrFormTextAttribute::getFormTextShdwXVal() const
366 		{
367 			return mpSdrFormTextAttribute->getFormTextShdwXVal();
368 		}
369 
370 		sal_Int32 SdrFormTextAttribute::getFormTextShdwYVal() const
371 		{
372 			return mpSdrFormTextAttribute->getFormTextShdwYVal();
373 		}
374 
375 		sal_uInt16 SdrFormTextAttribute::getFormTextShdwTransp() const
376 		{
377 			return mpSdrFormTextAttribute->getFormTextShdwTransp();
378 		}
379 
380 		XFormTextStyle SdrFormTextAttribute::getFormTextStyle() const
381 		{
382 			return mpSdrFormTextAttribute->getFormTextStyle();
383 		}
384 
385 		XFormTextAdjust SdrFormTextAttribute::getFormTextAdjust() const
386 		{
387 			return mpSdrFormTextAttribute->getFormTextAdjust();
388 		}
389 
390 		XFormTextShadow SdrFormTextAttribute::getFormTextShadow() const
391 		{
392 			return mpSdrFormTextAttribute->getFormTextShadow();
393 		}
394 
395 		Color SdrFormTextAttribute::getFormTextShdwColor() const
396 		{
397 			return mpSdrFormTextAttribute->getFormTextShdwColor();
398 		}
399 
400 		const SdrFormTextOutlineAttribute& SdrFormTextAttribute::getOutline() const
401 		{
402 			return mpSdrFormTextAttribute->getOutline();
403 		}
404 
405 		const SdrFormTextOutlineAttribute& SdrFormTextAttribute::getShadowOutline() const
406 		{
407 			return mpSdrFormTextAttribute->getShadowOutline();
408 		}
409 
410 		bool SdrFormTextAttribute::getFormTextMirror() const
411 		{
412 			return mpSdrFormTextAttribute->getFormTextMirror();
413 		}
414 
415 		bool SdrFormTextAttribute::getFormTextOutline() const
416 		{
417 			return mpSdrFormTextAttribute->getFormTextOutline();
418 		}
419 	} // end of namespace attribute
420 } // end of namespace drawinglayer
421 
422 //////////////////////////////////////////////////////////////////////////////
423 // eof
424