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