xref: /AOO41X/main/vcl/source/gdi/lineinfo.cxx (revision 9f62ea84a806e17e6f2bbff75724a7257a0eb5d9)
1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9f62ea84SAndrew Rist  * distributed with this work for additional information
6*9f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*9f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist  * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9f62ea84SAndrew Rist  * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir #include <tools/stream.hxx>
27cdf0e10cSrcweir #include <tools/vcompat.hxx>
28cdf0e10cSrcweir #include <tools/debug.hxx>
29cdf0e10cSrcweir #include <vcl/lineinfo.hxx>
30cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
31cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
32cdf0e10cSrcweir #include <basegfx/polygon/b2dlinegeometry.hxx>
33cdf0e10cSrcweir #include <numeric>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir DBG_NAME( LineInfo )
36cdf0e10cSrcweir 
37cdf0e10cSrcweir // ----------------
38cdf0e10cSrcweir // - ImplLineInfo -
39cdf0e10cSrcweir // ----------------
40cdf0e10cSrcweir 
41cdf0e10cSrcweir ImplLineInfo::ImplLineInfo() :
42cdf0e10cSrcweir     mnRefCount	( 1 ),
43cdf0e10cSrcweir     meStyle		( LINE_SOLID ),
44cdf0e10cSrcweir 	mnWidth		( 0 ),
45cdf0e10cSrcweir 	mnDashCount	( 0 ),
46cdf0e10cSrcweir 	mnDashLen	( 0 ),
47cdf0e10cSrcweir 	mnDotCount	( 0 ),
48cdf0e10cSrcweir 	mnDotLen	( 0 ),
49cdf0e10cSrcweir 	mnDistance	( 0 ),
50cdf0e10cSrcweir     meLineJoin  ( basegfx::B2DLINEJOIN_ROUND )
51cdf0e10cSrcweir {
52cdf0e10cSrcweir }
53cdf0e10cSrcweir 
54cdf0e10cSrcweir // -----------------------------------------------------------------------
55cdf0e10cSrcweir 
56cdf0e10cSrcweir ImplLineInfo::ImplLineInfo( const ImplLineInfo& rImplLineInfo ) :
57cdf0e10cSrcweir 	mnRefCount	( 1 ),
58cdf0e10cSrcweir     meStyle		( rImplLineInfo.meStyle ),
59cdf0e10cSrcweir 	mnWidth		( rImplLineInfo.mnWidth ),
60cdf0e10cSrcweir 	mnDashCount	( rImplLineInfo.mnDashCount	),
61cdf0e10cSrcweir 	mnDashLen	( rImplLineInfo.mnDashLen ),
62cdf0e10cSrcweir 	mnDotCount	( rImplLineInfo.mnDotCount ),
63cdf0e10cSrcweir 	mnDotLen	( rImplLineInfo.mnDotLen ),
64cdf0e10cSrcweir 	mnDistance	( rImplLineInfo.mnDistance ),
65cdf0e10cSrcweir     meLineJoin  ( rImplLineInfo.meLineJoin )
66cdf0e10cSrcweir {
67cdf0e10cSrcweir }
68cdf0e10cSrcweir 
69cdf0e10cSrcweir // -----------------------------------------------------------------------
70cdf0e10cSrcweir 
71cdf0e10cSrcweir inline bool ImplLineInfo::operator==( const ImplLineInfo& rB ) const
72cdf0e10cSrcweir {
73cdf0e10cSrcweir 	return(meStyle == rB.meStyle
74cdf0e10cSrcweir 		&& mnWidth == rB.mnWidth
75cdf0e10cSrcweir 		&& mnDashCount == rB.mnDashCount
76cdf0e10cSrcweir 		&& mnDashLen == rB.mnDashLen
77cdf0e10cSrcweir 		&& mnDotCount == rB.mnDotCount
78cdf0e10cSrcweir 		&& mnDotLen == rB.mnDotLen
79cdf0e10cSrcweir 		&& mnDistance == rB.mnDistance
80cdf0e10cSrcweir 		&& meLineJoin == rB.meLineJoin);
81cdf0e10cSrcweir }
82cdf0e10cSrcweir 
83cdf0e10cSrcweir // ------------
84cdf0e10cSrcweir // - LineInfo -
85cdf0e10cSrcweir // ------------
86cdf0e10cSrcweir 
87cdf0e10cSrcweir LineInfo::LineInfo( LineStyle eStyle, long nWidth )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir     DBG_CTOR( LineInfo, NULL );
90cdf0e10cSrcweir     mpImplLineInfo = new ImplLineInfo;
91cdf0e10cSrcweir     mpImplLineInfo->meStyle = eStyle;
92cdf0e10cSrcweir     mpImplLineInfo->mnWidth = nWidth;
93cdf0e10cSrcweir }
94cdf0e10cSrcweir 
95cdf0e10cSrcweir // -----------------------------------------------------------------------
96cdf0e10cSrcweir 
97cdf0e10cSrcweir LineInfo::LineInfo( const LineInfo& rLineInfo )
98cdf0e10cSrcweir {
99cdf0e10cSrcweir     DBG_CTOR( LineInfo, NULL );
100cdf0e10cSrcweir     DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );
101cdf0e10cSrcweir     mpImplLineInfo = rLineInfo.mpImplLineInfo;
102cdf0e10cSrcweir     mpImplLineInfo->mnRefCount++;
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir // -----------------------------------------------------------------------
106cdf0e10cSrcweir 
107cdf0e10cSrcweir LineInfo::~LineInfo()
108cdf0e10cSrcweir {
109cdf0e10cSrcweir     DBG_DTOR( LineInfo, NULL );
110cdf0e10cSrcweir     if( !( --mpImplLineInfo->mnRefCount ) )
111cdf0e10cSrcweir         delete mpImplLineInfo;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir // -----------------------------------------------------------------------
115cdf0e10cSrcweir 
116cdf0e10cSrcweir LineInfo& LineInfo::operator=( const LineInfo& rLineInfo )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     DBG_CHKTHIS( LineInfo, NULL );
119cdf0e10cSrcweir     DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir     rLineInfo.mpImplLineInfo->mnRefCount++;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir     if( !( --mpImplLineInfo->mnRefCount ) )
124cdf0e10cSrcweir         delete mpImplLineInfo;
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 	mpImplLineInfo = rLineInfo.mpImplLineInfo;
127cdf0e10cSrcweir     return *this;
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir // -----------------------------------------------------------------------
131cdf0e10cSrcweir 
132cdf0e10cSrcweir sal_Bool LineInfo::operator==( const LineInfo& rLineInfo ) const
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     DBG_CHKTHIS( LineInfo, NULL );
135cdf0e10cSrcweir     DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );
136cdf0e10cSrcweir 
137cdf0e10cSrcweir     return( mpImplLineInfo == rLineInfo.mpImplLineInfo ||
138cdf0e10cSrcweir            *mpImplLineInfo == *rLineInfo.mpImplLineInfo );
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir // -----------------------------------------------------------------------
142cdf0e10cSrcweir 
143cdf0e10cSrcweir void LineInfo::ImplMakeUnique()
144cdf0e10cSrcweir {
145cdf0e10cSrcweir     if( mpImplLineInfo->mnRefCount != 1 )
146cdf0e10cSrcweir 	{
147cdf0e10cSrcweir 		if( mpImplLineInfo->mnRefCount )
148cdf0e10cSrcweir 			mpImplLineInfo->mnRefCount--;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir         mpImplLineInfo = new ImplLineInfo( *mpImplLineInfo );
151cdf0e10cSrcweir 	}
152cdf0e10cSrcweir }
153cdf0e10cSrcweir 
154cdf0e10cSrcweir // -----------------------------------------------------------------------
155cdf0e10cSrcweir 
156cdf0e10cSrcweir void LineInfo::SetStyle( LineStyle eStyle )
157cdf0e10cSrcweir {
158cdf0e10cSrcweir     DBG_CHKTHIS( LineInfo, NULL );
159cdf0e10cSrcweir     ImplMakeUnique();
160cdf0e10cSrcweir     mpImplLineInfo->meStyle = eStyle;
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir // -----------------------------------------------------------------------
164cdf0e10cSrcweir 
165cdf0e10cSrcweir void LineInfo::SetWidth( long nWidth )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir     DBG_CHKTHIS( LineInfo, NULL );
168cdf0e10cSrcweir     ImplMakeUnique();
169cdf0e10cSrcweir     mpImplLineInfo->mnWidth = nWidth;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir // -----------------------------------------------------------------------
173cdf0e10cSrcweir 
174cdf0e10cSrcweir void LineInfo::SetDashCount( sal_uInt16 nDashCount )
175cdf0e10cSrcweir {
176cdf0e10cSrcweir 	DBG_CHKTHIS( LineInfo, NULL );
177cdf0e10cSrcweir 	ImplMakeUnique();
178cdf0e10cSrcweir 	mpImplLineInfo->mnDashCount = nDashCount;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir // -----------------------------------------------------------------------
182cdf0e10cSrcweir 
183cdf0e10cSrcweir void LineInfo::SetDashLen( long nDashLen )
184cdf0e10cSrcweir {
185cdf0e10cSrcweir 	DBG_CHKTHIS( LineInfo, NULL );
186cdf0e10cSrcweir 	ImplMakeUnique();
187cdf0e10cSrcweir 	mpImplLineInfo->mnDashLen = nDashLen;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir // -----------------------------------------------------------------------
191cdf0e10cSrcweir 
192cdf0e10cSrcweir void LineInfo::SetDotCount( sal_uInt16 nDotCount )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir 	DBG_CHKTHIS( LineInfo, NULL );
195cdf0e10cSrcweir 	ImplMakeUnique();
196cdf0e10cSrcweir 	mpImplLineInfo->mnDotCount = nDotCount;
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir // -----------------------------------------------------------------------
200cdf0e10cSrcweir 
201cdf0e10cSrcweir void LineInfo::SetDotLen( long nDotLen )
202cdf0e10cSrcweir {
203cdf0e10cSrcweir 	DBG_CHKTHIS( LineInfo, NULL );
204cdf0e10cSrcweir 	ImplMakeUnique();
205cdf0e10cSrcweir 	mpImplLineInfo->mnDotLen = nDotLen;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
208cdf0e10cSrcweir // -----------------------------------------------------------------------
209cdf0e10cSrcweir 
210cdf0e10cSrcweir void LineInfo::SetDistance( long nDistance )
211cdf0e10cSrcweir {
212cdf0e10cSrcweir 	DBG_CHKTHIS( LineInfo, NULL );
213cdf0e10cSrcweir 	ImplMakeUnique();
214cdf0e10cSrcweir 	mpImplLineInfo->mnDistance = nDistance;
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir // -----------------------------------------------------------------------
218cdf0e10cSrcweir 
219cdf0e10cSrcweir void LineInfo::SetLineJoin(basegfx::B2DLineJoin eLineJoin)
220cdf0e10cSrcweir {
221cdf0e10cSrcweir 	DBG_CHKTHIS( LineInfo, NULL );
222cdf0e10cSrcweir 
223cdf0e10cSrcweir     if(eLineJoin != mpImplLineInfo->meLineJoin)
224cdf0e10cSrcweir     {
225cdf0e10cSrcweir     	ImplMakeUnique();
226cdf0e10cSrcweir         mpImplLineInfo->meLineJoin = eLineJoin;
227cdf0e10cSrcweir     }
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir // -----------------------------------------------------------------------
231cdf0e10cSrcweir 
232cdf0e10cSrcweir SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo )
233cdf0e10cSrcweir {
234cdf0e10cSrcweir     VersionCompat	aCompat( rIStm, STREAM_READ );
235cdf0e10cSrcweir     sal_uInt16			nTmp16;
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     rIStm >> nTmp16; rImplLineInfo.meStyle = (LineStyle) nTmp16;
238cdf0e10cSrcweir     rIStm >> rImplLineInfo.mnWidth;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	if( aCompat.GetVersion() >= 2 )
241cdf0e10cSrcweir 	{
242cdf0e10cSrcweir 		// version 2
243cdf0e10cSrcweir 		rIStm >> rImplLineInfo.mnDashCount >> rImplLineInfo.mnDashLen;
244cdf0e10cSrcweir 		rIStm >> rImplLineInfo.mnDotCount >> rImplLineInfo.mnDotLen;
245cdf0e10cSrcweir 		rIStm >> rImplLineInfo.mnDistance;
246cdf0e10cSrcweir 	}
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 	if( aCompat.GetVersion() >= 3 )
249cdf0e10cSrcweir 	{
250cdf0e10cSrcweir 		// version 3
251cdf0e10cSrcweir         rIStm >> nTmp16; rImplLineInfo.meLineJoin = (basegfx::B2DLineJoin) nTmp16;
252cdf0e10cSrcweir     }
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     return rIStm;
255cdf0e10cSrcweir }
256cdf0e10cSrcweir 
257cdf0e10cSrcweir // -----------------------------------------------------------------------
258cdf0e10cSrcweir 
259cdf0e10cSrcweir SvStream& operator<<( SvStream& rOStm, const ImplLineInfo& rImplLineInfo )
260cdf0e10cSrcweir {
261cdf0e10cSrcweir     VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
262cdf0e10cSrcweir 
263cdf0e10cSrcweir     // version 1
264cdf0e10cSrcweir 	rOStm << (sal_uInt16) rImplLineInfo.meStyle << rImplLineInfo.mnWidth;
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 	// since version2
267cdf0e10cSrcweir 	rOStm << rImplLineInfo.mnDashCount << rImplLineInfo.mnDashLen;
268cdf0e10cSrcweir 	rOStm << rImplLineInfo.mnDotCount << rImplLineInfo.mnDotLen;
269cdf0e10cSrcweir 	rOStm << rImplLineInfo.mnDistance;
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 	// since version3
272cdf0e10cSrcweir 	rOStm << (sal_uInt16) rImplLineInfo.meLineJoin;
273cdf0e10cSrcweir 
274cdf0e10cSrcweir     return rOStm;
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir // -----------------------------------------------------------------------
278cdf0e10cSrcweir 
279cdf0e10cSrcweir SvStream& operator>>( SvStream& rIStm, LineInfo& rLineInfo )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     rLineInfo.ImplMakeUnique();
282cdf0e10cSrcweir     return( rIStm >> *rLineInfo.mpImplLineInfo );
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir // -----------------------------------------------------------------------
286cdf0e10cSrcweir 
287cdf0e10cSrcweir SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo )
288cdf0e10cSrcweir {
289cdf0e10cSrcweir     return( rOStm << *rLineInfo.mpImplLineInfo );
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir // -----------------------------------------------------------------------
293cdf0e10cSrcweir 
294cdf0e10cSrcweir bool LineInfo::isDashDotOrFatLineUsed() const
295cdf0e10cSrcweir {
296cdf0e10cSrcweir 	return (LINE_DASH == GetStyle() || GetWidth() > 1);
297cdf0e10cSrcweir }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir // -----------------------------------------------------------------------
300cdf0e10cSrcweir 
301cdf0e10cSrcweir void LineInfo::applyToB2DPolyPolygon(
302cdf0e10cSrcweir 	basegfx::B2DPolyPolygon& io_rLinePolyPolygon,
303cdf0e10cSrcweir 	basegfx::B2DPolyPolygon& o_rFillPolyPolygon) const
304cdf0e10cSrcweir {
305cdf0e10cSrcweir 	o_rFillPolyPolygon.clear();
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 	if(io_rLinePolyPolygon.count())
308cdf0e10cSrcweir 	{
309cdf0e10cSrcweir 		if(LINE_DASH == GetStyle())
310cdf0e10cSrcweir 		{
311cdf0e10cSrcweir 			::std::vector< double > fDotDashArray;
312cdf0e10cSrcweir 			const double fDashLen(GetDashLen());
313cdf0e10cSrcweir 			const double fDotLen(GetDotLen());
314cdf0e10cSrcweir 			const double fDistance(GetDistance());
315cdf0e10cSrcweir 
316cdf0e10cSrcweir 			for(sal_uInt16 a(0); a < GetDashCount(); a++)
317cdf0e10cSrcweir 			{
318cdf0e10cSrcweir 				fDotDashArray.push_back(fDashLen);
319cdf0e10cSrcweir 				fDotDashArray.push_back(fDistance);
320cdf0e10cSrcweir 			}
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 			for(sal_uInt16 b(0); b < GetDotCount(); b++)
323cdf0e10cSrcweir 			{
324cdf0e10cSrcweir 				fDotDashArray.push_back(fDotLen);
325cdf0e10cSrcweir 				fDotDashArray.push_back(fDistance);
326cdf0e10cSrcweir 			}
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 			const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 			if(fAccumulated > 0.0)
331cdf0e10cSrcweir 			{
332cdf0e10cSrcweir 				basegfx::B2DPolyPolygon aResult;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 				for(sal_uInt32 c(0); c < io_rLinePolyPolygon.count(); c++)
335cdf0e10cSrcweir 				{
336cdf0e10cSrcweir 					basegfx::B2DPolyPolygon aLineTraget;
337cdf0e10cSrcweir 					basegfx::tools::applyLineDashing(
338cdf0e10cSrcweir 						io_rLinePolyPolygon.getB2DPolygon(c),
339cdf0e10cSrcweir 						fDotDashArray,
340cdf0e10cSrcweir 						&aLineTraget);
341cdf0e10cSrcweir 					aResult.append(aLineTraget);
342cdf0e10cSrcweir 				}
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 				io_rLinePolyPolygon = aResult;
345cdf0e10cSrcweir 			}
346cdf0e10cSrcweir 		}
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 		if(GetWidth() > 1 && io_rLinePolyPolygon.count())
349cdf0e10cSrcweir 		{
350cdf0e10cSrcweir 			const double fHalfLineWidth((GetWidth() * 0.5) + 0.5);
351cdf0e10cSrcweir 
352cdf0e10cSrcweir 			for(sal_uInt32 a(0); a < io_rLinePolyPolygon.count(); a++)
353cdf0e10cSrcweir 			{
354cdf0e10cSrcweir 				o_rFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
355cdf0e10cSrcweir 					io_rLinePolyPolygon.getB2DPolygon(a),
356cdf0e10cSrcweir 					fHalfLineWidth,
357cdf0e10cSrcweir 					GetLineJoin()));
358cdf0e10cSrcweir 			}
359cdf0e10cSrcweir 
360cdf0e10cSrcweir 			io_rLinePolyPolygon.clear();
361cdf0e10cSrcweir 		}
362cdf0e10cSrcweir 	}
363cdf0e10cSrcweir }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir // -----------------------------------------------------------------------
366