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/chart/chartdrawingfragment.hxx"
21 : :
22 : : #include "oox/core/xmlfilterbase.hxx"
23 : : #include "oox/drawingml/connectorshapecontext.hxx"
24 : : #include "oox/drawingml/graphicshapecontext.hxx"
25 : : #include "oox/drawingml/shapecontext.hxx"
26 : : #include "oox/drawingml/shapegroupcontext.hxx"
27 : :
28 : : namespace oox {
29 : : namespace drawingml {
30 : : namespace chart {
31 : :
32 : : // ============================================================================
33 : :
34 : : using namespace ::com::sun::star::awt;
35 : : using namespace ::com::sun::star::drawing;
36 : : using namespace ::com::sun::star::uno;
37 : : using namespace ::oox::core;
38 : :
39 : : using ::rtl::OUString;
40 : :
41 : : // ============================================================================
42 : :
43 : 0 : ShapeAnchor::ShapeAnchor( bool bRelSize ) :
44 : 0 : mbRelSize( bRelSize )
45 : : {
46 : 0 : }
47 : :
48 : 0 : void ShapeAnchor::importExt( const AttributeList& rAttribs )
49 : : {
50 : : OSL_ENSURE( !mbRelSize, "ShapeAnchor::importExt - unexpected 'cdr:ext' element" );
51 : 0 : maSize.Width = rAttribs.getHyper( XML_cx, 0 );
52 : 0 : maSize.Height = rAttribs.getHyper( XML_cy, 0 );
53 : 0 : }
54 : :
55 : 0 : void ShapeAnchor::setPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue )
56 : : {
57 : 0 : AnchorPosModel* pAnchorPos = 0;
58 [ # # # ]: 0 : switch( nParentContext )
59 : : {
60 : : case CDR_TOKEN( from ):
61 : 0 : pAnchorPos = &maFrom;
62 : 0 : break;
63 : : case CDR_TOKEN( to ):
64 : : OSL_ENSURE( mbRelSize, "ShapeAnchor::setPos - unexpected 'cdr:to' element" );
65 : 0 : pAnchorPos = &maTo;
66 : 0 : break;
67 : : default:
68 : : OSL_FAIL( "ShapeAnchor::setPos - unexpected parent element" );
69 : : }
70 [ # # ]: 0 : if( pAnchorPos ) switch( nElement )
[ # # # ]
71 : : {
72 : 0 : case CDR_TOKEN( x ): pAnchorPos->mfX = rValue.toDouble(); break;
73 : 0 : case CDR_TOKEN( y ): pAnchorPos->mfY = rValue.toDouble(); break;
74 : : default: OSL_FAIL( "ShapeAnchor::setPos - unexpected element" );
75 : : }
76 : 0 : }
77 : :
78 : 0 : EmuRectangle ShapeAnchor::calcAnchorRectEmu( const EmuRectangle& rChartRect ) const
79 : : {
80 : 0 : EmuRectangle aAnchorRect( -1, -1, -1, -1 );
81 : :
82 : : OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid from position" );
83 : : OSL_ENSURE( mbRelSize ? maTo.isValid() : maSize.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid to/size" );
84 [ # # ][ # # ]: 0 : if( maFrom.isValid() && (mbRelSize ? maTo.isValid() : maSize.isValid()) )
[ # # ][ # # ]
[ # # ]
85 : : {
86 : : // calculate shape position
87 : 0 : aAnchorRect.X = static_cast< sal_Int64 >( maFrom.mfX * rChartRect.Width + 0.5 );
88 : 0 : aAnchorRect.Y = static_cast< sal_Int64 >( maFrom.mfY * rChartRect.Height + 0.5 );
89 : :
90 : : // calculate shape size
91 [ # # ]: 0 : if( mbRelSize )
92 : : {
93 : 0 : aAnchorRect.Width = static_cast< sal_Int64 >( maTo.mfX * rChartRect.Width + 0.5 ) - aAnchorRect.X;
94 [ # # ]: 0 : if( aAnchorRect.Width < 0 )
95 : : {
96 : 0 : aAnchorRect.X += aAnchorRect.Width;
97 : 0 : aAnchorRect.Width *= -1;
98 : : }
99 : 0 : aAnchorRect.Height = static_cast< sal_Int64 >( maTo.mfY * rChartRect.Height + 0.5 ) - aAnchorRect.Y;
100 [ # # ]: 0 : if( aAnchorRect.Height < 0 )
101 : : {
102 : 0 : aAnchorRect.Y += aAnchorRect.Height;
103 : 0 : aAnchorRect.Height *= -1;
104 : : }
105 : : }
106 : : else
107 : : {
108 : 0 : aAnchorRect.setSize( maSize );
109 : : }
110 : : }
111 : :
112 : 0 : return aAnchorRect;
113 : : }
114 : : // ============================================================================
115 : :
116 : 0 : ChartDrawingFragment::ChartDrawingFragment( XmlFilterBase& rFilter,
117 : : const OUString& rFragmentPath, const Reference< XShapes >& rxDrawPage,
118 : : const Size& rChartSize, const Point& rShapesOffset, bool bOleSupport ) :
119 : : FragmentHandler2( rFilter, rFragmentPath ),
120 : : mxDrawPage( rxDrawPage ),
121 [ # # ][ # # ]: 0 : mbOleSupport( bOleSupport )
122 : : {
123 : 0 : maChartRectEmu.X = convertHmmToEmu( rShapesOffset.X );
124 : 0 : maChartRectEmu.Y = convertHmmToEmu( rShapesOffset.Y );
125 : 0 : maChartRectEmu.Width = convertHmmToEmu( rChartSize.Width );
126 : 0 : maChartRectEmu.Height = convertHmmToEmu( rChartSize.Height );
127 : 0 : }
128 : :
129 [ # # ][ # # ]: 0 : ChartDrawingFragment::~ChartDrawingFragment()
130 : : {
131 [ # # ]: 0 : }
132 : :
133 : 0 : ContextHandlerRef ChartDrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
134 : : {
135 [ # # # # : 0 : switch( getCurrentElement() )
# ]
136 : : {
137 : : case XML_ROOT_CONTEXT:
138 [ # # ]: 0 : if( nElement == C_TOKEN( userShapes ) ) return this;
139 : 0 : break;
140 : :
141 : : case C_TOKEN( userShapes ):
142 [ # # # ]: 0 : switch( nElement )
143 : : {
144 : : case CDR_TOKEN( absSizeAnchor ):
145 : 0 : mxAnchor.reset( new ShapeAnchor( false ) );
146 : 0 : return this;
147 : : case CDR_TOKEN( relSizeAnchor ):
148 : 0 : mxAnchor.reset( new ShapeAnchor( true ) );
149 : 0 : return this;
150 : : }
151 : 0 : break;
152 : :
153 : : case CDR_TOKEN( absSizeAnchor ):
154 : : case CDR_TOKEN( relSizeAnchor ):
155 [ # # # # : 0 : switch( nElement )
# # # # ]
156 : : {
157 : : case CDR_TOKEN( sp ):
158 [ # # ]: 0 : mxShape.reset( new Shape( "com.sun.star.drawing.CustomShape" ) );
159 [ # # ][ # # ]: 0 : return new ShapeContext( *this, ShapePtr(), mxShape );
[ # # ]
160 : : case CDR_TOKEN( cxnSp ):
161 [ # # ]: 0 : mxShape.reset( new Shape( "com.sun.star.drawing.ConnectorShape" ) );
162 [ # # ][ # # ]: 0 : return new ConnectorShapeContext( *this, ShapePtr(), mxShape );
[ # # ]
163 : : case CDR_TOKEN( pic ):
164 [ # # ]: 0 : mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) );
165 [ # # ][ # # ]: 0 : return new GraphicShapeContext( *this, ShapePtr(), mxShape );
[ # # ]
166 : : case CDR_TOKEN( graphicFrame ):
167 [ # # ]: 0 : if( !mbOleSupport )
168 : 0 : return 0;
169 [ # # ]: 0 : mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) );
170 [ # # ][ # # ]: 0 : return new GraphicalObjectFrameContext( *this, ShapePtr(), mxShape, true );
[ # # ]
171 : : case CDR_TOKEN( grpSp ):
172 [ # # ]: 0 : mxShape.reset( new Shape( "com.sun.star.drawing.GroupShape" ) );
173 [ # # ][ # # ]: 0 : return new ShapeGroupContext( *this, ShapePtr(), mxShape );
[ # # ]
174 : :
175 : : case CDR_TOKEN( from ):
176 : : case CDR_TOKEN( to ):
177 : 0 : return this;
178 : :
179 : : case CDR_TOKEN( ext ):
180 [ # # ]: 0 : if( mxAnchor.get() ) mxAnchor->importExt( rAttribs );
181 : 0 : return 0;
182 : : }
183 : 0 : break;
184 : :
185 : : case CDR_TOKEN( from ):
186 : : case CDR_TOKEN( to ):
187 [ # # ]: 0 : switch( nElement )
188 : : {
189 : : case CDR_TOKEN( x ):
190 : : case CDR_TOKEN( y ):
191 : 0 : return this; // collect value in onEndElement()
192 : : }
193 : 0 : break;
194 : : }
195 : 0 : return 0;
196 : : }
197 : :
198 : 0 : void ChartDrawingFragment::onCharacters( const OUString& rChars )
199 : : {
200 [ # # ][ # # ]: 0 : if( isCurrentElement( CDR_TOKEN( x ), CDR_TOKEN( y ) ) && mxAnchor.get() )
[ # # ]
201 : 0 : mxAnchor->setPos( getCurrentElement(), getParentElement(), rChars );
202 : 0 : }
203 : :
204 : 0 : void ChartDrawingFragment::onEndElement()
205 : : {
206 [ # # ]: 0 : if( isCurrentElement( CDR_TOKEN( absSizeAnchor ), CDR_TOKEN( relSizeAnchor ) ) )
207 : : {
208 [ # # ][ # # ]: 0 : if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() )
[ # # ][ # # ]
209 : : {
210 : 0 : EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( maChartRectEmu );
211 [ # # ][ # # ]: 0 : if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) )
[ # # ][ # # ]
212 : : {
213 : : // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle)
214 : : Rectangle aShapeRectEmu32(
215 [ # # ]: 0 : getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ),
216 [ # # ]: 0 : getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Y, 0, SAL_MAX_INT32 ),
217 [ # # ]: 0 : getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ),
218 [ # # ]: 0 : getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) );
219 [ # # ]: 0 : basegfx::B2DHomMatrix aMatrix;
220 [ # # ][ # # ]: 0 : mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, aMatrix, &aShapeRectEmu32 );
[ # # ][ # # ]
[ # # ]
221 : : }
222 : : }
223 : 0 : mxShape.reset();
224 : 0 : mxAnchor.reset();
225 : : }
226 : 0 : }
227 : :
228 : : // ============================================================================
229 : :
230 : : } // namespace chart
231 : : } // namespace drawingml
232 [ + - ][ + - ]: 285 : } // namespace oox
233 : :
234 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|