1*ca5ec200SAndrew Rist /**************************************************************
2*ca5ec200SAndrew Rist *
3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*ca5ec200SAndrew Rist * distributed with this work for additional information
6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance
9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at
10*ca5ec200SAndrew Rist *
11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*ca5ec200SAndrew Rist *
13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an
15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the
17*ca5ec200SAndrew Rist * specific language governing permissions and limitations
18*ca5ec200SAndrew Rist * under the License.
19*ca5ec200SAndrew Rist *
20*ca5ec200SAndrew Rist *************************************************************/
21*ca5ec200SAndrew Rist
22*ca5ec200SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "oox/drawingml/chart/chartdrawingfragment.hxx"
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include "oox/core/xmlfilterbase.hxx"
27cdf0e10cSrcweir #include "oox/drawingml/connectorshapecontext.hxx"
28cdf0e10cSrcweir #include "oox/drawingml/graphicshapecontext.hxx"
29cdf0e10cSrcweir #include "oox/drawingml/shapecontext.hxx"
30cdf0e10cSrcweir #include "oox/drawingml/shapegroupcontext.hxx"
31cdf0e10cSrcweir
32cdf0e10cSrcweir namespace oox {
33cdf0e10cSrcweir namespace drawingml {
34cdf0e10cSrcweir namespace chart {
35cdf0e10cSrcweir
36cdf0e10cSrcweir // ============================================================================
37cdf0e10cSrcweir
38cdf0e10cSrcweir using namespace ::com::sun::star::awt;
39cdf0e10cSrcweir using namespace ::com::sun::star::drawing;
40cdf0e10cSrcweir using namespace ::com::sun::star::uno;
41cdf0e10cSrcweir using namespace ::oox::core;
42cdf0e10cSrcweir
43cdf0e10cSrcweir using ::rtl::OUString;
44cdf0e10cSrcweir
45cdf0e10cSrcweir // ============================================================================
46cdf0e10cSrcweir
ShapeAnchor(bool bRelSize)47cdf0e10cSrcweir ShapeAnchor::ShapeAnchor( bool bRelSize ) :
48cdf0e10cSrcweir mbRelSize( bRelSize )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir }
51cdf0e10cSrcweir
importExt(const AttributeList & rAttribs)52cdf0e10cSrcweir void ShapeAnchor::importExt( const AttributeList& rAttribs )
53cdf0e10cSrcweir {
54cdf0e10cSrcweir OSL_ENSURE( !mbRelSize, "ShapeAnchor::importExt - unexpected 'cdr:ext' element" );
55cdf0e10cSrcweir maSize.Width = rAttribs.getHyper( XML_cx, 0 );
56cdf0e10cSrcweir maSize.Height = rAttribs.getHyper( XML_cy, 0 );
57cdf0e10cSrcweir }
58cdf0e10cSrcweir
setPos(sal_Int32 nElement,sal_Int32 nParentContext,const OUString & rValue)59cdf0e10cSrcweir void ShapeAnchor::setPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue )
60cdf0e10cSrcweir {
61cdf0e10cSrcweir AnchorPosModel* pAnchorPos = 0;
62cdf0e10cSrcweir switch( nParentContext )
63cdf0e10cSrcweir {
64cdf0e10cSrcweir case CDR_TOKEN( from ):
65cdf0e10cSrcweir pAnchorPos = &maFrom;
66cdf0e10cSrcweir break;
67cdf0e10cSrcweir case CDR_TOKEN( to ):
68cdf0e10cSrcweir OSL_ENSURE( mbRelSize, "ShapeAnchor::setPos - unexpected 'cdr:to' element" );
69cdf0e10cSrcweir pAnchorPos = &maTo;
70cdf0e10cSrcweir break;
71cdf0e10cSrcweir default:
72cdf0e10cSrcweir OSL_ENSURE( false, "ShapeAnchor::setPos - unexpected parent element" );
73cdf0e10cSrcweir }
74cdf0e10cSrcweir if( pAnchorPos ) switch( nElement )
75cdf0e10cSrcweir {
76cdf0e10cSrcweir case CDR_TOKEN( x ): pAnchorPos->mfX = rValue.toDouble(); break;
77cdf0e10cSrcweir case CDR_TOKEN( y ): pAnchorPos->mfY = rValue.toDouble(); break;
78cdf0e10cSrcweir default: OSL_ENSURE( false, "ShapeAnchor::setPos - unexpected element" );
79cdf0e10cSrcweir }
80cdf0e10cSrcweir }
81cdf0e10cSrcweir
calcAnchorRectEmu(const EmuRectangle & rChartRect) const82cdf0e10cSrcweir EmuRectangle ShapeAnchor::calcAnchorRectEmu( const EmuRectangle& rChartRect ) const
83cdf0e10cSrcweir {
84cdf0e10cSrcweir EmuRectangle aAnchorRect( -1, -1, -1, -1 );
85cdf0e10cSrcweir
86cdf0e10cSrcweir OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid from position" );
87cdf0e10cSrcweir OSL_ENSURE( mbRelSize ? maTo.isValid() : maSize.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid to/size" );
88cdf0e10cSrcweir if( maFrom.isValid() && (mbRelSize ? maTo.isValid() : maSize.isValid()) )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir // calculate shape position
91cdf0e10cSrcweir aAnchorRect.X = static_cast< sal_Int64 >( maFrom.mfX * rChartRect.Width + 0.5 );
92cdf0e10cSrcweir aAnchorRect.Y = static_cast< sal_Int64 >( maFrom.mfY * rChartRect.Height + 0.5 );
93cdf0e10cSrcweir
94cdf0e10cSrcweir // calculate shape size
95cdf0e10cSrcweir if( mbRelSize )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir aAnchorRect.Width = static_cast< sal_Int64 >( maTo.mfX * rChartRect.Width + 0.5 ) - aAnchorRect.X;
98cdf0e10cSrcweir if( aAnchorRect.Width < 0 )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir aAnchorRect.X += aAnchorRect.Width;
101cdf0e10cSrcweir aAnchorRect.Width *= -1;
102cdf0e10cSrcweir }
103cdf0e10cSrcweir aAnchorRect.Height = static_cast< sal_Int64 >( maTo.mfY * rChartRect.Height + 0.5 ) - aAnchorRect.Y;
104cdf0e10cSrcweir if( aAnchorRect.Height < 0 )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir aAnchorRect.Y += aAnchorRect.Height;
107cdf0e10cSrcweir aAnchorRect.Height *= -1;
108cdf0e10cSrcweir }
109cdf0e10cSrcweir }
110cdf0e10cSrcweir else
111cdf0e10cSrcweir {
112cdf0e10cSrcweir aAnchorRect.setSize( maSize );
113cdf0e10cSrcweir }
114cdf0e10cSrcweir }
115cdf0e10cSrcweir
116cdf0e10cSrcweir return aAnchorRect;
117cdf0e10cSrcweir }
118cdf0e10cSrcweir // ============================================================================
119cdf0e10cSrcweir
ChartDrawingFragment(XmlFilterBase & rFilter,const OUString & rFragmentPath,const Reference<XShapes> & rxDrawPage,const Size & rChartSize,const Point & rShapesOffset,bool bOleSupport)120cdf0e10cSrcweir ChartDrawingFragment::ChartDrawingFragment( XmlFilterBase& rFilter,
121cdf0e10cSrcweir const OUString& rFragmentPath, const Reference< XShapes >& rxDrawPage,
122cdf0e10cSrcweir const Size& rChartSize, const Point& rShapesOffset, bool bOleSupport ) :
123cdf0e10cSrcweir FragmentHandler2( rFilter, rFragmentPath ),
124cdf0e10cSrcweir mxDrawPage( rxDrawPage ),
125cdf0e10cSrcweir mbOleSupport( bOleSupport )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir maChartRectEmu.X = convertHmmToEmu( rShapesOffset.X );
128cdf0e10cSrcweir maChartRectEmu.Y = convertHmmToEmu( rShapesOffset.Y );
129cdf0e10cSrcweir maChartRectEmu.Width = convertHmmToEmu( rChartSize.Width );
130cdf0e10cSrcweir maChartRectEmu.Height = convertHmmToEmu( rChartSize.Height );
131cdf0e10cSrcweir }
132cdf0e10cSrcweir
~ChartDrawingFragment()133cdf0e10cSrcweir ChartDrawingFragment::~ChartDrawingFragment()
134cdf0e10cSrcweir {
135cdf0e10cSrcweir }
136cdf0e10cSrcweir
onCreateContext(sal_Int32 nElement,const AttributeList & rAttribs)137cdf0e10cSrcweir ContextHandlerRef ChartDrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
138cdf0e10cSrcweir {
139cdf0e10cSrcweir switch( getCurrentElement() )
140cdf0e10cSrcweir {
141cdf0e10cSrcweir case XML_ROOT_CONTEXT:
142cdf0e10cSrcweir if( nElement == C_TOKEN( userShapes ) ) return this;
143cdf0e10cSrcweir break;
144cdf0e10cSrcweir
145cdf0e10cSrcweir case C_TOKEN( userShapes ):
146cdf0e10cSrcweir switch( nElement )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir case CDR_TOKEN( absSizeAnchor ):
149cdf0e10cSrcweir mxAnchor.reset( new ShapeAnchor( false ) );
150cdf0e10cSrcweir return this;
151cdf0e10cSrcweir case CDR_TOKEN( relSizeAnchor ):
152cdf0e10cSrcweir mxAnchor.reset( new ShapeAnchor( true ) );
153cdf0e10cSrcweir return this;
154cdf0e10cSrcweir }
155cdf0e10cSrcweir break;
156cdf0e10cSrcweir
157cdf0e10cSrcweir case CDR_TOKEN( absSizeAnchor ):
158cdf0e10cSrcweir case CDR_TOKEN( relSizeAnchor ):
159cdf0e10cSrcweir switch( nElement )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir case CDR_TOKEN( sp ):
162cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.CustomShape" ) );
163cdf0e10cSrcweir return new ShapeContext( *this, ShapePtr(), mxShape );
164cdf0e10cSrcweir case CDR_TOKEN( cxnSp ):
165cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.ConnectorShape" ) );
166cdf0e10cSrcweir return new ConnectorShapeContext( *this, ShapePtr(), mxShape );
167cdf0e10cSrcweir case CDR_TOKEN( pic ):
168cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) );
169cdf0e10cSrcweir return new GraphicShapeContext( *this, ShapePtr(), mxShape );
170cdf0e10cSrcweir case CDR_TOKEN( graphicFrame ):
171cdf0e10cSrcweir if( !mbOleSupport )
172cdf0e10cSrcweir return 0;
173cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) );
174cdf0e10cSrcweir return new GraphicalObjectFrameContext( *this, ShapePtr(), mxShape, true );
175cdf0e10cSrcweir case CDR_TOKEN( grpSp ):
176cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.GroupShape" ) );
177cdf0e10cSrcweir return new ShapeGroupContext( *this, ShapePtr(), mxShape );
178cdf0e10cSrcweir
179cdf0e10cSrcweir case CDR_TOKEN( from ):
180cdf0e10cSrcweir case CDR_TOKEN( to ):
181cdf0e10cSrcweir return this;
182cdf0e10cSrcweir
183cdf0e10cSrcweir case CDR_TOKEN( ext ):
184cdf0e10cSrcweir if( mxAnchor.get() ) mxAnchor->importExt( rAttribs );
185cdf0e10cSrcweir return 0;
186cdf0e10cSrcweir }
187cdf0e10cSrcweir break;
188cdf0e10cSrcweir
189cdf0e10cSrcweir case CDR_TOKEN( from ):
190cdf0e10cSrcweir case CDR_TOKEN( to ):
191cdf0e10cSrcweir switch( nElement )
192cdf0e10cSrcweir {
193cdf0e10cSrcweir case CDR_TOKEN( x ):
194cdf0e10cSrcweir case CDR_TOKEN( y ):
195cdf0e10cSrcweir return this; // collect value in onEndElement()
196cdf0e10cSrcweir }
197cdf0e10cSrcweir break;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir return 0;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir
onCharacters(const OUString & rChars)202cdf0e10cSrcweir void ChartDrawingFragment::onCharacters( const OUString& rChars )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir if( isCurrentElement( CDR_TOKEN( x ), CDR_TOKEN( y ) ) && mxAnchor.get() )
205cdf0e10cSrcweir mxAnchor->setPos( getCurrentElement(), getParentElement(), rChars );
206cdf0e10cSrcweir }
207cdf0e10cSrcweir
onEndElement()208cdf0e10cSrcweir void ChartDrawingFragment::onEndElement()
209cdf0e10cSrcweir {
210cdf0e10cSrcweir if( isCurrentElement( CDR_TOKEN( absSizeAnchor ), CDR_TOKEN( relSizeAnchor ) ) )
211cdf0e10cSrcweir {
212cdf0e10cSrcweir if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( maChartRectEmu );
215cdf0e10cSrcweir if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) )
216cdf0e10cSrcweir {
217cdf0e10cSrcweir // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle)
218cdf0e10cSrcweir Rectangle aShapeRectEmu32(
219cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ),
220cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Y, 0, SAL_MAX_INT32 ),
221cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ),
222cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) );
223cdf0e10cSrcweir mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aShapeRectEmu32 );
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir mxShape.reset();
227cdf0e10cSrcweir mxAnchor.reset();
228cdf0e10cSrcweir }
229cdf0e10cSrcweir }
230cdf0e10cSrcweir
231cdf0e10cSrcweir // ============================================================================
232cdf0e10cSrcweir
233cdf0e10cSrcweir } // namespace chart
234cdf0e10cSrcweir } // namespace drawingml
235cdf0e10cSrcweir } // namespace oox
236