Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / oox / source / drawingml / linepropertiescontext.cxx
blobdbcae7caf5c70d2cd425d24021236e451a149db7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <drawingml/linepropertiescontext.hxx>
21 #include <drawingml/misccontexts.hxx>
22 #include <drawingml/lineproperties.hxx>
23 #include <oox/helper/attributelist.hxx>
24 #include <oox/token/namespaces.hxx>
25 #include <oox/token/tokens.hxx>
26 #include <docmodel/theme/FormatScheme.hxx>
28 using namespace ::oox::core;
29 using namespace ::com::sun::star::uno;
30 using namespace ::com::sun::star::xml::sax;
32 // CT_LineProperties
34 namespace oox::drawingml {
36 LinePropertiesContext::LinePropertiesContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs,
37 LineProperties& rLineProperties, model::LineStyle* pLineStyle) noexcept
38 : ContextHandler2(rParent)
39 , mpLineStyle(pLineStyle)
40 , mrLineProperties(rLineProperties)
42 mrLineProperties.moLineWidth = rAttribs.getInteger( XML_w );
43 mrLineProperties.moLineCompound = rAttribs.getToken( XML_cmpd );
44 mrLineProperties.moLineCap = rAttribs.getToken( XML_cap );
46 if (mpLineStyle)
48 mpLineStyle->mnWidth = rAttribs.getInteger(XML_w, 0);
50 switch (rAttribs.getToken(XML_cap, XML_TOKEN_INVALID))
52 case XML_rnd: mpLineStyle->meCapType = model::CapType::Round; break;
53 case XML_sq: mpLineStyle->meCapType = model::CapType::Square; break;
54 case XML_flat: mpLineStyle->meCapType = model::CapType::Flat; break;
55 default:
56 mpLineStyle->meCapType = model::CapType::Unset; break;
59 switch (rAttribs.getToken(XML_cmpd, XML_TOKEN_INVALID))
61 case XML_sng: mpLineStyle->meCompoundLineType = model::CompoundLineType::Single; break;
62 case XML_dbl: mpLineStyle->meCompoundLineType = model::CompoundLineType::Double; break;
63 case XML_thickThin: mpLineStyle->meCompoundLineType = model::CompoundLineType::ThickThin_Double; break;
64 case XML_thinThick: mpLineStyle->meCompoundLineType = model::CompoundLineType::ThinThick_Double; break;
65 case XML_tri: mpLineStyle->meCompoundLineType = model::CompoundLineType::Triple; break;
66 default:
67 mpLineStyle->meCompoundLineType = model::CompoundLineType::Unset; break;
70 switch (rAttribs.getToken(XML_algn, XML_TOKEN_INVALID))
72 case XML_ctr: mpLineStyle->mePenAlignment = model::PenAlignmentType::Center; break;
73 case XML_in: mpLineStyle->mePenAlignment = model::PenAlignmentType::Inset; break;
74 default:
75 mpLineStyle->mePenAlignment = model::PenAlignmentType::Unset; break;
80 LinePropertiesContext::~LinePropertiesContext()
84 ContextHandlerRef LinePropertiesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
86 switch( nElement )
88 // LineFillPropertiesGroup
89 case A_TOKEN( noFill ):
90 case A_TOKEN( solidFill ):
91 case A_TOKEN( gradFill ):
92 case A_TOKEN( pattFill ):
94 model::FillStyle* pFillStyle = nullptr;
95 if (mpLineStyle)
97 pFillStyle = &mpLineStyle->maLineFillStyle;
99 return FillPropertiesContext::createFillContext(*this, nElement, rAttribs, mrLineProperties.maLineFill, pFillStyle);
101 break;
103 // LineDashPropertiesGroup
104 case A_TOKEN( prstDash ): // CT_PresetLineDashProperties
106 mrLineProperties.moPresetDash = rAttribs.getToken( XML_val );
108 if (mpLineStyle)
110 auto& rLineDash = mpLineStyle->maLineDash;
111 switch (rAttribs.getToken(XML_val, XML_TOKEN_INVALID))
113 case XML_solid: rLineDash.mePresetType = model::PresetDashType::Solid; break;
114 case XML_dot: rLineDash.mePresetType = model::PresetDashType::Dot; break;
115 case XML_dash: rLineDash.mePresetType = model::PresetDashType::Dash; break;
116 case XML_lgDash: rLineDash.mePresetType = model::PresetDashType::LargeDash; break;
117 case XML_dashDot: rLineDash.mePresetType = model::PresetDashType::DashDot; break;
118 case XML_lgDashDot: rLineDash.mePresetType = model::PresetDashType::LargeDashDot; break;
119 case XML_lgDashDotDot: rLineDash.mePresetType = model::PresetDashType::LargeDashDotDot; break;
120 case XML_sysDash: rLineDash.mePresetType = model::PresetDashType::SystemDash; break;
121 case XML_sysDot: rLineDash.mePresetType = model::PresetDashType::SystemDot; break;
122 case XML_sysDashDot: rLineDash.mePresetType = model::PresetDashType::SystemDashDot; break;
123 case XML_sysDashDotDot: rLineDash.mePresetType = model::PresetDashType::SystemDashDotDot; break;
124 default:
125 rLineDash.mePresetType = model::PresetDashType::Unset; break;
129 break;
130 case A_TOKEN( custDash ): // CT_DashStopList
131 return this;
132 case A_TOKEN( ds ):
134 // 'a:ds' has 2 attributes : 'd' and 'sp'
135 // both are of type 'a:ST_PositivePercentage'
136 // according to the specs Office will read percentages formatted with a trailing percent sign
137 // or formatted as 1000th of a percent without a trailing percent sign, but only write percentages
138 // as 1000th's of a percent without a trailing percent sign.
139 // The code below takes care of both scenarios by converting to '1000th of a percent' always
140 OUString aStr;
141 sal_Int32 nDashLength = 0;
142 aStr = rAttribs.getStringDefaulted( XML_d);
143 if ( aStr.endsWith("%") )
145 // Ends with a '%'
146 aStr = aStr.copy(0, aStr.getLength() - 1);
147 aStr = aStr.trim();
148 nDashLength = aStr.toInt32();
150 // Convert to 1000th of a percent
151 nDashLength *= 1000;
153 else
155 nDashLength = rAttribs.getInteger( XML_d, 0 );
158 sal_Int32 nSpaceLength = 0;
159 aStr = rAttribs.getStringDefaulted( XML_sp);
160 if ( aStr.endsWith("%") )
162 // Ends with a '%'
163 aStr = aStr.copy(0, aStr.getLength() - 1);
164 aStr = aStr.trim();
165 nSpaceLength = aStr.toInt32();
167 // Convert to 1000th of a percent
168 nSpaceLength *= 1000;
170 else
172 nSpaceLength = rAttribs.getInteger( XML_sp, 0 );
175 mrLineProperties.maCustomDash.emplace_back( nDashLength, nSpaceLength );
177 if (mpLineStyle)
179 mpLineStyle->maLineDash.maCustomList.push_back({ nDashLength, nSpaceLength });
182 break;
184 // LineJoinPropertiesGroup
185 case A_TOKEN( round ):
186 case A_TOKEN( bevel ):
187 case A_TOKEN( miter ):
189 sal_Int32 nToken = getBaseToken(nElement);
190 mrLineProperties.moLineJoint = nToken;
192 if (mpLineStyle)
194 switch (nToken)
196 case XML_round: mpLineStyle->maLineJoin.meType = model::LineJoinType::Round; break;
197 case XML_bevel: mpLineStyle->maLineJoin.meType = model::LineJoinType::Bevel; break;
198 case XML_miter: mpLineStyle->maLineJoin.meType = model::LineJoinType::Miter; break;
199 default:
200 mpLineStyle->maLineJoin.meType = model::LineJoinType::Miter;
202 if (nToken == XML_miter)
204 sal_Int32 nMiterLimit = rAttribs.getInteger(XML_lim, 0);
205 mpLineStyle->maLineJoin.mnMiterLimit = nMiterLimit;
209 break;
211 case A_TOKEN( headEnd ): // CT_LineEndProperties
212 case A_TOKEN( tailEnd ): // CT_LineEndProperties
213 { // ST_LineEndType
214 bool bTailEnd = nElement == A_TOKEN( tailEnd );
215 LineArrowProperties& rArrowProps = bTailEnd ? mrLineProperties.maEndArrow : mrLineProperties.maStartArrow;
216 rArrowProps.moArrowType = rAttribs.getToken( XML_type );
217 rArrowProps.moArrowWidth = rAttribs.getToken( XML_w );
218 rArrowProps.moArrowLength = rAttribs.getToken( XML_len );
220 if (mpLineStyle)
222 model::LineEndType eLineEndType = model::LineEndType::None;
223 switch (rAttribs.getToken(XML_type, XML_none))
225 case XML_triangle: eLineEndType = model::LineEndType::Triangle; break;
226 case XML_stealth: eLineEndType = model::LineEndType::Stealth; break;
227 case XML_diamond: eLineEndType = model::LineEndType::Diamond; break;
228 case XML_oval: eLineEndType = model::LineEndType::Oval; break;
229 case XML_arrow: eLineEndType = model::LineEndType::Arrow; break;
230 default:
231 case XML_none: eLineEndType = model::LineEndType::None; break;
234 model::LineEndLength eLineEndLength = model::LineEndLength::Unset;
235 switch (rAttribs.getToken(XML_len, XML_TOKEN_INVALID))
237 case XML_sm: eLineEndLength = model::LineEndLength::Small; break;
238 case XML_med: eLineEndLength = model::LineEndLength::Medium; break;
239 case XML_lg: eLineEndLength = model::LineEndLength::Large; break;
240 default:
241 break;
244 model::LineEndWidth eLineEndWidth = model::LineEndWidth::Unset;
245 switch (rAttribs.getToken(XML_w, XML_TOKEN_INVALID))
247 case XML_sm: eLineEndWidth = model::LineEndWidth::Small; break;
248 case XML_med: eLineEndWidth = model::LineEndWidth::Medium; break;
249 case XML_lg: eLineEndWidth = model::LineEndWidth::Large; break;
250 default:
251 break;
254 if (nElement == A_TOKEN(tailEnd))
256 mpLineStyle->maTailEnd.meType = eLineEndType;
257 mpLineStyle->maTailEnd.meLength = eLineEndLength;
258 mpLineStyle->maTailEnd.meWidth = eLineEndWidth;
260 else if (nElement == A_TOKEN(headEnd))
262 mpLineStyle->maHeadEnd.meType = eLineEndType;
263 mpLineStyle->maHeadEnd.meLength = eLineEndLength;
264 mpLineStyle->maHeadEnd.meWidth = eLineEndWidth;
268 break;
270 return nullptr;
275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */