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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_drawinglayer.hxx"
26 
27 #include <drawinglayer/attribute/strokeattribute.hxx>
28 #include <numeric>
29 
30 //////////////////////////////////////////////////////////////////////////////
31 
32 namespace drawinglayer
33 {
34 	namespace attribute
35 	{
36 		class ImpStrokeAttribute
37 		{
38         public:
39 		    // refcounter
40 		    sal_uInt32								mnRefCount;
41 
42             // data definitions
43 			::std::vector< double >						maDotDashArray;			// array of double which defines the dot-dash pattern
44 			double										mfFullDotDashLen;		// sum of maDotDashArray (for convenience)
45 
ImpStrokeAttribute(const::std::vector<double> & rDotDashArray,double fFullDotDashLen)46 			ImpStrokeAttribute(
47 				const ::std::vector< double >& rDotDashArray,
48 				double fFullDotDashLen)
49 		    :	mnRefCount(0),
50 				maDotDashArray(rDotDashArray),
51 				mfFullDotDashLen(fFullDotDashLen)
52 			{
53 			}
54 
55 			// data read access
getDotDashArray() const56 			const ::std::vector< double >& getDotDashArray() const { return maDotDashArray; }
getFullDotDashLen() const57             double getFullDotDashLen() const
58             {
59                 if(0.0 == mfFullDotDashLen && maDotDashArray.size())
60                 {
61                     // calculate length on demand
62                     const double fAccumulated(::std::accumulate(maDotDashArray.begin(), maDotDashArray.end(), 0.0));
63                     const_cast< ImpStrokeAttribute* >(this)->mfFullDotDashLen = fAccumulated;
64                 }
65 
66                 return mfFullDotDashLen;
67             }
68 
operator ==(const ImpStrokeAttribute & rCandidate) const69             bool operator==(const ImpStrokeAttribute& rCandidate) const
70 			{
71 				return (getDotDashArray() == rCandidate.getDotDashArray()
72                     && getFullDotDashLen() == rCandidate.getFullDotDashLen());
73 			}
74 
get_global_default()75             static ImpStrokeAttribute* get_global_default()
76             {
77                 static ImpStrokeAttribute* pDefault = 0;
78 
79                 if(!pDefault)
80                 {
81                     pDefault = new ImpStrokeAttribute(
82 			            std::vector< double >(),
83 			            0.0);
84 
85                     // never delete; start with RefCount 1, not 0
86     			    pDefault->mnRefCount++;
87                 }
88 
89                 return pDefault;
90             }
91 		};
92 
StrokeAttribute(const::std::vector<double> & rDotDashArray,double fFullDotDashLen)93         StrokeAttribute::StrokeAttribute(
94 			const ::std::vector< double >& rDotDashArray,
95 			double fFullDotDashLen)
96 		:	mpStrokeAttribute(new ImpStrokeAttribute(
97                 rDotDashArray, fFullDotDashLen))
98 		{
99 		}
100 
StrokeAttribute()101 		StrokeAttribute::StrokeAttribute()
102         :	mpStrokeAttribute(ImpStrokeAttribute::get_global_default())
103 		{
104 			mpStrokeAttribute->mnRefCount++;
105 		}
106 
StrokeAttribute(const StrokeAttribute & rCandidate)107         StrokeAttribute::StrokeAttribute(const StrokeAttribute& rCandidate)
108 		:	mpStrokeAttribute(rCandidate.mpStrokeAttribute)
109 		{
110 			mpStrokeAttribute->mnRefCount++;
111 		}
112 
~StrokeAttribute()113 		StrokeAttribute::~StrokeAttribute()
114 		{
115 			if(mpStrokeAttribute->mnRefCount)
116 			{
117 				mpStrokeAttribute->mnRefCount--;
118 			}
119 			else
120 			{
121 				delete mpStrokeAttribute;
122 			}
123 		}
124 
isDefault() const125         bool StrokeAttribute::isDefault() const
126         {
127             return mpStrokeAttribute == ImpStrokeAttribute::get_global_default();
128         }
129 
operator =(const StrokeAttribute & rCandidate)130         StrokeAttribute& StrokeAttribute::operator=(const StrokeAttribute& rCandidate)
131 		{
132 			if(rCandidate.mpStrokeAttribute != mpStrokeAttribute)
133 			{
134 				if(mpStrokeAttribute->mnRefCount)
135 				{
136 					mpStrokeAttribute->mnRefCount--;
137 				}
138 				else
139 				{
140 					delete mpStrokeAttribute;
141 				}
142 
143 				mpStrokeAttribute = rCandidate.mpStrokeAttribute;
144 				mpStrokeAttribute->mnRefCount++;
145 			}
146 
147 			return *this;
148 		}
149 
operator ==(const StrokeAttribute & rCandidate) const150         bool StrokeAttribute::operator==(const StrokeAttribute& rCandidate) const
151 		{
152 			if(rCandidate.mpStrokeAttribute == mpStrokeAttribute)
153 			{
154 				return true;
155 			}
156 
157 			if(rCandidate.isDefault() != isDefault())
158 			{
159 				return false;
160 			}
161 
162 			return (*rCandidate.mpStrokeAttribute == *mpStrokeAttribute);
163 		}
164 
getDotDashArray() const165         const ::std::vector< double >& StrokeAttribute::getDotDashArray() const
166         {
167             return mpStrokeAttribute->getDotDashArray();
168         }
169 
getFullDotDashLen() const170 		double StrokeAttribute::getFullDotDashLen() const
171         {
172             return mpStrokeAttribute->getFullDotDashLen();
173         }
174 	} // end of namespace attribute
175 } // end of namespace drawinglayer
176 
177 //////////////////////////////////////////////////////////////////////////////
178 // eof
179