1*ca5ec200SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*ca5ec200SAndrew Rist * distributed with this work for additional information 6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance 9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an 15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the 17*ca5ec200SAndrew Rist * specific language governing permissions and limitations 18*ca5ec200SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*ca5ec200SAndrew Rist *************************************************************/ 21*ca5ec200SAndrew Rist 22*ca5ec200SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include <oox/export/vmlexport.hxx> 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <tokens.hxx> 27cdf0e10cSrcweir 28cdf0e10cSrcweir #include <rtl/strbuf.hxx> 29cdf0e10cSrcweir #include <rtl/ustring.hxx> 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include <tools/stream.hxx> 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include <cstdio> 34cdf0e10cSrcweir 35cdf0e10cSrcweir using rtl::OString; 36cdf0e10cSrcweir using rtl::OStringBuffer; 37cdf0e10cSrcweir using rtl::OUString; 38cdf0e10cSrcweir using rtl::OUStringBuffer; 39cdf0e10cSrcweir 40cdf0e10cSrcweir using namespace sax_fastparser; 41cdf0e10cSrcweir using namespace oox::vml; 42cdf0e10cSrcweir 43cdf0e10cSrcweir /// Implementation of an empty stream that silently succeeds, but does nothing. 44cdf0e10cSrcweir /// 45cdf0e10cSrcweir /// In fact, this is a hack. The right solution is to abstract EscherEx to be 46cdf0e10cSrcweir /// able to work without SvStream; but at the moment it is better to live with 47cdf0e10cSrcweir /// this I guess. 48cdf0e10cSrcweir class SvNullStream : public SvStream 49cdf0e10cSrcweir { 50cdf0e10cSrcweir protected: 51cdf0e10cSrcweir virtual sal_Size GetData( void* pData, sal_Size nSize ) { memset( pData, 0, nSize ); return nSize; } 52cdf0e10cSrcweir virtual sal_Size PutData( const void*, sal_Size nSize ) { return nSize; } 53cdf0e10cSrcweir virtual sal_Size SeekPos( sal_Size nPos ) { return nPos; } 54cdf0e10cSrcweir virtual void SetSize( sal_Size ) {} 55cdf0e10cSrcweir virtual void FlushData() {} 56cdf0e10cSrcweir 57cdf0e10cSrcweir public: 58cdf0e10cSrcweir SvNullStream() : SvStream() {} 59cdf0e10cSrcweir virtual ~SvNullStream() {} 60cdf0e10cSrcweir }; 61cdf0e10cSrcweir 62cdf0e10cSrcweir VMLExport::VMLExport( ::sax_fastparser::FSHelperPtr pSerializer ) 63cdf0e10cSrcweir : EscherEx( *( new SvNullStream ), 0 ), 64cdf0e10cSrcweir m_pSerializer( pSerializer ), 65cdf0e10cSrcweir m_pShapeAttrList( NULL ), 66cdf0e10cSrcweir m_nShapeType( ESCHER_ShpInst_Nil ), 67cdf0e10cSrcweir m_pShapeStyle( new OStringBuffer( 200 ) ), 68cdf0e10cSrcweir m_pShapeTypeWritten( new bool[ ESCHER_ShpInst_COUNT ] ) 69cdf0e10cSrcweir { 70cdf0e10cSrcweir mnGroupLevel = 1; 71cdf0e10cSrcweir memset( m_pShapeTypeWritten, 0, ESCHER_ShpInst_COUNT * sizeof( bool ) ); 72cdf0e10cSrcweir } 73cdf0e10cSrcweir 74cdf0e10cSrcweir VMLExport::~VMLExport() 75cdf0e10cSrcweir { 76cdf0e10cSrcweir delete mpOutStrm, mpOutStrm = NULL; 77cdf0e10cSrcweir delete m_pShapeStyle, m_pShapeStyle = NULL; 78cdf0e10cSrcweir delete[] m_pShapeTypeWritten, m_pShapeTypeWritten = NULL; 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir void VMLExport::OpenContainer( UINT16 nEscherContainer, int nRecInstance ) 82cdf0e10cSrcweir { 83cdf0e10cSrcweir EscherEx::OpenContainer( nEscherContainer, nRecInstance ); 84cdf0e10cSrcweir 85cdf0e10cSrcweir if ( nEscherContainer == ESCHER_SpContainer ) 86cdf0e10cSrcweir { 87cdf0e10cSrcweir // opening a shape container 88cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 89cdf0e10cSrcweir if ( m_nShapeType != ESCHER_ShpInst_Nil ) 90cdf0e10cSrcweir fprintf( stderr, "Warning! VMLExport::OpenContainer(): opening shape inside a shape.\n" ); 91cdf0e10cSrcweir #endif 92cdf0e10cSrcweir m_nShapeType = ESCHER_ShpInst_Nil; 93cdf0e10cSrcweir m_pShapeAttrList = m_pSerializer->createAttrList(); 94cdf0e10cSrcweir 95cdf0e10cSrcweir if ( m_pShapeStyle->getLength() ) 96cdf0e10cSrcweir m_pShapeStyle->makeStringAndClear(); 97cdf0e10cSrcweir 98cdf0e10cSrcweir m_pShapeStyle->ensureCapacity( 200 ); 99cdf0e10cSrcweir 100cdf0e10cSrcweir // postpone the ouput so that we are able to write even the elements 101cdf0e10cSrcweir // that we learn inside Commit() 102cdf0e10cSrcweir m_pSerializer->mark(); 103cdf0e10cSrcweir } 104cdf0e10cSrcweir } 105cdf0e10cSrcweir 106cdf0e10cSrcweir void VMLExport::CloseContainer() 107cdf0e10cSrcweir { 108cdf0e10cSrcweir if ( mRecTypes.back() == ESCHER_SpContainer ) 109cdf0e10cSrcweir { 110cdf0e10cSrcweir // write the shape now when we have all the info 111cdf0e10cSrcweir sal_Int32 nShapeElement = StartShape(); 112cdf0e10cSrcweir 113cdf0e10cSrcweir m_pSerializer->mergeTopMarks(); 114cdf0e10cSrcweir 115cdf0e10cSrcweir EndShape( nShapeElement ); 116cdf0e10cSrcweir 117cdf0e10cSrcweir // cleanup 118cdf0e10cSrcweir m_nShapeType = ESCHER_ShpInst_Nil; 119cdf0e10cSrcweir m_pShapeAttrList = NULL; 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir EscherEx::CloseContainer(); 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir UINT32 VMLExport::EnterGroup( const String& rShapeName, const Rectangle* pRect ) 126cdf0e10cSrcweir { 127cdf0e10cSrcweir UINT32 nShapeId = GetShapeID(); 128cdf0e10cSrcweir 129cdf0e10cSrcweir OStringBuffer aStyle( 200 ); 130cdf0e10cSrcweir FastAttributeList *pAttrList = m_pSerializer->createAttrList(); 131cdf0e10cSrcweir 132cdf0e10cSrcweir pAttrList->add( XML_id, ShapeIdString( nShapeId ) ); 133cdf0e10cSrcweir 134cdf0e10cSrcweir if ( rShapeName.Len() ) 135cdf0e10cSrcweir pAttrList->add( XML_alt, OUStringToOString( OUString( rShapeName ), RTL_TEXTENCODING_UTF8 ) ); 136cdf0e10cSrcweir 137cdf0e10cSrcweir // style 138cdf0e10cSrcweir if ( pRect ) 139cdf0e10cSrcweir AddRectangleDimensions( aStyle, *pRect ); 140cdf0e10cSrcweir 141cdf0e10cSrcweir if ( aStyle.getLength() ) 142cdf0e10cSrcweir pAttrList->add( XML_style, aStyle.makeStringAndClear() ); 143cdf0e10cSrcweir 144cdf0e10cSrcweir // coordorigin/coordsize 145cdf0e10cSrcweir if ( pRect && ( mnGroupLevel == 1 ) ) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir pAttrList->add( XML_coordorigin, 148cdf0e10cSrcweir OStringBuffer( 20 ).append( sal_Int32( pRect->Left() ) ) 149cdf0e10cSrcweir .append( "," ).append( sal_Int32( pRect->Top() ) ) 150cdf0e10cSrcweir .makeStringAndClear() ); 151cdf0e10cSrcweir 152cdf0e10cSrcweir pAttrList->add( XML_coordsize, 153cdf0e10cSrcweir OStringBuffer( 20 ).append( sal_Int32( pRect->Right() ) - sal_Int32( pRect->Left() ) ) 154cdf0e10cSrcweir .append( "," ).append( sal_Int32( pRect->Bottom() ) - sal_Int32( pRect->Top() ) ) 155cdf0e10cSrcweir .makeStringAndClear() ); 156cdf0e10cSrcweir } 157cdf0e10cSrcweir 158cdf0e10cSrcweir m_pSerializer->startElementNS( XML_v, XML_group, XFastAttributeListRef( pAttrList ) ); 159cdf0e10cSrcweir 160cdf0e10cSrcweir mnGroupLevel++; 161cdf0e10cSrcweir return nShapeId; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir void VMLExport::LeaveGroup() 165cdf0e10cSrcweir { 166cdf0e10cSrcweir --mnGroupLevel; 167cdf0e10cSrcweir m_pSerializer->endElementNS( XML_v, XML_group ); 168cdf0e10cSrcweir } 169cdf0e10cSrcweir 170cdf0e10cSrcweir void VMLExport::AddShape( UINT32 nShapeType, UINT32 nShapeFlags, UINT32 nShapeId ) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir m_nShapeType = nShapeType; 173cdf0e10cSrcweir m_nShapeFlags = nShapeFlags; 174cdf0e10cSrcweir 175cdf0e10cSrcweir m_pShapeAttrList->add( XML_id, ShapeIdString( nShapeId ) ); 176cdf0e10cSrcweir } 177cdf0e10cSrcweir 178cdf0e10cSrcweir static void impl_AddArrowHead( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue ) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir if ( !pAttrList ) 181cdf0e10cSrcweir return; 182cdf0e10cSrcweir 183cdf0e10cSrcweir const char *pArrowHead = NULL; 184cdf0e10cSrcweir switch ( nValue ) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir case ESCHER_LineNoEnd: pArrowHead = "none"; break; 187cdf0e10cSrcweir case ESCHER_LineArrowEnd: pArrowHead = "block"; break; 188cdf0e10cSrcweir case ESCHER_LineArrowStealthEnd: pArrowHead = "classic"; break; 189cdf0e10cSrcweir case ESCHER_LineArrowDiamondEnd: pArrowHead = "diamond"; break; 190cdf0e10cSrcweir case ESCHER_LineArrowOvalEnd: pArrowHead = "oval"; break; 191cdf0e10cSrcweir case ESCHER_LineArrowOpenEnd: pArrowHead = "open"; break; 192cdf0e10cSrcweir } 193cdf0e10cSrcweir 194cdf0e10cSrcweir if ( pArrowHead ) 195cdf0e10cSrcweir pAttrList->add( nElement, pArrowHead ); 196cdf0e10cSrcweir } 197cdf0e10cSrcweir 198cdf0e10cSrcweir static void impl_AddArrowLength( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue ) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir if ( !pAttrList ) 201cdf0e10cSrcweir return; 202cdf0e10cSrcweir 203cdf0e10cSrcweir const char *pArrowLength = NULL; 204cdf0e10cSrcweir switch ( nValue ) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir case ESCHER_LineShortArrow: pArrowLength = "short"; break; 207cdf0e10cSrcweir case ESCHER_LineMediumLenArrow: pArrowLength = "medium"; break; 208cdf0e10cSrcweir case ESCHER_LineLongArrow: pArrowLength = "long"; break; 209cdf0e10cSrcweir } 210cdf0e10cSrcweir 211cdf0e10cSrcweir if ( pArrowLength ) 212cdf0e10cSrcweir pAttrList->add( nElement, pArrowLength ); 213cdf0e10cSrcweir } 214cdf0e10cSrcweir 215cdf0e10cSrcweir static void impl_AddArrowWidth( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue ) 216cdf0e10cSrcweir { 217cdf0e10cSrcweir if ( !pAttrList ) 218cdf0e10cSrcweir return; 219cdf0e10cSrcweir 220cdf0e10cSrcweir const char *pArrowWidth = NULL; 221cdf0e10cSrcweir switch ( nValue ) 222cdf0e10cSrcweir { 223cdf0e10cSrcweir case ESCHER_LineNarrowArrow: pArrowWidth = "narrow"; break; 224cdf0e10cSrcweir case ESCHER_LineMediumWidthArrow: pArrowWidth = "medium"; break; 225cdf0e10cSrcweir case ESCHER_LineWideArrow: pArrowWidth = "wide"; break; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir if ( pArrowWidth ) 229cdf0e10cSrcweir pAttrList->add( nElement, pArrowWidth ); 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir static void impl_AddBool( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, bool bValue ) 233cdf0e10cSrcweir { 234cdf0e10cSrcweir if ( !pAttrList ) 235cdf0e10cSrcweir return; 236cdf0e10cSrcweir 237cdf0e10cSrcweir pAttrList->add( nElement, bValue? "t": "f" ); 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir static void impl_AddColor( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nColor ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 243cdf0e10cSrcweir if ( nColor & 0xFF000000 ) 244cdf0e10cSrcweir fprintf( stderr, "TODO: this is not a RGB value!\n" ); 245cdf0e10cSrcweir #endif 246cdf0e10cSrcweir 247cdf0e10cSrcweir if ( !pAttrList || ( nColor & 0xFF000000 ) ) 248cdf0e10cSrcweir return; 249cdf0e10cSrcweir 250cdf0e10cSrcweir nColor = ( ( nColor & 0xFF ) << 16 ) + ( nColor & 0xFF00 ) + ( ( nColor & 0xFF0000 ) >> 16 ); 251cdf0e10cSrcweir 252cdf0e10cSrcweir const char *pColor = NULL; 253cdf0e10cSrcweir char pRgbColor[10]; 254cdf0e10cSrcweir switch ( nColor ) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir case 0x000000: pColor = "black"; break; 257cdf0e10cSrcweir case 0xC0C0C0: pColor = "silver"; break; 258cdf0e10cSrcweir case 0x808080: pColor = "gray"; break; 259cdf0e10cSrcweir case 0xFFFFFF: pColor = "white"; break; 260cdf0e10cSrcweir case 0x800000: pColor = "maroon"; break; 261cdf0e10cSrcweir case 0xFF0000: pColor = "red"; break; 262cdf0e10cSrcweir case 0x800080: pColor = "purple"; break; 263cdf0e10cSrcweir case 0xFF00FF: pColor = "fuchsia"; break; 264cdf0e10cSrcweir case 0x008000: pColor = "green"; break; 265cdf0e10cSrcweir case 0x00FF00: pColor = "lime"; break; 266cdf0e10cSrcweir case 0x808000: pColor = "olive"; break; 267cdf0e10cSrcweir case 0xFFFF00: pColor = "yellow"; break; 268cdf0e10cSrcweir case 0x000080: pColor = "navy"; break; 269cdf0e10cSrcweir case 0x0000FF: pColor = "blue"; break; 270cdf0e10cSrcweir case 0x008080: pColor = "teal"; break; 271cdf0e10cSrcweir case 0x00FFFF: pColor = "aqua"; break; 272cdf0e10cSrcweir default: 273cdf0e10cSrcweir { 274cdf0e10cSrcweir snprintf( pRgbColor, sizeof( pRgbColor ), "#%06x", static_cast< unsigned int >( nColor ) ); // not too handy to use OString::valueOf() here :-( 275cdf0e10cSrcweir pColor = pRgbColor; 276cdf0e10cSrcweir } 277cdf0e10cSrcweir break; 278cdf0e10cSrcweir } 279cdf0e10cSrcweir 280cdf0e10cSrcweir pAttrList->add( nElement, pColor ); 281cdf0e10cSrcweir } 282cdf0e10cSrcweir 283cdf0e10cSrcweir static void impl_AddInt( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue ) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir if ( !pAttrList ) 286cdf0e10cSrcweir return; 287cdf0e10cSrcweir 288cdf0e10cSrcweir pAttrList->add( nElement, OString::valueOf( static_cast< sal_Int32 >( nValue ) ).getStr() ); 289cdf0e10cSrcweir } 290cdf0e10cSrcweir 291cdf0e10cSrcweir inline sal_uInt16 impl_GetUInt16( const sal_uInt8* &pVal ) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir sal_uInt16 nRet = *pVal++; 294cdf0e10cSrcweir nRet += ( *pVal++ ) << 8; 295cdf0e10cSrcweir return nRet; 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298cdf0e10cSrcweir inline sal_Int32 impl_GetPointComponent( const sal_uInt8* &pVal, sal_uInt16 nPointSize ) 299cdf0e10cSrcweir { 300cdf0e10cSrcweir sal_Int32 nRet = 0; 301cdf0e10cSrcweir if ( ( nPointSize == 0xfff0 ) || ( nPointSize == 4 ) ) 302cdf0e10cSrcweir { 303cdf0e10cSrcweir sal_uInt16 nUnsigned = *pVal++; 304cdf0e10cSrcweir nUnsigned += ( *pVal++ ) << 8; 305cdf0e10cSrcweir 306cdf0e10cSrcweir nRet = sal_Int16( nUnsigned ); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir else if ( nPointSize == 8 ) 309cdf0e10cSrcweir { 310cdf0e10cSrcweir sal_uInt32 nUnsigned = *pVal++; 311cdf0e10cSrcweir nUnsigned += ( *pVal++ ) << 8; 312cdf0e10cSrcweir nUnsigned += ( *pVal++ ) << 16; 313cdf0e10cSrcweir nUnsigned += ( *pVal++ ) << 24; 314cdf0e10cSrcweir 315cdf0e10cSrcweir nRet = nUnsigned; 316cdf0e10cSrcweir } 317cdf0e10cSrcweir 318cdf0e10cSrcweir return nRet; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect ) 322cdf0e10cSrcweir { 323cdf0e10cSrcweir if ( m_nShapeType == ESCHER_ShpInst_Nil ) 324cdf0e10cSrcweir return; 325cdf0e10cSrcweir 326cdf0e10cSrcweir // postpone the output of the embedded elements so that they are written 327cdf0e10cSrcweir // inside the shapes 328cdf0e10cSrcweir m_pSerializer->mark(); 329cdf0e10cSrcweir 330cdf0e10cSrcweir // dimensions 331cdf0e10cSrcweir if ( m_nShapeType == ESCHER_ShpInst_Line ) 332cdf0e10cSrcweir AddLineDimensions( rRect ); 333cdf0e10cSrcweir else 334cdf0e10cSrcweir AddRectangleDimensions( *m_pShapeStyle, rRect ); 335cdf0e10cSrcweir 336cdf0e10cSrcweir // properties 337cdf0e10cSrcweir bool bAlreadyWritten[ 0xFFF ]; 338cdf0e10cSrcweir memset( bAlreadyWritten, 0, sizeof( bAlreadyWritten ) ); 339cdf0e10cSrcweir const EscherProperties &rOpts = rProps.GetOpts(); 340cdf0e10cSrcweir for ( EscherProperties::const_iterator it = rOpts.begin(); it != rOpts.end(); ++it ) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir sal_uInt16 nId = ( it->nPropId & 0x0FFF ); 343cdf0e10cSrcweir 344cdf0e10cSrcweir if ( bAlreadyWritten[ nId ] ) 345cdf0e10cSrcweir continue; 346cdf0e10cSrcweir 347cdf0e10cSrcweir switch ( nId ) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir case ESCHER_Prop_WrapText: // 133 350cdf0e10cSrcweir { 351cdf0e10cSrcweir const char *pWrapType = NULL; 352cdf0e10cSrcweir switch ( it->nPropValue ) 353cdf0e10cSrcweir { 354cdf0e10cSrcweir case ESCHER_WrapSquare: 355cdf0e10cSrcweir case ESCHER_WrapByPoints: pWrapType = "square"; break; // these two are equivalent according to the docu 356cdf0e10cSrcweir case ESCHER_WrapNone: pWrapType = "none"; break; 357cdf0e10cSrcweir case ESCHER_WrapTopBottom: pWrapType = "topAndBottom"; break; 358cdf0e10cSrcweir case ESCHER_WrapThrough: pWrapType = "through"; break; 359cdf0e10cSrcweir } 360cdf0e10cSrcweir if ( pWrapType ) 361cdf0e10cSrcweir m_pSerializer->singleElementNS( XML_w10, XML_wrap, 362cdf0e10cSrcweir FSNS( XML_w10, XML_type ), pWrapType, 363cdf0e10cSrcweir FSEND ); 364cdf0e10cSrcweir } 365cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_WrapText ] = true; 366cdf0e10cSrcweir break; 367cdf0e10cSrcweir 368cdf0e10cSrcweir // coordorigin 369cdf0e10cSrcweir case ESCHER_Prop_geoLeft: // 320 370cdf0e10cSrcweir case ESCHER_Prop_geoTop: // 321 371cdf0e10cSrcweir { 372cdf0e10cSrcweir sal_uInt32 nLeft = 0, nTop = 0; 373cdf0e10cSrcweir 374cdf0e10cSrcweir if ( nId == ESCHER_Prop_geoLeft ) 375cdf0e10cSrcweir { 376cdf0e10cSrcweir nLeft = it->nPropValue; 377cdf0e10cSrcweir rProps.GetOpt( ESCHER_Prop_geoTop, nTop ); 378cdf0e10cSrcweir } 379cdf0e10cSrcweir else 380cdf0e10cSrcweir { 381cdf0e10cSrcweir nTop = it->nPropValue; 382cdf0e10cSrcweir rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft ); 383cdf0e10cSrcweir } 384cdf0e10cSrcweir 385cdf0e10cSrcweir m_pShapeAttrList->add( XML_coordorigin, 386cdf0e10cSrcweir OStringBuffer( 20 ).append( sal_Int32( nLeft ) ) 387cdf0e10cSrcweir .append( "," ).append( sal_Int32( nTop ) ) 388cdf0e10cSrcweir .makeStringAndClear() ); 389cdf0e10cSrcweir } 390cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_geoLeft ] = true; 391cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_geoTop ] = true; 392cdf0e10cSrcweir break; 393cdf0e10cSrcweir 394cdf0e10cSrcweir // coordsize 395cdf0e10cSrcweir case ESCHER_Prop_geoRight: // 322 396cdf0e10cSrcweir case ESCHER_Prop_geoBottom: // 323 397cdf0e10cSrcweir { 398cdf0e10cSrcweir sal_uInt32 nLeft = 0, nRight = 0, nTop = 0, nBottom = 0; 399cdf0e10cSrcweir rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft ); 400cdf0e10cSrcweir rProps.GetOpt( ESCHER_Prop_geoTop, nTop ); 401cdf0e10cSrcweir 402cdf0e10cSrcweir if ( nId == ESCHER_Prop_geoRight ) 403cdf0e10cSrcweir { 404cdf0e10cSrcweir nRight = it->nPropValue; 405cdf0e10cSrcweir rProps.GetOpt( ESCHER_Prop_geoBottom, nBottom ); 406cdf0e10cSrcweir } 407cdf0e10cSrcweir else 408cdf0e10cSrcweir { 409cdf0e10cSrcweir nBottom = it->nPropValue; 410cdf0e10cSrcweir rProps.GetOpt( ESCHER_Prop_geoRight, nRight ); 411cdf0e10cSrcweir } 412cdf0e10cSrcweir 413cdf0e10cSrcweir m_pShapeAttrList->add( XML_coordsize, 414cdf0e10cSrcweir OStringBuffer( 20 ).append( sal_Int32( nRight ) - sal_Int32( nLeft ) ) 415cdf0e10cSrcweir .append( "," ).append( sal_Int32( nBottom ) - sal_Int32( nTop ) ) 416cdf0e10cSrcweir .makeStringAndClear() ); 417cdf0e10cSrcweir } 418cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_geoRight ] = true; 419cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_geoBottom ] = true; 420cdf0e10cSrcweir break; 421cdf0e10cSrcweir 422cdf0e10cSrcweir case ESCHER_Prop_pVertices: // 325 423cdf0e10cSrcweir case ESCHER_Prop_pSegmentInfo: // 326 424cdf0e10cSrcweir { 425cdf0e10cSrcweir EscherPropSortStruct aVertices; 426cdf0e10cSrcweir EscherPropSortStruct aSegments; 427cdf0e10cSrcweir 428cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_pVertices, aVertices ) && 429cdf0e10cSrcweir rProps.GetOpt( ESCHER_Prop_pSegmentInfo, aSegments ) ) 430cdf0e10cSrcweir { 431cdf0e10cSrcweir const sal_uInt8 *pVerticesIt = aVertices.pBuf + 6; 432cdf0e10cSrcweir const sal_uInt8 *pSegmentIt = aSegments.pBuf; 433cdf0e10cSrcweir OStringBuffer aPath( 512 ); 434cdf0e10cSrcweir 435cdf0e10cSrcweir sal_uInt16 nPointSize = aVertices.pBuf[4] + ( aVertices.pBuf[5] << 8 ); 436cdf0e10cSrcweir 437cdf0e10cSrcweir // number of segments 438cdf0e10cSrcweir sal_uInt16 nSegments = impl_GetUInt16( pSegmentIt ); 439cdf0e10cSrcweir pSegmentIt += 4; 440cdf0e10cSrcweir 441cdf0e10cSrcweir for ( ; nSegments; --nSegments ) 442cdf0e10cSrcweir { 443cdf0e10cSrcweir sal_uInt16 nSeg = impl_GetUInt16( pSegmentIt ); 444cdf0e10cSrcweir switch ( nSeg ) 445cdf0e10cSrcweir { 446cdf0e10cSrcweir case 0x4000: // moveto 447cdf0e10cSrcweir { 448cdf0e10cSrcweir sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize ); 449cdf0e10cSrcweir sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize ); 450cdf0e10cSrcweir aPath.append( "m" ).append( nX ).append( "," ).append( nY ); 451cdf0e10cSrcweir } 452cdf0e10cSrcweir break; 453cdf0e10cSrcweir case 0xb300: 454cdf0e10cSrcweir case 0xac00: 455cdf0e10cSrcweir break; 456cdf0e10cSrcweir case 0x0001: // lineto 457cdf0e10cSrcweir { 458cdf0e10cSrcweir sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize ); 459cdf0e10cSrcweir sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize ); 460cdf0e10cSrcweir aPath.append( "l" ).append( nX ).append( "," ).append( nY ); 461cdf0e10cSrcweir } 462cdf0e10cSrcweir break; 463cdf0e10cSrcweir case 0x2001: // curveto 464cdf0e10cSrcweir { 465cdf0e10cSrcweir sal_Int32 nX1 = impl_GetPointComponent( pVerticesIt, nPointSize ); 466cdf0e10cSrcweir sal_Int32 nY1 = impl_GetPointComponent( pVerticesIt, nPointSize ); 467cdf0e10cSrcweir sal_Int32 nX2 = impl_GetPointComponent( pVerticesIt, nPointSize ); 468cdf0e10cSrcweir sal_Int32 nY2 = impl_GetPointComponent( pVerticesIt, nPointSize ); 469cdf0e10cSrcweir sal_Int32 nX3 = impl_GetPointComponent( pVerticesIt, nPointSize ); 470cdf0e10cSrcweir sal_Int32 nY3 = impl_GetPointComponent( pVerticesIt, nPointSize ); 471cdf0e10cSrcweir aPath.append( "c" ).append( nX1 ).append( "," ).append( nY1 ).append( "," ) 472cdf0e10cSrcweir .append( nX2 ).append( "," ).append( nY2 ).append( "," ) 473cdf0e10cSrcweir .append( nX3 ).append( "," ).append( nY3 ); 474cdf0e10cSrcweir } 475cdf0e10cSrcweir break; 476cdf0e10cSrcweir case 0xaa00: // nofill 477cdf0e10cSrcweir aPath.append( "nf" ); 478cdf0e10cSrcweir break; 479cdf0e10cSrcweir case 0xab00: // nostroke 480cdf0e10cSrcweir aPath.append( "ns" ); 481cdf0e10cSrcweir break; 482cdf0e10cSrcweir case 0x6001: // close 483cdf0e10cSrcweir aPath.append( "x" ); 484cdf0e10cSrcweir break; 485cdf0e10cSrcweir case 0x8000: // end 486cdf0e10cSrcweir aPath.append( "e" ); 487cdf0e10cSrcweir break; 488cdf0e10cSrcweir default: 489cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 490cdf0e10cSrcweir fprintf( stderr, "TODO: unhandled segment '%x' in the path\n", nSeg ); 491cdf0e10cSrcweir #endif 492cdf0e10cSrcweir break; 493cdf0e10cSrcweir } 494cdf0e10cSrcweir } 495cdf0e10cSrcweir 496cdf0e10cSrcweir if ( aPath.getLength() ) 497cdf0e10cSrcweir m_pShapeAttrList->add( XML_path, aPath.getStr() ); 498cdf0e10cSrcweir } 499cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 500cdf0e10cSrcweir else 501cdf0e10cSrcweir fprintf( stderr, "TODO: unhandled shape path, missing either pVertices or pSegmentInfo.\n" ); 502cdf0e10cSrcweir #endif 503cdf0e10cSrcweir } 504cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_pVertices ] = true; 505cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_pSegmentInfo ] = true; 506cdf0e10cSrcweir break; 507cdf0e10cSrcweir 508cdf0e10cSrcweir case ESCHER_Prop_fillType: // 384 509cdf0e10cSrcweir case ESCHER_Prop_fillColor: // 385 510cdf0e10cSrcweir case ESCHER_Prop_fillBackColor: // 387 511cdf0e10cSrcweir case ESCHER_Prop_fNoFillHitTest: // 447 512cdf0e10cSrcweir { 513cdf0e10cSrcweir sal_uInt32 nValue; 514cdf0e10cSrcweir sax_fastparser::FastAttributeList *pAttrList = m_pSerializer->createAttrList(); 515cdf0e10cSrcweir 516cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_fillType, nValue ) ) 517cdf0e10cSrcweir { 518cdf0e10cSrcweir const char *pFillType = NULL; 519cdf0e10cSrcweir switch ( nValue ) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir case ESCHER_FillSolid: pFillType = "solid"; break; 522cdf0e10cSrcweir // TODO case ESCHER_FillPattern: pFillType = ""; break; 523cdf0e10cSrcweir // TODO case ESCHER_FillTexture: pFillType = ""; break; 524cdf0e10cSrcweir // TODO case ESCHER_FillPicture: pFillType = ""; break; 525cdf0e10cSrcweir // TODO case ESCHER_FillShade: pFillType = ""; break; 526cdf0e10cSrcweir // TODO case ESCHER_FillShadeCenter: pFillType = ""; break; 527cdf0e10cSrcweir // TODO case ESCHER_FillShadeShape: pFillType = ""; break; 528cdf0e10cSrcweir // TODO case ESCHER_FillShadeScale: pFillType = ""; break; 529cdf0e10cSrcweir // TODO case ESCHER_FillShadeTitle: pFillType = ""; break; 530cdf0e10cSrcweir // TODO case ESCHER_FillBackground: pFillType = ""; break; 531cdf0e10cSrcweir default: 532cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 533cdf0e10cSrcweir fprintf( stderr, "TODO: unhandled fill type\n" ); 534cdf0e10cSrcweir #endif 535cdf0e10cSrcweir break; 536cdf0e10cSrcweir } 537cdf0e10cSrcweir if ( pFillType ) 538cdf0e10cSrcweir pAttrList->add( XML_type, pFillType ); 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_fillColor, nValue ) ) 542cdf0e10cSrcweir impl_AddColor( pAttrList, XML_color, nValue ); 543cdf0e10cSrcweir 544cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_fillBackColor, nValue ) ) 545cdf0e10cSrcweir impl_AddColor( pAttrList, XML_color2, nValue ); 546cdf0e10cSrcweir 547cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ) ) 548cdf0e10cSrcweir impl_AddBool( pAttrList, XML_detectmouseclick, nValue ); 549cdf0e10cSrcweir 550cdf0e10cSrcweir m_pSerializer->singleElementNS( XML_v, XML_fill, XFastAttributeListRef( pAttrList ) ); 551cdf0e10cSrcweir } 552cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_fillType ] = true; 553cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_fillColor ] = true; 554cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_fillBackColor ] = true; 555cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_fNoFillHitTest ] = true; 556cdf0e10cSrcweir break; 557cdf0e10cSrcweir 558cdf0e10cSrcweir case ESCHER_Prop_lineColor: // 448 559cdf0e10cSrcweir case ESCHER_Prop_lineWidth: // 459 560cdf0e10cSrcweir case ESCHER_Prop_lineDashing: // 462 561cdf0e10cSrcweir case ESCHER_Prop_lineStartArrowhead: // 464 562cdf0e10cSrcweir case ESCHER_Prop_lineEndArrowhead: // 465 563cdf0e10cSrcweir case ESCHER_Prop_lineStartArrowWidth: // 466 564cdf0e10cSrcweir case ESCHER_Prop_lineStartArrowLength: // 467 565cdf0e10cSrcweir case ESCHER_Prop_lineEndArrowWidth: // 468 566cdf0e10cSrcweir case ESCHER_Prop_lineEndArrowLength: // 469 567cdf0e10cSrcweir case ESCHER_Prop_lineJoinStyle: // 470 568cdf0e10cSrcweir case ESCHER_Prop_lineEndCapStyle: // 471 569cdf0e10cSrcweir { 570cdf0e10cSrcweir sal_uInt32 nValue; 571cdf0e10cSrcweir sax_fastparser::FastAttributeList *pAttrList = m_pSerializer->createAttrList(); 572cdf0e10cSrcweir 573cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineColor, nValue ) ) 574cdf0e10cSrcweir impl_AddColor( pAttrList, XML_color, nValue ); 575cdf0e10cSrcweir 576cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineWidth, nValue ) ) 577cdf0e10cSrcweir impl_AddInt( pAttrList, XML_weight, nValue ); 578cdf0e10cSrcweir 579cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineDashing, nValue ) ) 580cdf0e10cSrcweir { 581cdf0e10cSrcweir const char *pDashStyle = NULL; 582cdf0e10cSrcweir switch ( nValue ) 583cdf0e10cSrcweir { 584cdf0e10cSrcweir case ESCHER_LineSolid: pDashStyle = "solid"; break; 585cdf0e10cSrcweir case ESCHER_LineDashSys: pDashStyle = "shortdash"; break; 586cdf0e10cSrcweir case ESCHER_LineDotSys: pDashStyle = "shortdot"; break; 587cdf0e10cSrcweir case ESCHER_LineDashDotSys: pDashStyle = "shortdashdot"; break; 588cdf0e10cSrcweir case ESCHER_LineDashDotDotSys: pDashStyle = "shortdashdotdot"; break; 589cdf0e10cSrcweir case ESCHER_LineDotGEL: pDashStyle = "dot"; break; 590cdf0e10cSrcweir case ESCHER_LineDashGEL: pDashStyle = "dash"; break; 591cdf0e10cSrcweir case ESCHER_LineLongDashGEL: pDashStyle = "longdash"; break; 592cdf0e10cSrcweir case ESCHER_LineDashDotGEL: pDashStyle = "dashdot"; break; 593cdf0e10cSrcweir case ESCHER_LineLongDashDotGEL: pDashStyle = "longdashdot"; break; 594cdf0e10cSrcweir case ESCHER_LineLongDashDotDotGEL: pDashStyle = "longdashdotdot"; break; 595cdf0e10cSrcweir } 596cdf0e10cSrcweir if ( pDashStyle ) 597cdf0e10cSrcweir pAttrList->add( XML_dashstyle, pDashStyle ); 598cdf0e10cSrcweir } 599cdf0e10cSrcweir 600cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowhead, nValue ) ) 601cdf0e10cSrcweir impl_AddArrowHead( pAttrList, XML_startarrow, nValue ); 602cdf0e10cSrcweir 603cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowhead, nValue ) ) 604cdf0e10cSrcweir impl_AddArrowHead( pAttrList, XML_endarrow, nValue ); 605cdf0e10cSrcweir 606cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowWidth, nValue ) ) 607cdf0e10cSrcweir impl_AddArrowWidth( pAttrList, XML_startarrowwidth, nValue ); 608cdf0e10cSrcweir 609cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowLength, nValue ) ) 610cdf0e10cSrcweir impl_AddArrowLength( pAttrList, XML_startarrowlength, nValue ); 611cdf0e10cSrcweir 612cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowWidth, nValue ) ) 613cdf0e10cSrcweir impl_AddArrowWidth( pAttrList, XML_endarrowwidth, nValue ); 614cdf0e10cSrcweir 615cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowLength, nValue ) ) 616cdf0e10cSrcweir impl_AddArrowLength( pAttrList, XML_endarrowlength, nValue ); 617cdf0e10cSrcweir 618cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineJoinStyle, nValue ) ) 619cdf0e10cSrcweir { 620cdf0e10cSrcweir const char *pJoinStyle = NULL; 621cdf0e10cSrcweir switch ( nValue ) 622cdf0e10cSrcweir { 623cdf0e10cSrcweir case ESCHER_LineJoinBevel: pJoinStyle = "bevel"; break; 624cdf0e10cSrcweir case ESCHER_LineJoinMiter: pJoinStyle = "miter"; break; 625cdf0e10cSrcweir case ESCHER_LineJoinRound: pJoinStyle = "round"; break; 626cdf0e10cSrcweir } 627cdf0e10cSrcweir if ( pJoinStyle ) 628cdf0e10cSrcweir pAttrList->add( XML_joinstyle, pJoinStyle ); 629cdf0e10cSrcweir } 630cdf0e10cSrcweir 631cdf0e10cSrcweir if ( rProps.GetOpt( ESCHER_Prop_lineEndCapStyle, nValue ) ) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir const char *pEndCap = NULL; 634cdf0e10cSrcweir switch ( nValue ) 635cdf0e10cSrcweir { 636cdf0e10cSrcweir case ESCHER_LineEndCapRound: pEndCap = "round"; break; 637cdf0e10cSrcweir case ESCHER_LineEndCapSquare: pEndCap = "square"; break; 638cdf0e10cSrcweir case ESCHER_LineEndCapFlat: pEndCap = "flat"; break; 639cdf0e10cSrcweir } 640cdf0e10cSrcweir if ( pEndCap ) 641cdf0e10cSrcweir pAttrList->add( XML_endcap, pEndCap ); 642cdf0e10cSrcweir } 643cdf0e10cSrcweir 644cdf0e10cSrcweir m_pSerializer->singleElementNS( XML_v, XML_stroke, XFastAttributeListRef( pAttrList ) ); 645cdf0e10cSrcweir } 646cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineColor ] = true; 647cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineWidth ] = true; 648cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineDashing ] = true; 649cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineStartArrowhead ] = true; 650cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineEndArrowhead ] = true; 651cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineStartArrowWidth ] = true; 652cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineStartArrowLength ] = true; 653cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineEndArrowWidth ] = true; 654cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineEndArrowLength ] = true; 655cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineJoinStyle ] = true; 656cdf0e10cSrcweir bAlreadyWritten[ ESCHER_Prop_lineEndCapStyle ] = true; 657cdf0e10cSrcweir break; 658cdf0e10cSrcweir 659cdf0e10cSrcweir case ESCHER_Prop_fHidden: 660cdf0e10cSrcweir m_pShapeStyle->append( ";visibility:hidden" ); 661cdf0e10cSrcweir break; 662cdf0e10cSrcweir default: 663cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 664cdf0e10cSrcweir fprintf( stderr, "TODO VMLExport::Commit(), unimplemented id: %d, value: %d, data: [%d, %p]\n", 665cdf0e10cSrcweir it->nPropId, it->nPropValue, it->nPropSize, it->pBuf ); 666cdf0e10cSrcweir if ( it->nPropSize ) 667cdf0e10cSrcweir { 668cdf0e10cSrcweir const sal_uInt8 *pIt = it->pBuf; 669cdf0e10cSrcweir fprintf( stderr, " ( " ); 670cdf0e10cSrcweir for ( int nCount = it->nPropSize; nCount; --nCount ) 671cdf0e10cSrcweir { 672cdf0e10cSrcweir fprintf( stderr, "%02x ", *pIt ); 673cdf0e10cSrcweir ++pIt; 674cdf0e10cSrcweir } 675cdf0e10cSrcweir fprintf( stderr, ")\n" ); 676cdf0e10cSrcweir } 677cdf0e10cSrcweir #endif 678cdf0e10cSrcweir break; 679cdf0e10cSrcweir } 680cdf0e10cSrcweir } 681cdf0e10cSrcweir 682cdf0e10cSrcweir m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE ); 683cdf0e10cSrcweir } 684cdf0e10cSrcweir 685cdf0e10cSrcweir OString VMLExport::ShapeIdString( sal_uInt32 nId ) 686cdf0e10cSrcweir { 687cdf0e10cSrcweir return OStringBuffer( 20 ).append( "shape_" ).append( sal_Int64( nId ) ).makeStringAndClear(); 688cdf0e10cSrcweir } 689cdf0e10cSrcweir 690cdf0e10cSrcweir void VMLExport::AddLineDimensions( const Rectangle& rRectangle ) 691cdf0e10cSrcweir { 692cdf0e10cSrcweir // style 693cdf0e10cSrcweir if ( m_pShapeStyle->getLength() ) 694cdf0e10cSrcweir m_pShapeStyle->append( ";" ); 695cdf0e10cSrcweir 696cdf0e10cSrcweir m_pShapeStyle->append( "position:absolute" ); 697cdf0e10cSrcweir 698cdf0e10cSrcweir switch ( m_nShapeFlags & 0xC0 ) 699cdf0e10cSrcweir { 700cdf0e10cSrcweir case 0x40: m_pShapeStyle->append( ";flip:y" ); break; 701cdf0e10cSrcweir case 0x80: m_pShapeStyle->append( ";flip:x" ); break; 702cdf0e10cSrcweir case 0xC0: m_pShapeStyle->append( ";flip:xy" ); break; 703cdf0e10cSrcweir } 704cdf0e10cSrcweir 705cdf0e10cSrcweir // the actual dimensions 706cdf0e10cSrcweir OString aLeft, aTop, aRight, aBottom; 707cdf0e10cSrcweir 708cdf0e10cSrcweir if ( mnGroupLevel == 1 ) 709cdf0e10cSrcweir { 710cdf0e10cSrcweir const OString aPt( "pt" ); 711cdf0e10cSrcweir aLeft = OString::valueOf( double( rRectangle.Left() ) / 20 ) + aPt; 712cdf0e10cSrcweir aTop = OString::valueOf( double( rRectangle.Top() ) / 20 ) + aPt; 713cdf0e10cSrcweir aRight = OString::valueOf( double( rRectangle.Right() ) / 20 ) + aPt; 714cdf0e10cSrcweir aBottom = OString::valueOf( double( rRectangle.Bottom() ) / 20 ) + aPt; 715cdf0e10cSrcweir } 716cdf0e10cSrcweir else 717cdf0e10cSrcweir { 718cdf0e10cSrcweir aLeft = OString::valueOf( rRectangle.Left() ); 719cdf0e10cSrcweir aTop = OString::valueOf( rRectangle.Top() ); 720cdf0e10cSrcweir aRight = OString::valueOf( rRectangle.Right() ); 721cdf0e10cSrcweir aBottom = OString::valueOf( rRectangle.Bottom() ); 722cdf0e10cSrcweir } 723cdf0e10cSrcweir 724cdf0e10cSrcweir m_pShapeAttrList->add( XML_from, 725cdf0e10cSrcweir OStringBuffer( 20 ).append( aLeft ) 726cdf0e10cSrcweir .append( "," ).append( aTop ) 727cdf0e10cSrcweir .makeStringAndClear() ); 728cdf0e10cSrcweir 729cdf0e10cSrcweir m_pShapeAttrList->add( XML_to, 730cdf0e10cSrcweir OStringBuffer( 20 ).append( aRight ) 731cdf0e10cSrcweir .append( "," ).append( aBottom ) 732cdf0e10cSrcweir .makeStringAndClear() ); 733cdf0e10cSrcweir } 734cdf0e10cSrcweir 735cdf0e10cSrcweir void VMLExport::AddRectangleDimensions( rtl::OStringBuffer& rBuffer, const Rectangle& rRectangle ) 736cdf0e10cSrcweir { 737cdf0e10cSrcweir if ( rBuffer.getLength() ) 738cdf0e10cSrcweir rBuffer.append( ";" ); 739cdf0e10cSrcweir 740cdf0e10cSrcweir rBuffer.append( "position:absolute;" ); 741cdf0e10cSrcweir 742cdf0e10cSrcweir if ( mnGroupLevel == 1 ) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir rBuffer.append( "margin-left:" ).append( double( rRectangle.Left() ) / 20 ) 745cdf0e10cSrcweir .append( "pt;margin-top:" ).append( double( rRectangle.Top() ) / 20 ) 746cdf0e10cSrcweir .append( "pt;width:" ).append( double( rRectangle.Right() - rRectangle.Left() ) / 20 ) 747cdf0e10cSrcweir .append( "pt;height:" ).append( double( rRectangle.Bottom() - rRectangle.Top() ) / 20 ) 748cdf0e10cSrcweir .append( "pt" ); 749cdf0e10cSrcweir } 750cdf0e10cSrcweir else 751cdf0e10cSrcweir { 752cdf0e10cSrcweir rBuffer.append( "left:" ).append( rRectangle.Left() ) 753cdf0e10cSrcweir .append( ";top:" ).append( rRectangle.Top() ) 754cdf0e10cSrcweir .append( ";width:" ).append( rRectangle.Right() - rRectangle.Left() ) 755cdf0e10cSrcweir .append( ";height:" ).append( rRectangle.Bottom() - rRectangle.Top() ); 756cdf0e10cSrcweir } 757cdf0e10cSrcweir } 758cdf0e10cSrcweir 759cdf0e10cSrcweir void VMLExport::AddShapeAttribute( sal_Int32 nAttribute, const rtl::OString& rValue ) 760cdf0e10cSrcweir { 761cdf0e10cSrcweir m_pShapeAttrList->add( nAttribute, rValue ); 762cdf0e10cSrcweir } 763cdf0e10cSrcweir 764cdf0e10cSrcweir extern const char* pShapeTypes[]; 765cdf0e10cSrcweir 766cdf0e10cSrcweir sal_Int32 VMLExport::StartShape() 767cdf0e10cSrcweir { 768cdf0e10cSrcweir if ( m_nShapeType == ESCHER_ShpInst_Nil ) 769cdf0e10cSrcweir return -1; 770cdf0e10cSrcweir 771cdf0e10cSrcweir // some of the shapes have their own name ;-) 772cdf0e10cSrcweir sal_Int32 nShapeElement = -1; 773cdf0e10cSrcweir bool bReferToShapeType = false; 774cdf0e10cSrcweir switch ( m_nShapeType ) 775cdf0e10cSrcweir { 776cdf0e10cSrcweir case ESCHER_ShpInst_NotPrimitive: nShapeElement = XML_shape; break; 777cdf0e10cSrcweir case ESCHER_ShpInst_Rectangle: nShapeElement = XML_rect; break; 778cdf0e10cSrcweir case ESCHER_ShpInst_RoundRectangle: nShapeElement = XML_roundrect; break; 779cdf0e10cSrcweir case ESCHER_ShpInst_Ellipse: nShapeElement = XML_oval; break; 780cdf0e10cSrcweir case ESCHER_ShpInst_Arc: nShapeElement = XML_arc; break; 781cdf0e10cSrcweir case ESCHER_ShpInst_Line: nShapeElement = XML_line; break; 782cdf0e10cSrcweir default: 783cdf0e10cSrcweir if ( m_nShapeType < ESCHER_ShpInst_COUNT ) 784cdf0e10cSrcweir { 785cdf0e10cSrcweir nShapeElement = XML_shape; 786cdf0e10cSrcweir 787cdf0e10cSrcweir // a predefined shape? 788cdf0e10cSrcweir const char* pShapeType = pShapeTypes[ m_nShapeType ]; 789cdf0e10cSrcweir if ( pShapeType ) 790cdf0e10cSrcweir { 791cdf0e10cSrcweir bReferToShapeType = true; 792cdf0e10cSrcweir if ( !m_pShapeTypeWritten[ m_nShapeType ] ) 793cdf0e10cSrcweir { 794cdf0e10cSrcweir m_pSerializer->write( pShapeType ); 795cdf0e10cSrcweir m_pShapeTypeWritten[ m_nShapeType ] = true; 796cdf0e10cSrcweir } 797cdf0e10cSrcweir } 798cdf0e10cSrcweir else 799cdf0e10cSrcweir { 800cdf0e10cSrcweir // rectangle is probably the best fallback... 801cdf0e10cSrcweir nShapeElement = XML_rect; 802cdf0e10cSrcweir } 803cdf0e10cSrcweir } 804cdf0e10cSrcweir break; 805cdf0e10cSrcweir } 806cdf0e10cSrcweir 807cdf0e10cSrcweir // add style 808cdf0e10cSrcweir m_pShapeAttrList->add( XML_style, m_pShapeStyle->makeStringAndClear() ); 809cdf0e10cSrcweir 810cdf0e10cSrcweir if ( nShapeElement >= 0 ) 811cdf0e10cSrcweir { 812cdf0e10cSrcweir if ( bReferToShapeType ) 813cdf0e10cSrcweir { 814cdf0e10cSrcweir m_pShapeAttrList->add( XML_type, OStringBuffer( 20 ) 815cdf0e10cSrcweir .append( "shapetype_" ).append( sal_Int32( m_nShapeType ) ) 816cdf0e10cSrcweir .makeStringAndClear() ); 817cdf0e10cSrcweir } 818cdf0e10cSrcweir 819cdf0e10cSrcweir // start of the shape 820cdf0e10cSrcweir m_pSerializer->startElementNS( XML_v, nShapeElement, XFastAttributeListRef( m_pShapeAttrList ) ); 821cdf0e10cSrcweir } 822cdf0e10cSrcweir 823cdf0e10cSrcweir return nShapeElement; 824cdf0e10cSrcweir } 825cdf0e10cSrcweir 826cdf0e10cSrcweir void VMLExport::EndShape( sal_Int32 nShapeElement ) 827cdf0e10cSrcweir { 828cdf0e10cSrcweir if ( nShapeElement >= 0 ) 829cdf0e10cSrcweir { 830cdf0e10cSrcweir // end of the shape 831cdf0e10cSrcweir m_pSerializer->endElementNS( XML_v, nShapeElement ); 832cdf0e10cSrcweir } 833cdf0e10cSrcweir } 834