1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/stream.hxx>
21 #include <tools/vcompat.hxx>
22 #include <vcl/lineinfo.hxx>
23 #include <basegfx/polygon/b2dpolypolygon.hxx>
24 #include <basegfx/polygon/b2dpolygontools.hxx>
25 #include <basegfx/polygon/b2dlinegeometry.hxx>
29 ImplLineInfo::ImplLineInfo()
34 , meLineJoin(basegfx::B2DLineJoin::Round
)
35 , meLineCap(css::drawing::LineCap_BUTT
)
36 , meStyle(LineStyle::Solid
)
42 inline bool ImplLineInfo::operator==( const ImplLineInfo
& rB
) const
44 return(meStyle
== rB
.meStyle
45 && mnWidth
== rB
.mnWidth
46 && mnDashCount
== rB
.mnDashCount
47 && mnDashLen
== rB
.mnDashLen
48 && mnDotCount
== rB
.mnDotCount
49 && mnDotLen
== rB
.mnDotLen
50 && mnDistance
== rB
.mnDistance
51 && meLineJoin
== rB
.meLineJoin
52 && meLineCap
== rB
.meLineCap
);
56 LineInfo::LineInfo( LineStyle eStyle
, double nWidth
) : mpImplLineInfo()
58 mpImplLineInfo
->meStyle
= eStyle
;
59 mpImplLineInfo
->mnWidth
= nWidth
;
62 LineInfo::LineInfo( const LineInfo
& ) = default;
64 LineInfo::LineInfo( LineInfo
&& ) = default;
66 LineInfo::~LineInfo() = default;
68 LineInfo
& LineInfo::operator=( const LineInfo
& ) = default;
70 LineInfo
& LineInfo::operator=( LineInfo
&& ) = default;
72 bool LineInfo::operator==( const LineInfo
& rLineInfo
) const
74 return mpImplLineInfo
== rLineInfo
.mpImplLineInfo
;
77 void LineInfo::SetStyle( LineStyle eStyle
)
79 mpImplLineInfo
->meStyle
= eStyle
;
82 void LineInfo::SetWidth( double nWidth
)
84 mpImplLineInfo
->mnWidth
= nWidth
;
87 void LineInfo::SetDashCount( sal_uInt16 nDashCount
)
89 mpImplLineInfo
->mnDashCount
= nDashCount
;
92 void LineInfo::SetDashLen( double nDashLen
)
94 mpImplLineInfo
->mnDashLen
= nDashLen
;
97 void LineInfo::SetDotCount( sal_uInt16 nDotCount
)
99 mpImplLineInfo
->mnDotCount
= nDotCount
;
102 void LineInfo::SetDotLen( double nDotLen
)
104 mpImplLineInfo
->mnDotLen
= nDotLen
;
107 void LineInfo::SetDistance( double nDistance
)
109 mpImplLineInfo
->mnDistance
= nDistance
;
112 void LineInfo::SetLineJoin(basegfx::B2DLineJoin eLineJoin
)
114 mpImplLineInfo
->meLineJoin
= eLineJoin
;
117 void LineInfo::SetLineCap(css::drawing::LineCap eLineCap
)
119 mpImplLineInfo
->meLineCap
= eLineCap
;
122 bool LineInfo::IsDefault() const
124 return( !mpImplLineInfo
->mnWidth
125 && ( LineStyle::Solid
== mpImplLineInfo
->meStyle
)
126 && ( css::drawing::LineCap_BUTT
== mpImplLineInfo
->meLineCap
));
129 SvStream
& ReadLineInfo( SvStream
& rIStm
, LineInfo
& rLineInfo
)
131 VersionCompatRead
aCompat( rIStm
);
132 sal_uInt16
nTmp16(0);
135 rIStm
.ReadUInt16( nTmp16
);
136 rLineInfo
.mpImplLineInfo
->meStyle
= static_cast<LineStyle
>(nTmp16
);
137 rIStm
.ReadInt32( nTmp32
);
138 rLineInfo
.mpImplLineInfo
->mnWidth
= nTmp32
;
140 if( aCompat
.GetVersion() >= 2 )
143 rIStm
.ReadUInt16( rLineInfo
.mpImplLineInfo
->mnDashCount
).ReadInt32( nTmp32
);
144 rLineInfo
.mpImplLineInfo
->mnDashLen
= nTmp32
;
145 rIStm
.ReadUInt16( rLineInfo
.mpImplLineInfo
->mnDotCount
).ReadInt32( nTmp32
);
146 rLineInfo
.mpImplLineInfo
->mnDotLen
= nTmp32
;
147 rIStm
.ReadInt32( nTmp32
);
148 rLineInfo
.mpImplLineInfo
->mnDistance
= nTmp32
;
151 if( aCompat
.GetVersion() >= 3 )
154 rIStm
.ReadUInt16( nTmp16
);
155 rLineInfo
.mpImplLineInfo
->meLineJoin
= static_cast<basegfx::B2DLineJoin
>(nTmp16
);
158 if( aCompat
.GetVersion() >= 4 )
161 rIStm
.ReadUInt16( nTmp16
);
162 rLineInfo
.mpImplLineInfo
->meLineCap
= static_cast<css::drawing::LineCap
>(nTmp16
);
165 if( aCompat
.GetVersion() >= 5 )
168 rIStm
.ReadDouble( rLineInfo
.mpImplLineInfo
->mnWidth
);
169 rIStm
.ReadDouble( rLineInfo
.mpImplLineInfo
->mnDashLen
);
170 rIStm
.ReadDouble( rLineInfo
.mpImplLineInfo
->mnDotLen
);
171 rIStm
.ReadDouble( rLineInfo
.mpImplLineInfo
->mnDistance
);
177 SvStream
& WriteLineInfo( SvStream
& rOStm
, const LineInfo
& rLineInfo
)
179 VersionCompatWrite
aCompat( rOStm
, 5 );
182 rOStm
.WriteUInt16( static_cast<sal_uInt16
>(rLineInfo
.mpImplLineInfo
->meStyle
) )
183 .WriteInt32( basegfx::fround( rLineInfo
.mpImplLineInfo
->mnWidth
));
186 rOStm
.WriteUInt16( rLineInfo
.mpImplLineInfo
->mnDashCount
)
187 .WriteInt32( basegfx::fround( rLineInfo
.mpImplLineInfo
->mnDashLen
));
188 rOStm
.WriteUInt16( rLineInfo
.mpImplLineInfo
->mnDotCount
)
189 .WriteInt32( basegfx::fround( rLineInfo
.mpImplLineInfo
->mnDotLen
));
190 rOStm
.WriteInt32( basegfx::fround( rLineInfo
.mpImplLineInfo
->mnDistance
));
193 rOStm
.WriteUInt16( static_cast<sal_uInt16
>(rLineInfo
.mpImplLineInfo
->meLineJoin
) );
196 rOStm
.WriteUInt16( static_cast<sal_uInt16
>(rLineInfo
.mpImplLineInfo
->meLineCap
) );
199 rOStm
.WriteDouble( rLineInfo
.mpImplLineInfo
->mnWidth
);
200 rOStm
.WriteDouble( rLineInfo
.mpImplLineInfo
->mnDashLen
);
201 rOStm
.WriteDouble( rLineInfo
.mpImplLineInfo
->mnDotLen
);
202 rOStm
.WriteDouble( rLineInfo
.mpImplLineInfo
->mnDistance
);
207 void LineInfo::applyToB2DPolyPolygon(
208 basegfx::B2DPolyPolygon
& io_rLinePolyPolygon
,
209 basegfx::B2DPolyPolygon
& o_rFillPolyPolygon
) const
211 o_rFillPolyPolygon
.clear();
213 if(!io_rLinePolyPolygon
.count())
216 if(LineStyle::Dash
== GetStyle())
218 ::std::vector
< double > fDotDashArray
;
219 const double fDashLen(GetDashLen());
220 const double fDotLen(GetDotLen());
221 const double fDistance(GetDistance());
223 for(sal_uInt16
a(0); a
< GetDashCount(); a
++)
225 fDotDashArray
.push_back(fDashLen
);
226 fDotDashArray
.push_back(fDistance
);
229 for(sal_uInt16
b(0); b
< GetDotCount(); b
++)
231 fDotDashArray
.push_back(fDotLen
);
232 fDotDashArray
.push_back(fDistance
);
235 const double fAccumulated(::std::accumulate(fDotDashArray
.begin(), fDotDashArray
.end(), 0.0));
237 if(fAccumulated
> 0.0)
239 basegfx::B2DPolyPolygon aResult
;
241 for(auto const& rPolygon
: io_rLinePolyPolygon
)
243 basegfx::B2DPolyPolygon aLineTarget
;
244 basegfx::utils::applyLineDashing(
248 aResult
.append(aLineTarget
);
251 io_rLinePolyPolygon
= aResult
;
255 if(!(GetWidth() > 1 && io_rLinePolyPolygon
.count()))
258 const double fHalfLineWidth((GetWidth() * 0.5) + 0.5);
260 for(auto const& rPolygon
: io_rLinePolyPolygon
)
262 o_rFillPolyPolygon
.append(basegfx::utils::createAreaGeometry(
269 io_rLinePolyPolygon
.clear();
272 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */