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() :
30 meStyle ( LineStyle::Solid
),
37 meLineJoin ( basegfx::B2DLineJoin::Round
),
38 meLineCap ( css::drawing::LineCap_BUTT
)
42 ImplLineInfo::ImplLineInfo( const ImplLineInfo
& rImplLineInfo
) :
43 meStyle ( rImplLineInfo
.meStyle
),
44 mnWidth ( rImplLineInfo
.mnWidth
),
45 mnDashCount ( rImplLineInfo
.mnDashCount
),
46 mnDashLen ( rImplLineInfo
.mnDashLen
),
47 mnDotCount ( rImplLineInfo
.mnDotCount
),
48 mnDotLen ( rImplLineInfo
.mnDotLen
),
49 mnDistance ( rImplLineInfo
.mnDistance
),
50 meLineJoin ( rImplLineInfo
.meLineJoin
),
51 meLineCap ( rImplLineInfo
.meLineCap
)
55 inline bool ImplLineInfo::operator==( const ImplLineInfo
& rB
) const
57 return(meStyle
== rB
.meStyle
58 && mnWidth
== rB
.mnWidth
59 && mnDashCount
== rB
.mnDashCount
60 && mnDashLen
== rB
.mnDashLen
61 && mnDotCount
== rB
.mnDotCount
62 && mnDotLen
== rB
.mnDotLen
63 && mnDistance
== rB
.mnDistance
64 && meLineJoin
== rB
.meLineJoin
65 && meLineCap
== rB
.meLineCap
);
69 LineInfo::LineInfo( LineStyle eStyle
, long nWidth
) : mpImplLineInfo()
71 mpImplLineInfo
->meStyle
= eStyle
;
72 mpImplLineInfo
->mnWidth
= nWidth
;
75 LineInfo::LineInfo( const LineInfo
& rLineInfo
) : mpImplLineInfo(rLineInfo
.mpImplLineInfo
)
79 LineInfo::LineInfo( LineInfo
&& rLineInfo
) : mpImplLineInfo(std::move(rLineInfo
.mpImplLineInfo
))
87 LineInfo
& LineInfo::operator=( const LineInfo
& rLineInfo
)
89 mpImplLineInfo
= rLineInfo
.mpImplLineInfo
;
93 LineInfo
& LineInfo::operator=( LineInfo
&& rLineInfo
)
95 mpImplLineInfo
= std::move(rLineInfo
.mpImplLineInfo
);
99 bool LineInfo::operator==( const LineInfo
& rLineInfo
) const
101 return mpImplLineInfo
== rLineInfo
.mpImplLineInfo
;
104 void LineInfo::SetStyle( LineStyle eStyle
)
106 mpImplLineInfo
->meStyle
= eStyle
;
109 void LineInfo::SetWidth( long nWidth
)
111 mpImplLineInfo
->mnWidth
= nWidth
;
114 void LineInfo::SetDashCount( sal_uInt16 nDashCount
)
116 mpImplLineInfo
->mnDashCount
= nDashCount
;
119 void LineInfo::SetDashLen( long nDashLen
)
121 mpImplLineInfo
->mnDashLen
= nDashLen
;
124 void LineInfo::SetDotCount( sal_uInt16 nDotCount
)
126 mpImplLineInfo
->mnDotCount
= nDotCount
;
129 void LineInfo::SetDotLen( long nDotLen
)
131 mpImplLineInfo
->mnDotLen
= nDotLen
;
134 void LineInfo::SetDistance( long nDistance
)
136 mpImplLineInfo
->mnDistance
= nDistance
;
139 void LineInfo::SetLineJoin(basegfx::B2DLineJoin eLineJoin
)
142 if(eLineJoin
!= mpImplLineInfo
->meLineJoin
)
144 mpImplLineInfo
->meLineJoin
= eLineJoin
;
148 void LineInfo::SetLineCap(css::drawing::LineCap eLineCap
)
150 if(eLineCap
!= mpImplLineInfo
->meLineCap
)
152 mpImplLineInfo
->meLineCap
= eLineCap
;
156 bool LineInfo::IsDefault() const
158 return( !mpImplLineInfo
->mnWidth
159 && ( LineStyle::Solid
== mpImplLineInfo
->meStyle
)
160 && ( css::drawing::LineCap_BUTT
== mpImplLineInfo
->meLineCap
));
163 SvStream
& ReadLineInfo( SvStream
& rIStm
, LineInfo
& rLineInfo
)
165 VersionCompat
aCompat( rIStm
, StreamMode::READ
);
166 sal_uInt16
nTmp16(0);
169 rIStm
.ReadUInt16( nTmp16
); rLineInfo
.mpImplLineInfo
->meStyle
= (LineStyle
) nTmp16
;
170 rIStm
.ReadInt32( nTmp32
);
171 rLineInfo
.mpImplLineInfo
->mnWidth
= nTmp32
;
173 if( aCompat
.GetVersion() >= 2 )
176 rIStm
.ReadUInt16( rLineInfo
.mpImplLineInfo
->mnDashCount
).ReadInt32( nTmp32
);
177 rLineInfo
.mpImplLineInfo
->mnDashLen
= nTmp32
;
178 rIStm
.ReadUInt16( rLineInfo
.mpImplLineInfo
->mnDotCount
).ReadInt32( nTmp32
);
179 rLineInfo
.mpImplLineInfo
->mnDotLen
= nTmp32
;
180 rIStm
.ReadInt32( nTmp32
);
181 rLineInfo
.mpImplLineInfo
->mnDistance
= nTmp32
;
184 if( aCompat
.GetVersion() >= 3 )
187 rIStm
.ReadUInt16( nTmp16
); rLineInfo
.mpImplLineInfo
->meLineJoin
= (basegfx::B2DLineJoin
) nTmp16
;
190 if( aCompat
.GetVersion() >= 4 )
193 rIStm
.ReadUInt16( nTmp16
); rLineInfo
.mpImplLineInfo
->meLineCap
= (css::drawing::LineCap
) nTmp16
;
199 SvStream
& WriteLineInfo( SvStream
& rOStm
, const LineInfo
& rLineInfo
)
201 VersionCompat
aCompat( rOStm
, StreamMode::WRITE
, 4 );
204 rOStm
.WriteUInt16( (sal_uInt16
)rLineInfo
.mpImplLineInfo
->meStyle
)
205 .WriteInt32( rLineInfo
.mpImplLineInfo
->mnWidth
);
208 rOStm
.WriteUInt16( rLineInfo
.mpImplLineInfo
->mnDashCount
)
209 .WriteInt32( rLineInfo
.mpImplLineInfo
->mnDashLen
);
210 rOStm
.WriteUInt16( rLineInfo
.mpImplLineInfo
->mnDotCount
)
211 .WriteInt32( rLineInfo
.mpImplLineInfo
->mnDotLen
);
212 rOStm
.WriteInt32( rLineInfo
.mpImplLineInfo
->mnDistance
);
215 rOStm
.WriteUInt16( static_cast<sal_uInt16
>(rLineInfo
.mpImplLineInfo
->meLineJoin
) );
218 rOStm
.WriteUInt16( (sal_uInt16
)rLineInfo
.mpImplLineInfo
->meLineCap
);
223 void LineInfo::applyToB2DPolyPolygon(
224 basegfx::B2DPolyPolygon
& io_rLinePolyPolygon
,
225 basegfx::B2DPolyPolygon
& o_rFillPolyPolygon
) const
227 o_rFillPolyPolygon
.clear();
229 if(io_rLinePolyPolygon
.count())
231 if(LineStyle::Dash
== GetStyle())
233 ::std::vector
< double > fDotDashArray
;
234 const double fDashLen(GetDashLen());
235 const double fDotLen(GetDotLen());
236 const double fDistance(GetDistance());
238 for(sal_uInt16
a(0); a
< GetDashCount(); a
++)
240 fDotDashArray
.push_back(fDashLen
);
241 fDotDashArray
.push_back(fDistance
);
244 for(sal_uInt16
b(0); b
< GetDotCount(); b
++)
246 fDotDashArray
.push_back(fDotLen
);
247 fDotDashArray
.push_back(fDistance
);
250 const double fAccumulated(::std::accumulate(fDotDashArray
.begin(), fDotDashArray
.end(), 0.0));
252 if(fAccumulated
> 0.0)
254 basegfx::B2DPolyPolygon aResult
;
256 for(sal_uInt32
c(0); c
< io_rLinePolyPolygon
.count(); c
++)
258 basegfx::B2DPolyPolygon aLineTraget
;
259 basegfx::tools::applyLineDashing(
260 io_rLinePolyPolygon
.getB2DPolygon(c
),
263 aResult
.append(aLineTraget
);
266 io_rLinePolyPolygon
= aResult
;
270 if(GetWidth() > 1 && io_rLinePolyPolygon
.count())
272 const double fHalfLineWidth((GetWidth() * 0.5) + 0.5);
274 for(sal_uInt32
a(0); a
< io_rLinePolyPolygon
.count(); a
++)
276 o_rFillPolyPolygon
.append(basegfx::tools::createAreaGeometry(
277 io_rLinePolyPolygon
.getB2DPolygon(a
),
283 io_rLinePolyPolygon
.clear();
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */