/************************************************************************* * * $RCSfile: wrtw8esh.cxx,v $ * * $Revision: 1.3 $ * * last change: $Author: cmc $ $Date: 2000-10-10 16:54:06 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://www.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifdef PCH #include "filt_pch.hxx" #endif #pragma hdrstop #ifndef _HINTIDS_HXX #include #endif #ifndef _COM_SUN_STAR_DRAWING_XSHAPE_HPP_ #include #endif #ifndef _SVSTOR_HXX #include #endif #ifndef _IPOBJ_HXX #include #endif #ifndef _FILTER_HXX #include #endif #ifndef _SFXITEMITER_HXX #include #endif #ifndef _SVDOBJ_HXX #include #endif #ifndef _SVDOTEXT_HXX #include #endif #ifndef _SVDMODEL_HXX #include #endif #ifndef _SVDPAGE_HXX #include #endif #ifndef _SVDTRANS_HXX #include #endif #ifndef _OUTLOBJ_HXX #include #endif #ifndef _EDITOBJ_HXX #include #endif #ifndef _ESCHEREX_HXX #include #endif #ifndef _SVX_UNOSHAPE_HXX #include #endif #ifndef _SVX_BRSHITEM_HXX #include #endif #ifndef _SVX_BOXITEM_HXX #include #endif #ifndef _SVX_LRSPITEM_HXX #include #endif #ifndef _SVX_ULSPITEM_HXX #include #endif #ifndef _SVX_FONTITEM_HXX #include #endif #ifndef _EEITEM_HXX #include #endif #ifndef _MyEDITENG_HXX #include #endif #ifndef _SVX_FMGLOB_HXX #include #endif #ifndef _SVDOUNO_HXX #include #endif #ifndef _SVX_UNOAPI_HXX_ #include #endif #ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ #include #endif #ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_ #include #endif #ifndef _WRTWW8_HXX #include #endif #ifndef _FLYPOS_HXX #include #endif #ifndef _FMTCNCT_HXX #include #endif #ifndef _FMTANCHR_HXX #include #endif #ifndef _FMTSRND_HXX #include #endif #ifndef _FMTORNT_HXX #include #endif #ifndef _FMTFSIZE_HXX #include #endif #ifndef _DCONTACT_HXX #include #endif #ifndef _CALBCK_HXX #include #endif #ifndef _FRMFMT_HXX #include #endif #ifndef _FMTCNTNT_HXX #include #endif #ifndef _NDINDEX_HXX #include #endif #ifndef _NODE_HXX #include #endif #ifndef _DOC_HXX #include #endif #ifndef _DOCARY_HXX #include #endif #ifndef _PAM_HXX #include #endif #ifndef _SWRECT_HXX #include #endif #ifndef _NDGRF_HXX #include #endif #ifndef _GRFATR_HXX #include #endif #ifndef _NDOLE_HXX #include #endif #ifndef _UNODRAW_HXX #include #endif #ifndef _WW8PAR_HXX #include #endif #ifndef _ERRHDL_HXX #include #endif using namespace ::com::sun::star; SV_DECL_VARARR_SORT( SvULongsSort, ULONG, 1, 1 ) SV_IMPL_VARARR_SORT( SvULongsSort, ULONG ) #define sEscherStream String::CreateFromAscii( \ RTL_CONSTASCII_STRINGPARAM( "tempEsher" )) #define sEscherPictStream String::CreateFromAscii( \ RTL_CONSTASCII_STRINGPARAM( "EsherPicts" )) WW8_WrPlcDrawObj::WW8_WrPlcDrawObj( BYTE nTyp ) : nTTyp( nTyp ), aParentPos( 0, 16 ) { } WW8_WrPlcDrawObj::~WW8_WrPlcDrawObj() { for( USHORT n = aParentPos.Count(); n; ) delete (Point*)aParentPos[ --n ]; } void WW8_WrPlcDrawObj::WritePlc( SwWW8Writer& rWrt ) const { if( 8 != rWrt.pFib->nVersion ) return ; // solange kein DrawObjects in 95 exportiert wird ULONG nFcStart = rWrt.pTableStrm->Tell(); USHORT nLen = aCps.Count(); if( nLen ) { // write CPs WW8Fib& rFib = *rWrt.pFib; ULONG nCpOffs = TXT_TXTBOX == nTTyp ? 0 : (rWrt.pFib->ccpText + rWrt.pFib->ccpFtn); register USHORT i; for( i = 0; i < nLen; i++ ) SwWW8Writer::WriteLong( *rWrt.pTableStrm, aCps[ i ] - nCpOffs ); SwWW8Writer::WriteLong( *rWrt.pTableStrm, rFib.ccpText + rFib.ccpFtn + rFib.ccpHdr + rFib.ccpEdn + rFib.ccpTxbx + rFib.ccpHdrTxbx + 1 ); for( i = 0; i < nLen; ++i ) { // write the fspa-struct const SwFrmFmt& rFmt = *(SwFrmFmt*)aCntnt[ i ]; const SdrObject* pObj = rFmt.FindRealSdrObject(); Rectangle aRect; if( RES_FLYFRMFMT == rFmt.Which() ) { Point aObjPos; SwRect aLayRect( rFmt.FindLayoutRect( FALSE, &aObjPos )); if( aLayRect.IsEmpty() ) { // the Object is not visible - so get the values from // the format. The Position may not be correct. const SwFmtVertOrient& rVOr = rFmt.GetVertOrient(); if( VERT_NONE == rVOr.GetVertOrient() ) aObjPos.Y() = rVOr.GetPos(); const SwFmtHoriOrient& rHOr = rFmt.GetHoriOrient(); if( HORI_NONE == rHOr.GetHoriOrient() ) aObjPos.X() = rHOr.GetPos(); aRect.SetSize( rFmt.GetFrmSize().GetSize() ); aRect.SetPos( aObjPos ); } else aRect = aLayRect.SVRect(); } else { ASSERT( pObj, "wo ist das SDR-Object?" ); if( pObj ) aRect = pObj->GetSnapRect(); } aRect -= *(Point*)aParentPos[ i ]; // spid SwWW8Writer::WriteLong( *rWrt.pTableStrm, aShapeIds[ i ] ); //xaLeft/yaTop/xaRight/yaBottom - rel. to anchor SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRect.Left() ); SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRect.Top() ); SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRect.Right() ); SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRect.Bottom() ); //fHdr/bx/by/wr/wrk/fRcaSimple/fBelowText/fAnchorLock USHORT nFlags; if( FLY_PAGE == rFmt.GetAnchor().GetAnchorId() ) nFlags = 0x0A; // x-rel to top Page, y-rel to top Page else nFlags = 0x14; // x-rel to text, y-rel to text const SwFmtSurround& rSurr = rFmt.GetSurround(); USHORT nContour = rSurr.IsContour() ? 0x80 : 0x40; switch( rSurr.GetSurround() ) { case SURROUND_NONE: nFlags |= 0x020; break; case SURROUND_THROUGHT: nFlags |= 0x060; break; case SURROUND_PARALLEL: nFlags |= 0x000 | nContour; break; case SURROUND_IDEAL: nFlags |= 0x600 | nContour; break; case SURROUND_LEFT: nFlags |= 0x200 | nContour; break; case SURROUND_RIGHT: nFlags |= 0x400 | nContour; break; } if( pObj && pObj->GetLayer() == rWrt.pDoc->GetHellId() ) nFlags |= 0x4000; SwWW8Writer::WriteShort( *rWrt.pTableStrm, nFlags ); // cTxbx SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 ); } if( TXT_TXTBOX == nTTyp ) { rFib.fcPlcfspaMom = nFcStart; rFib.lcbPlcfspaMom = rWrt.pTableStrm->Tell() - nFcStart; } else { rFib.fcPlcfspaHdr = nFcStart; rFib.lcbPlcfspaHdr = rWrt.pTableStrm->Tell() - nFcStart; } } } BOOL WW8_WrPlcDrawObj::Append( SwWW8Writer& rWrt, WW8_CP nCp, const SwFrmFmt& rFmt, const Point& rNdTopLeft ) { BOOL bRet = FALSE; if( TXT_HDFT == rWrt.nTxtTyp || TXT_MAINTEXT == rWrt.nTxtTyp ) { const SdrObject* pObj = rFmt.FindSdrObject(), *pInsObj = 0; if( RES_FLYFRMFMT == rFmt.Which() ) { // check for textflyframe and if it is the first in a Chain const SwNodeIndex* pNdIdx = rFmt.GetCntnt().GetCntntIdx(); if( pNdIdx ) bRet = TRUE; } else bRet = TRUE; } if( bRet ) { aCps.Insert( nCp, aCps.Count() ); void* p = (void*)&rFmt; aCntnt.Insert( p, aCntnt.Count() ); void* pPos = new Point( rNdTopLeft ); aParentPos.Insert( pPos, aParentPos.Count() ); aShapeIds.Insert( ULONG(0), aShapeIds.Count() ); } return bRet; } void WW8_WrPlcDrawObj::SetShapeId( const SwFrmFmt& rFmt, UINT32 nId ) { const VoidPtr p = (void*)&rFmt; USHORT nPos = aCntnt.GetPos( p ); if( USHRT_MAX != nPos ) aShapeIds[ nPos ] = nId; } /* */ void WW8_WrPlcTxtBoxes::WriteTxt( SwWW8Writer& rWrt ) { rWrt.bInWriteEscher = TRUE; long& rccp = TXT_TXTBOX == nTyp ? rWrt.pFib->ccpTxbx : rWrt.pFib->ccpHdrTxbx; WW8_WrPlcSubDoc::WriteTxt( rWrt, nTyp, rccp ); WW8_CP nCP = rWrt.Fc2Cp( rWrt.Strm().Tell() ); WW8Fib& rFib = *rWrt.pFib; long nOffset = rFib.ccpText + rFib.ccpFtn + rFib.ccpHdr + rFib.ccpAtn + rFib.ccpEdn; if( TXT_TXTBOX == nTyp ) rWrt.pFldTxtBxs->Finish( nCP, nOffset ); else rWrt.pFldHFTxtBxs->Finish( nCP, nOffset + rFib.ccpTxbx ); rWrt.bInWriteEscher = FALSE; } void WW8_WrPlcTxtBoxes::Append( const SdrObject& rObj, UINT32 nShapeId ) { void* p = (void*)&rObj; aCntnt.Insert( p, aCntnt.Count() ); aShapeIds.Insert( nShapeId, aShapeIds.Count() ); } const SvULongs* WW8_WrPlcTxtBoxes::GetShapeIdArr() const { return &aShapeIds; } /* */ UINT32 SwWW8Writer::GetSdrOrdNum( const SwFrmFmt& rFmt ) const { UINT32 nOrdNum; const SdrObject* pObj = rFmt.FindRealSdrObject(); if( pObj ) nOrdNum = pObj->GetOrdNum(); else { // no Layout for this format, then recalc the ordnum SwFrmFmt* pFmt = (SwFrmFmt*)&rFmt; nOrdNum = pDoc->GetSpzFrmFmts()->GetPos( pFmt ); const SdrModel* pModel = pDoc->GetDrawModel(); if( pModel ) nOrdNum += pModel->GetPage( 0 )->GetObjCount(); } return nOrdNum; } void SwWW8Writer::AppendFlyInFlys( WW8_CP& rCP, const SwFrmFmt& rFrmFmt, const Point& rNdTopLeft ) { ASSERT( !pEscher, "der EscherStream wurde schon geschrieben!" ); if( pEscher ) return ; WW8_WrPlcDrawObj *pDrwO = TXT_HDFT == nTxtTyp ? pHFSdrObjs : pSdrObjs; if( pDrwO->Append( *this, rCP, rFrmFmt, rNdTopLeft )) { static BYTE __READONLY_DATA aSpec8[] = { 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation (wahrscheinlich unnoetig) 0x55, 0x08, 1 // sprmCFSpec }; // fSpec-Attribut TRUE // Fuer DrawObjets muss ein Spezial-Zeichen // in den Text und darum ein fSpec-Attribut pChpPlc->AppendFkpEntry( Strm().Tell() ); WriteChar( 0x8 ); rCP += 1; // to next charakter position pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aSpec8 ), aSpec8 ); if( RES_FLYFRMFMT == rFrmFmt.Which() ) { // search all Flys/DrawObj in Flys and put it behind this // text position. const SwNodeIndex* pNdIdx = rFrmFmt.GetCntnt().GetCntntIdx(); ASSERT( pNdIdx, "wo ist der NodeIndex geblieben?" ); ULONG nStart = pNdIdx->GetIndex(), nEnd = pNdIdx->GetNode().EndOfSectionIndex(), nIdx; USHORT nArrLen = pDoc->GetSpzFrmFmts()->Count(); for( USHORT n = 0; n < nArrLen; ++n ) { const SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n]; const SwFmtAnchor* pAnchor = &pFmt->GetAnchor(); const SwPosition* pAPos; if( ( pAnchor->GetAnchorId() == FLY_AT_CNTNT || pAnchor->GetAnchorId() == FLY_AT_FLY || pAnchor->GetAnchorId() == FLY_AUTO_CNTNT ) && 0 != ( pAPos = pAnchor->GetCntntAnchor()) && nStart <= ( nIdx = pAPos->nNode.GetIndex()) && nIdx < nEnd ) { AppendFlyInFlys( rCP, *pFmt, rNdTopLeft ); } } } } } USHORT SwWW8Writer::TranslateToEditEngineId( USHORT nWhich ) { switch( nWhich ) { case RES_LR_SPACE: nWhich = EE_PARA_LRSPACE; break; case RES_UL_SPACE: nWhich = EE_PARA_ULSPACE; break; case RES_PARATR_LINESPACING: nWhich = EE_PARA_SBL; break; case RES_PARATR_ADJUST: nWhich = EE_PARA_JUST; break; case RES_PARATR_TABSTOP: nWhich = EE_PARA_TABS; break; case RES_CHRATR_COLOR: nWhich = EE_CHAR_COLOR; break; case RES_CHRATR_FONT: nWhich = EE_CHAR_FONTINFO; break; case RES_CHRATR_FONTSIZE: nWhich = EE_CHAR_FONTHEIGHT; break; case RES_CHRATR_WEIGHT: nWhich = EE_CHAR_WEIGHT; break; case RES_CHRATR_UNDERLINE: nWhich = EE_CHAR_UNDERLINE; break; case RES_CHRATR_CROSSEDOUT: nWhich = EE_CHAR_STRIKEOUT; break; case RES_CHRATR_POSTURE: nWhich = EE_CHAR_ITALIC; break; case RES_CHRATR_CONTOUR: nWhich = EE_CHAR_OUTLINE; break; case RES_CHRATR_SHADOWED: nWhich = EE_CHAR_SHADOW; break; case RES_CHRATR_ESCAPEMENT: nWhich = EE_CHAR_ESCAPEMENT; break; case RES_CHRATR_AUTOKERN: nWhich = EE_CHAR_PAIRKERNING; break; case RES_CHRATR_KERNING: nWhich = EE_CHAR_KERNING; break; case RES_CHRATR_WORDLINEMODE: nWhich = EE_CHAR_WLM; break; case RES_CHRATR_CHARSETCOLOR: nWhich = EE_FEATURE_NOTCONV; break; default: // case EE_PARA_NUMBULLET: // case EE_PARA_HYPHENATE: // case EE_PARA_BULLETSTATE: // case EE_PARA_OUTLLRSPACE: // case EE_PARA_OUTLLEVEL: // case EE_PARA_BULLET: //ITEMID_FONTWIDTH EE_CHAR_FONTWIDTH nWhich = 0; break; } return nWhich; } USHORT SwWW8Writer::TranslateFromEditEngineId( USHORT nWhich ) { switch( nWhich ) { case EE_PARA_LRSPACE: nWhich = RES_LR_SPACE; break; case EE_PARA_ULSPACE: nWhich = RES_UL_SPACE; break; case EE_PARA_SBL: nWhich = RES_PARATR_LINESPACING; break; case EE_PARA_JUST: nWhich = RES_PARATR_ADJUST; break; case EE_PARA_TABS: nWhich = RES_PARATR_TABSTOP; break; case EE_CHAR_COLOR: nWhich = RES_CHRATR_COLOR; break; case EE_CHAR_FONTINFO: nWhich = RES_CHRATR_FONT; break; case EE_CHAR_FONTHEIGHT: nWhich = RES_CHRATR_FONTSIZE; break; case EE_CHAR_WEIGHT: nWhich = RES_CHRATR_WEIGHT; break; case EE_CHAR_UNDERLINE: nWhich = RES_CHRATR_UNDERLINE; break; case EE_CHAR_STRIKEOUT: nWhich = RES_CHRATR_CROSSEDOUT; break; case EE_CHAR_ITALIC: nWhich = RES_CHRATR_POSTURE; break; case EE_CHAR_OUTLINE: nWhich = RES_CHRATR_CONTOUR; break; case EE_CHAR_SHADOW: nWhich = RES_CHRATR_SHADOWED; break; case EE_CHAR_ESCAPEMENT: nWhich = RES_CHRATR_ESCAPEMENT; break; case EE_CHAR_PAIRKERNING: nWhich = RES_CHRATR_AUTOKERN; break; case EE_CHAR_KERNING: nWhich = RES_CHRATR_KERNING; break; case EE_CHAR_WLM: nWhich = RES_CHRATR_WORDLINEMODE; break; case EE_FEATURE_NOTCONV: nWhich = RES_CHRATR_CHARSETCOLOR; break; default: // case EE_PARA_NUMBULLET: // case EE_PARA_HYPHENATE: // case EE_PARA_BULLETSTATE: // case EE_PARA_OUTLLRSPACE: // case EE_PARA_OUTLLEVEL: // case EE_PARA_BULLET: //ITEMID_FONTWIDTH EE_CHAR_FONTWIDTH nWhich = 0; break; } return nWhich; } class WW8_SdrAttrIter : public WW8_AttrIter { const EditTextObject* pEditObj; EECharAttribArray aTxtAtrArr; SvPtrarr aChrTxtAtrArr; SvUShorts aChrSetArr; USHORT nPara; xub_StrLen nAktSwPos; xub_StrLen nTmpSwPos; // fuer HasItem() rtl_TextEncoding eNdChrSet; xub_StrLen SearchNext( xub_StrLen nStartPos ); void SetCharSet( const EECharAttrib& rTxtAttr, BOOL bStart ); public: WW8_SdrAttrIter( SwWW8Writer& rWr, const EditTextObject& rEditObj ); void NextPara( USHORT nPar ); void OutParaAttr( BOOL bCharAttr ); BOOL IsTxtAttr( xub_StrLen nSwPos ); void NextPos() { nAktSwPos = SearchNext( nAktSwPos + 1 ); } void OutAttr( xub_StrLen nSwPos ); virtual const SfxPoolItem* HasTextItem( USHORT nWhich ) const; virtual const SfxPoolItem& GetItem( USHORT nWhich ) const; BOOL OutAttrWithRange( xub_StrLen nPos ); xub_StrLen WhereNext() const { return nAktSwPos; } rtl_TextEncoding GetNextCharSet() const; rtl_TextEncoding GetNodeCharSet() const { return eNdChrSet; } }; WW8_SdrAttrIter::WW8_SdrAttrIter( SwWW8Writer& rWr, const EditTextObject& rEditObj ) : WW8_AttrIter( rWr ), pEditObj( &rEditObj ), aTxtAtrArr( 0, 4 ), aChrTxtAtrArr( 0, 4 ), aChrSetArr( 0, 4 ) { NextPara( 0 ); } void WW8_SdrAttrIter::NextPara( USHORT nPar ) { nPara = nPar; // Attributwechsel an Pos 0 wird ignoriert, da davon ausgegangen // wird, dass am Absatzanfang sowieso die Attribute neu ausgegeben // werden. aChrTxtAtrArr.Remove( 0, aChrTxtAtrArr.Count() ); aChrSetArr.Remove( 0, aChrSetArr.Count() ); nAktSwPos = nTmpSwPos = 0; SfxItemSet aSet( pEditObj->GetParaAttribs( nPara )); eNdChrSet = ((SvxFontItem&)aSet.Get( EE_CHAR_FONTINFO )).GetCharSet(); pEditObj->GetCharAttribs( nPara, aTxtAtrArr ); nAktSwPos = SearchNext( 1 ); } rtl_TextEncoding WW8_SdrAttrIter::GetNextCharSet() const { if( aChrSetArr.Count() ) return (rtl_TextEncoding)aChrSetArr[ aChrSetArr.Count() - 1 ]; return eNdChrSet; } // der erste Parameter in SearchNext() liefert zurueck, ob es ein TxtAtr ist. xub_StrLen WW8_SdrAttrIter::SearchNext( xub_StrLen nStartPos ) { register xub_StrLen nPos; register xub_StrLen nMinPos = STRING_MAXLEN; register xub_StrLen i; for( i = 0; i < aTxtAtrArr.Count(); i++ ) { const EECharAttrib& rHt = aTxtAtrArr[ i ]; nPos = rHt.nStart; // gibt erstes Attr-Zeichen if( nPos >= nStartPos && nPos <= nMinPos ) { nMinPos = nPos; SetCharSet( rHt, TRUE ); } //?? if( pHt->GetEnd() ) // Attr mit Ende { nPos = rHt.nEnd; // gibt letztes Attr-Zeichen + 1 if( nPos >= nStartPos && nPos < nMinPos ) { nMinPos = nPos; SetCharSet( rHt, FALSE ); } } /* else { // Attr ohne Ende nPos = rHt.nStart + 1; // Laenge 1 wegen CH_TXTATR im Text if( nPos >= nStartPos && nPos < nMinPos ) { nMinPos = nPos; SetCharSet( rHt, FALSE ); } } */ } return nMinPos; } void WW8_SdrAttrIter::SetCharSet( const EECharAttrib& rAttr, BOOL bStart ) { void* p = 0; rtl_TextEncoding eChrSet; const SfxPoolItem& rItem = *rAttr.pAttr; switch( rItem.Which() ) { case EE_CHAR_FONTINFO: p = (void*)&rAttr; eChrSet = ((SvxFontItem&)rItem).GetCharSet(); break; } if( p ) { USHORT nPos; if( bStart ) { nPos = aChrSetArr.Count(); aChrSetArr.Insert( eChrSet, nPos ); aChrTxtAtrArr.Insert( p, nPos ); } else if( USHRT_MAX != ( nPos = aChrTxtAtrArr.GetPos( p )) ) { aChrTxtAtrArr.Remove( nPos ); aChrSetArr.Remove( nPos ); } } } void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos ) { OutParaAttr( TRUE ); if( aTxtAtrArr.Count() ) { const SwModify* pOldMod = rWrt.pOutFmtNode; rWrt.pOutFmtNode = 0; nTmpSwPos = nSwPos; register USHORT i, nWhich; FnAttrOut pOut; for( i = 0; i < aTxtAtrArr.Count(); i++ ) { const EECharAttrib& rHt = aTxtAtrArr[ i ]; if( nSwPos >= rHt.nStart && nSwPos < rHt.nEnd && 0 != ( nWhich = rWrt.TranslateFromEditEngineId( rHt.pAttr->Which() )) && 0 != ( pOut = aWW8AttrFnTab[ nWhich - RES_CHRATR_BEGIN ] ) ) (*pOut)( rWrt, *rHt.pAttr ); else if( nSwPos < rHt.nStart ) break; } nTmpSwPos = 0; // HasTextItem nur in dem obigen Bereich erlaubt rWrt.pOutFmtNode = pOldMod; } } BOOL WW8_SdrAttrIter::IsTxtAttr( xub_StrLen nSwPos ) { // solange die EditEngine keine Attribute hat, die nur eine Position haben return FALSE; // search for attrs without end position register USHORT i; for( i = 0; i < aTxtAtrArr.Count(); i++ ) if( aTxtAtrArr[ i ].nStart == nSwPos ) return TRUE; return FALSE; } // HasItem ist fuer die Zusammenfassung des Doppel-Attributes Underline // und WordLineMode als TextItems. OutAttr() ruft die Ausgabefunktion, // die dann ueber HasItem() nach anderen Items an der // Attribut-Anfangposition fragen kann. // Es koennen nur Attribute mit Ende abgefragt werden. // Es wird mit bDeep gesucht const SfxPoolItem* WW8_SdrAttrIter::HasTextItem( USHORT nWhich ) const { const SfxPoolItem* pRet = 0; if( 0 != ( nWhich = rWrt.TranslateToEditEngineId( nWhich )) ) { register USHORT i; for( i = 0; i < aTxtAtrArr.Count(); ++i ) { const EECharAttrib& rHt = aTxtAtrArr[ i ]; if( nWhich == rHt.pAttr->Which() && nTmpSwPos >= rHt.nStart && nTmpSwPos < rHt.nEnd ) { pRet = rHt.pAttr; // gefunden break; } else if( nTmpSwPos < rHt.nStart ) break; // dann kommt da nichts mehr } } return pRet; } const SfxPoolItem& WW8_SdrAttrIter::GetItem( USHORT nWhich ) const { const SfxPoolItem* pRet = HasTextItem( nWhich ); if( !pRet ) { SfxItemSet aSet( pEditObj->GetParaAttribs( nPara )); pRet = &aSet.Get( rWrt.TranslateToEditEngineId( nWhich ) ); } return *pRet; } void WW8_SdrAttrIter::OutParaAttr( BOOL bCharAttr ) { SfxItemSet aSet( pEditObj->GetParaAttribs( nPara )); if( aSet.Count() ) { const SfxItemSet* pOldSet = rWrt.GetCurItemSet(); rWrt.SetCurItemSet( &aSet ); SfxItemIter aIter( aSet ); const SfxPoolItem* pItem = aIter.GetCurItem(); FnAttrOut pOut; do { USHORT nWhich = rWrt.TranslateFromEditEngineId( pItem->Which() ); if( nWhich && 0 != ( pOut = aWW8AttrFnTab[ nWhich - RES_CHRATR_BEGIN ] ) && ( bCharAttr ? ( nWhich >= RES_CHRATR_BEGIN && nWhich < RES_TXTATR_END) : (nWhich >= RES_PARATR_BEGIN && nWhich < RES_FRMATR_END) ) ) (*pOut)( rWrt, *pItem ); } while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) ); rWrt.SetCurItemSet( pOldSet ); } } void SwWW8Writer::WriteSdrTextObj( const SdrObject& rObj ) { const SdrTextObj* pTxtObj = PTR_CAST( SdrTextObj, &rObj ); ASSERT( pTxtObj, "das ist gar kein SdrTextObj!" ); BOOL bAnyWrite = FALSE; const OutlinerParaObject* pParaObj = pTxtObj->GetOutlinerParaObject(); if( pParaObj ) { const EditTextObject& rEditObj = pParaObj->GetTextObject(); WW8_SdrAttrIter aAttrIter( *this, rEditObj ); USHORT nPara = rEditObj.GetParagraphCount(); BYTE bNul = 0; for( USHORT n = 0; n < nPara; ++n ) { if( n ) aAttrIter.NextPara( n ); rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet(); ASSERT( !pO->Count(), " pO ist am Zeilenanfang nicht leer" ); String aStr( rEditObj.GetText( n )); xub_StrLen nAktPos = 0; xub_StrLen nEnd = aStr.Len(); BOOL bUnicode = TRUE; do { /* switch( eChrSet ) { // case CHARSET_DONTKNOW: ???? case CHARSET_SYMBOL: // case CHARSET_WIN_SYMBOL: // case CHARSET_WIN_WINGDINGS: // case CHARSET_MAC_DINGBATS: // case CHARSET_MAC_SYMBOL: // case CHARSET_ADOBE_SYMBOL: // case CHARSET_ADOBE_DINGBATS: // case CHARSET_STAR_STARBATS: // case CHARSET_STAR_STARMATH: bUnicode = bWrtWW8 ? TRUE : FALSE; break; default: bUnicode = FALSE; break; } */ xub_StrLen nNextAttr = aAttrIter.WhereNext(); rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet(); if( nNextAttr > nEnd ) nNextAttr = nEnd; BOOL bTxtAtr = aAttrIter.IsTxtAttr( nAktPos ); if( !bTxtAtr ) OutSwString( aStr, nAktPos, nNextAttr - nAktPos, bUnicode, eChrSet ); // Am Zeilenende werden die Attribute bis ueber das CR // aufgezogen. Ausnahme: Fussnoten am Zeilenende if( nNextAttr == nEnd && !bTxtAtr ) WriteCR(); // CR danach // Ausgabe der Zeichenattribute aAttrIter.OutAttr( nAktPos ); // nAktPos - 1 ?? pChpPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), pO->GetData() ); pO->Remove( 0, pO->Count() ); // leeren // Ausnahme: Fussnoten am Zeilenende if( nNextAttr == nEnd && bTxtAtr ) WriteCR(); // CR danach nAktPos = nNextAttr; eChrSet = eNextChrSet; aAttrIter.NextPos(); } while( nAktPos < nEnd ); ASSERT( !pO->Count(), " pO ist am ZeilenEnde nicht leer" ); pO->Insert( bNul, pO->Count() ); // Style # as short pO->Insert( bNul, pO->Count() ); aAttrIter.OutParaAttr( FALSE ); ULONG nPos = Strm().Tell(); pPapPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), pO->GetData() ); pO->Remove( 0, pO->Count() ); // leeren pChpPlc->AppendFkpEntry( nPos ); } bAnyWrite = 0 != nPara; } if( !bAnyWrite ) WriteStringAsPara( aEmptyStr ); } /* */ class SwEscherEx : public EscherEx { // private members SvULongs aFollowShpIds; SvPtrarr aSortFmts; SwWW8Writer& rWrt; WW8_WrPlcTxtBoxes *pTxtBxs; SvStream* pEscherStrm, *pPictStrm; long nEmuMul, nEmuDiv; // private methods void Init(); UINT32 GetFlyShapeId( const SwFrmFmt& rFmt ); void MakeZOrderArrAndFollowIds( const SvPtrarr& rSrcArr ); INT32 ToFract16( INT32 nVal, UINT32 nMax ) const { if( nMax ) { INT32 nMSVal = ( nVal / 65536) * nMax; nMSVal += ( nVal * 65536 ) / nMax; return nMSVal; } return 0; } INT32 DrawModelToEmu( INT32 nVal ) const { return BigMulDiv( nVal, nEmuMul, nEmuDiv ); } void WriteTxtFlyFrame( const SwFrmFmt& rFmt, UINT32 nShapeId, UINT32 nTxtBox ); void WriteGrfFlyFrame( const SwFrmFmt& rFmt, UINT32 nShapeId ); void WriteOLEFlyFrame( const SwFrmFmt& rFmt, UINT32 nShapeId ); void WriteOCXControl( const SwFrmFmt& rFmt, UINT32 nShapeId ); void WriteFlyFrameAttr( const SwFrmFmt& rFmt ); void WriteGrfAttr( const SwNoTxtNode& rNd ); UINT32 WriteFlyFrm( const SwFrmFmt& rFmt ); virtual SvStream* QueryPicStream(); virtual UINT32 QueryTextID( const uno::Reference< drawing::XShape>& , UINT32 ); SwEscherEx( const SwEscherEx& ); public: SwEscherEx( SvStream* pStrm, SwWW8Writer& rWW8Wrt ); virtual ~SwEscherEx(); void FinishEscher(); void WritePictures(); }; /* */ void SwWW8Writer::CreateEscher() { if(pHFSdrObjs->GetCntntArr().Count() || pSdrObjs->GetCntntArr().Count()) { ASSERT( !pEscher, "wer hat den Pointer nicht geloescht?" ); SvStream* pEscherStrm = pStg->OpenStream( sEscherStream, STREAM_READWRITE | STREAM_SHARE_DENYALL ); pEscherStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); pEscher = new SwEscherEx( pEscherStrm, *this ); } } void SwWW8Writer::WriteEscher() { if( pEscher ) { ULONG nStart = pTableStrm->Tell(); pEscher->WritePictures(); pEscher->FinishEscher(); pFib->fcDggInfo = nStart; pFib->lcbDggInfo = pTableStrm->Tell() - nStart; delete pEscher, pEscher = 0; } } /* */ // Output- Routines for Escher Export SwEscherEx::SwEscherEx( SvStream* pStrm, SwWW8Writer& rWW8Wrt ) /* : SvxEscherEx( *pStrm, rWW8Wrt.pHFSdrObjs->GetCntntArr().Count() ? 2 : 1, *rWW8Wrt.pDoc->GetDrawModel(), 1440 ), */ : EscherEx( *pStrm, rWW8Wrt.pHFSdrObjs->GetCntntArr().Count() ? 2 : 1 ), rWrt( rWW8Wrt ), pTxtBxs( 0 ), pEscherStrm( pStrm ), pPictStrm( 0 ) { Init(); OpenContainer( ESCHER_DggContainer ); BeginCount(); AddColor( 0x08000004 ); AddColor( 0x08000001 ); AddColor( 0x08000002 ); AddColor( 0x100000f7 ); EndCount( ESCHER_SplitMenuColors ); CloseContainer(); // ESCHER_DggContainer BYTE i = 2; // for header/footer and the other WW8_WrPlcDrawObj *pSdrObjs = rWrt.pHFSdrObjs; pTxtBxs = rWrt.pHFTxtBxs; if( !pSdrObjs->GetCntntArr().Count() ) // if no header/footer -> skip over { --i; pSdrObjs = rWrt.pSdrObjs; pTxtBxs = rWrt.pTxtBxs; } for( ; i--; pSdrObjs = rWrt.pSdrObjs, pTxtBxs = rWrt.pTxtBxs ) { // "dummy char" (or any Count ?) - why? This knows only M$ GetStream() << (sal_Char)i; OpenContainer( ESCHER_DgContainer ); EnterGroup( 0 ); ULONG nSecondShapeId = pSdrObjs == rWrt.pSdrObjs ? GetShapeID() : 0; // write now all Writer-/DrawObjects MakeZOrderArrAndFollowIds( pSdrObjs->GetCntntArr() ); ULONG nShapeId; for( USHORT n = 0; n < aSortFmts.Count(); ++n ) { const SwFrmFmt& rFmt = *(SwFrmFmt*)aSortFmts[ n ]; if( RES_FLYFRMFMT == rFmt.Which()) nShapeId = WriteFlyFrm( rFmt ); else if (rFmt.FindRealSdrObject()->GetObjInventor() == FmFormInventor) WriteOCXControl(rFmt,nShapeId=GetShapeID()); else { const SdrObject* pObj = rFmt.FindRealSdrObject(); if( pObj ) { nShapeId = AddSdrObject( *pObj ); } #ifndef PRODUCT else ASSERT( !this, "wo ist das SDR-Object?" ); #endif } if( !nShapeId ) { /*!!!*/ const SdrObject* pObj = 0; nShapeId = AddDummyShape( *pObj ); } pSdrObjs->SetShapeId( rFmt, nShapeId ); } EndSdrObjectPage(); // ???? Bugfix for 74724 LeaveGroup(); if( nSecondShapeId ) { OpenContainer( ESCHER_SpContainer ); AddShape( ESCHER_ShpInst_Rectangle, 0xe00, nSecondShapeId ); BeginCount(); // default Fuellfarbe ist das StarOffice blau7 // ----> von DrawingLayer besorgen !! AddOpt( ESCHER_Prop_fillColor, 0xffb800 ); AddOpt( ESCHER_Prop_fillBackColor, 0 ); AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00100010 ); AddOpt( ESCHER_Prop_lineColor, 0x8000001 ); AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080008 ); AddOpt( ESCHER_Prop_shadowColor, 0x8000002 ); AddOpt( ESCHER_Prop_lineWidth, 0 ); // winword defaults! // AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 ); // AddOpt( ESCHER_Prop_lineWidth, 0 ); // AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 ); // AddOpt( ESCHER_Prop_bWMode, 0x9 ); // AddOpt( ESCHER_Prop_fBackground, 0x10001 ); EndCount( ESCHER_OPT, 3 ); AddAtom( 4, ESCHER_ClientData ); GetStream() << 1L; CloseContainer(); // ESCHER_SpContainer } CloseContainer(); // ESCHER_DgContainer } } SwEscherEx::~SwEscherEx() { } void SwEscherEx::Init() { SdrModel& rModel = *rWrt.pDoc->GetDrawModel(); // PPT arbeitet nur mit Einheiten zu 576DPI // WW hingegen verwendet twips, dh. 1440DPI. MapUnit eMap = rModel.GetScaleUnit(); // Fraction aFact( nAppScale ); // aFact /= GetMapFactor( MAP_INCH, eMap ).X(); // create little values // aFact = Fraction( aFact.GetNumerator(), aFact.GetDenominator() ); // Bei 100TH_MM -> 2540/576=635/144 // Bei Twip -> 1440/576=5/2 // nMapMul = aFact.GetNumerator(); // nMapDiv = aFact.GetDenominator(); // bNeedMap = nMapMul != nMapDiv; // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben // 1mm=36000emu, 1twip=635emu Fraction aFact( 360, 1 ); // aFact = Fraction( 360, 1 ); aFact /= GetMapFactor( MAP_100TH_MM, eMap ).X(); // create little values aFact = Fraction( aFact.GetNumerator(), aFact.GetDenominator() ); nEmuMul = aFact.GetNumerator(); nEmuDiv = aFact.GetDenominator(); // Und noch was fuer typografische Points // aFact = Fraction( 1, 1 ); // aFact /= GetMapFactor(MAP_POINT,eMap).X(); // nPntMul = aFact.GetNumerator(); // nPntDiv = aFact.GetDenominator(); SetHellLayerId( rWrt.pDoc->GetHellId() ); } void SwEscherEx::WritePictures() { if( pPictStrm ) { // set the blip - entries to the correct stream pos INT32 nEndPos = rWrt.Strm().Tell(); SetNewBlipStreamOffset( nEndPos ); pPictStrm->Seek( 0 ); rWrt.Strm() << *pPictStrm; delete pPictStrm, pPictStrm = 0; rWrt.GetStorage().Remove( sEscherPictStream ); } Flush(); } void SwEscherEx::FinishEscher() { pEscherStrm->Seek( 0 ); *rWrt.pTableStrm << *pEscherStrm; delete pEscherStrm, pEscherStrm = 0; rWrt.GetStorage().Remove( sEscherStream ); } UINT32 SwEscherEx::WriteFlyFrm( const SwFrmFmt& rFmt ) { // check for textflyframe and if it is the first in a Chain UINT32 nShapeId = 0; const SwNodeIndex* pNdIdx = rFmt.GetCntnt().GetCntntIdx(); if( pNdIdx ) { SwNodeIndex aIdx( *pNdIdx, 1 ); switch( aIdx.GetNode().GetNodeType() ) { case ND_GRFNODE: WriteGrfFlyFrame( rFmt, nShapeId =GetShapeID() ); break; case ND_OLENODE: WriteOLEFlyFrame( rFmt, nShapeId =GetShapeID() ); break; default: { const SdrObject* pObj = rFmt.FindRealSdrObject(); if( pObj ) { // check for the first in a Chain UINT32 nTxtId; USHORT nOff = 0; const SwFrmFmt* pFmt = &rFmt, *pPrev; while( 0 != ( pPrev = pFmt->GetChain().GetPrev() )) { ++nOff; pFmt = pPrev; } nShapeId = GetFlyShapeId( rFmt ); if( !nOff ) { void* p = (void*)pObj; nTxtId = pTxtBxs->GetPos( p ); if( USHRT_MAX == nTxtId ) { pTxtBxs->Append( *pObj, nShapeId ); nTxtId = pTxtBxs->Count(); } else ++nTxtId; } else { const SdrObject* pPrevObj = pFmt->FindRealSdrObject(); void* p = (void*)pPrevObj; nTxtId = pTxtBxs->GetPos( p ); if( USHRT_MAX == nTxtId ) { UINT32 nPrevShapeId = GetFlyShapeId( *pFmt ); pTxtBxs->Append( *pPrevObj, nPrevShapeId ); nTxtId = pTxtBxs->Count(); } else ++nTxtId; } nTxtId *= 0x10000; nTxtId += nOff; WriteTxtFlyFrame( rFmt, nShapeId, nTxtId ); } } } } return nShapeId; } void SwEscherEx::WriteTxtFlyFrame( const SwFrmFmt& rFmt, UINT32 nShapeId, UINT32 nTxtBox ) { OpenContainer( ESCHER_SpContainer ); AddShape( ESCHER_ShpInst_TextBox, 0xa00, nShapeId ); BeginCount(); AddOpt( ESCHER_Prop_lTxid, nTxtBox ); const VoidPtr pNext = rFmt.GetChain().GetNext(); if( pNext ) { USHORT nPos = aSortFmts.GetPos( pNext ); if( USHRT_MAX != nPos && aFollowShpIds[ nPos ] ) AddOpt( ESCHER_Prop_hspNext, aFollowShpIds[ nPos ] ); } WriteFlyFrameAttr( rFmt ); EndCount( ESCHER_OPT, 3 ); AddAtom( 4, ESCHER_ClientAnchor ); GetStream() << 0L; AddAtom( 4, ESCHER_ClientData ); GetStream() << 1L; AddAtom( 4, ESCHER_ClientTextbox ); GetStream() << nTxtBox; CloseContainer(); // ESCHER_SpContainer } void SwEscherEx::WriteGrfFlyFrame( const SwFrmFmt& rFmt, UINT32 nShapeId ) { OpenContainer( ESCHER_SpContainer ); AddShape( ESCHER_ShpInst_PictureFrame, 0xa00, nShapeId ); BeginCount(); UINT32 nFlags = ESCHER_BlipFlagDefault; SwNodeIndex aIdx( *rFmt.GetCntnt().GetCntntIdx(), 1 ); SwGrfNode& rGrfNd = *aIdx.GetNode().GetGrfNode(); if( rGrfNd.IsLinkedFile() ) { String sURL; rGrfNd.GetFileFilterNms( &sURL, 0 ); WW8Bytes aBuf; SwWW8Writer::InsAsString16( aBuf, sURL ); SwWW8Writer::InsUInt16( aBuf, 0 ); USHORT nArrLen = aBuf.Count(); BYTE* pArr = new BYTE[ nArrLen ]; memcpy( pArr, aBuf.GetData(), nArrLen ); AddOpt( ESCHER_Prop_pibName, TRUE, nArrLen, pArr, nArrLen ); nFlags = ESCHER_BlipFlagLinkToFile | ESCHER_BlipFlagURL | ESCHER_BlipFlagDoNotSave; } else { rGrfNd.SwapIn( TRUE ); AddOpt( ESCHER_Prop_pib, AddGraphic( *QueryPicStream(), rGrfNd.GetGrf() ), TRUE ); } AddOpt( ESCHER_Prop_pibFlags, nFlags ); WriteFlyFrameAttr( rFmt ); WriteGrfAttr( rGrfNd ); EndCount( ESCHER_OPT, 3 ); AddAtom( 4, ESCHER_ClientAnchor ); GetStream() << 0L; AddAtom( 4, ESCHER_ClientData ); GetStream() << 1L; CloseContainer(); // ESCHER_SpContainer } void SwEscherEx::WriteOCXControl( const SwFrmFmt& rFmt, UINT32 nShapeId ) { const SdrObject* pSdrObj = rFmt.FindRealSdrObject(); if( pSdrObj) { OpenContainer( ESCHER_SpContainer ); AddShape( ESCHER_ShpInst_PictureFrame, 0xa10, nShapeId ); BeginCount(); Size aSz( pSdrObj->GetLogicRect().GetSize() ); aSz.Width() = DrawModelToEmu( aSz.Width() ); aSz.Height() = DrawModelToEmu( aSz.Height() ); Rectangle aRect( Point(0,0), aSz ); pTxtBxs->Append( *pSdrObj, nShapeId ); UINT32 nPicId = pTxtBxs->Count(); nPicId *= 0x10000; AddOpt( ESCHER_Prop_pictureId, nPicId ); AddOpt( ESCHER_Prop_pictureActive, 0x10000 ); WriteFlyFrameAttr( rFmt ); EndCount( ESCHER_OPT, 3 ); AddAtom( 4, ESCHER_ClientAnchor ); GetStream() << 0L; AddAtom( 4, ESCHER_ClientData ); GetStream() << 1L; CloseContainer(); // ESCHER_SpContainer } } void SwEscherEx::WriteOLEFlyFrame( const SwFrmFmt& rFmt, UINT32 nShapeId ) { SwNodeIndex aIdx( *rFmt.GetCntnt().GetCntntIdx(), 1 ); SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode(); const SvInPlaceObjectRef xObj( rOLENd.GetOLEObj().GetOleRef() ); SvData aData( FORMAT_GDIMETAFILE ); GDIMetaFile* pMtf; const SdrObject* pSdrObj = rFmt.FindRealSdrObject(); if( pSdrObj && xObj->GetData( &aData ) && aData.GetData( &pMtf, TRANSFER_MOVE ) ) { OpenContainer( ESCHER_SpContainer ); AddShape( ESCHER_ShpInst_PictureFrame, 0xa10, nShapeId ); BeginCount(); { SvMemoryStream aGrfStrm; WriteWindowMetafile( aGrfStrm, *pMtf ); const BYTE* pMem = (BYTE*)aGrfStrm.GetData(); UINT32 nLen = aGrfStrm.GetSize(); Size aSz( rOLENd.GetTwipSize() ); aSz.Width() = DrawModelToEmu( aSz.Width() ); aSz.Height() = DrawModelToEmu( aSz.Height() ); Rectangle aRect( Point(0,0), aSz ); AddOpt( ESCHER_Prop_pib, AddWMF( *QueryPicStream(), pMem + 22, nLen - 22, aRect ), TRUE ); } pTxtBxs->Append( *pSdrObj, nShapeId ); UINT32 nPicId = pTxtBxs->Count(); nPicId *= 0x10000; AddOpt( ESCHER_Prop_pictureId, nPicId ); AddOpt( ESCHER_Prop_pictureActive, 0x10000 ); WriteFlyFrameAttr( rFmt ); WriteGrfAttr( rOLENd ); EndCount( ESCHER_OPT, 3 ); AddAtom( 4, ESCHER_ClientAnchor ); GetStream() << 0L; AddAtom( 4, ESCHER_ClientData ); GetStream() << 1L; CloseContainer(); // ESCHER_SpContainer } } void SwEscherEx::WriteGrfAttr( const SwNoTxtNode& rNd ) { const SfxPoolItem* pItem; if( SFX_ITEM_SET == rNd.GetSwAttrSet().GetItemState( RES_GRFATR_CROPGRF, TRUE, &pItem )) { const Size aSz( rNd.GetTwipSize() ); INT32 nVal; if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetLeft() ) ) AddOpt( ESCHER_Prop_cropFromLeft, ToFract16( nVal, aSz.Width()) ); if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetRight() ) ) AddOpt( ESCHER_Prop_cropFromRight, ToFract16( nVal, aSz.Width())); if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetTop() ) ) AddOpt( ESCHER_Prop_cropFromTop, ToFract16( nVal, aSz.Height())); if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetBottom() ) ) AddOpt( ESCHER_Prop_cropFromBottom, ToFract16( nVal, aSz.Height())); } // mirror ?? } void SwEscherEx::WriteFlyFrameAttr( const SwFrmFmt& rFmt ) { const SfxPoolItem* pItem; BOOL bFirstLine = TRUE; if( SFX_ITEM_SET == rFmt.GetItemState( RES_BOX, TRUE, &pItem ) ) { static UINT16 __READONLY_DATA aExhperProp[ 4 ] = { ESCHER_Prop_dyTextTop, ESCHER_Prop_dyTextBottom, ESCHER_Prop_dxTextLeft, ESCHER_Prop_dxTextRight }; const SvxBorderLine* pLine; for( int n = 0; n < 4; ++n ) if( 0 != ( pLine = ((SvxBoxItem*)pItem)->GetLine( n )) ) { if( bFirstLine ) { UINT32 nLineColor = GetColor( pLine->GetColor(), FALSE ); AddOpt( ESCHER_Prop_lineColor, nLineColor ); AddOpt( ESCHER_Prop_lineBackColor, nLineColor ^ 0xffffff ); UINT32 nLineWidth; ESCHER_LineStyle eStyle; if( pLine->GetInWidth() ) { // double line nLineWidth = pLine->GetInWidth() + pLine->GetOutWidth() + pLine->GetDistance(); if( pLine->GetInWidth() == pLine->GetOutWidth() ) eStyle = ESCHER_LineDouble; else if( pLine->GetInWidth() < pLine->GetOutWidth() ) eStyle = ESCHER_LineThickThin; else eStyle = ESCHER_LineThinThick; } else { // simple line eStyle = ESCHER_LineSimple; nLineWidth = pLine->GetOutWidth(); } AddOpt( ESCHER_Prop_lineStyle, eStyle ); AddOpt( ESCHER_Prop_lineWidth, DrawModelToEmu( nLineWidth )); bFirstLine = FALSE; } AddOpt( aExhperProp[ n ], DrawModelToEmu( ((SvxBoxItem*)pItem)->GetDistance( n ) )); } } if( bFirstLine ) // no valid line found { AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 ); AddOpt( ESCHER_Prop_dyTextTop, 0 ); AddOpt( ESCHER_Prop_dyTextBottom, 0 ); AddOpt( ESCHER_Prop_dxTextLeft, 0 ); AddOpt( ESCHER_Prop_dxTextRight, 0 ); } // write shadow /* WinWord dont know any shadow at textboxes if( SFX_ITEM_SET == rFmt.GetItemState( RES_SHADOW, TRUE, &pItem ) ) { mpEscherEx->AddOpt( ESCHER_Prop_fshadowObscured, 0x20002 ); if( rObj.ImplGetPropertyValue( C2U("ShadowColor") ) ) mpEscherEx->AddOpt( ESCHER_Prop_shadowColor, mpEscherEx->GetColor( *((UINT32*)rObj.GetUsrAny().get()) ) ); if ( rObj.ImplGetPropertyValue( C2U("Shadow") ) ) { if ( rObj.GetUsrAny().getBOOL() ) { if( rObj.ImplGetPropertyValue( C2U("ShadowXDistance") ) ) mpEscherEx->AddOpt( ESCHER_Prop_shadowOffsetX, *((INT32*)rObj.GetUsrAny().get()) * 360 ); if( rObj.ImplGetPropertyValue( C2U("ShadowYDistance") ) ) mpEscherEx->AddOpt( ESCHER_Prop_shadowOffsetY, *((INT32*)rObj.GetUsrAny().get()) * 360 ); if( rObj.ImplGetPropertyValue( C2U("ShadowTransparence") ) ) mpEscherEx->AddOpt( ESCHER_Prop_shadowOpacity, ( ( 100 - (*((UINT16*)rObj.GetUsrAny().get()) ) << 16 ) / 100 ) ); } } } */ if( SFX_ITEM_SET == rFmt.GetItemState( RES_BACKGROUND, TRUE, &pItem ) ) { if( /* ((SvxBrushItem*)pItem)->GetGraphicLink() || */ ((SvxBrushItem*)pItem)->GetGraphic() ) { /* if( ((SvxBrushItem*)pItem)->GetGraphicLink() ) { AddOpt( ESCHER_Prop_fillBlipName, TRUE, // wie jetzt ?? AddOpt( UINT16 nPropertyID, BOOL bBlib, UINT32 nPropValue, BYTE* pProp, UINT32 nPropSize ); } else */ { AddOpt( ESCHER_Prop_fillBlip, AddGraphic( *QueryPicStream(), *((SvxBrushItem*)pItem)->GetGraphic() ), TRUE ); } AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture ); AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 ); AddOpt( ESCHER_Prop_fillBackColor, 0 ); } else if( !((SvxBrushItem*)pItem)->GetColor().GetTransparency() ) { UINT32 nFillColor = GetColor( ((SvxBrushItem*)pItem)-> GetColor(), FALSE ); AddOpt( ESCHER_Prop_fillColor, nFillColor ); AddOpt( ESCHER_Prop_fillBackColor, nFillColor ^ 0xffffff ); AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100010 ); } else { AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 ); } } if( SFX_ITEM_SET == rFmt.GetItemState( RES_LR_SPACE, TRUE, &pItem )) { AddOpt( ESCHER_Prop_dxWrapDistLeft, DrawModelToEmu( ((SvxLRSpaceItem*)pItem)->GetLeft() ) ); AddOpt( ESCHER_Prop_dxWrapDistRight, DrawModelToEmu( ((SvxLRSpaceItem*)pItem)->GetRight() ) ); } if( SFX_ITEM_SET == rFmt.GetItemState( RES_UL_SPACE, TRUE, &pItem )) { AddOpt( ESCHER_Prop_dyWrapDistTop, DrawModelToEmu( ((SvxULSpaceItem*)pItem)->GetUpper() ) ); AddOpt( ESCHER_Prop_dyWrapDistBottom, DrawModelToEmu( ((SvxULSpaceItem*)pItem)->GetLower() ) ); } const SdrObject* pObj = rFmt.FindRealSdrObject(); if( pObj && pObj->GetLayer() == GetHellLayerId() ) AddOpt( ESCHER_Prop_fPrint, 0x200020 ); } void SwEscherEx::MakeZOrderArrAndFollowIds( const SvPtrarr& rSrcArr ) { if( aSortFmts.Count() ) aSortFmts.Remove( 0, aSortFmts.Count() ); USHORT n, nPos, nCnt = rSrcArr.Count(); SvULongsSort aSort( 255 < nCnt ? 255 : nCnt, 255 ); for( n = 0; n < nCnt; ++n ) { void* p = rSrcArr[ n ]; ULONG nOrdNum = rWrt.GetSdrOrdNum( *(SwFrmFmt*)p ); aSort.Insert( nOrdNum, nPos ); aSortFmts.Insert( p, nPos ); } if( aFollowShpIds.Count() ) aFollowShpIds.Remove( 0, aFollowShpIds.Count() ); ULONG nShapeId; const SwFmtChain* pChain; for( n = 0; n < nCnt; ++n ) { const SwFrmFmt* pFmt = (SwFrmFmt*)aSortFmts[ n ]; if( RES_FLYFRMFMT == pFmt->Which() && ( ( pChain = &pFmt->GetChain())->GetPrev() || pChain->GetNext() ) ) { // the format needs a shapeid nShapeId = GetShapeID(); } else nShapeId = 0; aFollowShpIds.Insert( nShapeId, n ); } } UINT32 SwEscherEx::GetFlyShapeId( const SwFrmFmt& rFmt ) { const VoidPtr pFmt = (void*)&rFmt; USHORT nPos = aSortFmts.GetPos( pFmt ); UINT32 nShapeId; if( USHRT_MAX != nPos ) { if( 0 == ( nShapeId = aFollowShpIds[ nPos ] )) { nShapeId = GetShapeID(); aFollowShpIds[ nPos ] = nShapeId; } } else nShapeId = GetShapeID(); return nShapeId; } UINT32 SwEscherEx::QueryTextID( const uno::Reference< drawing::XShape>& xXShapeRef, UINT32 nShapeId ) { UINT32 nId = 0; uno::Reference< lang::XUnoTunnel > xTunnel(xXShapeRef, uno::UNO_QUERY); SvxShape* pSvxShape = xTunnel.is() ? (SvxShape*)xTunnel->getSomething(SvxShape::getUnoTunnelId()) : 0; if( pSvxShape ) { SdrObject* pObj = pSvxShape->GetSdrObject(); if( pObj ) { pTxtBxs->Append( *pObj, nShapeId ); nId = pTxtBxs->Count(); nId *= 0x10000; } } return nId; } SvStream* SwEscherEx::QueryPicStream() { if( !pPictStrm ) { pPictStrm = rWrt.GetStorage().OpenStream( sEscherPictStream, STREAM_READWRITE | STREAM_SHARE_DENYALL ); pPictStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); } return pPictStrm; } BOOL SwMSConvertControls::ExportControl(Writer &rWrt, const SdrObject *pObj) { SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; if (!rWW8Wrt.bWrtWW8) return FALSE; SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObj); uno::Reference< awt::XControlModel > xControlModel = pFormObj->GetUnoControlModel(); //Why oh lord do we use so many different units ? //I think I painted myself into a little bit of a //corner by trying to use the uno interface for //controls export Size aTempSize=pFormObj->GetLogicRect().GetSize(); awt::Size aSize; aSize.Width = TWIPS_TO_MM(aTempSize.A()); aSize.Height = TWIPS_TO_MM(aTempSize.B()); //Open the ObjectPool SvStorageRef xObjPool = rWW8Wrt.GetStorage().OpenStorage( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("ObjectPool")), STREAM_READWRITE|STREAM_SHARE_DENYALL); //Create a destination storage for the microsoft control String sStorageName('_'); sStorageName += String::CreateFromInt32((UINT32)pObj); SvStorageRef xOleStg = xObjPool->OpenStorage(sStorageName, STREAM_READWRITE|STREAM_SHARE_DENYALL); if (!xOleStg.Is()) return FALSE; String sName; if (!WriteOCXStream(xOleStg,xControlModel,aSize,sName)) return FALSE; BYTE aSpecOLE[] = { 0x03, 0x6a, 0xFF, 0xFF, 0xFF, 0xFF, // sprmCPicLocation 0x0a, 0x08, 1, // sprmCFOLE2 0x55, 0x08, 1, // sprmCFSpec 0x56, 0x08, 1 // sprmCFObj }; //Set the obj id into the sprmCPicLocation BYTE *pData = aSpecOLE+2; Set_UInt32(pData,(UINT32)pObj); sName.InsertAscii(" CONTROL Forms.",0); sName.AppendAscii(".1 \\s "); rWW8Wrt.OutField(0,87,sName, WRITEFIELD_START|WRITEFIELD_CMD_START|WRITEFIELD_CMD_END); rWW8Wrt.pChpPlc->AppendFkpEntry(rWW8Wrt.Strm().Tell(),sizeof(aSpecOLE), aSpecOLE); rWW8Wrt.WriteChar( 0x1 ); rWW8Wrt.OutField( 0, 87, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE ); return TRUE; } /************************************************************************* Source Code Control System - Header $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/filter/ww8/wrtw8esh.cxx,v 1.3 2000-10-10 16:54:06 cmc Exp $ Source Code Control System - Update $Log: not supported by cvs2svn $ Revision 1.2 2000/09/21 12:18:55 khz #78753# Avoid dividing by zero. Revision 1.1.1.1 2000/09/18 17:14:58 hr initial import Revision 1.23 2000/09/18 16:04:57 willem.vandorp OpenOffice header added. Revision 1.22 2000/08/25 12:27:31 jp Graphic Crop-Attribut exported to SVX Revision 1.21 2000/07/17 20:28:23 jp WriteGrfFlyFrame: alloc buffer for the linked graphics Revision 1.20 2000/05/16 17:39:17 jp Changes for Unicode Revision 1.19 2000/05/12 16:13:51 jp Changes for Unicode Revision 1.18 2000/04/11 17:35:37 jp Bug #74724#: CTOR SwEscherEx - call the end outproc for the SdrPage Revision 1.17 2000/03/24 13:55:29 jp Bug #74452#: after writing the escher delete the escher object Revision 1.16 2000/03/21 15:04:57 os UNOIII Revision 1.15 2000/03/03 15:20:01 os StarView remainders removed Revision 1.14 2000/02/23 18:40:03 jp Task #73176#: AddWmf will have EMU values Revision 1.13 2000/02/11 14:39:51 hr #70473# changes for unicode ( patched by automated patchtool ) Revision 1.12 1999/11/24 14:55:55 hr #65293#: added header Revision 1.11 1999/10/14 21:05:57 jp Bug #68617#,#68705# and other little things Revision 1.10 1999/10/13 09:08:41 jp write character attributs of SdrObjects Revision 1.9 1999/10/11 10:57:30 jp some bugfixes #68745#/#69033#/#68681# Revision 1.8 1999/09/10 16:27:59 jp write FlyFrms too if no SdrObject exist Revision 1.7 1999/09/08 16:29:18 jp Bug #68618#: recognize the write of escher stream Revision 1.6 1999/09/01 17:32:38 JP new: write the text of SdrTextObjects Rev 1.5 01 Sep 1999 19:32:38 JP new: write the text of SdrTextObjects Rev 1.4 31 Aug 1999 09:51:36 JP set NumberFormatInt at streams to littleendian Rev 1.3 24 Aug 1999 20:15:48 JP Escher Export Rev 1.2 16 Aug 1999 17:16:30 JP W97 Export: experimental escher export (1) Rev 1.1 16 Aug 1999 13:05:42 JP write EscherObjects - only a testversion! Rev 1.0 21 Jul 1999 18:28:56 JP W97 Export: experimental escher export *************************************************************************/