| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmloff.hxx" |
| #include "ximpcustomshape.hxx" |
| #include "ximpshap.hxx" |
| #include "xmlehelp.hxx" |
| #include <rtl/math.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <rtl/ustring.hxx> |
| #include <com/sun/star/uno/Reference.h> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/xml/sax/XAttributeList.hpp> |
| #include <com/sun/star/container/XIndexContainer.hpp> |
| #include <xmloff/xmltoken.hxx> |
| #include "EnhancedCustomShapeToken.hxx" |
| #include <xmloff/xmlimp.hxx> |
| #include <xmloff/xmltkmap.hxx> |
| #include "xmloff/xmlnmspe.hxx" |
| #include <xmloff/nmspmap.hxx> |
| #include <xmloff/xmluconv.hxx> |
| #include "xexptran.hxx" |
| #include "xmloff/xmlerror.hxx" |
| #include <tools/debug.hxx> |
| #include <com/sun/star/drawing/Direction3D.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp> |
| #include <com/sun/star/drawing/ProjectionMode.hpp> |
| #include <com/sun/star/drawing/HomogenMatrix3.hpp> |
| #include <basegfx/vector/b2dvector.hxx> |
| #include <hash_map> |
| |
| using namespace ::com::sun::star; |
| using namespace ::xmloff::token; |
| using namespace ::xmloff::EnhancedCustomShapeToken; |
| |
| TYPEINIT1( XMLEnhancedCustomShapeContext, SvXMLImportContext ); |
| |
| XMLEnhancedCustomShapeContext::XMLEnhancedCustomShapeContext( SvXMLImport& rImport, |
| ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, |
| sal_uInt16 nPrefix, const rtl::OUString& rLocalName, |
| std::vector< com::sun::star::beans::PropertyValue >& rCustomShapeGeometry ) : |
| SvXMLImportContext( rImport, nPrefix, rLocalName ), |
| mrUnitConverter( rImport.GetMM100UnitConverter() ), |
| mrxShape( rxShape ), |
| mrCustomShapeGeometry( rCustomShapeGeometry ) |
| { |
| } |
| |
| const SvXMLEnumMapEntry aXML_GluePointEnumMap[] = |
| { |
| { XML_NONE, 0 }, |
| { XML_SEGMENTS, 1 }, |
| { XML_NONE, 2 }, |
| { XML_RECTANGLE, 3 }, |
| { XML_TOKEN_INVALID, 0 } |
| }; |
| void GetBool( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| sal_Bool bAttrBool; |
| if ( SvXMLUnitConverter::convertBool( bAttrBool, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= bAttrBool; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetInt32( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| sal_Int32 nAttrNumber; |
| if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= nAttrNumber; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetDouble( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| double fAttrDouble; |
| if ( SvXMLUnitConverter::convertDouble( fAttrDouble, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= fAttrDouble; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetDistance( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| double fAttrDouble; |
| MapUnit eSrcUnit( SvXMLExportHelper::GetUnitFromString( rValue, MAP_100TH_MM ) ); |
| if ( SvXMLUnitConverter::convertDouble( fAttrDouble, rValue, eSrcUnit, MAP_100TH_MM ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= fAttrDouble; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetString( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= rValue; |
| rDest.push_back( aProp ); |
| } |
| |
| void GetEnum( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp, |
| const SvXMLEnumMapEntry& rMap ) |
| { |
| sal_uInt16 eKind; |
| if( SvXMLUnitConverter::convertEnum( eKind, rValue, &rMap ) ) |
| { |
| sal_Int16 nEnum = (sal_Int16)eKind; |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= nEnum; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetDoublePercentage( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| MapUnit eSrcUnit = SvXMLExportHelper::GetUnitFromString( rValue, MAP_100TH_MM ); |
| if ( eSrcUnit == MAP_RELATIVE ) |
| { |
| rtl_math_ConversionStatus eStatus; |
| double fAttrDouble = ::rtl::math::stringToDouble( rValue, |
| (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL ); |
| if ( eStatus == rtl_math_ConversionStatus_Ok ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= fAttrDouble; |
| rDest.push_back( aProp ); |
| } |
| } |
| } |
| |
| void GetB3DVector( std::vector< com::sun::star::beans::PropertyValue >& rDest, |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| ::basegfx::B3DVector aB3DVector; |
| if ( SvXMLUnitConverter::convertB3DVector( aB3DVector, rValue ) ) |
| { |
| drawing::Direction3D aDirection3D( aB3DVector.getX(), aB3DVector.getY(), aB3DVector.getZ() ); |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= aDirection3D; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| sal_Bool GetEquationName( const rtl::OUString& rEquation, const sal_Int32 nStart, rtl::OUString& rEquationName ) |
| { |
| sal_Int32 nIndex = nStart; |
| while( nIndex < rEquation.getLength() ) |
| { |
| sal_Unicode nChar = rEquation[ nIndex ]; |
| if ( |
| ( ( nChar >= 'a' ) && ( nChar <= 'z' ) ) |
| || ( ( nChar >= 'A' ) && ( nChar <= 'Z' ) ) |
| || ( ( nChar >= '0' ) && ( nChar <= '9' ) ) |
| ) |
| { |
| nIndex++; |
| } |
| else |
| break; |
| } |
| sal_Bool bValid = ( nIndex - nStart ) != 0; |
| if ( bValid ) |
| rEquationName = rEquation.copy( nStart, nIndex - nStart ); |
| return bValid; |
| } |
| |
| sal_Bool GetNextParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, sal_Int32& nIndex, const rtl::OUString& rParaString ) |
| { |
| if ( nIndex >= rParaString.getLength() ) |
| return sal_False; |
| |
| sal_Bool bValid = sal_True; |
| sal_Bool bNumberRequired = sal_True; |
| sal_Bool bMustBePositiveWholeNumbered = sal_False; |
| |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL; |
| if ( rParaString[ nIndex ] == (sal_Unicode)'$' ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT; |
| bMustBePositiveWholeNumbered = sal_True; |
| nIndex++; |
| } |
| else if ( rParaString[ nIndex ] == (sal_Unicode)'?' ) |
| { |
| nIndex++; |
| bNumberRequired = sal_False; |
| rtl::OUString aEquationName; |
| bValid = GetEquationName( rParaString, nIndex, aEquationName ); |
| if ( bValid ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION; |
| rParameter.Value <<= aEquationName; |
| nIndex += aEquationName.getLength(); |
| } |
| } |
| else if ( rParaString[ nIndex ] > (sal_Unicode)'9' ) |
| { |
| bNumberRequired = sal_False; |
| if ( rParaString.matchIgnoreAsciiCaseAsciiL( "left", 4, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT; |
| nIndex += 4; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "top", 3, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP; |
| nIndex += 3; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "right", 5, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT; |
| nIndex += 5; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "bottom", 6, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM; |
| nIndex += 6; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "xstretch", 8, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::XSTRETCH; |
| nIndex += 8; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "ystretch", 8, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::YSTRETCH; |
| nIndex += 8; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "hasstroke", 9, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HASSTROKE; |
| nIndex += 9; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "hasfill", 7, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HASFILL; |
| nIndex += 7; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "width", 5, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::WIDTH; |
| nIndex += 5; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "height", 6, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HEIGHT; |
| nIndex += 6; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "logwidth", 8, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGWIDTH; |
| nIndex += 8; |
| } |
| else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "logheight", 9, nIndex ) ) |
| { |
| rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT; |
| nIndex += 9; |
| } |
| else |
| bValid = sal_False; |
| } |
| if ( bValid ) |
| { |
| if ( bNumberRequired ) |
| { |
| sal_Int32 nStartIndex = nIndex; |
| |
| sal_Bool bM = sal_False; // set if the value is negative |
| sal_Bool bE = sal_False; // set if a double is including a "E" statement |
| sal_Bool bEM = sal_False; // set if a double is including a "E-"statement |
| sal_Bool bDot = sal_False; // set if there is a dot included |
| sal_Bool bEnd = sal_False; // set for each value that can not be part of a double/integer |
| |
| while( ( nIndex < rParaString.getLength() ) && bValid ) |
| { |
| switch( rParaString[ nIndex ] ) |
| { |
| case '.' : |
| { |
| if ( bMustBePositiveWholeNumbered ) |
| bValid = sal_False; |
| else |
| { |
| if ( bDot ) |
| bValid = sal_False; |
| else |
| bDot = sal_True; |
| } |
| } |
| break; |
| case '-' : |
| { |
| if ( bMustBePositiveWholeNumbered ) |
| bValid = sal_False; |
| else |
| { |
| if ( nStartIndex == nIndex ) |
| bM = sal_True; |
| else if ( bE ) |
| bEM = sal_True; |
| else |
| bValid = sal_False; |
| } |
| } |
| break; |
| |
| case 'e' : |
| case 'E' : |
| { |
| if ( bMustBePositiveWholeNumbered ) |
| bEnd = sal_True; |
| else |
| { |
| if ( !bE ) |
| bE = sal_True; |
| else |
| bEnd = sal_True; |
| } |
| } |
| break; |
| case '0' : |
| case '1' : |
| case '2' : |
| case '3' : |
| case '4' : |
| case '5' : |
| case '6' : |
| case '7' : |
| case '8' : |
| case '9' : |
| break; |
| default: |
| bEnd = sal_True; |
| } |
| if ( !bEnd ) |
| nIndex++; |
| else |
| break; |
| } |
| if ( nIndex == nStartIndex ) |
| bValid = sal_False; |
| if ( bValid ) |
| { |
| rtl::OUString aNumber( rParaString.copy( nStartIndex, nIndex - nStartIndex ) ); |
| if ( bE || bDot ) |
| { |
| double fAttrDouble; |
| if ( SvXMLUnitConverter::convertDouble( fAttrDouble, aNumber ) ) |
| rParameter.Value <<= fAttrDouble; |
| else |
| bValid = sal_False; |
| } |
| else |
| { |
| sal_Int32 nValue; |
| if ( SvXMLUnitConverter::convertNumber( nValue, aNumber ) ) |
| rParameter.Value <<= nValue; |
| else |
| bValid = sal_False; |
| } |
| } |
| } |
| } |
| if ( bValid ) |
| { |
| // skipping white spaces and commatas (#121507#) |
| const sal_Unicode aSpace(sal_Unicode(' ')); |
| const sal_Unicode aCommata(sal_Unicode(',')); |
| |
| while(nIndex < rParaString.getLength()) |
| { |
| const sal_Unicode aCandidate(rParaString[nIndex]); |
| |
| if(aSpace == aCandidate || aCommata == aCandidate) |
| { |
| nIndex++; |
| } |
| else |
| { |
| break; |
| } |
| } |
| } |
| return bValid; |
| } |
| |
| void GetPosition3D( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:extrusion-viewpoint |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp, |
| SvXMLUnitConverter& rUnitConverter ) |
| { |
| drawing::Position3D aPosition3D; |
| if ( rUnitConverter.convertPosition3D( aPosition3D, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= aPosition3D; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetDoubleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-point-leaving-directions |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| std::vector< double > vDirection; |
| sal_Int32 nIndex = 0; |
| do |
| { |
| double fAttrDouble; |
| rtl::OUString aToken( rValue.getToken( 0, ',', nIndex ) ); |
| if ( !SvXMLUnitConverter::convertDouble( fAttrDouble, aToken ) ) |
| break; |
| else |
| vDirection.push_back( fAttrDouble ); |
| } |
| while ( nIndex >= 0 ); |
| |
| if ( !vDirection.empty() ) |
| { |
| uno::Sequence< double > aDirectionsSeq( vDirection.size() ); |
| std::vector< double >::const_iterator aIter = vDirection.begin(); |
| std::vector< double >::const_iterator aEnd = vDirection.end(); |
| double* pValues = aDirectionsSeq.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= aDirectionsSeq; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetEnhancedParameter( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| sal_Int32 nIndex = 0; |
| com::sun::star::drawing::EnhancedCustomShapeParameter aParameter; |
| if ( GetNextParameter( aParameter, nIndex, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= aParameter; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetEnhancedParameterPair( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| sal_Int32 nIndex = 0; |
| com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair; |
| if ( GetNextParameter( aParameterPair.First, nIndex, rValue ) |
| && GetNextParameter( aParameterPair.Second, nIndex, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= aParameterPair; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| sal_Int32 GetEnhancedParameterPairSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-points |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vParameter; |
| com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameter; |
| |
| sal_Int32 nIndex = 0; |
| while ( GetNextParameter( aParameter.First, nIndex, rValue ) |
| && GetNextParameter( aParameter.Second, nIndex, rValue ) ) |
| { |
| vParameter.push_back( aParameter ); |
| } |
| if ( !vParameter.empty() ) |
| { |
| uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aParameterSeq( vParameter.size() ); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aIter = vParameter.begin(); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aEnd = vParameter.end(); |
| com::sun::star::drawing::EnhancedCustomShapeParameterPair* pValues = aParameterSeq.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= aParameterSeq; |
| rDest.push_back( aProp ); |
| } |
| return vParameter.size(); |
| } |
| |
| void GetEnhancedRectangleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:text-areas |
| const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) |
| { |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame > vTextFrame; |
| com::sun::star::drawing::EnhancedCustomShapeTextFrame aParameter; |
| |
| sal_Int32 nIndex = 0; |
| |
| while ( GetNextParameter( aParameter.TopLeft.First, nIndex, rValue ) |
| && GetNextParameter( aParameter.TopLeft.Second, nIndex, rValue ) |
| && GetNextParameter( aParameter.BottomRight.First, nIndex, rValue ) |
| && GetNextParameter( aParameter.BottomRight.Second, nIndex, rValue ) ) |
| { |
| vTextFrame.push_back( aParameter ); |
| } |
| if ( !vTextFrame.empty() ) |
| { |
| uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrameSeq( vTextFrame.size() ); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aIter = vTextFrame.begin(); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aEnd = vTextFrame.end(); |
| com::sun::star::drawing::EnhancedCustomShapeTextFrame* pValues = aTextFrameSeq.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( eDestProp ); |
| aProp.Value <<= aTextFrameSeq; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void GetEnhancedPath( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:enhanced-path |
| const rtl::OUString& rValue ) |
| { |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vCoordinates; |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment > vSegments; |
| |
| sal_Int32 nIndex = 0; |
| sal_Int32 nParameterCount = 0; |
| |
| sal_Int32 nParametersNeeded = 1; |
| sal_Int16 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO; |
| |
| sal_Bool bValid = sal_True; |
| |
| while( bValid && ( nIndex < rValue.getLength() ) ) |
| { |
| switch( rValue[ nIndex ] ) |
| { |
| case 'M' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO; |
| nParametersNeeded = 1; |
| nIndex++; |
| } |
| break; |
| case 'L' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO; |
| nParametersNeeded = 1; |
| nIndex++; |
| } |
| break; |
| case 'C' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO; |
| nParametersNeeded = 3; |
| nIndex++; |
| } |
| break; |
| case 'Z' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; |
| nParametersNeeded = 0; |
| nIndex++; |
| } |
| break; |
| case 'N' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH; |
| nParametersNeeded = 0; |
| nIndex++; |
| } |
| break; |
| case 'F' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL; |
| nParametersNeeded = 0; |
| nIndex++; |
| } |
| break; |
| case 'S' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE; |
| nParametersNeeded = 0; |
| nIndex++; |
| } |
| break; |
| case 'T' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO; |
| nParametersNeeded = 3; |
| nIndex++; |
| } |
| break; |
| case 'U' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE; |
| nParametersNeeded = 3; |
| nIndex++; |
| } |
| break; |
| case 'A' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO; |
| nParametersNeeded = 4; |
| nIndex++; |
| } |
| break; |
| case 'B' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC; |
| nParametersNeeded = 4; |
| nIndex++; |
| } |
| break; |
| case 'W' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO; |
| nParametersNeeded = 4; |
| nIndex++; |
| } |
| break; |
| case 'V' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC; |
| nParametersNeeded = 4; |
| nIndex++; |
| } |
| break; |
| case 'X' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX; |
| nParametersNeeded = 1; |
| nIndex++; |
| } |
| break; |
| case 'Y' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY; |
| nParametersNeeded = 1; |
| nIndex++; |
| } |
| break; |
| case 'Q' : |
| { |
| nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO; |
| nParametersNeeded = 2; |
| nIndex++; |
| } |
| break; |
| case ' ' : |
| { |
| nIndex++; |
| } |
| break; |
| |
| case '$' : |
| case '?' : |
| case '0' : |
| case '1' : |
| case '2' : |
| case '3' : |
| case '4' : |
| case '5' : |
| case '6' : |
| case '7' : |
| case '8' : |
| case '9' : |
| case '.' : |
| case '-' : |
| { |
| com::sun::star::drawing::EnhancedCustomShapeParameterPair aPair; |
| if ( GetNextParameter( aPair.First, nIndex, rValue ) && |
| GetNextParameter( aPair.Second, nIndex, rValue ) ) |
| { |
| vCoordinates.push_back( aPair ); |
| nParameterCount++; |
| } |
| else |
| bValid = sal_False; |
| } |
| break; |
| default: |
| nIndex++; |
| break; |
| } |
| if ( !nParameterCount && !nParametersNeeded ) |
| { |
| com::sun::star::drawing::EnhancedCustomShapeSegment aSegment; |
| aSegment.Command = nLatestSegmentCommand; |
| aSegment.Count = 0; |
| vSegments.push_back( aSegment ); |
| nParametersNeeded = 0x7fffffff; |
| } |
| else if ( nParameterCount >= nParametersNeeded ) |
| { |
| // check if the last command is identical, |
| // if so, we just need to increment the count |
| if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) ) |
| vSegments[ vSegments.size() -1 ].Count++; |
| else |
| { |
| com::sun::star::drawing::EnhancedCustomShapeSegment aSegment; |
| aSegment.Command = nLatestSegmentCommand; |
| aSegment.Count = 1; |
| vSegments.push_back( aSegment ); |
| } |
| nParameterCount = 0; |
| } |
| } |
| // adding the Coordinates property |
| uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > seqCoordinates( vCoordinates.size() ); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesIter = vCoordinates.begin(); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesEnd = vCoordinates.end(); |
| com::sun::star::drawing::EnhancedCustomShapeParameterPair* pCoordinateValues = seqCoordinates.getArray(); |
| |
| while ( aCoordinatesIter != aCoordinatesEnd ) |
| *pCoordinateValues++ = *aCoordinatesIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_Coordinates ); |
| aProp.Value <<= seqCoordinates; |
| rDest.push_back( aProp ); |
| |
| |
| // adding the Segments property |
| uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments( vSegments.size() ); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsIter = vSegments.begin(); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsEnd = vSegments.end(); |
| com::sun::star::drawing::EnhancedCustomShapeSegment* pSegmentValues = seqSegments.getArray(); |
| |
| while ( aSegmentsIter != aSegmentsEnd ) |
| *pSegmentValues++ = *aSegmentsIter++; |
| |
| aProp.Name = EASGet( EAS_Segments ); |
| aProp.Value <<= seqSegments; |
| rDest.push_back( aProp ); |
| } |
| |
| void GetAdjustmentValues( std::vector< com::sun::star::beans::PropertyValue >& rDest, // draw:adjustments |
| const rtl::OUString& rValue ) |
| { |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > vAdjustmentValue; |
| com::sun::star::drawing::EnhancedCustomShapeParameter aParameter; |
| sal_Int32 nIndex = 0; |
| while ( GetNextParameter( aParameter, nIndex, rValue ) ) |
| { |
| com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue aAdj; |
| if ( aParameter.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL ) |
| { |
| aAdj.Value <<= aParameter.Value; |
| aAdj.State = beans::PropertyState_DIRECT_VALUE; |
| } |
| else |
| aAdj.State = beans::PropertyState_DEFAULT_VALUE; // this should not be, but better than setting nothing |
| |
| vAdjustmentValue.push_back( aAdj ); |
| } |
| |
| sal_Int32 nAdjustmentValues = vAdjustmentValue.size(); |
| if ( nAdjustmentValues ) |
| { |
| uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( nAdjustmentValues ); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aIter = vAdjustmentValue.begin(); |
| std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aEnd = vAdjustmentValue.end(); |
| com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue* pValues = aAdjustmentValues.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_AdjustmentValues ); |
| aProp.Value <<= aAdjustmentValues; |
| rDest.push_back( aProp ); |
| } |
| } |
| |
| void XMLEnhancedCustomShapeContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) |
| { |
| sal_Int16 nLength = xAttrList->getLength(); |
| if ( nLength ) |
| { |
| sal_Int32 nAttrNumber; |
| for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) |
| { |
| rtl::OUString aLocalName; |
| const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); |
| /* sven fixme, this must be checked! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); |
| |
| switch( EASGet( aLocalName ) ) |
| { |
| case EAS_type : |
| GetString( mrCustomShapeGeometry, rValue, EAS_Type ); |
| break; |
| case EAS_mirror_horizontal : |
| GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredX ); |
| break; |
| case EAS_mirror_vertical : |
| GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredY ); |
| break; |
| case EAS_viewBox : |
| { |
| SdXMLImExViewBox aViewBox( rValue, GetImport().GetMM100UnitConverter() ); |
| awt::Rectangle aRect( |
| basegfx::fround(aViewBox.GetX()), |
| basegfx::fround(aViewBox.GetY()), |
| basegfx::fround(aViewBox.GetWidth()), |
| basegfx::fround(aViewBox.GetHeight())); |
| |
| if(0 == aRect.Width && 0 == aRect.Height) |
| { |
| // #124452# If in svg:viewBox no width and height is given the objects should normally |
| // not be visible at all, but in this case it is a bug in LO to write empty svg:viewBox |
| // entries for CustomShapes. To allow for a better ODF user experience, just correct this |
| // here by getting the real object scale from the already set transformation from the xShape. |
| // Hopefully LO will fix that bug (but this will still leave the files with the error), but |
| // even when not this will do no harm as long no one uses this state explicitly for some |
| // purpose (e.g. to really have CustomShapes without content, but unlikely). |
| // When they do fix this they will need this fix anyways to read their own misformed ODF files |
| // again, so I guess it will be taken, too... |
| uno::Reference< beans::XPropertySet > xProps(mrxShape, uno::UNO_QUERY_THROW); |
| uno::Any aObjectTransform = xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation"))); |
| drawing::HomogenMatrix3 aTransformMatrix; |
| aObjectTransform >>= aTransformMatrix; |
| basegfx::B2DHomMatrix aMatrix; |
| |
| aMatrix.set(0, 0, aTransformMatrix.Line1.Column1); |
| aMatrix.set(0, 1, aTransformMatrix.Line1.Column2); |
| aMatrix.set(0, 2, aTransformMatrix.Line1.Column3); |
| aMatrix.set(1, 0, aTransformMatrix.Line2.Column1); |
| aMatrix.set(1, 1, aTransformMatrix.Line2.Column2); |
| aMatrix.set(1, 2, aTransformMatrix.Line2.Column3); |
| aMatrix.set(2, 0, aTransformMatrix.Line3.Column1); |
| aMatrix.set(2, 1, aTransformMatrix.Line3.Column2); |
| aMatrix.set(2, 2, aTransformMatrix.Line3.Column3); |
| |
| basegfx::B2DVector aScale, aTranslate; |
| double fRotate, fShearX; |
| |
| aMatrix.decompose(aScale, aTranslate, fRotate, fShearX); |
| |
| aRect.Width = basegfx::fround(fabs(aScale.getX())); |
| aRect.Height = basegfx::fround(fabs(aScale.getY())); |
| } |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_ViewBox ); |
| aProp.Value <<= aRect; |
| mrCustomShapeGeometry.push_back( aProp ); |
| } |
| break; |
| case EAS_text_rotate_angle : |
| GetDouble( mrCustomShapeGeometry, rValue, EAS_TextRotateAngle ); |
| break; |
| case EAS_extrusion_allowed : |
| GetBool( maPath, rValue, EAS_ExtrusionAllowed ); |
| break; |
| case EAS_text_path_allowed : |
| GetBool( maPath, rValue, EAS_TextPathAllowed ); |
| break; |
| case EAS_concentric_gradient_fill_allowed : |
| GetBool( maPath, rValue, EAS_ConcentricGradientFillAllowed ); |
| break; |
| case EAS_extrusion : |
| GetBool( maExtrusion, rValue, EAS_Extrusion ); |
| break; |
| case EAS_extrusion_brightness : |
| GetDoublePercentage( maExtrusion, rValue, EAS_Brightness ); |
| break; |
| case EAS_extrusion_depth : |
| { |
| sal_Int32 nIndex = 0; |
| com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair; |
| com::sun::star::drawing::EnhancedCustomShapeParameter& rDepth = aParameterPair.First; |
| com::sun::star::drawing::EnhancedCustomShapeParameter& rFraction = aParameterPair.Second; |
| if ( GetNextParameter( rDepth, nIndex, rValue ) ) |
| { |
| // try to catch the unit for the depth |
| MapUnit eSrcUnit( SvXMLExportHelper::GetUnitFromString( rValue, MAP_100TH_MM ) ); |
| |
| rtl::OUStringBuffer aUnitStr; |
| double fFactor = SvXMLExportHelper::GetConversionFactor( aUnitStr, MAP_100TH_MM, eSrcUnit ); |
| if ( ( fFactor != 1.0 ) && ( fFactor != 0.0 ) ) |
| { |
| double fDepth; |
| if ( rDepth.Value >>= fDepth ) |
| { |
| fDepth /= fFactor; |
| rDepth.Value <<= fDepth; |
| } |
| } |
| if ( rValue.matchIgnoreAsciiCase( rtl::OUString( aUnitStr ), nIndex ) ) |
| nIndex += aUnitStr.getLength(); |
| |
| // skipping white spaces |
| while( ( nIndex < rValue.getLength() ) && rValue[ nIndex ] == (sal_Unicode)' ' ) |
| nIndex++; |
| |
| if ( GetNextParameter( rFraction, nIndex, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_Depth ); |
| aProp.Value <<= aParameterPair; |
| maExtrusion.push_back( aProp ); |
| } |
| } |
| } |
| break; |
| case EAS_extrusion_diffusion : |
| GetDoublePercentage( maExtrusion, rValue, EAS_Diffusion ); |
| break; |
| case EAS_extrusion_number_of_line_segments : |
| GetInt32( maExtrusion, rValue, EAS_NumberOfLineSegments ); |
| break; |
| case EAS_extrusion_light_face : |
| GetBool( maExtrusion, rValue, EAS_LightFace ); |
| break; |
| case EAS_extrusion_first_light_harsh : |
| GetBool( maExtrusion, rValue, EAS_FirstLightHarsh ); |
| break; |
| case EAS_extrusion_second_light_harsh : |
| GetBool( maExtrusion, rValue, EAS_SecondLightHarsh ); |
| break; |
| case EAS_extrusion_first_light_level : |
| GetDoublePercentage( maExtrusion, rValue, EAS_FirstLightLevel ); |
| break; |
| case EAS_extrusion_second_light_level : |
| GetDoublePercentage( maExtrusion, rValue, EAS_SecondLightLevel ); |
| break; |
| case EAS_extrusion_first_light_direction : |
| GetB3DVector( maExtrusion, rValue, EAS_FirstLightDirection ); |
| break; |
| case EAS_extrusion_second_light_direction : |
| GetB3DVector( maExtrusion, rValue, EAS_SecondLightDirection ); |
| break; |
| case EAS_extrusion_metal : |
| GetBool( maExtrusion, rValue, EAS_Metal ); |
| break; |
| case EAS_shade_mode : |
| { |
| drawing::ShadeMode eShadeMode( drawing::ShadeMode_FLAT ); |
| if( IsXMLToken( rValue, XML_PHONG ) ) |
| eShadeMode = drawing::ShadeMode_PHONG; |
| else if ( IsXMLToken( rValue, XML_GOURAUD ) ) |
| eShadeMode = drawing::ShadeMode_SMOOTH; |
| else if ( IsXMLToken( rValue, XML_DRAFT ) ) |
| eShadeMode = drawing::ShadeMode_DRAFT; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_ShadeMode ); |
| aProp.Value <<= eShadeMode; |
| maExtrusion.push_back( aProp ); |
| } |
| break; |
| case EAS_extrusion_rotation_angle : |
| GetEnhancedParameterPair( maExtrusion, rValue, EAS_RotateAngle ); |
| break; |
| case EAS_extrusion_rotation_center : |
| GetB3DVector( maExtrusion, rValue, EAS_RotationCenter ); |
| break; |
| case EAS_extrusion_shininess : |
| GetDoublePercentage( maExtrusion, rValue, EAS_Shininess ); |
| break; |
| case EAS_extrusion_skew : |
| GetEnhancedParameterPair( maExtrusion, rValue, EAS_Skew ); |
| break; |
| case EAS_extrusion_specularity : |
| GetDoublePercentage( maExtrusion, rValue, EAS_Specularity ); |
| break; |
| case EAS_projection : |
| { |
| drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PERSPECTIVE ); |
| if( IsXMLToken( rValue, XML_PARALLEL ) ) |
| eProjectionMode = drawing::ProjectionMode_PARALLEL; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_ProjectionMode ); |
| aProp.Value <<= eProjectionMode; |
| maExtrusion.push_back( aProp ); |
| } |
| break; |
| case EAS_extrusion_viewpoint : |
| GetPosition3D( maExtrusion, rValue, EAS_ViewPoint, mrUnitConverter ); |
| break; |
| case EAS_extrusion_origin : |
| GetEnhancedParameterPair( maExtrusion, rValue, EAS_Origin ); |
| break; |
| case EAS_extrusion_color : |
| GetBool( maExtrusion, rValue, EAS_Color ); |
| break; |
| case EAS_enhanced_path : |
| GetEnhancedPath( maPath, rValue ); |
| break; |
| case EAS_path_stretchpoint_x : |
| { |
| if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_StretchX ); |
| aProp.Value <<= nAttrNumber; |
| maPath.push_back( aProp ); |
| } |
| } |
| break; |
| case EAS_path_stretchpoint_y : |
| { |
| if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) |
| { |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_StretchY ); |
| aProp.Value <<= nAttrNumber; |
| maPath.push_back( aProp ); |
| } |
| } |
| break; |
| case EAS_text_areas : |
| GetEnhancedRectangleSequence( maPath, rValue, EAS_TextFrames ); |
| break; |
| case EAS_glue_points : |
| { |
| sal_Int32 i, nPairs = GetEnhancedParameterPairSequence( maPath, rValue, EAS_GluePoints ); |
| GetImport().GetShapeImport()->moveGluePointMapping( mrxShape, nPairs ); |
| for ( i = 0; i < nPairs; i++ ) |
| GetImport().GetShapeImport()->addGluePointMapping( mrxShape, i + 4, i + 4 ); |
| } |
| break; |
| case EAS_glue_point_type : |
| GetEnum( maPath, rValue, EAS_GluePointType, *aXML_GluePointEnumMap ); |
| break; |
| case EAS_glue_point_leaving_directions : |
| GetDoubleSequence( maPath, rValue, EAS_GluePointLeavingDirections ); |
| break; |
| case EAS_text_path : |
| GetBool( maTextPath, rValue, EAS_TextPath ); |
| break; |
| case EAS_text_path_mode : |
| { |
| com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode( com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL ); |
| if( IsXMLToken( rValue, XML_PATH ) ) |
| eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH; |
| else if ( IsXMLToken( rValue, XML_SHAPE ) ) |
| eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_TextPathMode ); |
| aProp.Value <<= eTextPathMode; |
| maTextPath.push_back( aProp ); |
| } |
| break; |
| case EAS_text_path_scale : |
| { |
| sal_Bool bScaleX = IsXMLToken( rValue, XML_SHAPE ); |
| beans::PropertyValue aProp; |
| aProp.Name = EASGet( EAS_ScaleX ); |
| aProp.Value <<= bScaleX; |
| maTextPath.push_back( aProp ); |
| } |
| break; |
| case EAS_text_path_same_letter_heights : |
| GetBool( maTextPath, rValue, EAS_SameLetterHeights ); |
| break; |
| case EAS_modifiers : |
| GetAdjustmentValues( mrCustomShapeGeometry, rValue ); |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| } |
| |
| void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, |
| const std::vector< beans::PropertyValues >& rElement, |
| const rtl::OUString& rElementName ) |
| { |
| if ( !rElement.empty() ) |
| { |
| uno::Sequence< beans::PropertyValues > aPropSeq( rElement.size() ); |
| std::vector< beans::PropertyValues >::const_iterator aIter = rElement.begin(); |
| std::vector< beans::PropertyValues >::const_iterator aEnd = rElement.end(); |
| beans::PropertyValues* pValues = aPropSeq.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = rElementName; |
| aProp.Value <<= aPropSeq; |
| rPropVec.push_back( aProp ); |
| } |
| } |
| |
| void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, |
| const std::vector< rtl::OUString >& rElement, |
| const rtl::OUString& rElementName ) |
| { |
| if ( !rElement.empty() ) |
| { |
| uno::Sequence< rtl::OUString > aPropSeq( rElement.size() ); |
| std::vector< rtl::OUString >::const_iterator aIter = rElement.begin(); |
| std::vector< rtl::OUString >::const_iterator aEnd = rElement.end(); |
| rtl::OUString* pValues = aPropSeq.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = rElementName; |
| aProp.Value <<= aPropSeq; |
| rPropVec.push_back( aProp ); |
| } |
| } |
| |
| void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, |
| const std::vector< com::sun::star::beans::PropertyValue >& rElement, |
| const rtl::OUString& rElementName ) |
| { |
| if ( !rElement.empty() ) |
| { |
| uno::Sequence< beans::PropertyValue > aPropSeq( rElement.size() ); |
| std::vector< beans::PropertyValue >::const_iterator aIter = rElement.begin(); |
| std::vector< beans::PropertyValue >::const_iterator aEnd = rElement.end(); |
| beans::PropertyValue* pValues = aPropSeq.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| beans::PropertyValue aProp; |
| aProp.Name = rElementName; |
| aProp.Value <<= aPropSeq; |
| rPropVec.push_back( aProp ); |
| } |
| } |
| |
| typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash, OUStringEqFunc> EquationHashMap; |
| |
| /* if rPara.Type is from type EnhancedCustomShapeParameterType::EQUATION, the name of the equation |
| will be converted from rtl::OUString to index */ |
| void CheckAndResolveEquationParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rPara, EquationHashMap* pH ) |
| { |
| if ( rPara.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION ) |
| { |
| rtl::OUString aEquationName; |
| if ( rPara.Value >>= aEquationName ) |
| { |
| sal_Int32 nIndex = 0; |
| EquationHashMap::iterator aHashIter( pH->find( aEquationName ) ); |
| if ( aHashIter != pH->end() ) |
| nIndex = (*aHashIter).second; |
| rPara.Value <<= nIndex; |
| } |
| } |
| } |
| |
| void XMLEnhancedCustomShapeContext::EndElement() |
| { |
| // resolve properties that are indexing a Equation |
| if ( !maEquations.empty() ) |
| { |
| // creating hash map containing the name and index of each equation |
| EquationHashMap* pH = new EquationHashMap; |
| std::vector< rtl::OUString >::iterator aEquationNameIter = maEquationNames.begin(); |
| std::vector< rtl::OUString >::iterator aEquationNameEnd = maEquationNames.end(); |
| while( aEquationNameIter != aEquationNameEnd ) |
| { |
| (*pH)[ *aEquationNameIter ] = (sal_Int32)( aEquationNameIter - maEquationNames.begin() ); |
| aEquationNameIter++; |
| } |
| |
| // resolve equation |
| std::vector< rtl::OUString >::iterator aEquationIter = maEquations.begin(); |
| std::vector< rtl::OUString >::iterator aEquationEnd = maEquations.end(); |
| while( aEquationIter != aEquationEnd ) |
| { |
| sal_Int32 nIndexOf = 0; |
| do |
| { |
| nIndexOf = aEquationIter->indexOf( '?', nIndexOf ); |
| if ( nIndexOf != -1 ) |
| { |
| rtl::OUString aEquationName; |
| if ( GetEquationName( *aEquationIter, nIndexOf + 1, aEquationName ) ) |
| { |
| // copying first characters inclusive '?' |
| rtl::OUString aNew( aEquationIter->copy( 0, nIndexOf + 1 ) ); |
| sal_Int32 nIndex = 0; |
| EquationHashMap::iterator aHashIter( pH->find( aEquationName ) ); |
| if ( aHashIter != pH->end() ) |
| nIndex = (*aHashIter).second; |
| aNew += rtl::OUString::valueOf( nIndex ); |
| aNew += aEquationIter->copy( nIndexOf + aEquationName.getLength() + 1 ); |
| *aEquationIter = aNew; |
| } |
| nIndexOf++; |
| } |
| } |
| while( nIndexOf != -1 ); |
| aEquationIter++; |
| } |
| |
| // Path |
| sal_Int32 i; |
| std::vector< beans::PropertyValue >::iterator aPathIter = maPath.begin(); |
| std::vector< beans::PropertyValue >::iterator aPathEnd = maPath.end(); |
| while ( aPathIter != aPathEnd ) |
| { |
| switch( EASGet( aPathIter->Name ) ) |
| { |
| case EAS_Coordinates : |
| case EAS_GluePoints : |
| { |
| uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rSeq = |
| *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >*) |
| aPathIter->Value.getValue()); |
| for ( i = 0; i < rSeq.getLength(); i++ ) |
| { |
| CheckAndResolveEquationParameter( rSeq[ i ].First, pH ); |
| CheckAndResolveEquationParameter( rSeq[ i ].Second, pH ); |
| } |
| } |
| break; |
| case EAS_TextFrames : |
| { |
| uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >& rSeq = |
| *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >*) |
| aPathIter->Value.getValue()); |
| for ( i = 0; i < rSeq.getLength(); i++ ) |
| { |
| CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.First, pH ); |
| CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.Second, pH ); |
| CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.First, pH ); |
| CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.Second, pH ); |
| } |
| } |
| break; |
| default: |
| break; |
| } |
| aPathIter++; |
| } |
| std::vector< beans::PropertyValues >::iterator aHandleIter = maHandles.begin(); |
| std::vector< beans::PropertyValues >::iterator aHandleEnd = maHandles.end(); |
| while ( aHandleIter != aHandleEnd ) |
| { |
| beans::PropertyValue* pValues = aHandleIter->getArray(); |
| for ( i = 0; i < aHandleIter->getLength(); i++ ) |
| { |
| switch( EASGet( pValues->Name ) ) |
| { |
| case EAS_RangeYMinimum : |
| case EAS_RangeYMaximum : |
| case EAS_RangeXMinimum : |
| case EAS_RangeXMaximum : |
| case EAS_RadiusRangeMinimum : |
| case EAS_RadiusRangeMaximum : |
| { |
| CheckAndResolveEquationParameter( *((com::sun::star::drawing::EnhancedCustomShapeParameter*) |
| pValues->Value.getValue()), pH ); |
| } |
| break; |
| |
| case EAS_Position : |
| case EAS_Polar : |
| { |
| CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*) |
| pValues->Value.getValue())).First, pH ); |
| CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*) |
| pValues->Value.getValue())).Second, pH ); |
| } |
| break; |
| default: |
| break; |
| } |
| pValues++; |
| } |
| aHandleIter++; |
| } |
| delete pH; |
| } |
| |
| SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maExtrusion, EASGet( EAS_Extrusion ) ); |
| SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maPath, EASGet( EAS_Path ) ); |
| SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maTextPath, EASGet( EAS_TextPath ) ); |
| SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maEquations, EASGet( EAS_Equations ) ); |
| if ( !maHandles.empty() ) |
| SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maHandles, EASGet( EAS_Handles ) ); |
| } |
| |
| SvXMLImportContext* XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt16 nPrefix,const rtl::OUString& rLocalName, |
| const uno::Reference< xml::sax::XAttributeList> & xAttrList ) |
| { |
| EnhancedCustomShapeTokenEnum aTokenEnum = EASGet( rLocalName ); |
| if ( aTokenEnum == EAS_equation ) |
| { |
| sal_Int16 nLength = xAttrList->getLength(); |
| if ( nLength ) |
| { |
| rtl::OUString aFormula; |
| rtl::OUString aFormulaName; |
| for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) |
| { |
| rtl::OUString aLocalName; |
| const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); |
| /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); |
| |
| switch( EASGet( aLocalName ) ) |
| { |
| case EAS_formula : |
| aFormula = rValue; |
| break; |
| case EAS_name : |
| aFormulaName = rValue; |
| break; |
| default: |
| break; |
| } |
| } |
| if ( aFormulaName.getLength() || aFormula.getLength() ) |
| { |
| maEquations.push_back( aFormula ); |
| maEquationNames.push_back( aFormulaName ); |
| } |
| } |
| } |
| else if ( aTokenEnum == EAS_handle ) |
| { |
| std::vector< com::sun::star::beans::PropertyValue > aHandle; |
| const sal_Int16 nLength = xAttrList->getLength(); |
| for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) |
| { |
| rtl::OUString aLocalName; |
| const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); |
| /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); |
| switch( EASGet( aLocalName ) ) |
| { |
| case EAS_handle_mirror_vertical : |
| GetBool( aHandle, rValue, EAS_MirroredY ); |
| break; |
| case EAS_handle_mirror_horizontal : |
| GetBool( aHandle, rValue, EAS_MirroredX ); |
| break; |
| case EAS_handle_switched : |
| GetBool( aHandle, rValue, EAS_Switched ); |
| break; |
| case EAS_handle_position : |
| GetEnhancedParameterPair( aHandle, rValue, EAS_Position ); |
| break; |
| case EAS_handle_range_x_minimum : |
| GetEnhancedParameter( aHandle, rValue, EAS_RangeXMinimum ); |
| break; |
| case EAS_handle_range_x_maximum : |
| GetEnhancedParameter( aHandle, rValue, EAS_RangeXMaximum ); |
| break; |
| case EAS_handle_range_y_minimum : |
| GetEnhancedParameter( aHandle, rValue, EAS_RangeYMinimum ); |
| break; |
| case EAS_handle_range_y_maximum : |
| GetEnhancedParameter( aHandle, rValue, EAS_RangeYMaximum ); |
| break; |
| case EAS_handle_polar : |
| GetEnhancedParameterPair( aHandle, rValue, EAS_Polar ); |
| break; |
| case EAS_handle_radius_range_minimum : |
| GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMinimum ); |
| break; |
| case EAS_handle_radius_range_maximum : |
| GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMaximum ); |
| break; |
| default: |
| break; |
| } |
| } |
| beans::PropertyValues aPropSeq( aHandle.size() ); |
| std::vector< beans::PropertyValue >::const_iterator aIter = aHandle.begin(); |
| std::vector< beans::PropertyValue >::const_iterator aEnd = aHandle.end(); |
| beans::PropertyValue* pValues = aPropSeq.getArray(); |
| |
| while ( aIter != aEnd ) |
| *pValues++ = *aIter++; |
| |
| maHandles.push_back( aPropSeq ); |
| } |
| return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList ); |
| } |