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
, sal_Int32 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( sal_Int32 nWidth
)
84 mpImplLineInfo
->mnWidth
= nWidth
;
87 void LineInfo::SetDashCount( sal_uInt16 nDashCount
)
89 mpImplLineInfo
->mnDashCount
= nDashCount
;
92 void LineInfo::SetDashLen( sal_Int32 nDashLen
)
94 mpImplLineInfo
->mnDashLen
= nDashLen
;
97 void LineInfo::SetDotCount( sal_uInt16 nDotCount
)
99 mpImplLineInfo
->mnDotCount
= nDotCount
;
102 void LineInfo::SetDotLen( sal_Int32 nDotLen
)
104 mpImplLineInfo
->mnDotLen
= nDotLen
;
107 void LineInfo::SetDistance( sal_Int32 nDistance
)
109 mpImplLineInfo
->mnDistance
= nDistance
;
112 void LineInfo::SetLineJoin(basegfx::B2DLineJoin eLineJoin
)
115 if(eLineJoin
!= mpImplLineInfo
->meLineJoin
)
117 mpImplLineInfo
->meLineJoin
= eLineJoin
;
121 void LineInfo::SetLineCap(css::drawing::LineCap eLineCap
)
123 if(eLineCap
!= mpImplLineInfo
->meLineCap
)
125 mpImplLineInfo
->meLineCap
= eLineCap
;
129 bool LineInfo::IsDefault() const
131 return( !mpImplLineInfo
->mnWidth
132 && ( LineStyle::Solid
== mpImplLineInfo
->meStyle
)
133 && ( css::drawing::LineCap_BUTT
== mpImplLineInfo
->meLineCap
));
136 SvStream
& ReadLineInfo( SvStream
& rIStm
, LineInfo
& rLineInfo
)
138 VersionCompat
aCompat( rIStm
, StreamMode::READ
);
139 sal_uInt16
nTmp16(0);
142 rIStm
.ReadUInt16( nTmp16
); rLineInfo
.mpImplLineInfo
->meStyle
= static_cast<LineStyle
>(nTmp16
);
143 rIStm
.ReadInt32( nTmp32
);
144 rLineInfo
.mpImplLineInfo
->mnWidth
= nTmp32
;
146 if( aCompat
.GetVersion() >= 2 )
149 rIStm
.ReadUInt16( rLineInfo
.mpImplLineInfo
->mnDashCount
).ReadInt32( nTmp32
);
150 rLineInfo
.mpImplLineInfo
->mnDashLen
= nTmp32
;
151 rIStm
.ReadUInt16( rLineInfo
.mpImplLineInfo
->mnDotCount
).ReadInt32( nTmp32
);
152 rLineInfo
.mpImplLineInfo
->mnDotLen
= nTmp32
;
153 rIStm
.ReadInt32( nTmp32
);
154 rLineInfo
.mpImplLineInfo
->mnDistance
= nTmp32
;
157 if( aCompat
.GetVersion() >= 3 )
160 rIStm
.ReadUInt16( nTmp16
); rLineInfo
.mpImplLineInfo
->meLineJoin
= static_cast<basegfx::B2DLineJoin
>(nTmp16
);
163 if( aCompat
.GetVersion() >= 4 )
166 rIStm
.ReadUInt16( nTmp16
); rLineInfo
.mpImplLineInfo
->meLineCap
= static_cast<css::drawing::LineCap
>(nTmp16
);
172 SvStream
& WriteLineInfo( SvStream
& rOStm
, const LineInfo
& rLineInfo
)
174 VersionCompat
aCompat( rOStm
, StreamMode::WRITE
, 4 );
177 rOStm
.WriteUInt16( static_cast<sal_uInt16
>(rLineInfo
.mpImplLineInfo
->meStyle
) )
178 .WriteInt32( rLineInfo
.mpImplLineInfo
->mnWidth
);
181 rOStm
.WriteUInt16( rLineInfo
.mpImplLineInfo
->mnDashCount
)
182 .WriteInt32( rLineInfo
.mpImplLineInfo
->mnDashLen
);
183 rOStm
.WriteUInt16( rLineInfo
.mpImplLineInfo
->mnDotCount
)
184 .WriteInt32( rLineInfo
.mpImplLineInfo
->mnDotLen
);
185 rOStm
.WriteInt32( rLineInfo
.mpImplLineInfo
->mnDistance
);
188 rOStm
.WriteUInt16( static_cast<sal_uInt16
>(rLineInfo
.mpImplLineInfo
->meLineJoin
) );
191 rOStm
.WriteUInt16( static_cast<sal_uInt16
>(rLineInfo
.mpImplLineInfo
->meLineCap
) );
196 void LineInfo::applyToB2DPolyPolygon(
197 basegfx::B2DPolyPolygon
& io_rLinePolyPolygon
,
198 basegfx::B2DPolyPolygon
& o_rFillPolyPolygon
) const
200 o_rFillPolyPolygon
.clear();
202 if(io_rLinePolyPolygon
.count())
204 if(LineStyle::Dash
== GetStyle())
206 ::std::vector
< double > fDotDashArray
;
207 const double fDashLen(GetDashLen());
208 const double fDotLen(GetDotLen());
209 const double fDistance(GetDistance());
211 for(sal_uInt16
a(0); a
< GetDashCount(); a
++)
213 fDotDashArray
.push_back(fDashLen
);
214 fDotDashArray
.push_back(fDistance
);
217 for(sal_uInt16
b(0); b
< GetDotCount(); b
++)
219 fDotDashArray
.push_back(fDotLen
);
220 fDotDashArray
.push_back(fDistance
);
223 const double fAccumulated(::std::accumulate(fDotDashArray
.begin(), fDotDashArray
.end(), 0.0));
225 if(fAccumulated
> 0.0)
227 basegfx::B2DPolyPolygon aResult
;
229 for(auto const& rPolygon
: io_rLinePolyPolygon
)
231 basegfx::B2DPolyPolygon aLineTraget
;
232 basegfx::utils::applyLineDashing(
236 aResult
.append(aLineTraget
);
239 io_rLinePolyPolygon
= aResult
;
243 if(GetWidth() > 1 && io_rLinePolyPolygon
.count())
245 const double fHalfLineWidth((GetWidth() * 0.5) + 0.5);
247 for(auto const& rPolygon
: io_rLinePolyPolygon
)
249 o_rFillPolyPolygon
.append(basegfx::utils::createAreaGeometry(
256 io_rLinePolyPolygon
.clear();
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */