tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / oox / source / drawingml / linepropertiescontext.cxx
blob5a4c1fe449b8bc5451ae3ed77526140db36cbf7c
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;
30 // CT_LineProperties
32 namespace oox::drawingml {
34 LinePropertiesContext::LinePropertiesContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs,
35 LineProperties& rLineProperties, model::LineStyle* pLineStyle) noexcept
36 : ContextHandler2(rParent)
37 , mpLineStyle(pLineStyle)
38 , mrLineProperties(rLineProperties)
40 mrLineProperties.moLineWidth = rAttribs.getInteger( XML_w );
41 mrLineProperties.moLineCompound = rAttribs.getToken( XML_cmpd );
42 mrLineProperties.moLineCap = rAttribs.getToken( XML_cap );
44 if (mpLineStyle)
46 mpLineStyle->mnWidth = rAttribs.getInteger(XML_w, 0);
48 switch (rAttribs.getToken(XML_cap, XML_TOKEN_INVALID))
50 case XML_rnd: mpLineStyle->meCapType = model::CapType::Round; break;
51 case XML_sq: mpLineStyle->meCapType = model::CapType::Square; break;
52 case XML_flat: mpLineStyle->meCapType = model::CapType::Flat; break;
53 default:
54 mpLineStyle->meCapType = model::CapType::Unset; break;
57 switch (rAttribs.getToken(XML_cmpd, XML_TOKEN_INVALID))
59 case XML_sng: mpLineStyle->meCompoundLineType = model::CompoundLineType::Single; break;
60 case XML_dbl: mpLineStyle->meCompoundLineType = model::CompoundLineType::Double; break;
61 case XML_thickThin: mpLineStyle->meCompoundLineType = model::CompoundLineType::ThickThin_Double; break;
62 case XML_thinThick: mpLineStyle->meCompoundLineType = model::CompoundLineType::ThinThick_Double; break;
63 case XML_tri: mpLineStyle->meCompoundLineType = model::CompoundLineType::Triple; break;
64 default:
65 mpLineStyle->meCompoundLineType = model::CompoundLineType::Unset; break;
68 switch (rAttribs.getToken(XML_algn, XML_TOKEN_INVALID))
70 case XML_ctr: mpLineStyle->mePenAlignment = model::PenAlignmentType::Center; break;
71 case XML_in: mpLineStyle->mePenAlignment = model::PenAlignmentType::Inset; break;
72 default:
73 mpLineStyle->mePenAlignment = model::PenAlignmentType::Unset; break;
78 LinePropertiesContext::~LinePropertiesContext()
82 ContextHandlerRef LinePropertiesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
84 switch( nElement )
86 // LineFillPropertiesGroup
87 case A_TOKEN( noFill ):
88 case A_TOKEN( solidFill ):
89 case A_TOKEN( gradFill ):
90 case A_TOKEN( pattFill ):
92 model::FillStyle* pFillStyle = nullptr;
93 if (mpLineStyle)
95 pFillStyle = &mpLineStyle->maLineFillStyle;
97 return FillPropertiesContext::createFillContext(*this, nElement, rAttribs, mrLineProperties.maLineFill, pFillStyle);
99 break;
101 // LineDashPropertiesGroup
102 case A_TOKEN( prstDash ): // CT_PresetLineDashProperties
104 mrLineProperties.moPresetDash = rAttribs.getToken( XML_val );
106 if (mpLineStyle)
108 auto& rLineDash = mpLineStyle->maLineDash;
109 switch (rAttribs.getToken(XML_val, XML_TOKEN_INVALID))
111 case XML_solid: rLineDash.mePresetType = model::PresetDashType::Solid; break;
112 case XML_dot: rLineDash.mePresetType = model::PresetDashType::Dot; break;
113 case XML_dash: rLineDash.mePresetType = model::PresetDashType::Dash; break;
114 case XML_lgDash: rLineDash.mePresetType = model::PresetDashType::LargeDash; break;
115 case XML_dashDot: rLineDash.mePresetType = model::PresetDashType::DashDot; break;
116 case XML_lgDashDot: rLineDash.mePresetType = model::PresetDashType::LargeDashDot; break;
117 case XML_lgDashDotDot: rLineDash.mePresetType = model::PresetDashType::LargeDashDotDot; break;
118 case XML_sysDash: rLineDash.mePresetType = model::PresetDashType::SystemDash; break;
119 case XML_sysDot: rLineDash.mePresetType = model::PresetDashType::SystemDot; break;
120 case XML_sysDashDot: rLineDash.mePresetType = model::PresetDashType::SystemDashDot; break;
121 case XML_sysDashDotDot: rLineDash.mePresetType = model::PresetDashType::SystemDashDotDot; break;
122 default:
123 rLineDash.mePresetType = model::PresetDashType::Unset; break;
127 break;
128 case A_TOKEN( custDash ): // CT_DashStopList
129 return this;
130 case A_TOKEN( ds ):
132 // 'a:ds' has 2 attributes : 'd' and 'sp'
133 // both are of type 'a:ST_PositivePercentage'
134 // according to the specs Office will read percentages formatted with a trailing percent sign
135 // or formatted as 1000th of a percent without a trailing percent sign, but only write percentages
136 // as 1000th's of a percent without a trailing percent sign.
137 // The code below takes care of both scenarios by converting to '1000th of a percent' always
138 OUString aStr;
139 sal_Int32 nDashLength = 0;
140 aStr = rAttribs.getStringDefaulted( XML_d);
141 if ( aStr.endsWith("%") )
143 // Ends with a '%'
144 aStr = aStr.copy(0, aStr.getLength() - 1);
145 aStr = aStr.trim();
146 nDashLength = aStr.toInt32();
148 // Convert to 1000th of a percent
149 nDashLength *= 1000;
151 else
153 nDashLength = rAttribs.getInteger( XML_d, 0 );
156 sal_Int32 nSpaceLength = 0;
157 aStr = rAttribs.getStringDefaulted( XML_sp);
158 if ( aStr.endsWith("%") )
160 // Ends with a '%'
161 aStr = aStr.copy(0, aStr.getLength() - 1);
162 aStr = aStr.trim();
163 nSpaceLength = aStr.toInt32();
165 // Convert to 1000th of a percent
166 nSpaceLength *= 1000;
168 else
170 nSpaceLength = rAttribs.getInteger( XML_sp, 0 );
173 mrLineProperties.maCustomDash.emplace_back( nDashLength, nSpaceLength );
175 if (mpLineStyle)
177 mpLineStyle->maLineDash.maCustomList.push_back({ nDashLength, nSpaceLength });
180 break;
182 // LineJoinPropertiesGroup
183 case A_TOKEN( round ):
184 case A_TOKEN( bevel ):
185 case A_TOKEN( miter ):
187 sal_Int32 nToken = getBaseToken(nElement);
188 mrLineProperties.moLineJoint = nToken;
190 if (mpLineStyle)
192 switch (nToken)
194 case XML_round: mpLineStyle->maLineJoin.meType = model::LineJoinType::Round; break;
195 case XML_bevel: mpLineStyle->maLineJoin.meType = model::LineJoinType::Bevel; break;
196 case XML_miter: mpLineStyle->maLineJoin.meType = model::LineJoinType::Miter; break;
197 default:
198 mpLineStyle->maLineJoin.meType = model::LineJoinType::Miter;
200 if (nToken == XML_miter)
202 sal_Int32 nMiterLimit = rAttribs.getInteger(XML_lim, 0);
203 mpLineStyle->maLineJoin.mnMiterLimit = nMiterLimit;
207 break;
209 case A_TOKEN( headEnd ): // CT_LineEndProperties
210 case A_TOKEN( tailEnd ): // CT_LineEndProperties
211 { // ST_LineEndType
212 bool bTailEnd = nElement == A_TOKEN( tailEnd );
213 LineArrowProperties& rArrowProps = bTailEnd ? mrLineProperties.maEndArrow : mrLineProperties.maStartArrow;
214 rArrowProps.moArrowType = rAttribs.getToken( XML_type );
215 rArrowProps.moArrowWidth = rAttribs.getToken( XML_w );
216 rArrowProps.moArrowLength = rAttribs.getToken( XML_len );
218 if (mpLineStyle)
220 model::LineEndType eLineEndType = model::LineEndType::None;
221 switch (rAttribs.getToken(XML_type, XML_none))
223 case XML_triangle: eLineEndType = model::LineEndType::Triangle; break;
224 case XML_stealth: eLineEndType = model::LineEndType::Stealth; break;
225 case XML_diamond: eLineEndType = model::LineEndType::Diamond; break;
226 case XML_oval: eLineEndType = model::LineEndType::Oval; break;
227 case XML_arrow: eLineEndType = model::LineEndType::Arrow; break;
228 default:
229 case XML_none: eLineEndType = model::LineEndType::None; break;
232 model::LineEndLength eLineEndLength = model::LineEndLength::Unset;
233 switch (rAttribs.getToken(XML_len, XML_TOKEN_INVALID))
235 case XML_sm: eLineEndLength = model::LineEndLength::Small; break;
236 case XML_med: eLineEndLength = model::LineEndLength::Medium; break;
237 case XML_lg: eLineEndLength = model::LineEndLength::Large; break;
238 default:
239 break;
242 model::LineEndWidth eLineEndWidth = model::LineEndWidth::Unset;
243 switch (rAttribs.getToken(XML_w, XML_TOKEN_INVALID))
245 case XML_sm: eLineEndWidth = model::LineEndWidth::Small; break;
246 case XML_med: eLineEndWidth = model::LineEndWidth::Medium; break;
247 case XML_lg: eLineEndWidth = model::LineEndWidth::Large; break;
248 default:
249 break;
252 if (nElement == A_TOKEN(tailEnd))
254 mpLineStyle->maTailEnd.meType = eLineEndType;
255 mpLineStyle->maTailEnd.meLength = eLineEndLength;
256 mpLineStyle->maTailEnd.meWidth = eLineEndWidth;
258 else if (nElement == A_TOKEN(headEnd))
260 mpLineStyle->maHeadEnd.meType = eLineEndType;
261 mpLineStyle->maHeadEnd.meLength = eLineEndLength;
262 mpLineStyle->maHeadEnd.meWidth = eLineEndWidth;
266 break;
268 return nullptr;
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */