Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #include "oox/drawingml/lineproperties.hxx"
21 : : #include <vector>
22 : : #include <rtl/ustrbuf.hxx>
23 : : #include <com/sun/star/beans/NamedValue.hpp>
24 : : #include <com/sun/star/container/XNameContainer.hpp>
25 : : #include <com/sun/star/drawing/FlagSequence.hpp>
26 : : #include <com/sun/star/drawing/LineDash.hpp>
27 : : #include <com/sun/star/drawing/LineJoint.hpp>
28 : : #include <com/sun/star/drawing/LineStyle.hpp>
29 : : #include <com/sun/star/drawing/PointSequence.hpp>
30 : : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
31 : : #include "oox/drawingml/drawingmltypes.hxx"
32 : : #include "oox/drawingml/shapepropertymap.hxx"
33 : : #include "oox/helper/containerhelper.hxx"
34 : : #include "oox/helper/graphichelper.hxx"
35 : : #include "oox/token/tokens.hxx"
36 : :
37 : : using namespace ::com::sun::star::beans;
38 : : using namespace ::com::sun::star::drawing;
39 : :
40 : : using ::rtl::OUString;
41 : : using ::rtl::OUStringBuffer;
42 : : using ::com::sun::star::uno::Any;
43 : : using ::com::sun::star::uno::Reference;
44 : : using ::com::sun::star::awt::Point;
45 : : using ::com::sun::star::container::XNameContainer;
46 : :
47 : : namespace oox {
48 : : namespace drawingml {
49 : :
50 : : // ============================================================================
51 : :
52 : : namespace {
53 : :
54 : 0 : void lclSetDashData( LineDash& orLineDash, sal_Int16 nDots, sal_Int32 nDotLen,
55 : : sal_Int16 nDashes, sal_Int32 nDashLen, sal_Int32 nDistance )
56 : : {
57 : 0 : orLineDash.Dots = nDots;
58 : 0 : orLineDash.DotLen = nDotLen;
59 : 0 : orLineDash.Dashes = nDashes;
60 : 0 : orLineDash.DashLen = nDashLen;
61 : 0 : orLineDash.Distance = nDistance;
62 : 0 : }
63 : :
64 : : /** Converts the specified preset dash to API dash.
65 : :
66 : : Line length and dot length are set relative to line width and have to be
67 : : multiplied by the actual line width after this function.
68 : : */
69 : 0 : void lclConvertPresetDash( LineDash& orLineDash, sal_Int32 nPresetDash )
70 : : {
71 [ # # # # : 0 : switch( nPresetDash )
# # # # #
# # ]
72 : : {
73 : 0 : case XML_dot: lclSetDashData( orLineDash, 1, 1, 0, 0, 3 ); break;
74 : 0 : case XML_dash: lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); break;
75 : 0 : case XML_dashDot: lclSetDashData( orLineDash, 1, 1, 1, 4, 3 ); break;
76 : :
77 : 0 : case XML_lgDash: lclSetDashData( orLineDash, 0, 0, 1, 8, 3 ); break;
78 : 0 : case XML_lgDashDot: lclSetDashData( orLineDash, 1, 1, 1, 8, 3 ); break;
79 : 0 : case XML_lgDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 8, 3 ); break;
80 : :
81 : 0 : case XML_sysDot: lclSetDashData( orLineDash, 1, 1, 0, 0, 1 ); break;
82 : 0 : case XML_sysDash: lclSetDashData( orLineDash, 0, 0, 1, 3, 1 ); break;
83 : 0 : case XML_sysDashDot: lclSetDashData( orLineDash, 1, 1, 1, 3, 1 ); break;
84 : 0 : case XML_sysDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 3, 1 ); break;
85 : :
86 : : default:
87 : : OSL_FAIL( "lclConvertPresetDash - unsupported preset dash" );
88 : 0 : lclSetDashData( orLineDash, 0, 0, 1, 4, 3 );
89 : : }
90 : 0 : }
91 : :
92 : : /** Converts the passed custom dash to API dash.
93 : :
94 : : Line length and dot length are set relative to line width and have to be
95 : : multiplied by the actual line width after this function.
96 : : */
97 : 0 : void lclConvertCustomDash( LineDash& orLineDash, const LineProperties::DashStopVector& rCustomDash )
98 : : {
99 [ # # ]: 0 : if( rCustomDash.empty() )
100 : : {
101 : : OSL_FAIL( "lclConvertCustomDash - unexpected empty custom dash" );
102 : 0 : lclSetDashData( orLineDash, 0, 0, 1, 4, 3 );
103 : 0 : return;
104 : : }
105 : :
106 : : // count dashes and dots (stops equal or less than 2 are assumed to be dots)
107 : 0 : sal_Int16 nDots = 0;
108 : 0 : sal_Int32 nDotLen = 0;
109 : 0 : sal_Int16 nDashes = 0;
110 : 0 : sal_Int32 nDashLen = 0;
111 : 0 : sal_Int32 nDistance = 0;
112 [ # # ][ # # ]: 0 : for( LineProperties::DashStopVector::const_iterator aIt = rCustomDash.begin(), aEnd = rCustomDash.end(); aIt != aEnd; ++aIt )
[ # # ]
113 : : {
114 [ # # ][ # # ]: 0 : if( aIt->first <= 2 )
115 : : {
116 : 0 : ++nDots;
117 [ # # ]: 0 : nDotLen += aIt->first;
118 : : }
119 : : else
120 : : {
121 : 0 : ++nDashes;
122 [ # # ]: 0 : nDashLen += aIt->first;
123 : : }
124 [ # # ]: 0 : nDistance += aIt->second;
125 : : }
126 [ # # ][ # # ]: 0 : orLineDash.DotLen = (nDots > 0) ? ::std::max< sal_Int32 >( nDotLen / nDots, 1 ) : 0;
[ # # ][ # # ]
[ # # # # ]
127 : 0 : orLineDash.Dots = nDots;
128 [ # # ][ # # ]: 0 : orLineDash.DashLen = (nDashes > 0) ? ::std::max< sal_Int32 >( nDashLen / nDashes, 1 ) : 0;
[ # # ][ # # ]
[ # # # # ]
129 : 0 : orLineDash.Dashes = nDashes;
130 [ # # ]: 0 : orLineDash.Distance = ::std::max< sal_Int32 >( nDistance / rCustomDash.size(), 1 );
131 : : }
132 : :
133 : 0 : DashStyle lclGetDashStyle( sal_Int32 nToken )
134 : : {
135 : : OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
136 [ # # # # ]: 0 : switch( nToken )
137 : : {
138 : 0 : case XML_rnd: return DashStyle_ROUNDRELATIVE;
139 : 0 : case XML_sq: return DashStyle_RECTRELATIVE;
140 : 0 : case XML_flat: return DashStyle_RECT;
141 : : }
142 : 0 : return DashStyle_ROUNDRELATIVE;
143 : : }
144 : :
145 : 39 : LineJoint lclGetLineJoint( sal_Int32 nToken )
146 : : {
147 : : OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
148 [ + - + - ]: 39 : switch( nToken )
149 : : {
150 : 18 : case XML_round: return LineJoint_ROUND;
151 : 0 : case XML_bevel: return LineJoint_BEVEL;
152 : 21 : case XML_miter: return LineJoint_MITER;
153 : : }
154 : 39 : return LineJoint_ROUND;
155 : : }
156 : :
157 : : const sal_Int32 OOX_ARROWSIZE_SMALL = 0;
158 : : const sal_Int32 OOX_ARROWSIZE_MEDIUM = 1;
159 : : const sal_Int32 OOX_ARROWSIZE_LARGE = 2;
160 : :
161 : 48 : sal_Int32 lclGetArrowSize( sal_Int32 nToken )
162 : : {
163 : : OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
164 [ - + - - ]: 48 : switch( nToken )
165 : : {
166 : 0 : case XML_sm: return OOX_ARROWSIZE_SMALL;
167 : 48 : case XML_med: return OOX_ARROWSIZE_MEDIUM;
168 : 0 : case XML_lg: return OOX_ARROWSIZE_LARGE;
169 : : }
170 : 48 : return OOX_ARROWSIZE_MEDIUM;
171 : : }
172 : :
173 : : // ----------------------------------------------------------------------------
174 : :
175 : 246 : void lclPushMarkerProperties( ShapePropertyMap& rPropMap,
176 : : const LineArrowProperties& rArrowProps, sal_Int32 nLineWidth, bool bLineEnd )
177 : : {
178 : : /* Store the marker polygon and the marker name in a single value, to be
179 : : able to pass both to the ShapePropertyMap::setProperty() function. */
180 : 246 : NamedValue aNamedMarker;
181 : :
182 : 246 : OUStringBuffer aBuffer;
183 : 246 : sal_Int32 nMarkerWidth = 0;
184 : 246 : bool bMarkerCenter = false;
185 : 246 : sal_Int32 nArrowType = rArrowProps.moArrowType.get( XML_none );
186 : : OSL_ASSERT((nArrowType & sal_Int32(0xFFFF0000))==0);
187 [ + + - - : 246 : switch( nArrowType )
- + ]
188 : : {
189 : : case XML_triangle:
190 [ + - ][ + - ]: 12 : aBuffer.append( CREATE_OUSTRING( "msArrowEnd" ) );
191 : 12 : break;
192 : : case XML_arrow:
193 [ + - ][ + - ]: 12 : aBuffer.append( CREATE_OUSTRING( "msArrowOpenEnd" ) );
194 : 12 : break;
195 : : case XML_stealth:
196 [ # # ][ # # ]: 0 : aBuffer.append( CREATE_OUSTRING( "msArrowStealthEnd" ) );
197 : 0 : break;
198 : : case XML_diamond:
199 [ # # ][ # # ]: 0 : aBuffer.append( CREATE_OUSTRING( "msArrowDiamondEnd" ) );
200 : 0 : bMarkerCenter = true;
201 : 0 : break;
202 : : case XML_oval:
203 [ # # ][ # # ]: 0 : aBuffer.append( CREATE_OUSTRING( "msArrowOvalEnd" ) );
204 : 0 : bMarkerCenter = true;
205 : 0 : break;
206 : : }
207 : :
208 [ + + ]: 246 : if( aBuffer.getLength() > 0 )
209 : : {
210 : 24 : sal_Int32 nLength = lclGetArrowSize( rArrowProps.moArrowLength.get( XML_med ) );
211 : 24 : sal_Int32 nWidth = lclGetArrowSize( rArrowProps.moArrowWidth.get( XML_med ) );
212 : :
213 : 24 : sal_Int32 nNameIndex = nWidth * 3 + nLength + 1;
214 [ + - ][ + - ]: 24 : aBuffer.append( sal_Unicode( ' ' ) ).append( nNameIndex );
215 [ + - ]: 24 : OUString aMarkerName = aBuffer.makeStringAndClear();
216 : :
217 : 24 : bool bIsArrow = nArrowType == XML_arrow;
218 : 24 : double fArrowLength = 1.0;
219 [ - + - - ]: 24 : switch( nLength )
220 : : {
221 [ # # ]: 0 : case OOX_ARROWSIZE_SMALL: fArrowLength = (bIsArrow ? 3.5 : 2.0); break;
222 [ + + ]: 24 : case OOX_ARROWSIZE_MEDIUM: fArrowLength = (bIsArrow ? 4.5 : 3.0); break;
223 [ # # ]: 0 : case OOX_ARROWSIZE_LARGE: fArrowLength = (bIsArrow ? 6.0 : 5.0); break;
224 : : }
225 : 24 : double fArrowWidth = 1.0;
226 [ - + - - ]: 24 : switch( nWidth )
227 : : {
228 [ # # ]: 0 : case OOX_ARROWSIZE_SMALL: fArrowWidth = (bIsArrow ? 3.5 : 2.0); break;
229 [ + + ]: 24 : case OOX_ARROWSIZE_MEDIUM: fArrowWidth = (bIsArrow ? 4.5 : 3.0); break;
230 [ # # ]: 0 : case OOX_ARROWSIZE_LARGE: fArrowWidth = (bIsArrow ? 6.0 : 5.0); break;
231 : : }
232 : : // set arrow width relative to line width
233 [ + - ]: 24 : sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 70 );
234 : 24 : nMarkerWidth = static_cast< sal_Int32 >( fArrowWidth * nBaseLineWidth );
235 : :
236 : : /* Test if the marker already exists in the marker table, do not
237 : : create it again in this case. If markers are inserted explicitly
238 : : instead by their name, the polygon will be created always.
239 : : TODO: this can be optimized by using a map. */
240 [ + - ][ + + ]: 24 : if( !rPropMap.hasNamedLineMarkerInTable( aMarkerName ) )
241 : : {
242 : : // pass X and Y as percentage to OOX_ARROW_POINT
243 : : #define OOX_ARROW_POINT( x, y ) Point( static_cast< sal_Int32 >( fArrowWidth * x ), static_cast< sal_Int32 >( fArrowLength * y ) )
244 : :
245 [ + - ]: 9 : ::std::vector< Point > aPoints;
246 : : OSL_ASSERT((rArrowProps.moArrowType.get() & sal_Int32(0xFFFF0000))==0);
247 [ + + - - : 9 : switch( rArrowProps.moArrowType.get() )
- - ]
248 : : {
249 : : case XML_triangle:
250 [ + - ]: 6 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
251 [ + - ]: 6 : aPoints.push_back( OOX_ARROW_POINT( 100, 100 ) );
252 [ + - ]: 6 : aPoints.push_back( OOX_ARROW_POINT( 0, 100 ) );
253 [ + - ]: 6 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
254 : 6 : break;
255 : : case XML_arrow:
256 [ + - ]: 3 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
257 [ + - ]: 3 : aPoints.push_back( OOX_ARROW_POINT( 100, 91 ) );
258 [ + - ]: 3 : aPoints.push_back( OOX_ARROW_POINT( 85, 100 ) );
259 [ + - ]: 3 : aPoints.push_back( OOX_ARROW_POINT( 50, 36 ) );
260 [ + - ]: 3 : aPoints.push_back( OOX_ARROW_POINT( 15, 100 ) );
261 [ + - ]: 3 : aPoints.push_back( OOX_ARROW_POINT( 0, 91 ) );
262 [ + - ]: 3 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
263 : 3 : break;
264 : : case XML_stealth:
265 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
266 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 100, 100 ) );
267 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 60 ) );
268 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 0, 100 ) );
269 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
270 : 0 : break;
271 : : case XML_diamond:
272 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
273 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 100, 50 ) );
274 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 100 ) );
275 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 0, 50 ) );
276 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
277 : 0 : break;
278 : : case XML_oval:
279 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
280 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 75, 7 ) );
281 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 93, 25 ) );
282 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 100, 50 ) );
283 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 93, 75 ) );
284 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 75, 93 ) );
285 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 100 ) );
286 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 25, 93 ) );
287 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 7, 75 ) );
288 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 0, 50 ) );
289 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 7, 25 ) );
290 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 25, 7 ) );
291 [ # # ]: 0 : aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
292 : 0 : break;
293 : : }
294 : : #undef OOX_ARROW_POINT
295 : :
296 : : OSL_ENSURE( !aPoints.empty(), "lclPushMarkerProperties - missing arrow coordinates" );
297 [ + - ]: 9 : if( !aPoints.empty() )
298 : : {
299 [ + - ]: 9 : PolyPolygonBezierCoords aMarkerCoords;
300 [ + - ]: 9 : aMarkerCoords.Coordinates.realloc( 1 );
301 [ + - ][ + - ]: 9 : aMarkerCoords.Coordinates[ 0 ] = ContainerHelper::vectorToSequence( aPoints );
[ + - ][ + - ]
302 : :
303 [ + - ]: 9 : ::std::vector< PolygonFlags > aFlags( aPoints.size(), PolygonFlags_NORMAL );
304 [ + - ]: 9 : aMarkerCoords.Flags.realloc( 1 );
305 [ + - ][ + - ]: 9 : aMarkerCoords.Flags[ 0 ] = ContainerHelper::vectorToSequence( aFlags );
[ + - ][ + - ]
306 : :
307 : 9 : aNamedMarker.Name = aMarkerName;
308 [ + - ][ + - ]: 9 : aNamedMarker.Value <<= aMarkerCoords;
309 : 9 : }
310 : : }
311 : : else
312 : : {
313 : : /* Named marker object exists already in the marker table, pass
314 : : its name only. This will set the name as property value, but
315 : : does not create a new object in the marker table. */
316 : 15 : aNamedMarker.Name = aMarkerName;
317 : 24 : }
318 : : }
319 : :
320 : : // push the properties (filled aNamedMarker.Name indicates valid marker)
321 [ + + ]: 246 : if( !aNamedMarker.Name.isEmpty() )
322 : : {
323 [ + + ]: 24 : if( bLineEnd )
324 : : {
325 [ + - ]: 21 : rPropMap.setProperty( SHAPEPROP_LineEnd, aNamedMarker );
326 [ + - ]: 21 : rPropMap.setProperty( SHAPEPROP_LineEndWidth, nMarkerWidth );
327 [ + - ]: 21 : rPropMap.setProperty( SHAPEPROP_LineEndCenter, bMarkerCenter );
328 : : }
329 : : else
330 : : {
331 [ + - ]: 3 : rPropMap.setProperty( SHAPEPROP_LineStart, aNamedMarker );
332 [ + - ]: 3 : rPropMap.setProperty( SHAPEPROP_LineStartWidth, nMarkerWidth );
333 [ + - ]: 3 : rPropMap.setProperty( SHAPEPROP_LineStartCenter, bMarkerCenter );
334 : : }
335 : 246 : }
336 : 246 : }
337 : :
338 : : } // namespace
339 : :
340 : : // ============================================================================
341 : :
342 : 210 : void LineArrowProperties::assignUsed( const LineArrowProperties& rSourceProps )
343 : : {
344 : 210 : moArrowType.assignIfUsed( rSourceProps.moArrowType );
345 : 210 : moArrowWidth.assignIfUsed( rSourceProps.moArrowWidth );
346 : 210 : moArrowLength.assignIfUsed( rSourceProps.moArrowLength );
347 : 210 : }
348 : :
349 : : // ============================================================================
350 : :
351 : 105 : void LineProperties::assignUsed( const LineProperties& rSourceProps )
352 : : {
353 : 105 : maStartArrow.assignUsed( rSourceProps.maStartArrow );
354 : 105 : maEndArrow.assignUsed( rSourceProps.maEndArrow );
355 : 105 : maLineFill.assignUsed( rSourceProps.maLineFill );
356 [ - + ]: 105 : if( !rSourceProps.maCustomDash.empty() )
357 : 0 : maCustomDash = rSourceProps.maCustomDash;
358 : 105 : moLineWidth.assignIfUsed( rSourceProps.moLineWidth );
359 : 105 : moPresetDash.assignIfUsed( rSourceProps.moPresetDash );
360 : 105 : moLineCompound.assignIfUsed( rSourceProps.moLineCompound );
361 : 105 : moLineCap.assignIfUsed( rSourceProps.moLineCap );
362 : 105 : moLineJoint.assignIfUsed( rSourceProps.moLineJoint );
363 : 105 : }
364 : :
365 : 123 : void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap,
366 : : const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr ) const
367 : : {
368 : : // line fill type must exist, otherwise ignore other properties
369 [ + - ]: 123 : if( maLineFill.moFillType.has() )
370 : : {
371 : : // line style (our core only supports none and solid)
372 : 123 : LineStyle eLineStyle = (maLineFill.moFillType.get() == XML_noFill) ? LineStyle_NONE : LineStyle_SOLID;
373 : :
374 : : // convert line width from EMUs to 1/100mm
375 [ + - ]: 123 : sal_Int32 nLineWidth = convertEmuToHmm( moLineWidth.get( 0 ) );
376 : :
377 : : // create line dash from preset dash token (not for invisible line)
378 [ + + ][ + - ]: 123 : if( (eLineStyle != LineStyle_NONE) && (moPresetDash.differsFrom( XML_solid ) || (!moPresetDash && !maCustomDash.empty())) )
[ + + ][ - + ]
[ - + ]
379 : : {
380 : 0 : LineDash aLineDash;
381 : 0 : aLineDash.Style = lclGetDashStyle( moLineCap.get( XML_rnd ) );
382 : :
383 : : // convert preset dash or custom dash
384 [ # # ]: 0 : if( moPresetDash.has() )
385 : 0 : lclConvertPresetDash( aLineDash, moPresetDash.get() );
386 : : else
387 [ # # ]: 0 : lclConvertCustomDash( aLineDash, maCustomDash );
388 : :
389 : : // convert relative dash/dot length to absolute length
390 [ # # ]: 0 : sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 35 );
391 : 0 : aLineDash.DotLen *= nBaseLineWidth;
392 : 0 : aLineDash.DashLen *= nBaseLineWidth;
393 : 0 : aLineDash.Distance *= nBaseLineWidth;
394 : :
395 [ # # ][ # # ]: 0 : if( rPropMap.setProperty( SHAPEPROP_LineDash, aLineDash ) )
396 : 0 : eLineStyle = LineStyle_DASH;
397 : : }
398 : :
399 : : // set final line style property
400 [ + - ]: 123 : rPropMap.setProperty( SHAPEPROP_LineStyle, eLineStyle );
401 : :
402 : : // line joint type
403 [ + + ]: 123 : if( moLineJoint.has() )
404 [ + - ]: 39 : rPropMap.setProperty( SHAPEPROP_LineJoint, lclGetLineJoint( moLineJoint.get() ) );
405 : :
406 : : // line width in 1/100mm
407 [ + - ]: 123 : rPropMap.setProperty( SHAPEPROP_LineWidth, nLineWidth );
408 : :
409 : : // line color and transparence
410 [ + - ]: 123 : Color aLineColor = maLineFill.getBestSolidColor();
411 [ + + ]: 123 : if( aLineColor.isUsed() )
412 : : {
413 [ + - ][ + - ]: 54 : rPropMap.setProperty( SHAPEPROP_LineColor, aLineColor.getColor( rGraphicHelper, nPhClr ) );
414 [ + - ][ - + ]: 54 : if( aLineColor.hasTransparency() )
415 [ # # ][ # # ]: 0 : rPropMap.setProperty( SHAPEPROP_LineTransparency, aLineColor.getTransparency() );
416 : : }
417 : :
418 : : // line markers
419 [ + - ]: 123 : lclPushMarkerProperties( rPropMap, maStartArrow, nLineWidth, false );
420 [ + - ][ + - ]: 123 : lclPushMarkerProperties( rPropMap, maEndArrow, nLineWidth, true );
421 : : }
422 : 123 : }
423 : :
424 : : // ============================================================================
425 : :
426 : : } // namespace drawingml
427 [ + - ][ + - ]: 285 : } // namespace oox
428 : :
429 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|