diff options
author | Daniel Rentz <dr@openoffice.org> | 2010-07-27 17:12:01 +0200 |
---|---|---|
committer | Daniel Rentz <dr@openoffice.org> | 2010-07-27 17:12:01 +0200 |
commit | 11c19ba7fb8c78662e64fa31e86f150057df33d9 (patch) | |
tree | 5793fc5ab7830ea8dba1136e5c17d2fbeb5e97ca /oox/source/vml | |
parent | 67948f27546e46818e3b630fcb753c6d8dc8a20a (diff) | |
parent | fea4f71bcd4727fe0b445990d062fa4bc12dc18d (diff) |
mib17: rebase to DEV300_m84
Diffstat (limited to 'oox/source/vml')
-rw-r--r-- | oox/source/vml/vmldrawing.cxx | 5 | ||||
-rw-r--r-- | oox/source/vml/vmldrawingfragment.cxx | 1 | ||||
-rw-r--r-- | oox/source/vml/vmlformatting.cxx | 18 | ||||
-rw-r--r-- | oox/source/vml/vmlinputstream.cxx | 219 | ||||
-rw-r--r-- | oox/source/vml/vmlshape.cxx | 32 | ||||
-rw-r--r-- | oox/source/vml/vmlshapecontainer.cxx | 2 | ||||
-rw-r--r-- | oox/source/vml/vmlshapecontext.cxx | 30 |
7 files changed, 268 insertions, 39 deletions
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx index 9a5f4451ec04..1cc74c32aa2d 100644 --- a/oox/source/vml/vmldrawing.cxx +++ b/oox/source/vml/vmldrawing.cxx @@ -39,6 +39,7 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::awt::Rectangle; using ::com::sun::star::awt::XControlModel; using ::com::sun::star::drawing::XDrawPage; +using ::com::sun::star::drawing::XShape; using ::com::sun::star::drawing::XShapes; using ::oox::core::XmlFilterBase; @@ -155,6 +156,10 @@ void Drawing::convertControlClientData( const Reference< XControlModel >& /*rxCt { } +void Drawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& /*rShapeRect*/ ) +{ +} + // ============================================================================ } // namespace vml diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index aae5b5c40556..333df72bbaf7 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -50,6 +50,7 @@ DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragm Reference< XInputStream > DrawingFragment::openFragmentStream() const { + // #i104719# create an input stream that preprocesses the VML data return new InputStream( FragmentHandler2::openFragmentStream() ); } diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index 6baea708c8a2..827930c22496 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -470,6 +470,7 @@ void FillModel::assignUsed( const FillModel& rSource ) moFocus.assignIfUsed( rSource.moFocus ); moFocusPos.assignIfUsed( rSource.moFocusPos ); moFocusSize.assignIfUsed( rSource.moFocusSize ); + moBitmapPath.assignIfUsed( rSource.moBitmapPath ); moRotate.assignIfUsed( rSource.moRotate ); } @@ -561,6 +562,23 @@ void FillModel::pushToPropMap( PropertyMap& rPropMap, } break; + case XML_pattern: + case XML_tile: + case XML_frame: + { + if( moBitmapPath.has() && moBitmapPath.get().getLength() > 0 ) + { + aFillProps.maBlipProps.mxGraphic = rGraphicHelper.importEmbeddedGraphic( moBitmapPath.get() ); + if( aFillProps.maBlipProps.mxGraphic.is() ) + { + aFillProps.moFillType = XML_blipFill; + aFillProps.maBlipProps.moBitmapMode = (nFillType == XML_frame) ? XML_stretch : XML_tile; + break; // do not break if bitmap is missing, but run to XML_solid instead + } + } + } + // run-through to XML_solid in case of missing bitmap path intended! + case XML_solid: default: { diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx index d80058c8f3e0..a6d50e193bc4 100644 --- a/oox/source/vml/vmlinputstream.cxx +++ b/oox/source/vml/vmlinputstream.cxx @@ -26,9 +26,13 @@ ************************************************************************/ #include "oox/vml/vmlinputstream.hxx" -#include <algorithm> -#include <string.h> +#include <map> +#include <rtl/strbuf.hxx> +#include <rtl/strbuf.hxx> +#include "oox/helper/helper.hxx" +using ::rtl::OString; +using ::rtl::OStringBuffer; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::io::XInputStream; @@ -38,6 +42,116 @@ namespace vml { // ============================================================================ +namespace { + +inline const sal_Char* lclFindCharacter( const sal_Char* pcBeg, const sal_Char* pcEnd, sal_Char cChar ) +{ + sal_Int32 nIndex = rtl_str_indexOfChar_WithLength( pcBeg, static_cast< sal_Int32 >( pcEnd - pcBeg ), cChar ); + return (nIndex < 0) ? pcEnd : (pcBeg + nIndex); +} + +inline bool lclIsWhiteSpace( sal_Char cChar ) +{ + return (cChar == ' ') || (cChar == '\t') || (cChar == '\n') || (cChar == '\r'); +} + +const sal_Char* lclFindWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + for( ; pcBeg < pcEnd; ++pcBeg ) + if( lclIsWhiteSpace( *pcBeg ) ) + return pcBeg; + return pcEnd; +} + +const sal_Char* lclFindNonWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + for( ; pcBeg < pcEnd; ++pcBeg ) + if( !lclIsWhiteSpace( *pcBeg ) ) + return pcBeg; + return pcEnd; +} + +const sal_Char* lclTrimWhiteSpaceFromEnd( const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + while( (pcBeg < pcEnd) && lclIsWhiteSpace( pcEnd[ -1 ] ) ) + --pcEnd; + return pcEnd; +} + +inline void lclAppendToBuffer( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + rBuffer.append( pcBeg, static_cast< sal_Int32 >( pcEnd - pcBeg ) ); +} + +// ---------------------------------------------------------------------------- + +void lclProcessAttribs( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + /* Map attribute names to char-pointer of all attributes. This map is used + to find multiple occurences of attributes with the same name. The + mapped pointers are used as map key in the next map below. */ + typedef ::std::map< OString, const sal_Char* > AttributeNameMap; + AttributeNameMap aAttributeNames; + + /* Map the char-pointers of all attributes to the full attribute definition + string. This preserves the original order of the used attributes. */ + typedef ::std::map< const sal_Char*, OString > AttributeDataMap; + AttributeDataMap aAttributes; + + bool bOk = true; + const sal_Char* pcNameBeg = pcBeg; + while( bOk && (pcNameBeg < pcEnd) ) + { + // pcNameBeg points to begin of attribute name, find equality sign + const sal_Char* pcEqualSign = lclFindCharacter( pcNameBeg, pcEnd, '=' ); + if( (bOk = pcEqualSign < pcEnd) == true ) + { + // find end of attribute name (ignore whitespace between name and equality sign) + const sal_Char* pcNameEnd = lclTrimWhiteSpaceFromEnd( pcNameBeg, pcEqualSign ); + if( (bOk = pcNameBeg < pcNameEnd) == true ) + { + // find begin of attribute value (must be single or double quote) + const sal_Char* pcValueBeg = lclFindNonWhiteSpace( pcEqualSign + 1, pcEnd ); + if( (bOk = (pcValueBeg < pcEnd) && ((*pcValueBeg == '\'') || (*pcValueBeg == '"'))) == true ) + { + // find end of attribute value (matching quote character) + const sal_Char* pcValueEnd = lclFindCharacter( pcValueBeg + 1, pcEnd, *pcValueBeg ); + if( (bOk = pcValueEnd < pcEnd) == true ) + { + ++pcValueEnd; + OString aAttribName( pcNameBeg, static_cast< sal_Int32 >( pcNameEnd - pcNameBeg ) ); + OString aAttribData( pcNameBeg, static_cast< sal_Int32 >( pcValueEnd - pcNameBeg ) ); + // search for an existing attribute with the same name + AttributeNameMap::iterator aIt = aAttributeNames.find( aAttribName ); + // remove its definition from the data map + if( aIt != aAttributeNames.end() ) + aAttributes.erase( aIt->second ); + // insert the attribute into both maps + aAttributeNames[ aAttribName ] = pcNameBeg; + aAttributes[ pcNameBeg ] = aAttribData; + // continue with next attribute (skip whitespace after this attribute) + pcNameBeg = pcValueEnd; + if( (pcNameBeg < pcEnd) && ((bOk = lclIsWhiteSpace( *pcNameBeg )) == true) ) + pcNameBeg = lclFindNonWhiteSpace( pcNameBeg + 1, pcEnd ); + } + } + } + } + } + + // if no error has occured, build the resulting attribute list + if( bOk ) + for( AttributeDataMap::iterator aIt = aAttributes.begin(), aEnd = aAttributes.end(); aIt != aEnd; ++aIt ) + rBuffer.append( ' ' ).append( aIt->second ); + // on error, just append the complete passed string + else + lclAppendToBuffer( rBuffer, pcBeg, pcEnd ); +} + +} // namespace + +// ============================================================================ + StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInStrm ) { if( rxInStrm.is() ) try @@ -49,26 +163,101 @@ StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInS { } - // parse the data and eat all parser instructions that make expat sad if( maDataSeq.hasElements() ) { - sal_Char* pcBeg = reinterpret_cast< sal_Char* >( maDataSeq.getArray() ); - sal_Char* pcEnd = pcBeg + maDataSeq.getLength(); - sal_Char* pcCurr = pcBeg; + const OString aCDataOpen = CREATE_OSTRING( "<![CDATA[" ); + const OString aCDataClose = CREATE_OSTRING( "]]>" ); + + OStringBuffer aBuffer; + aBuffer.ensureCapacity( maDataSeq.getLength() + 256 ); + const sal_Char* pcCurr = reinterpret_cast< const sal_Char* >( maDataSeq.getConstArray() ); + const sal_Char* pcEnd = pcCurr + maDataSeq.getLength(); while( pcCurr < pcEnd ) { - pcCurr = ::std::find( pcCurr, pcEnd, '<' ); - sal_Char* pcClose = ::std::find( pcCurr, pcEnd, '>' ); - if( (pcCurr < pcEnd) && (pcClose < pcEnd) && (pcClose - pcCurr >= 5) && (pcCurr[ 1 ] == '!') && (pcCurr[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) + // look for the next opening angle bracket + const sal_Char* pcOpen = lclFindCharacter( pcCurr, pcEnd, '<' ); + // copy all characters from current position to opening bracket + lclAppendToBuffer( aBuffer, pcCurr, pcOpen ); + + // nothing to do if no opening bracket has been found + if( pcOpen < pcEnd ) { - ++pcClose; - memmove( pcCurr, pcClose, pcEnd - pcClose ); - pcEnd -= (pcClose - pcCurr); + // string length from opening bracket to end + sal_Int32 nLengthToEnd = static_cast< sal_Int32 >( pcEnd - pcOpen ); + + // check for CDATA part, starting with '<![CDATA[' + if( rtl_str_compare_WithLength( pcOpen, nLengthToEnd, aCDataOpen.getStr(), aCDataOpen.getLength() ) == 0 ) + { + // search the position after the end tag ']]>' + sal_Int32 nClosePos = rtl_str_indexOfStr_WithLength( pcOpen, nLengthToEnd, aCDataClose.getStr(), aCDataClose.getLength() ); + pcCurr = (nClosePos < 0) ? pcEnd : (pcOpen + nClosePos + aCDataClose.getLength()); + // copy the entire CDATA part + lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); + } + + // no CDATA part - process the element starting at pcOpen + else + { + // look for the next closing angle bracket + const sal_Char* pcClose = lclFindCharacter( pcOpen + 1, pcEnd, '>' ); + // complete element found? + if( pcClose < pcEnd ) + { + // continue after closing bracket + pcCurr = pcClose + 1; + // length of entire element with angle brackets + sal_Int32 nElementLen = static_cast< sal_Int32 >( pcCurr - pcOpen ); + + // skip parser instructions: '<![...]>' + if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) + { + // do nothing + } + + // replace '<br>' elements with '<br/>' elements + else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) ) + { + aBuffer.append( RTL_CONSTASCII_STRINGPARAM( "<br/>" ) ); + } + + // check start elements and empty elements for repeated attributes + else if( pcOpen[ 1 ] != '/' ) + { + // find positions of text content inside brackets, exclude '/' in '<emptyelement/>' + const sal_Char* pcContentBeg = pcOpen + 1; + bool bIsEmptyElement = pcClose[ -1 ] == '/'; + const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose; + // append element name to buffer + const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd ); + lclAppendToBuffer( aBuffer, pcOpen, pcWhiteSpace ); + // find begin of attributes, and process all attributes + const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd ); + if( pcAttribBeg < pcContentEnd ) + lclProcessAttribs( aBuffer, pcAttribBeg, pcContentEnd ); + // close the element + if( bIsEmptyElement ) + aBuffer.append( '/' ); + aBuffer.append( '>' ); + } + + // append end elements without further processing + else + { + lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); + } + } + else + { + // no complete element found, copy all from opening bracket to end + lclAppendToBuffer( aBuffer, pcOpen, pcEnd ); + pcCurr = pcEnd; + } + } } - else - pcCurr = pcClose; } - maDataSeq.realloc( static_cast< sal_Int32 >( pcEnd - pcBeg ) ); + + // set the final data sequence + maDataSeq = ::comphelper::ByteSequence( reinterpret_cast< const sal_Int8* >( aBuffer.getStr() ), aBuffer.getLength() ); } } diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index 40b3e9952b43..d557a7f50354 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -36,6 +36,7 @@ #include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/graphic/XGraphic.hpp> #include "properties.hxx" +#include "oox/helper/graphichelper.hxx" #include "oox/helper/propertymap.hxx" #include "oox/helper/propertyset.hxx" #include "oox/core/xmlfilterbase.hxx" @@ -99,7 +100,7 @@ Reference< XShape > lclCreateXShape( const XmlFilterBase& rFilter, const OUStrin Reference< XShape > xShape; try { - Reference< XMultiServiceFactory > xFactory( rFilter.getModel(), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rFilter.getModelFactory(), UNO_SET_THROW ); xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); } catch( Exception& ) @@ -165,7 +166,7 @@ void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource ) // ---------------------------------------------------------------------------- -ShapeType::ShapeType( const Drawing& rDrawing ) : +ShapeType::ShapeType( Drawing& rDrawing ) : mrDrawing( rDrawing ) { } @@ -237,7 +238,7 @@ ShapeClientData& ShapeModel::createClientData() // ---------------------------------------------------------------------------- -ShapeBase::ShapeBase( const Drawing& rDrawing ) : +ShapeBase::ShapeBase( Drawing& rDrawing ) : ShapeType( rDrawing ) { } @@ -270,7 +271,14 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); // convert the shape, if the calculated rectangle is not empty if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) + { xShape = implConvertAndInsert( rxShapes, aShapeRect ); + /* Notify the drawing that a new shape has been inserted (but not + for children of group shapes). For convenience, pass the + rectangle that contains position and size of the shape. */ + if( !pParentAnchor && xShape.is() ) + mrDrawing.notifyShapeInserted( xShape, aShapeRect ); + } } return xShape; } @@ -318,7 +326,7 @@ void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) con // ============================================================================ -SimpleShape::SimpleShape( const Drawing& rDrawing, const OUString& rService ) : +SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) : ShapeBase( rDrawing ), maService( rService ) { @@ -333,21 +341,21 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes // ============================================================================ -RectangleShape::RectangleShape( const Drawing& rDrawing ) : +RectangleShape::RectangleShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ) ) { } // ============================================================================ -EllipseShape::EllipseShape( const Drawing& rDrawing ) : +EllipseShape::EllipseShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ) ) { } // ============================================================================ -PolyLineShape::PolyLineShape( const Drawing& rDrawing ) : +PolyLineShape::PolyLineShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ) ) { } @@ -372,7 +380,7 @@ Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShape // ============================================================================ -CustomShape::CustomShape( const Drawing& rDrawing ) : +CustomShape::CustomShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.CustomShape" ) ) { } @@ -397,7 +405,7 @@ Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes // ============================================================================ -ComplexShape::ComplexShape( const Drawing& rDrawing ) : +ComplexShape::ComplexShape( Drawing& rDrawing ) : CustomShape( rDrawing ) { } @@ -424,7 +432,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes // set the replacement graphic if( aGraphicPath.getLength() > 0 ) { - Reference< XGraphic > xGraphic = rFilter.importEmbeddedGraphic( aGraphicPath ); + Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath ); if( xGraphic.is() ) aOleProps[ PROP_Graphic ] <<= xGraphic; } @@ -471,7 +479,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes Reference< XShape > xShape = lclCreateAndInsertXShape( rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rShapeRect ); if( xShape.is() ) { - OUString aGraphicUrl = rFilter.importEmbeddedGraphicObject( aGraphicPath ); + OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( aGraphicPath ); if( aGraphicUrl.getLength() > 0 ) { PropertySet aPropSet( xShape ); @@ -487,7 +495,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes // ============================================================================ -GroupShape::GroupShape( const Drawing& rDrawing ) : +GroupShape::GroupShape( Drawing& rDrawing ) : ShapeBase( rDrawing ), mxChildren( new ShapeContainer( rDrawing ) ) { diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx index 8e36e4b0054e..a3bdfdb217d7 100644 --- a/oox/source/vml/vmlshapecontainer.cxx +++ b/oox/source/vml/vmlshapecontainer.cxx @@ -60,7 +60,7 @@ void lclMapShapesById( RefMap< OUString, ShapeType >& orMap, const RefVector< Sh // ============================================================================ -ShapeContainer::ShapeContainer( const Drawing& rDrawing ) : +ShapeContainer::ShapeContainer( Drawing& rDrawing ) : mrDrawing( rDrawing ) { } diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index 2fc64fc8b275..08115d4f8d25 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -44,9 +44,9 @@ namespace { /** Returns the boolean value from the specified VML attribute (if present). */ -OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nElement ) +OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nToken ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); if( oValue.has() ) return OptValue< bool >( ConversionHelper::decodeBool( oValue.get() ) ); return OptValue< bool >(); } @@ -54,18 +54,18 @@ OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nElemen /** Returns the percentage value from the specified VML attribute (if present). The value will be normalized (1.0 is returned for 100%). */ -OptValue< double > lclDecodePercent( const AttributeList& rAttribs, sal_Int32 nElement, double fDefValue ) +OptValue< double > lclDecodePercent( const AttributeList& rAttribs, sal_Int32 nToken, double fDefValue ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); if( oValue.has() ) return OptValue< double >( ConversionHelper::decodePercent( oValue.get(), fDefValue ) ); return OptValue< double >(); } /** Returns the integer value pair from the specified VML attribute (if present). */ -OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int32 nElement ) +OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int32 nToken ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); OptValue< Int32Pair > oRetValue; if( oValue.has() ) { @@ -78,9 +78,9 @@ OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int /** Returns the percentage pair from the specified VML attribute (if present). */ -OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_Int32 nElement ) +OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_Int32 nToken ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); OptValue< DoublePair > oRetValue; if( oValue.has() ) { @@ -235,18 +235,26 @@ ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const A mrTypeModel.maFillModel.moFocus = lclDecodePercent( rAttribs, XML_focus, 0.0 ); mrTypeModel.maFillModel.moFocusPos = lclDecodePercentPair( rAttribs, XML_focusposition ); mrTypeModel.maFillModel.moFocusSize = lclDecodePercentPair( rAttribs, XML_focussize ); + mrTypeModel.maFillModel.moBitmapPath = decodeFragmentPath( rAttribs, O_TOKEN( relid ) ); mrTypeModel.maFillModel.moRotate = lclDecodeBool( rAttribs, XML_rotate ); break; case VML_TOKEN( imagedata ): - OptValue< OUString > oGraphicRelId = rAttribs.getString( O_TOKEN( relid ) ); - if( oGraphicRelId.has() ) - mrTypeModel.moGraphicPath = getFragmentPathFromRelId( oGraphicRelId.get() ); + mrTypeModel.moGraphicPath = decodeFragmentPath( rAttribs, O_TOKEN( relid ) ); mrTypeModel.moGraphicTitle = rAttribs.getString( O_TOKEN( title ) ); break; } return 0; } +OptValue< OUString > ShapeTypeContext::decodeFragmentPath( const AttributeList& rAttribs, sal_Int32 nToken ) const +{ + OptValue< OUString > oFragmentPath; + OptValue< OUString > oRelId = rAttribs.getString( nToken ); + if( oRelId.has() ) + oFragmentPath = getFragmentPathFromRelId( oRelId.get() ); + return oFragmentPath; +} + void ShapeTypeContext::setStyle( const OUString& rStyle ) { sal_Int32 nIndex = 0; |