/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 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 #include #include #include #include #include #include #include #include "EnhancedCustomShapeToken.hxx" #include #include #include "xmlnmspe.hxx" #include #include #include "xexptran.hxx" #include "xmlerror.hxx" #include #include #include #include #include #include #include #include #include #include #include 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 ) { 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 ) { USHORT 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 bE = 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 { bValid = ( nStartIndex == nIndex ) || bE; } } 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 while( ( nIndex < rParaString.getLength() ) && rParaString[ nIndex ] == (sal_Unicode)' ' ) nIndex++; } 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( aViewBox.GetX(), aViewBox.GetY(), aViewBox.GetWidth(), aViewBox.GetHeight() ); 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(0.0); 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_Position : 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_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( USHORT 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 ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */