cmcfixes76: #i113073# redundant dereferences
[LibreOffice.git] / sw / source / filter / rtf / rtfatr.cxx
blob17050299c84b342598d6a598ac0de5466f67acdf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
33 * Dieses File enthaelt alle Ausgabe-Funktionen des RTF-Writers;
34 * fuer alle Nodes, Attribute, Formate und Chars.
36 #include <hintids.hxx>
38 #include <com/sun/star/i18n/ScriptType.hdl>
39 #include <vcl/cvtgrf.hxx>
40 #include <svl/urihelper.hxx>
41 #include <svl/stritem.hxx>
42 #include <svtools/rtfkeywd.hxx>
43 #include <svl/whiter.hxx>
44 #include <svtools/rtfout.hxx>
45 #include <svl/itemiter.hxx>
46 #include <editeng/fontitem.hxx>
47 #include <editeng/hyznitem.hxx>
48 #include <editeng/tstpitem.hxx>
49 #include <editeng/lspcitem.hxx>
50 #include <editeng/langitem.hxx>
51 #include <editeng/keepitem.hxx>
52 #include <editeng/udlnitem.hxx>
53 #include <editeng/shaditem.hxx>
54 #include <editeng/cmapitem.hxx>
55 #include <editeng/brshitem.hxx>
56 #include <editeng/protitem.hxx>
57 #include <editeng/opaqitem.hxx>
58 #include <editeng/ulspitem.hxx>
59 #include <editeng/prntitem.hxx>
60 #include <editeng/colritem.hxx>
61 #include <editeng/escpitem.hxx>
62 #include <editeng/fhgtitem.hxx>
63 #include <editeng/spltitem.hxx>
64 #include <editeng/adjitem.hxx>
65 #include <editeng/lrspitem.hxx>
66 #include <editeng/boxitem.hxx>
67 #include <editeng/crsditem.hxx>
68 #include <editeng/cntritem.hxx>
69 #include <editeng/postitem.hxx>
70 #include <editeng/shdditem.hxx>
71 #include <editeng/wghtitem.hxx>
72 #include <editeng/wrlmitem.hxx>
73 #include <editeng/emphitem.hxx>
74 #include <editeng/twolinesitem.hxx>
75 #include <editeng/charscaleitem.hxx>
76 #include <editeng/charrotateitem.hxx>
77 #include <editeng/charreliefitem.hxx>
78 #include <svx/xoutbmp.hxx>
79 #include <editeng/paravertalignitem.hxx>
80 #include <editeng/hngpnctitem.hxx>
81 #include <editeng/scriptspaceitem.hxx>
82 #include <editeng/forbiddenruleitem.hxx>
83 #include <editeng/frmdiritem.hxx>
84 #include <editeng/charhiddenitem.hxx>
85 #include <unotools/charclass.hxx>
86 #include <reffld.hxx>
87 #include <frmatr.hxx>
88 #include <charatr.hxx>
89 #include <fmtfsize.hxx>
90 #include <fmtpdsc.hxx>
91 #include <fmtfld.hxx>
92 #include <fmtflcnt.hxx>
93 #include <fmtftn.hxx>
94 #include <fchrfmt.hxx>
95 #include <fmtautofmt.hxx>
96 #include <fmtcntnt.hxx>
97 #include <fmthdft.hxx>
98 #include <fmtclds.hxx>
99 #include <txtftn.hxx>
100 #include <fmtsrnd.hxx>
101 #include <fmtanchr.hxx>
102 #include <charfmt.hxx>
103 #include <fmtinfmt.hxx>
104 #include <txtinet.hxx>
105 #include <doc.hxx>
106 #include <docary.hxx>
107 #include <ndtxt.hxx>
108 #include <pam.hxx>
109 #include <paratr.hxx>
110 #include <fldbas.hxx> // fuer SwField ...
111 #include <wrtrtf.hxx>
112 #include <rtf.hxx> // fuer SwPictureType
113 #include <ndgrf.hxx>
114 #include <grfatr.hxx>
115 #include <docufld.hxx>
116 #include <flddat.hxx>
117 #include <pagedesc.hxx> // fuer SwPageDesc ...
118 #include <swtable.hxx> // fuer SwPageDesc ...
119 #include <docsh.hxx>
120 #include <swrect.hxx>
121 #include <section.hxx>
122 #include <wrtswtbl.hxx>
123 #include <htmltbl.hxx>
124 #include <fmtclbl.hxx>
125 #include <breakit.hxx>
126 #include <fmtruby.hxx>
127 #include <txtatr.hxx>
128 #include <fltini.hxx>
129 #include <fmtrowsplt.hxx>
132 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
133 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
134 * definiert und mit der akt. verglichen. Bei unterschieden wird der
135 * Compiler schon meckern.
137 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
138 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
140 #if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
142 #define ATTRFNTAB_SIZE 130
143 #if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
144 #error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
145 #endif
147 #ifdef FORMAT_TABELLE
148 // da sie nicht benutzt wird!
149 #define FORMATTAB_SIZE 7
150 #if FORMATTAB_SIZE != RES_FMT_END - RES_FMT_BEGIN
151 #error Format-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
152 #endif
153 #endif
155 #define NODETAB_SIZE 3
156 #if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
157 #error Node-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
158 #endif
160 #endif
162 #ifdef WNT
163 // ueber xoutbmp.hxx wird das winuser.h angezogen. Dort gibt es ein
164 // define GetProp das mit unserem SvxEscapement kollidiert!
165 #undef GetProp
166 #endif
169 using namespace com::sun::star;
171 //-----------------------------------------------------------------------
173 static Writer& OutRTF_SwFmtCol( Writer& rWrt, const SfxPoolItem& rHt );
175 //-----------------------------------------------------------------------
177 SvStream& OutComment( Writer& rWrt, const sal_Char* pStr )
179 return (rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << pStr);
182 SvStream& OutComment( Writer& rWrt, const char* pStr, BOOL bSetFlag )
184 // setze Flag, damit bei der Ausgabe von Attributen zu erkennen,
185 // ob ueberhaupt etwas ausgegeben wurde.
186 ((SwRTFWriter&)rWrt).bOutFmtAttr = bSetFlag;
187 return (rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << pStr);
190 Writer& OutRTF_AsByteString( Writer& rWrt, const String& rStr, rtl_TextEncoding eEncoding)
192 ByteString sOutStr( rStr, eEncoding );
193 rWrt.Strm() << sOutStr.GetBuffer();
194 return rWrt;
197 void OutRTF_SfxItemSet( SwRTFWriter& rWrt, const SfxItemSet& rSet,
198 BOOL bDeep )
200 bool bFrameDirOut=false;
201 bool bAdjustOut=false;
202 // erst die eigenen Attribute ausgeben
203 SvPtrarr aAsian( 0, 5 ), aCmplx( 0, 5 ), aLatin( 0, 5 );
205 const SfxItemPool& rPool = *rSet.GetPool();
206 SfxWhichIter aIter( rSet );
207 const SfxPoolItem* pItem;
208 FnAttrOut pOut;
209 USHORT nWhich = aIter.FirstWhich();
210 while( nWhich )
212 if( SFX_ITEM_SET == rSet.GetItemState( nWhich, bDeep, &pItem ))
214 pOut = aRTFAttrFnTab[ nWhich - RES_CHRATR_BEGIN];
215 if( pOut &&
216 ( *pItem != rPool.GetDefaultItem( nWhich )
217 || ( rSet.GetParent() &&
218 *pItem != rSet.GetParent()->Get( nWhich ) )
219 || ( rWrt.GetAttrSet() &&
220 *pItem != rWrt.GetAttrSet()->Get( nWhich ) )
223 else
224 pOut = 0;
226 else if( !bDeep )
227 pOut = 0;
228 else if( 0 != ( pItem = rPool.GetPoolDefaultItem( nWhich )) )
229 pOut = aRTFAttrFnTab[ nWhich - RES_CHRATR_BEGIN];
230 else
231 pOut = 0;
233 if (!pOut && bDeep)
235 switch( nWhich )
237 case RES_CHRATR_FONTSIZE:
238 case RES_CHRATR_CJK_FONTSIZE:
239 case RES_CHRATR_CTL_FONTSIZE:
240 case RES_CHRATR_LANGUAGE:
241 case RES_CHRATR_CJK_LANGUAGE:
242 case RES_CHRATR_CTL_LANGUAGE:
243 pItem = &rPool.GetDefaultItem( nWhich );
244 pOut = aRTFAttrFnTab[ nWhich - RES_CHRATR_BEGIN];
245 break;
246 default:
247 break;
251 if( pOut )
253 void* pVoidItem = (void*)pItem;
254 switch( nWhich )
256 case RES_CHRATR_FONT:
257 case RES_CHRATR_FONTSIZE:
258 case RES_CHRATR_LANGUAGE:
259 case RES_CHRATR_POSTURE:
260 case RES_CHRATR_WEIGHT:
261 aLatin.Insert( pVoidItem, aLatin.Count() );
262 pOut = 0;
263 break;
265 case RES_CHRATR_CJK_FONT:
266 case RES_CHRATR_CJK_FONTSIZE:
267 case RES_CHRATR_CJK_LANGUAGE:
268 case RES_CHRATR_CJK_POSTURE:
269 case RES_CHRATR_CJK_WEIGHT:
270 aAsian.Insert( pVoidItem, aAsian.Count() );
271 pOut = 0;
272 break;
274 case RES_CHRATR_CTL_FONT:
275 case RES_CHRATR_CTL_FONTSIZE:
276 case RES_CHRATR_CTL_LANGUAGE:
277 case RES_CHRATR_CTL_POSTURE:
278 case RES_CHRATR_CTL_WEIGHT:
279 aCmplx.Insert( pVoidItem, aCmplx.Count() );
280 pOut = 0;
281 break;
283 case RES_FRAMEDIR:
284 bFrameDirOut=true;
285 break;
286 case RES_PARATR_ADJUST:
287 bAdjustOut=true;
288 break;
292 if (pOut)
293 (*pOut)( rWrt, *pItem );
294 nWhich = aIter.NextWhich();
297 //If rtlpar set and no following alignment. And alignment is not rtl then
298 //output alignment
299 if (bFrameDirOut && !bAdjustOut && !rWrt.pFlyFmt && !rWrt.bOutPageDesc)
301 pOut = aRTFAttrFnTab[ static_cast< USHORT >(RES_PARATR_ADJUST) - RES_CHRATR_BEGIN];
302 if (pOut)
303 (*pOut)(rWrt, rSet.Get(RES_PARATR_ADJUST));
305 if (rWrt.pFlyFmt && !rWrt.bOutPageDesc && !bFrameDirOut)
307 pOut = aRTFAttrFnTab[ static_cast< USHORT >(RES_FRAMEDIR) - RES_CHRATR_BEGIN];
308 if (pOut)
309 (*pOut)(rWrt, rSet.Get(RES_FRAMEDIR));
312 if (aAsian.Count() || aCmplx.Count() || aLatin.Count())
314 SvPtrarr* aArr[4];
315 switch (rWrt.GetCurrScriptType())
317 case i18n::ScriptType::LATIN:
318 aArr[ 0 ] = &aCmplx;
319 aArr[ 1 ] = &aAsian;
320 aArr[ 2 ] = &aLatin;
321 aArr[ 3 ] = &aLatin;
322 break;
324 case i18n::ScriptType::ASIAN:
325 aArr[ 0 ] = &aCmplx;
326 aArr[ 1 ] = &aLatin;
327 aArr[ 2 ] = &aLatin;
328 aArr[ 3 ] = &aAsian;
329 break;
331 case i18n::ScriptType::COMPLEX:
332 aArr[ 0 ] = &aLatin;
333 aArr[ 1 ] = &aLatin;
334 aArr[ 2 ] = &aAsian;
335 aArr[ 3 ] = &aCmplx;
336 break;
338 default:
339 return ;
342 //The final entry is the one that is actually in use
343 //so it uses e.g. \b \i \fs, the others are not in
344 //use and so are "associated". Both asian and western
345 //are ltr runs, with asian being the dbch varient
346 //and western being the loch/hich varient
347 bool bOutLTOR = true;
348 bool bLowLTOR = false;
349 for( int nArrCnt = 0; nArrCnt < 4; ++nArrCnt )
351 SvPtrarr* pCurArr = aArr[ nArrCnt ];
352 if (pCurArr->Count())
354 bool bInUse = (aArr[nArrCnt] == aArr[3]);
355 rWrt.SetAssociatedFlag(!bInUse);
356 if (pCurArr == &aLatin)
358 if (bOutLTOR)
360 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
361 bOutLTOR = false;
364 if (bLowLTOR)
365 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LOCH;
366 else
368 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_HICH;
369 bLowLTOR = true;
372 else if( pCurArr == &aAsian )
374 if( bOutLTOR )
376 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
377 bOutLTOR = false;
379 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DBCH;
381 else
382 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLCH;
384 for (USHORT n = 0; n < pCurArr->Count(); ++n)
386 pItem = (const SfxPoolItem*)(*pCurArr)[ n ];
387 pOut = aRTFAttrFnTab[ pItem->Which() - RES_CHRATR_BEGIN];
388 (*pOut)( rWrt, *pItem );
395 // fuer die Formate muesste eine einzige Ausgabe-Funktion genuegen !
397 * Formate wie folgt ausgeben:
398 * - gebe alle Attribute vom Format aus
401 bool SwFmtToSet(SwRTFWriter& rWrt, const SwFmt& rFmt, SfxItemSet &rSet)
403 bool bOutItemSet = true;
404 rSet.SetParent(rFmt.GetAttrSet().GetParent());
406 switch( rFmt.Which() )
408 case RES_CONDTXTFMTCOLL:
409 case RES_TXTFMTCOLL:
411 USHORT nId = rWrt.GetId( (const SwTxtFmtColl&)rFmt );
412 if (0 == nId )
413 return false; // Default-TextStyle nicht ausgeben !!
415 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_S;
416 rWrt.OutULong( nId );
417 rWrt.bOutFmtAttr = TRUE;
418 // BYTE nLvl = ((const SwTxtFmtColl&)rFmt).GetOutlineLevel(); //#outline level,zhaojianwei
419 // if( MAXLEVEL > nLvl )
420 // {
421 if(((const SwTxtFmtColl&)rFmt).IsAssignedToListLevelOfOutlineStyle())
423 int nLvl = ((const SwTxtFmtColl&)rFmt).GetAssignedOutlineStyleLevel(); //<-end,zhaojianwei
424 USHORT nNumId = rWrt.GetNumRuleId(
425 *rWrt.pDoc->GetOutlineNumRule() );
426 if( USHRT_MAX != nNumId )
428 BYTE nWWLvl = 8 >= nLvl ? static_cast<BYTE>(nLvl) : 8;
429 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LS;
430 rWrt.OutULong( nNumId );
431 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ILVL; rWrt.OutULong( nWWLvl );
432 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL; rWrt.OutULong( nWWLvl );
433 if( nWWLvl != nLvl ) // RTF-kennt nur 9 Ebenen
435 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_SOUTLVL );
436 rWrt.OutULong( nLvl ) << '}';
440 const SwNumFmt* pNFmt = &rWrt.pDoc->GetOutlineNumRule()->Get( static_cast<USHORT>(nLvl) );
441 if( pNFmt->GetAbsLSpace() )
443 SfxItemSet aSet( *rFmt.GetAttrSet().GetPool(),
444 rFmt.GetAttrSet().GetRanges() );
445 aSet.SetParent( &rFmt.GetAttrSet() );
446 SvxLRSpaceItem aLR( (SvxLRSpaceItem&)aSet.Get( RES_LR_SPACE ) );
448 aLR.SetTxtLeft( aLR.GetTxtLeft() + pNFmt->GetAbsLSpace() );
449 aLR.SetTxtFirstLineOfst( pNFmt->GetFirstLineOffset() );
451 aSet.Put(aLR);
452 rSet.Put(aSet);
453 bOutItemSet = false;
457 break;
458 case RES_CHRFMT:
460 USHORT nId = rWrt.GetId( (const SwCharFmt&)rFmt );
461 if (0 == nId)
462 return false; // Default-CharStyle nicht ausgeben !!
464 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_CS;
465 rWrt.OutULong( nId );
466 rWrt.bOutFmtAttr = TRUE;
468 break;
470 // case RES_GRFFMTCOLL:
471 // ?????
474 if (bOutItemSet)
475 rSet.Put(rFmt.GetAttrSet());
477 return true;
480 Writer& OutRTF_SwFmt(Writer& rWrt, const SwFmt& rFmt)
482 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
484 SfxItemSet aSet(*rFmt.GetAttrSet().GetPool(),
485 rFmt.GetAttrSet().GetRanges() );
486 if (SwFmtToSet(rRTFWrt, rFmt, aSet))
487 OutRTF_SfxItemSet(rRTFWrt, aSet, TRUE);
489 return rWrt;
492 void OutRTF_SwFlyFrmFmt( SwRTFWriter& rRTFWrt )
494 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
495 // muessen noch die Attribute dafuer ausgegeben werden.
496 ASSERT( rRTFWrt.pFlyFmt, "wo ist das Fly-Format?" );
498 if( rRTFWrt.bOutFmtAttr )
500 rRTFWrt.Strm() << ' ';
501 rRTFWrt.bOutFmtAttr = false;
503 // gebe erstmal alle RTF-Spezifischen Attribute aus
504 rRTFWrt.bRTFFlySyntax = TRUE;
505 OutRTF_SwFmt( rRTFWrt, *rRTFWrt.pFlyFmt );
507 // dann gebe alle eigenen Attribute aus
509 // dazu erzeuge einen temp strstream, um festzustellen ob es
510 // ueberhaupt eigene Attribute gibt !
511 SvMemoryStream aTmpStrm;
512 SvStream* pSaveStrm = &rRTFWrt.Strm();
513 rRTFWrt.SetStream( &aTmpStrm );
515 rRTFWrt.bRTFFlySyntax = false;
516 OutRTF_SwFmt( rRTFWrt, *rRTFWrt.pFlyFmt );
518 rRTFWrt.SetStream( pSaveStrm ); // Stream-Pointer wieder zurueck
520 if ( aTmpStrm.GetEndOfData() ) // gibt es SWG spezifische Attribute?
522 aTmpStrm.Seek( 0L );
523 rRTFWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << aTmpStrm << '}';
526 // rRTFWrt.pFlyFmt = 0; // wieder zuruecksetzen !!
529 /* Ausgabe der Nodes */
532 * Ausgabe der Texte-Attribute:
533 * Die Text-Attribute sind in einem VarArray nach ihren Start-Positionen
534 * sortiert. Fuer den RTF-Writer ist aber auch das Ende von Bedeutung.
535 * Darum die Idee, sobald im SwpHints-Array ein Attribut mit der Start-
536 * Position gefunden wurde, in einem Sortierten-Array die Endposition
537 * zu speichern. Sobald der Writer die Position erreicht hat, wird die
538 * schliessende Klammer ausgegeben und die Position aus dem Sort.Array
539 * geloescht.
540 * 15.3.93: Es reicht leider nicht aus nur Start und End zuspeichern, denn
541 * im SwpHints Array stehen sie nicht nach Ende sortiert, so dass
542 * Attribute die falsche schliessende Klammer bekommen. (z.B
543 * Bold von 0..3, dann folgt Underline von 0..4. Dann bekommt Underline
544 * die schliessende Klammer von Bold !!)
545 * Also muessen erst alle Attribute einer Position gesammelt, nach
546 * Ende sortiert und dann erst ausgegeben werden.
549 SV_DECL_PTRARR( SfxPoolItems, SfxPoolItem*, 4, 4 )
550 class RTFEndPosLst;
552 class SttEndPos
554 // falls mehrere Attribute den gleichen Bereich umspannen, sammeln
555 SfxPoolItems aArr;
556 xub_StrLen nStart, nEnd;
558 SttEndPos( const SttEndPos & rSEPos );
560 public:
561 SttEndPos( const SfxPoolItem& rAttr, xub_StrLen nStt, xub_StrLen nEnd );
562 ~SttEndPos();
564 xub_StrLen GetStart() const { return nStart; }
565 xub_StrLen GetEnd() const { return nEnd; }
567 const SfxPoolItems& GetAttrs() const { return aArr; }
568 void AddAttr( const SfxPoolItem& rAttr );
569 BOOL HasScriptChange() const;
573 SV_DECL_PTRARR_DEL( _EndPosLst, SttEndPos*, 5, 5 )
574 SV_IMPL_PTRARR( _EndPosLst, SttEndPos* )
576 class RTFEndPosLst : private _EndPosLst
578 const SwTxtNode& rNode;
579 SwRTFWriter& rWrt;
580 RTFEndPosLst* pOldPosLst;
581 xub_StrLen nCurPos;
582 USHORT nCurScript;
584 public:
585 using _EndPosLst::Count;
586 using _EndPosLst::operator[];
587 using _EndPosLst::DeleteAndDestroy;
589 RTFEndPosLst( SwRTFWriter& rWrt, const SwTxtNode& rNd, xub_StrLen nStart );
590 ~RTFEndPosLst();
592 USHORT GetCurScript() const { return nCurScript; }
593 BOOL MatchScriptToId( USHORT nId ) const;
594 int Insert( const SfxPoolItem& rAttr, xub_StrLen nStt, xub_StrLen nEnd );
596 void OutAttrs( xub_StrLen nStrPos );
597 void EndAttrs( xub_StrLen nStrPos );
598 void OutScriptChange( xub_StrLen nStrPos );
600 const SfxPoolItem* HasItem( USHORT nWhich ) const;
601 const SfxPoolItem& GetItem( USHORT nWhich ) const;
602 void OutFontAttrs(const SfxPoolItem &rItem);
603 void OutFontAttrs(USHORT nScript, bool bRTL);
605 SfxItemPool& GetPool() {return *rNode.GetSwAttrSet().GetPool(); }
609 SttEndPos::SttEndPos( const SfxPoolItem& rAttr,
610 xub_StrLen nStt, xub_StrLen nEd )
611 : nStart( nStt ), nEnd( nEd )
613 AddAttr( rAttr );
616 SttEndPos::~SttEndPos()
618 for( USHORT n = 0, nCount = aArr.Count(); n < nCount; ++n )
619 if( RES_FLTRATTR_BEGIN <= aArr[ n ]->Which() )
620 delete aArr[ n ];
623 BOOL SttEndPos::HasScriptChange() const
625 for( USHORT n = 0, nCount = aArr.Count(); n < nCount; ++n )
626 if( RES_FLTR_SCRIPTTYPE == aArr[ n ]->Which() )
627 return TRUE;
628 return FALSE;
631 void SttEndPos::AddAttr( const SfxPoolItem& rAttr )
633 const SfxPoolItem* pI = &rAttr;
634 aArr.Insert(pI, aArr.Count());
637 RTFEndPosLst::RTFEndPosLst(SwRTFWriter& rWriter, const SwTxtNode& rNd,
638 xub_StrLen nStart)
639 : rNode(rNd), rWrt(rWriter), nCurPos(STRING_NOTFOUND)
641 pOldPosLst = rWrt.pCurEndPosLst;
642 rWrt.pCurEndPosLst = this;
644 using namespace sw::util;
645 CharRuns aCharRuns(GetPseudoCharRuns(rNd, nStart));
646 cCharRunIter aEnd = aCharRuns.end();
647 xub_StrLen nSttPos = nStart;
648 for (cCharRunIter aI = aCharRuns.begin(); aI != aEnd; ++aI)
650 if (nSttPos != aI->mnEndPos)
652 SfxPoolItem* pChg = new SfxUInt32Item(RES_FLTR_SCRIPTTYPE,
653 (sal_uInt32(aI->mnScript) << 16) | static_cast<sal_uInt32>(aI->mbRTL));
654 Insert(*pChg, nSttPos, aI->mnEndPos);
655 nSttPos = aI->mnEndPos;
660 RTFEndPosLst::~RTFEndPosLst()
662 rWrt.pCurEndPosLst = pOldPosLst;
665 int RTFEndPosLst::Insert( const SfxPoolItem& rAttr, xub_StrLen nStt,
666 xub_StrLen nEnd )
668 if (rAttr.Which() == RES_TXTATR_INETFMT)
669 return false;
671 if( nStt == nEnd )
672 return false;
674 USHORT nPos;
675 for( nPos = 0; nPos < Count(); ++nPos )
677 SttEndPos* pTmp = GetObject( nPos );
678 if( pTmp->GetStart() == nStt && pTmp->GetEnd() == nEnd )
680 pTmp->AddAttr( rAttr );
681 return false; // schon vorhanden
683 if( nEnd < pTmp->GetEnd() )
685 SttEndPos* pNew = new SttEndPos( rAttr, nStt, nEnd );
686 _EndPosLst::C40_INSERT( SttEndPos, pNew, nPos );
687 return TRUE;
691 SttEndPos* pNew = new SttEndPos( rAttr, nStt, nEnd );
692 _EndPosLst::C40_INSERT( SttEndPos, pNew, nPos );
693 return TRUE;
696 void RTFEndPosLst::OutScriptChange( xub_StrLen nStrPos )
698 SttEndPos* pStt;
699 for( USHORT n = 0, nEnd = Count(); n < nEnd; ++n )
700 if( nStrPos == (pStt = GetObject( n ))->GetStart())
702 if( pStt->HasScriptChange() )
703 OutAttrs( nStrPos );
704 break;
708 void RTFEndPosLst::OutAttrs( xub_StrLen nStrPos )
710 SttEndPos* pStt;
711 nCurPos = nStrPos;
712 for( USHORT n = Count(); n ; )
713 if( nStrPos == (pStt = (*this)[ --n ])->GetStart() )
715 rWrt.Strm() << '{';
716 for( USHORT i = 0; i < pStt->GetAttrs().Count(); ++i )
718 const SfxPoolItem* pItem = pStt->GetAttrs()[i];
719 if( RES_FLTR_SCRIPTTYPE == pItem->Which() )
720 OutFontAttrs(*pItem);
721 else
722 Out( aRTFAttrFnTab, *pItem, rWrt );
726 nCurPos = STRING_NOTFOUND;
729 //Just a little decoding hack for the RES_FLTR_SCRIPTTYPE thing
730 void RTFEndPosLst::OutFontAttrs(const SfxPoolItem &rItem)
732 sal_uInt32 nValue = ((const SfxUInt32Item&)rItem).GetValue();
733 sal_uInt16 nScript = static_cast<sal_uInt16>(nValue >> 16);
734 bool bBiDi = nValue & 0x1;
735 OutFontAttrs(nScript, bBiDi);
738 void RTFEndPosLst::OutFontAttrs(USHORT nScript, bool bRTL)
740 // script change, write the correct attributes:
741 // start first with the Fontname
743 rWrt.bOutFmtAttr = TRUE;
744 nCurScript = nScript;
745 rWrt.SetCurrScriptType( nScript );
746 rWrt.SetAssociatedFlag(false);
748 // the font MUST be at the first position !!!
749 static const USHORT aLatinIds[] =
751 RES_CHRATR_FONT,
752 RES_CHRATR_FONTSIZE, RES_CHRATR_LANGUAGE,
753 RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT,
756 static const USHORT aAsianIds[] =
758 RES_CHRATR_CJK_FONT,
759 RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CJK_LANGUAGE,
760 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT,
763 static const USHORT aCmplxIds[] =
765 RES_CHRATR_CTL_FONT,
766 RES_CHRATR_CTL_FONTSIZE, RES_CHRATR_CTL_LANGUAGE,
767 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT,
772 You would have thought that
773 rWrt.Strm() << (bRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficent here ,
774 but looks like word needs to see the other directional token to be
775 satisified that all is kosher, otherwise it seems in ver 2003 to go and
776 semi-randomlyly stick strike through about the place. Perhaps
777 strikethrough is some ms developers "something is wrong signal" debugging
778 code that we're triggering ?
780 if (bRTL)
782 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
783 rWrt.Strm() << ' ';
784 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLCH;
786 else
788 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLCH;
789 rWrt.Strm() << ' ';
790 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
793 // size/weight/posture optional
794 const USHORT* pIdArr = 0;
795 ByteString sOut;
796 switch (nScript)
798 default: //fall through
799 ASSERT(pIdArr, "unknown script, strange");
800 case i18n::ScriptType::LATIN:
801 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LOCH;
802 pIdArr = aLatinIds;
803 break;
804 case i18n::ScriptType::ASIAN:
805 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DBCH;
806 pIdArr = aAsianIds;
807 break;
808 case i18n::ScriptType::COMPLEX:
809 pIdArr = aCmplxIds;
810 break;
813 for (const USHORT* pId = pIdArr; *pId; ++pId)
815 if (FnAttrOut pOut = aRTFAttrFnTab[ *pId - RES_CHRATR_BEGIN])
817 const SfxPoolItem* pItem = HasItem(*pId);
818 if (!pItem)
819 pItem = &GetPool().GetDefaultItem(*pId);
820 (*pOut)(rWrt, *pItem);
825 void RTFEndPosLst::EndAttrs( xub_StrLen nStrPos )
827 xub_StrLen nClipStart=STRING_MAXLEN;
828 bool bClosed=false;
829 SttEndPos* pSEPos;
830 while( 0 != Count() && 0 != (pSEPos = GetObject( 0 )) &&
831 ( STRING_MAXLEN == nStrPos || nStrPos == pSEPos->GetEnd() ))
833 const SfxPoolItems& rAttrs = pSEPos->GetAttrs();
834 for( USHORT nAttr = rAttrs.Count(); nAttr; )
836 switch( rAttrs[ --nAttr ]->Which() )
838 case RES_TXTATR_CJK_RUBY:
839 rWrt.Strm() << ")}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << " }}";
840 break;
844 rWrt.Strm() << '}'; // end of all attributes from this position
845 if (pSEPos->GetStart() < nClipStart)
846 nClipStart = pSEPos->GetStart();
847 bClosed=true;
848 DeleteAndDestroy( 0, 1 );
851 if (bClosed)
853 //If there are open ranges whose start is before this point, and whose
854 //start is after the cliping start then they have been closed whether
855 //we wanted this or not. So accept that fact and then restart then
856 //again
857 USHORT nSize = Count();
858 while (nSize > 0)
860 pSEPos = GetObject(--nSize);
861 if ( pSEPos->GetStart() < nStrPos &&
862 pSEPos->GetStart() >= nClipStart)
864 rWrt.Strm() << '}';
868 nSize = Count();
869 USHORT n = 0;
870 while (n < nSize)
872 SttEndPos* pStt = (*this)[n++];
873 if (pStt->GetStart() < nStrPos && pStt->GetStart() >= nClipStart)
875 rWrt.Strm() << '{';
876 for( USHORT i = 0; i < pStt->GetAttrs().Count(); ++i )
878 const SfxPoolItem* pItem = pStt->GetAttrs()[i];
879 if( RES_FLTR_SCRIPTTYPE == pItem->Which() )
880 OutFontAttrs(*pItem);
881 else
882 Out( aRTFAttrFnTab, *pItem, rWrt );
889 BOOL RTFEndPosLst::MatchScriptToId( USHORT nWhich ) const
891 BOOL bRet = false;
892 switch( nWhich )
894 case RES_CHRATR_FONT:
895 case RES_CHRATR_FONTSIZE:
896 case RES_CHRATR_LANGUAGE:
897 case RES_CHRATR_POSTURE:
898 case RES_CHRATR_WEIGHT:
899 bRet = nCurScript == i18n::ScriptType::LATIN;
900 break;
901 case RES_CHRATR_CJK_FONT:
902 case RES_CHRATR_CJK_FONTSIZE:
903 case RES_CHRATR_CJK_LANGUAGE:
904 case RES_CHRATR_CJK_POSTURE:
905 case RES_CHRATR_CJK_WEIGHT:
906 bRet = nCurScript == i18n::ScriptType::ASIAN;
907 break;
908 case RES_CHRATR_CTL_FONT:
909 case RES_CHRATR_CTL_FONTSIZE:
910 case RES_CHRATR_CTL_LANGUAGE:
911 case RES_CHRATR_CTL_POSTURE:
912 case RES_CHRATR_CTL_WEIGHT:
913 bRet = nCurScript == i18n::ScriptType::COMPLEX;
914 break;
916 return bRet;
919 const SfxPoolItem& RTFEndPosLst::GetItem( USHORT nWhich ) const
921 const SfxPoolItem* pItem = HasItem( nWhich );
922 if( !pItem )
923 pItem = &rNode.GetSwAttrSet().GetPool()->GetDefaultItem( nWhich );
924 return *pItem;
927 const SfxPoolItem* RTFEndPosLst::HasItem( USHORT nWhich ) const
929 const SfxPoolItem* pItem;
930 if( RES_TXTATR_END > nWhich )
932 // it's a character/text attribute so look into the item array
933 for( USHORT n = Count(); n; )
935 SttEndPos* pTmp = GetObject( --n );
936 for( USHORT i = pTmp->GetAttrs().Count(); i; )
938 pItem = pTmp->GetAttrs()[ --i ];
939 if( pItem->Which() == nWhich )
940 return pItem;
942 // look into the charfmt?
943 if( RES_TXTATR_CHARFMT == pItem->Which() &&
944 ((SwFmtCharFmt*) pItem)->GetCharFmt() &&
945 SFX_ITEM_SET == ((SwFmtCharFmt*) pItem)->GetCharFmt()->
946 GetItemState( nWhich, TRUE, &pItem ))
947 return pItem;
952 if( SFX_ITEM_SET != rNode.GetSwAttrSet().GetItemState(
953 nWhich, TRUE, &pItem ))
954 pItem = 0;
955 return pItem;
958 const SfxPoolItem& SwRTFWriter::GetItem( USHORT nWhich ) const
960 if( pCurEndPosLst )
961 return pCurEndPosLst->GetItem( nWhich );
962 if( pAttrSet )
963 return pAttrSet->Get( nWhich );
965 return pDoc->GetAttrPool().GetDefaultItem( nWhich );
968 static void OutSvxFrmDir(SwRTFWriter& rRTFWrt, const SfxPoolItem& rHt )
970 // write it only for pasgedesc's - not for frames
971 SvxFrameDirectionItem aItem((const SvxFrameDirectionItem&)rHt);
972 USHORT nVal = 0;
973 const sal_Char* pStr = 0;
974 bool bRTL = false;
976 if (rRTFWrt.pFlyFmt)
977 aItem.SetValue(rRTFWrt.TrueFrameDirection(*rRTFWrt.pFlyFmt));
979 switch (aItem.GetValue())
981 case FRMDIR_ENVIRONMENT:
982 ASSERT(0, "Not expected to see FRMDIR_ENVIRONMENT here");
983 break;
984 case FRMDIR_VERT_TOP_RIGHT:
985 nVal = 1;
986 pStr = OOO_STRING_SVTOOLS_RTF_FRMTXTBRLV;
987 break;
988 case FRMDIR_HORI_RIGHT_TOP:
989 bRTL = true;
990 // nVal = 3;
991 // A val of three isn't working as expected in word :-( so leave it
992 // as normal ltr 0 textflow with rtl sect property, neither does
993 // the frame textflow
994 // pStr = OOO_STRING_SVTOOLS_RTF_FRMTXTBRL;
995 break;
996 case FRMDIR_VERT_TOP_LEFT:
997 nVal = 4;
998 pStr = OOO_STRING_SVTOOLS_RTF_FRMTXLRTBV;
999 break;
1002 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax && pStr )
1004 rRTFWrt.Strm() << pStr;
1005 rRTFWrt.bOutFmtAttr = TRUE;
1007 else if( rRTFWrt.bOutPageDesc)
1009 if (nVal)
1011 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_STEXTFLOW;
1012 rRTFWrt.OutULong( nVal );
1014 if (bRTL)
1015 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLSECT;
1016 rRTFWrt.bOutFmtAttr = TRUE;
1018 else if (!rRTFWrt.pFlyFmt && !rRTFWrt.bOutPageDesc)
1020 rRTFWrt.Strm() << (bRTL ? OOO_STRING_SVTOOLS_RTF_RTLPAR : OOO_STRING_SVTOOLS_RTF_LTRPAR);
1021 rRTFWrt.bOutFmtAttr = TRUE;
1025 void OutRTF_SwRTL(SwRTFWriter& rWrt, const SwTxtNode *pNd)
1027 if (!pNd)
1028 return;
1029 SvxFrameDirection eDir = FRMDIR_ENVIRONMENT;
1030 if (const SvxFrameDirectionItem* pItem = (const SvxFrameDirectionItem*)
1031 pNd->GetSwAttrSet().GetItem(RES_FRAMEDIR))
1033 eDir = static_cast<SvxFrameDirection>(pItem->GetValue());
1035 if (eDir == FRMDIR_ENVIRONMENT)
1037 SwPosition aPos(*pNd);
1038 eDir =
1039 static_cast<SvxFrameDirection>(rWrt.pDoc->GetTextDirection(aPos));
1041 OutSvxFrmDir(rWrt, SvxFrameDirectionItem(eDir, RES_FRAMEDIR));
1044 static Writer& OutRTF_SwTxtINetFmt( Writer& rWrt, const SfxPoolItem& rHt )
1046 const SwFmtINetFmt& rURL = (const SwFmtINetFmt&)rHt;
1047 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
1048 if( rURL.GetValue().Len() )
1050 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_FIELD << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE
1051 << OOO_STRING_SVTOOLS_RTF_FLDINST << " HYPERLINK ";
1053 String sURL( rURL.GetValue() );
1054 if( INET_MARK_TOKEN != sURL.GetChar(0) )
1056 INetURLObject aTmp( URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(),
1057 sURL));
1060 sURL = aTmp.GetURLNoMark( INetURLObject::DECODE_UNAMBIGUOUS);
1061 /* if( INET_PROT_FILE == aTmp.GetProtocol() )
1063 // WW97 wollen keine FILE-URL haben, sondern einen normalen
1064 // Dateinamen. Aber ab WW2000 kennen sie FileURLs.
1065 sURL = aTmp.GetFull();
1067 */ rWrt.Strm() << '\"';
1068 RTFOutFuncs::Out_String( rWrt.Strm(), sURL, rRTFWrt.eCurrentEncoding,
1069 rRTFWrt.bWriteHelpFmt ) << "\" ";
1070 sURL = aTmp.GetMark();
1073 if( sURL.Len() )
1075 rWrt.Strm() << "\\\\l \"";
1076 sURL.Erase( 0, 1 );
1077 RTFOutFuncs::Out_String( rWrt.Strm(), sURL, rRTFWrt.eCurrentEncoding,
1078 rRTFWrt.bWriteHelpFmt ) << "\" ";
1081 if( rURL.GetTargetFrame().Len() )
1083 rWrt.Strm() << "\\\\t \"";
1084 RTFOutFuncs::Out_String( rWrt.Strm(), rURL.GetTargetFrame(),
1085 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt ) << "\" ";
1088 rWrt.Strm() << "}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << ' ';
1089 rRTFWrt.bOutFmtAttr = false;
1091 // und dann noch die Attributierung ausgeben
1092 const SwCharFmt* pFmt;
1093 const SwTxtINetFmt* pTxtAtr = rURL.GetTxtINetFmt();
1094 if( pTxtAtr && 0 != ( pFmt = pTxtAtr->GetCharFmt() ))
1095 OutRTF_SwFmt( rWrt, *pFmt );
1097 return rWrt;
1100 void HandleHyperlinks(Writer& rWrt, const SwpHints* pTxtAttrs, xub_StrLen nPos )
1102 USHORT nCount = pTxtAttrs ? pTxtAttrs->Count() : 0;
1103 for(USHORT i = 0; i < nCount; ++i )
1105 const SwTxtAttr* pHt = (*pTxtAttrs)[i];
1106 const SfxPoolItem &rItem = pHt->GetAttr();
1107 if (rItem.Which() == RES_TXTATR_INETFMT)
1109 const xub_StrLen* pEnd;
1110 if (nPos == *pHt->GetStart())
1111 OutRTF_SwTxtINetFmt(rWrt, rItem);
1112 if (0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd)
1114 // Hyperlinks werden als Felder geschrieben, aber der
1115 // "FieldResult" // steht als Text im TextNode. Also muss bei
1116 // diesen Attributen am // Ende 2 Klammern stehen!
1117 rWrt.Strm() << "}}";
1123 static Writer& OutRTF_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
1125 SwTxtNode * pNd = &((SwTxtNode&)rNode);
1126 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1127 xub_StrLen nStrPos = rRTFWrt.pCurPam->GetPoint()->nContent.GetIndex();
1128 RTFEndPosLst aEndPosLst( rRTFWrt, *pNd, nStrPos );
1129 USHORT nAttrPos = 0;
1131 const String& rStr = pNd->GetTxt();
1132 xub_StrLen nEnde = rStr.Len();
1133 if( rRTFWrt.pCurPam->GetPoint()->nNode == rRTFWrt.pCurPam->GetMark()->nNode )
1134 nEnde = Min( nEnde, rRTFWrt.pCurPam->GetMark()->nContent.GetIndex() );
1136 int bNewFmts = rRTFWrt.GetAttrSet() != &pNd->GetSwAttrSet();
1137 if( bNewFmts )
1139 // harte Attributierung am Node und am Vorgaenger ?
1140 const SfxItemSet* pNdSet = pNd->GetpSwAttrSet();
1141 if( pNdSet && rRTFWrt.GetAttrSet() && rRTFWrt.bAutoAttrSet &&
1142 pNdSet->GetParent() == rRTFWrt.GetAttrSet()->GetParent() &&
1143 pNdSet->Count() == rRTFWrt.GetAttrSet()->Count() )
1145 // die beiden Parents sind gleich, dann teste doch mal die
1146 // Attribute im Set
1148 int bEqual = TRUE;
1149 if( pNdSet->Count() )
1151 SfxItemIter aIter( *rRTFWrt.GetAttrSet() );
1152 const SfxPoolItem *pItem, *pCurr = aIter.GetCurItem();
1153 while( TRUE )
1155 if( SFX_ITEM_SET != pNdSet->GetItemState( pCurr->Which(),
1156 false, &pItem ) || *pItem != *pCurr )
1158 bEqual = false;
1159 break;
1162 if( aIter.IsAtEnd() )
1163 break;
1164 pCurr = aIter.NextItem();
1167 if (bEqual)
1168 bNewFmts = false;
1170 rRTFWrt.SetAttrSet( &pNd->GetSwAttrSet() );
1171 rRTFWrt.bAutoAttrSet = 0 != pNdSet;
1174 // Flag zuruecksetzen, damit nach der Ausgabe der Collection
1175 // getestet werden kann, ob noch ein Blank auszugeben ist
1176 rRTFWrt.bOutFmtAttr = false;
1178 // in der Ausgabe eines Flys? Dann vorm ausgeben der AbsatzAttribute
1179 // den Format-Pointer auf 0 setzen!
1180 const SwFlyFrmFmt* pSaveFmt = rRTFWrt.pFlyFmt;
1182 SfxItemSet aMergedSet(rRTFWrt.pDoc->GetAttrPool(), POOLATTR_BEGIN,
1183 POOLATTR_END-1);
1184 bool bDeep = false;
1186 if( rRTFWrt.bWriteAll )
1188 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN << ' '; // alle Attribute zuruecksetzen
1189 if( rRTFWrt.bOutTable )
1190 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_INTBL;
1192 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
1193 // muessen noch die Attribute dafuer ausgegeben werden.
1194 if( pSaveFmt )
1196 OutRTF_SwFlyFrmFmt( rRTFWrt );
1197 rRTFWrt.pFlyFmt = 0;
1200 rRTFWrt.OutListNum( *pNd );
1201 OutRTF_SwRTL(rRTFWrt, pNd);
1202 SwFmtToSet(rRTFWrt, pNd->GetAnyFmtColl(), aMergedSet);
1203 bDeep = true;
1205 else if( !rRTFWrt.bWriteAll && rRTFWrt.bFirstLine )
1207 OutRTF_SwRTL(rRTFWrt, pNd);
1208 SwFmtToSet(rRTFWrt, pNd->GetAnyFmtColl(), aMergedSet);
1209 bDeep = true;
1212 // gibt es harte Attributierung ?
1213 if( bNewFmts && pNd->HasSwAttrSet())
1215 rRTFWrt.pFlyFmt = 0;
1217 const SfxItemSet& rNdSet = pNd->GetSwAttrSet();
1219 const SwNumRule* pRule = pNd->GetNumRule();
1220 // --> OD 2008-03-19 #refactorlists#
1221 if ( pRule && pNd->IsInList() )
1222 // <--
1224 // --> OD 2008-03-18 #refactorlists#
1225 ASSERT( pNd->GetActualListLevel() >= 0 && pNd->GetActualListLevel() < MAXLEVEL,
1226 "<OutRTF_SwTxtNode(..)> - text node does not have valid list level. Serious defect -> please inform OD" );
1227 // <--
1228 BYTE nLvl = static_cast< BYTE >(pNd->GetActualListLevel());
1229 const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl );
1230 if( !pFmt )
1231 pFmt = &pRule->Get( nLvl );
1233 SfxItemSet aSet( rNdSet );
1234 SvxLRSpaceItem aLR( (SvxLRSpaceItem&)rNdSet.Get( RES_LR_SPACE ) );
1236 aLR.SetTxtLeft( aLR.GetTxtLeft() + pFmt->GetAbsLSpace() );
1237 if( MAXLEVEL > pNd->GetActualListLevel() )
1238 aLR.SetTxtFirstLineOfst( pFmt->GetFirstLineOffset() );
1239 else
1240 aSet.ClearItem( RES_PARATR_NUMRULE );
1241 aSet.Put( aLR );
1242 aMergedSet.Put(aSet);
1244 else
1245 aMergedSet.Put(rNdSet);
1248 SwTxtNode *txtNode=rNode.GetTxtNode();
1249 if (txtNode!=NULL && !txtNode->IsNumbered())
1251 aMergedSet.ClearItem(RES_PARATR_NUMRULE);
1253 OutRTF_SfxItemSet(rRTFWrt, aMergedSet, bDeep);
1255 rRTFWrt.pFlyFmt = pSaveFmt;
1257 rRTFWrt.bTxtAttr = true;
1258 // erstmal den Start berichtigen. D.h. wird nur ein Teil vom Satz
1259 // ausgegeben, so muessen auch da die Attribute stimmen!!
1260 const SwTxtAttr * pHt = 0;
1261 USHORT nCntAttr = pNd->HasHints() ? pNd->GetSwpHints().Count() : 0;
1262 if( nCntAttr && nStrPos > *( pHt = pNd->GetSwpHints()[ 0 ] )->GetStart() )
1264 // Ok, es gibt vorher Attribute, die ausgegeben werden muessen
1265 do {
1266 nAttrPos++;
1267 if( RES_TXTATR_FIELD == pHt->Which() ) // Felder nicht
1268 continue; // ausgeben
1270 if( pHt->GetEnd() )
1272 xub_StrLen nHtEnd = *pHt->GetEnd(), nHtStt = *pHt->GetStart();
1273 if( !rRTFWrt.bWriteAll && nHtEnd <= nStrPos )
1274 continue;
1276 // leere Hints am Anfang nicht beachten, oder ??
1277 if( nHtEnd == nHtStt )
1278 continue;
1280 // Attribut in die Liste aufnehemen
1281 if( !rRTFWrt.bWriteAll )
1283 if( nHtStt < nStrPos ) nHtStt = nStrPos;
1284 if( nHtEnd >= nEnde ) nHtEnd = nEnde;
1286 aEndPosLst.Insert( pHt->GetAttr(), nHtStt, nHtEnd );
1287 continue;
1288 // aber nicht ausgeben, das erfolgt spaeter !!
1290 Out( aRTFAttrFnTab, pHt->GetAttr(), rRTFWrt );
1292 } while( nAttrPos < nCntAttr && nStrPos >
1293 *( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );
1295 // dann gebe mal alle gesammelten Attribute von der String-Pos aus
1296 aEndPosLst.OutAttrs( nStrPos );
1299 if( rRTFWrt.bOutFmtAttr &&
1300 ( nAttrPos < nCntAttr ? *pHt->GetStart() != nStrPos : TRUE ))
1301 rRTFWrt.Strm() << ' ';
1303 // das Flag gibt an, ob das SwTxtFld am Ende vom Absatz steht. Denn
1304 // dann ist vor dem Absatzumbruch die schliessende Klammer auszugeben
1305 xub_StrLen nChrCnt = 0;
1306 for( ; nStrPos <= nEnde; nStrPos++ )
1308 rRTFWrt.bOutFmtAttr = false;
1309 if( nStrPos != nEnde && aEndPosLst.Count() )
1310 aEndPosLst.EndAttrs( nStrPos );
1312 // versuche nach ungefaehr 255 Zeichen eine neue Zeile zu beginnen
1313 if( nChrCnt != ( nStrPos & 0xff00 ))
1315 rWrt.Strm() << SwRTFWriter::sNewLine;
1316 nChrCnt = nStrPos & 0xff00;
1319 if( nAttrPos < nCntAttr && *pHt->GetStart() == nStrPos
1320 && nStrPos != nEnde )
1322 do {
1323 BOOL bEmpty = false;
1324 if( pHt->GetEnd() )
1326 if (false == (bEmpty = *pHt->GetEnd() == nStrPos))
1328 aEndPosLst.Insert( pHt->GetAttr(), nStrPos,
1329 *pHt->GetEnd() );
1330 continue;
1332 rRTFWrt.Strm() << '{';
1334 Out( aRTFAttrFnTab, pHt->GetAttr(), rRTFWrt );
1335 if( bEmpty )
1337 rRTFWrt.Strm() << '}';
1338 rRTFWrt.bOutFmtAttr = false;
1340 } while( ++nAttrPos < nCntAttr && nStrPos ==
1341 *( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );
1343 // dann gebe mal alle gesammelten Attribute von der String-Pos aus
1344 aEndPosLst.OutAttrs( nStrPos );
1347 else
1348 aEndPosLst.OutScriptChange( nStrPos );
1350 HandleHyperlinks(rWrt, pNd->GetpSwpHints(), nStrPos);
1352 if( rRTFWrt.bOutFmtAttr )
1353 rRTFWrt.Strm() << ' ';
1355 rRTFWrt.OutBookmarks( nStrPos );
1357 rRTFWrt.OutRedline( nStrPos);
1359 if (nStrPos != nEnde)
1361 RTFOutFuncs::Out_String(rWrt.Strm(), String(rStr.GetChar(nStrPos)),
1362 rRTFWrt.eCurrentEncoding, rRTFWrt.bWriteHelpFmt);
1366 rRTFWrt.bTxtAttr = false;
1368 // noch eine schliesende Klammer da ??
1369 if( aEndPosLst.Count() )
1370 aEndPosLst.EndAttrs( USHRT_MAX );
1372 // wenn bis zum Ende vom Node, dann auch das AbsatzEnde ausgeben
1373 if( rRTFWrt.pCurPam->GetMark()->nNode.GetIndex() ==
1374 rRTFWrt.pCurPam->GetPoint()->nNode.GetIndex() )
1376 if( pNd->Len() != rRTFWrt.pCurPam->GetMark()->nContent.GetIndex() )
1377 return rWrt;
1379 if( rRTFWrt.bOutTable )
1381 rRTFWrt.Strm() << SwRTFWriter::sNewLine;
1382 return rWrt;
1386 rRTFWrt.Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PAR << ' ';
1387 return rRTFWrt;
1390 bool IsEMF(const sal_uInt8 *pGraphicAry, unsigned long nSize)
1392 if (pGraphicAry && (nSize > 0x2c ))
1394 // check the magic number
1395 if (
1396 (pGraphicAry[0x28] == 0x20 ) && (pGraphicAry[0x29] == 0x45) &&
1397 (pGraphicAry[0x2a] == 0x4d ) && (pGraphicAry[0x2b] == 0x46)
1400 //emf detected
1401 return true;
1404 return false;
1407 bool StripMetafileHeader(const sal_uInt8 *&rpGraphicAry, unsigned long &rSize)
1409 if (rpGraphicAry && (rSize > 0x22))
1411 if (
1412 (rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) &&
1413 (rpGraphicAry[2] == 0xc6) && (rpGraphicAry[3] == 0x9a)
1415 { // we have to get rid of the metafileheader
1416 rpGraphicAry += 22;
1417 rSize -= 22;
1418 return true;
1421 return false;
1424 void ExportPICT(const Size &rOrig, const Size &rRendered, const Size &rMapped,
1425 const SwCropGrf &rCr, const char *pBLIPType, const sal_uInt8 *pGraphicAry,
1426 unsigned long nSize, SwRTFWriter &rWrt)
1428 bool bIsWMF = (const char *)pBLIPType == (const char *)OOO_STRING_SVTOOLS_RTF_WMETAFILE ? true : false;
1429 if (pBLIPType && nSize && pGraphicAry)
1431 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_PICT;
1433 long nXCroppedSize = rOrig.Width()-(rCr.GetLeft() + rCr.GetRight());
1434 long nYCroppedSize = rOrig.Height()-(rCr.GetTop() + rCr.GetBottom());
1435 /* #127543#: Graphic with a zero height or width, typically copied from webpages, caused
1436 crashes. */
1437 if( !nXCroppedSize )
1438 nXCroppedSize = 100;
1439 if( !nYCroppedSize )
1440 nYCroppedSize = 100;
1442 //Given the original size and taking cropping into account
1443 //first, how much has the original been scaled to get the
1444 //final rendered size
1445 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICSCALEX;
1446 rWrt.OutLong((100 * rRendered.Width()) / nXCroppedSize);
1447 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICSCALEY;
1448 rWrt.OutLong((100 * rRendered.Height()) / nYCroppedSize);
1450 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPL;
1451 rWrt.OutLong(rCr.GetLeft());
1452 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPR;
1453 rWrt.OutLong(rCr.GetRight());
1454 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPT;
1455 rWrt.OutLong(rCr.GetTop());
1456 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPB;
1457 rWrt.OutLong(rCr.GetBottom());
1459 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICW;
1460 rWrt.OutLong(rMapped.Width());
1461 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICH;
1462 rWrt.OutLong(rMapped.Height());
1464 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICWGOAL;
1465 rWrt.OutLong(rOrig.Width());
1466 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICHGOAL;
1467 rWrt.OutLong(rOrig.Height());
1469 rWrt.Strm() << pBLIPType;
1470 if (bIsWMF)
1472 rWrt.OutLong(8);
1473 StripMetafileHeader(pGraphicAry, nSize);
1475 rWrt.Strm() << SwRTFWriter::sNewLine;
1477 sal_uInt32 nBreak = 0;
1478 for (sal_uInt32 nI = 0; nI < nSize; ++nI)
1480 ByteString sNo = ByteString::CreateFromInt32(pGraphicAry[nI], 16);
1481 if (sNo.Len() < 2)
1482 rWrt.Strm() << '0';
1483 rWrt.Strm() << sNo.GetBuffer();
1484 if (++nBreak == 64)
1486 rWrt.Strm() << SwRTFWriter::sNewLine;
1487 nBreak = 0;
1491 rWrt.Strm() << '}';
1495 static Writer& OutRTF_SwGrfNode(Writer& rWrt, SwCntntNode & rNode)
1497 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1498 SwGrfNode &rNd = (SwGrfNode&)rNode;
1500 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
1501 // muessen noch die Attribute dafuer ausgegeben werden.
1502 if (rRTFWrt.pFlyFmt && !ExportAsInline(*rRTFWrt.pFlyFmt))
1503 OutRTF_SwFlyFrmFmt(rRTFWrt); //"classic" positioning and size export
1505 #if 1
1506 SvMemoryStream aStream;
1507 const sal_uInt8* pGraphicAry = 0;
1508 sal_uInt32 nSize = 0;
1510 Graphic aGraphic(rNd.GetGrf());
1512 // If there is no graphic there is not much point in parsing it
1513 if(aGraphic.GetType()==GRAPHIC_NONE)
1514 return rRTFWrt;
1516 GfxLink aGraphicLink;
1517 const sal_Char* pBLIPType = 0;
1518 if (aGraphic.IsLink())
1520 aGraphicLink = aGraphic.GetLink();
1521 nSize = aGraphicLink.GetDataSize();
1522 pGraphicAry = aGraphicLink.GetData();
1523 switch (aGraphicLink.GetType())
1525 case GFX_LINK_TYPE_NATIVE_JPG:
1526 pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
1527 break;
1528 case GFX_LINK_TYPE_NATIVE_PNG:
1529 pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
1530 case GFX_LINK_TYPE_NATIVE_WMF:
1531 pBLIPType =
1532 IsEMF(pGraphicAry, nSize) ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1533 break;
1534 default:
1535 break;
1539 GraphicType eGraphicType = aGraphic.GetType();
1540 if (!pGraphicAry)
1542 if (ERRCODE_NONE == GraphicConverter::Export(aStream, aGraphic,
1543 (eGraphicType == GRAPHIC_BITMAP) ? CVT_PNG : CVT_WMF))
1545 pBLIPType = (eGraphicType == GRAPHIC_BITMAP) ?
1546 OOO_STRING_SVTOOLS_RTF_PNGBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1547 aStream.Seek(STREAM_SEEK_TO_END);
1548 nSize = aStream.Tell();
1549 pGraphicAry = (sal_uInt8*)aStream.GetData();
1553 Size aMapped(eGraphicType == GRAPHIC_BITMAP ? aGraphic.GetSizePixel() : aGraphic.GetPrefSize());
1555 const SwCropGrf &rCr = (const SwCropGrf &)rNd.GetAttr(RES_GRFATR_CROPGRF);
1557 //Get original size in twips
1558 Size aSize(sw::util::GetSwappedInSize(rNd));
1559 Size aRendered(aSize);
1560 if (rRTFWrt.pFlyFmt)
1562 const SwFmtFrmSize& rS = rRTFWrt.pFlyFmt->GetFrmSize();
1563 aRendered.Width() = rS.GetWidth();
1564 aRendered.Height() = rS.GetHeight();
1568 If the graphic is not of type WMF then we will have to store two
1569 graphics, one in the native format wrapped in shppict, and the other in
1570 the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
1571 a wmf already then we don't need any such wrapping
1573 bool bIsWMF = (const sal_Char*)pBLIPType == (const sal_Char*)OOO_STRING_SVTOOLS_RTF_WMETAFILE ? true : false;
1574 if (!bIsWMF)
1575 OutComment(rRTFWrt, OOO_STRING_SVTOOLS_RTF_SHPPICT);
1577 if (pBLIPType)
1578 ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, rRTFWrt);
1579 else
1581 aStream.Seek(0);
1582 GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
1583 pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1584 aStream.Seek(STREAM_SEEK_TO_END);
1585 nSize = aStream.Tell();
1586 pGraphicAry = (sal_uInt8*)aStream.GetData();
1588 ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
1589 rRTFWrt);
1592 if (!bIsWMF)
1594 rRTFWrt.Strm() << '}' << '{' << OOO_STRING_SVTOOLS_RTF_NONSHPPICT;
1596 aStream.Seek(0);
1597 GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
1598 pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1599 aStream.Seek(STREAM_SEEK_TO_END);
1600 nSize = aStream.Tell();
1601 pGraphicAry = (sal_uInt8*)aStream.GetData();
1603 ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
1604 rRTFWrt);
1606 rRTFWrt.Strm() << '}';
1610 rRTFWrt.Strm() << SwRTFWriter::sNewLine;
1611 #else
1612 rRTFWrt.Strm() << "{{";
1614 // damit die eigenen Grafik-Attribute nach der PICT / import Anweisung
1615 // stehen, muessen die am Anfang ausgegeben werden.
1616 rRTFWrt.bOutFmtAttr = false;
1617 OutRTF_SwFmt( rRTFWrt, *pNd->GetFmtColl() );
1619 if( rRTFWrt.bOutFmtAttr ) // wurde ueberhaupt ein Attrribut
1620 rRTFWrt.Strm() << "}{"; // ausgegeben ??
1622 String aGrfNm;
1623 const SwMirrorGrf& rMirror = pNd->GetSwAttrSet().GetMirrorGrf();
1624 if( !pNd->IsLinkedFile() || RES_MIRROR_GRAPH_DONT != rMirror.GetValue() )
1626 USHORT nErr = 1;
1627 // Grafik als File-Referenz speichern (als JPEG-Grafik speichern)
1628 // but only if we save into a file and have a URL
1629 if( rWrt.GetOrigFileName() )
1631 aGrfNm = *rWrt.GetOrigFileName();
1632 pNd->SwapIn( TRUE );
1633 ULONG nFlags = XOUTBMP_USE_NATIVE_IF_POSSIBLE;
1634 switch( rMirror.GetValue() )
1636 case RES_MIRROR_GRAPH_VERT: nFlags = XOUTBMP_MIRROR_HORZ; break;
1637 case RES_MIRROR_GRAPH_HOR: nFlags = XOUTBMP_MIRROR_VERT; break;
1638 case RES_MIRROR_GRAPH_BOTH:
1639 nFlags = XOUTBMP_MIRROR_VERT | XOUTBMP_MIRROR_HORZ;
1640 break;
1643 Size aMM100Size;
1644 Size* pMM100Size = 0;
1645 if( rRTFWrt.pFlyFmt )
1647 const SwFmtFrmSize& rSize = rRTFWrt.pFlyFmt->GetFrmSize();
1648 aMM100Size = OutputDevice::LogicToLogic( rSize.GetSize(),
1649 MapMode( MAP_TWIP ), MapMode( MAP_100TH_MM ));
1650 pMM100Size = &aMM100Size;
1653 nErr = XOutBitmap::WriteGraphic( pNd->GetGrf(), aGrfNm,
1654 String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "JPG" )),
1655 nFlags, pMM100Size );
1657 if( nErr ) // fehlerhaft, da ist nichts auszugeben
1659 rRTFWrt.Strm() << "}}";
1660 return rWrt;
1663 else
1664 pNd->GetFileFilterNms( &aGrfNm, 0 );
1666 // MIB->JP: Warum erst AbsToRel und dann das URL-Objekt? So
1667 // kommt bei relativierbaren URLs als Protokoll "unknown" raus.
1668 // Ist das Absicht?
1669 aGrfNm = INetURLObject::AbsToRel( aGrfNm, INetURLObject::WAS_ENCODED,
1670 INetURLObject::DECODE_UNAMBIGUOUS);
1671 INetURLObject aUrl( aGrfNm );
1672 if( aUrl.GetProtocol() == INET_PROT_FILE )
1673 aGrfNm = aUrl.PathToFileName();
1675 // Bitmap als File-Referenz speichern
1676 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FIELD << OOO_STRING_SVTOOLS_RTF_FLDPRIV;
1677 OutComment( rRTFWrt, OOO_STRING_SVTOOLS_RTF_FLDINST ) << "{\\\\import ";
1678 RTFOutFuncs::Out_String( rWrt.Strm(), aGrfNm, rRTFWrt.eDefaultEncoding,
1679 rRTFWrt.bWriteHelpFmt );
1680 rRTFWrt.Strm() << "}}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << " }}";
1681 rRTFWrt.Strm() << '}' << SwRTFWriter::sNewLine;
1682 #endif
1683 return rRTFWrt;
1686 static Writer& OutRTF_SwOLENode( Writer& rWrt, SwCntntNode & /*rNode*/ )
1688 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1690 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
1691 // muessen noch die Attribute dafuer ausgegeben werden.
1692 if( rRTFWrt.pFlyFmt )
1693 OutRTF_SwFlyFrmFmt( rRTFWrt );
1695 rWrt.Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PAR;
1696 return rWrt;
1699 static void OutTBLBorderLine(SwRTFWriter& rWrt, const SvxBorderLine* pLine,
1700 const sal_Char* pStr)
1702 ByteString sLineStr;
1703 if( pLine->GetInWidth() )
1705 // doppelte Linie
1706 sLineStr = OOO_STRING_SVTOOLS_RTF_BRDRDB;
1707 switch( pLine->GetInWidth() )
1709 case DEF_LINE_WIDTH_0:
1710 ( sLineStr += OOO_STRING_SVTOOLS_RTF_BRDRW ) += "15";
1711 break;
1712 case DEF_LINE_WIDTH_1:
1713 ( sLineStr += OOO_STRING_SVTOOLS_RTF_BRDRW ) += "30";
1714 break;
1715 case DEF_LINE_WIDTH_2:
1716 case DEF_LINE_WIDTH_3:
1717 ( sLineStr += OOO_STRING_SVTOOLS_RTF_BRDRW ) += "45";
1718 break;
1721 else
1723 // einfache Linie
1724 if( DEF_LINE_WIDTH_1 >= pLine->GetOutWidth() )
1725 (( sLineStr = OOO_STRING_SVTOOLS_RTF_BRDRS ) += OOO_STRING_SVTOOLS_RTF_BRDRW ) +=
1726 ByteString::CreateFromInt32( pLine->GetOutWidth() );
1727 else
1728 (( sLineStr = OOO_STRING_SVTOOLS_RTF_BRDRTH ) += OOO_STRING_SVTOOLS_RTF_BRDRW ) +=
1729 ByteString::CreateFromInt32( pLine->GetOutWidth() / 2 );
1732 rWrt.Strm() << pStr << sLineStr.GetBuffer() << OOO_STRING_SVTOOLS_RTF_BRDRCF;
1733 rWrt.OutULong( rWrt.GetId( pLine->GetColor() ) );
1736 static void OutBorderLine(SwRTFWriter& rWrt, const SvxBorderLine* pLine,
1737 const sal_Char* pStr, USHORT nDist)
1739 OutTBLBorderLine(rWrt, pLine, pStr);
1740 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_BRSP;
1741 rWrt.OutULong( nDist );
1744 static void OutSwTblBorder(SwRTFWriter& rWrt, const SvxBoxItem& rBox,
1745 const SvxBoxItem *pDefault)
1747 static const USHORT aBorders[] =
1749 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1751 #ifdef __MINGW32__
1752 static const char* aBorderNames[] __attribute__((section(".data"))) =
1753 #else
1754 static const char* aBorderNames[] =
1755 #endif
1757 OOO_STRING_SVTOOLS_RTF_CLBRDRT, OOO_STRING_SVTOOLS_RTF_CLBRDRL, OOO_STRING_SVTOOLS_RTF_CLBRDRB, OOO_STRING_SVTOOLS_RTF_CLBRDRR
1759 //Yes left and top are swapped with eachother for cell padding! Because
1760 //that's what the thunderingly annoying rtf export/import word xp does.
1761 #ifdef __MINGW32__
1762 static const char* aCellPadNames[] __attribute__((section(".data"))) =
1763 #else
1764 static const char* aCellPadNames[] =
1765 #endif
1767 OOO_STRING_SVTOOLS_RTF_CLPADL, OOO_STRING_SVTOOLS_RTF_CLPADT, OOO_STRING_SVTOOLS_RTF_CLPADB, OOO_STRING_SVTOOLS_RTF_CLPADR
1769 #ifdef __MINGW32__
1770 static const char* aCellPadUnits[] __attribute__((section(".data"))) =
1771 #else
1772 static const char* aCellPadUnits[] =
1773 #endif
1775 OOO_STRING_SVTOOLS_RTF_CLPADFL, OOO_STRING_SVTOOLS_RTF_CLPADFT, OOO_STRING_SVTOOLS_RTF_CLPADFB, OOO_STRING_SVTOOLS_RTF_CLPADFR
1777 for (int i = 0; i < 4; ++i)
1779 if (const SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
1780 OutTBLBorderLine(rWrt, pLn, aBorderNames[i]);
1781 if (!pDefault || pDefault->GetDistance(aBorders[i]) !=
1782 rBox.GetDistance(aBorders[i]))
1784 rWrt.Strm() << aCellPadUnits[i];
1785 rWrt.OutULong(3);
1786 rWrt.Strm() << aCellPadNames[i];
1787 rWrt.OutULong(rBox.GetDistance(aBorders[i]));
1792 static void OutSwTblBackground( SwRTFWriter& rWrt, const SvxBrushItem& rBack )
1794 if( !rBack.GetColor().GetTransparency() )
1796 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLCBPAT;
1797 rWrt.OutULong( rWrt.GetId( rBack.GetColor() ) );
1802 Writer& OutRTF_SwTblNode(Writer& rWrt, const SwTableNode & rNode)
1804 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1805 const SwTable& rTbl = rNode.GetTable();
1806 SwTwips nPageSize = 0, nTblOffset = 0;
1807 const bool bNewTableModel = rTbl.IsNewModel();
1810 //!!!!!!!!!!!!! for clipboard create any view if the table is complex !!!
1811 if( rTbl.IsTblComplex() )
1813 // then we have to create any layout
1814 SFX_APP()->CreateViewFrame( *xDocSh, 0, TRUE );
1818 const SwFrmFmt *pFmt = rTbl.GetFrmFmt();
1819 ASSERT(pFmt, "Impossible");
1821 Point aPt;
1822 SwRect aRect( pFmt->FindLayoutRect( false, &aPt ));
1823 if( aRect.IsEmpty() )
1825 // dann besorge mal die Seitenbreite ohne Raender !!
1826 const SwFrmFmt* pFrmFmt = rRTFWrt.pFlyFmt ? rRTFWrt.pFlyFmt :
1827 const_cast<const SwDoc *>(rWrt.pDoc)
1828 ->GetPageDesc(0).GetPageFmtOfNode(rNode, false);
1830 aRect = pFrmFmt->FindLayoutRect( TRUE );
1831 if( 0 == ( nPageSize = aRect.Width() ))
1833 const SvxLRSpaceItem& rLR = pFrmFmt->GetLRSpace();
1834 nPageSize = pFrmFmt->GetFrmSize().GetWidth() -
1835 rLR.GetLeft() - rLR.GetRight();
1838 else
1839 nPageSize = aRect.Width();
1842 SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
1844 ByteString aTblAdjust( OOO_STRING_SVTOOLS_RTF_TRQL );
1845 switch (pFmt->GetHoriOrient().GetHoriOrient())
1847 case text::HoriOrientation::CENTER:
1848 aTblAdjust = OOO_STRING_SVTOOLS_RTF_TRQC;
1849 break;
1850 case text::HoriOrientation::RIGHT:
1851 aTblAdjust = OOO_STRING_SVTOOLS_RTF_TRQR;
1852 break;
1853 case text::HoriOrientation::NONE:
1854 case text::HoriOrientation::LEFT_AND_WIDTH:
1856 const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace();
1857 nTblOffset = rLRSp.GetLeft();
1858 nPageSize -= (nTblOffset + rLRSp.GetRight());
1859 aTblAdjust += OOO_STRING_SVTOOLS_RTF_TRLEFT;
1860 aTblAdjust += ByteString::CreateFromInt32( nTblOffset );
1862 break;
1863 default:
1864 break;
1867 if (rRTFWrt.TrueFrameDirection(*pFmt) == FRMDIR_HORI_RIGHT_TOP)
1868 aTblAdjust += OOO_STRING_SVTOOLS_RTF_RTLROW;
1870 // ist die Tabelle wesentlich (PageSize + 10%) groesser als die Seite,
1871 // dann sind die Box-Breiten relative Angaben.
1872 BOOL bRelBoxSize = TRUE /*ALWAYS relativ (nPageSize + ( nPageSize / 10 )) < nTblSz*/;
1874 SwWriteTable* pTableWrt;
1875 const SwHTMLTableLayout *pLayout = rTbl.GetHTMLTableLayout();
1876 if( pLayout && pLayout->IsExportable() )
1877 pTableWrt = new SwWriteTable( pLayout );
1878 else
1879 pTableWrt = new SwWriteTable(rTbl.GetTabLines(), (USHORT)nPageSize,
1880 (USHORT)nTblSz, false);
1882 // rCols are the array of all cols of the table
1883 const SwWriteTableCols& rCols = pTableWrt->GetCols();
1884 USHORT nColCnt = rCols.Count();
1885 SwWriteTableCellPtr* pBoxArr = new SwWriteTableCellPtr[ nColCnt ];
1886 USHORT* pRowSpans = new USHORT[ nColCnt ];
1887 memset( pBoxArr, 0, sizeof( pBoxArr[0] ) * nColCnt );
1888 memset( pRowSpans, 0, sizeof( pRowSpans[0] ) * nColCnt );
1889 const SwWriteTableRows& rRows = pTableWrt->GetRows();
1890 for( USHORT nLine = 0; nLine < rRows.Count(); ++nLine )
1892 USHORT nBox;
1894 const SwWriteTableRow *pRow = rRows[ nLine ];
1895 const SwWriteTableCells& rCells = pRow->GetCells();
1897 BOOL bFixRowHeight = false;
1899 USHORT nBoxes = rCells.Count();
1900 if (nColCnt < nBoxes)
1901 nBoxes = nColCnt;
1903 for( nColCnt = 0, nBox = 0; nBox < rCells.Count() && nColCnt < nBoxes; ++nColCnt )
1905 SwWriteTableCell* pCell = rCells[ nBox ];
1906 const bool bProcessCoveredCell = bNewTableModel && 0 == pCell->GetRowSpan();
1908 if( !pRowSpans[ nColCnt ] || bProcessCoveredCell )
1910 // set new BoxPtr
1911 nBox++;
1912 pBoxArr[ nColCnt ] = pCell;
1913 if ( !bProcessCoveredCell )
1914 pRowSpans[ nColCnt ] = pCell->GetRowSpan();
1915 for( USHORT nCellSpan = pCell->GetColSpan(), nCS = 1;
1916 nCS < nCellSpan; ++nCS, ++nColCnt )
1918 ASSERT( nColCnt+1 < rCols.Count(), "More colspan than columns" );
1919 if( nColCnt+1 < rCols.Count() ) // robust against wrong colspans
1921 pBoxArr[ nColCnt+1 ] = pBoxArr[ nColCnt ];
1922 pRowSpans[ nColCnt+1 ] = pRowSpans[ nColCnt ];
1926 if( 1 != pRowSpans[ nColCnt ] && !bNewTableModel )
1927 bFixRowHeight = TRUE;
1930 for( ; nColCnt < rCols.Count() && pRowSpans[ nColCnt ]; ++nColCnt )
1931 bFixRowHeight = TRUE;
1933 nColCnt = rCols.Count(); // A wrong cellspan-value could cause a nColCnt > rCols.Count()
1935 // Start Tabellendefinition
1936 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TROWD << aTblAdjust.GetBuffer();
1938 if( rTbl.GetRowsToRepeat() > nLine )
1939 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TRHDR;
1941 const SwTableLine* pLine = pBoxArr[ 0 ]->GetBox()->GetUpper();
1942 // Zeilenhoehe ausgeben
1943 long nHeight = 0;
1944 if( bFixRowHeight && rWrt.pDoc->GetRootFrm() )
1946 nHeight = -pRow->GetPos(); //neg. => abs. height!
1947 if( nLine )
1948 nHeight += rRows[ nLine - 1 ]->GetPos();
1950 else
1952 const SwFmtFrmSize& rLSz = pLine->GetFrmFmt()->GetFrmSize();
1953 if( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
1954 nHeight = ATT_MIN_SIZE == rLSz.GetHeightSizeType()
1955 ? rLSz.GetHeight()
1956 : -rLSz.GetHeight();
1959 //The rtf default is to allow a row to break, so if we are not
1960 //splittable export TRKEEP
1961 const SwFrmFmt *pLineFmt = pLine ? pLine->GetFrmFmt() : 0;
1962 if (!pLineFmt || pLineFmt->GetRowSplit().GetValue() == 0)
1963 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TRKEEP;
1965 if( nHeight )
1967 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TRRH;
1968 rWrt.OutLong( nHeight );
1971 const SvxBoxItem *pDefaultBox = 0;
1972 if (nColCnt)
1974 pDefaultBox = &(pBoxArr[0]->GetBox()->GetFrmFmt()->GetBox());
1976 static const USHORT aBorders[] =
1978 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1980 #ifdef __MINGW32__
1981 static const char* aRowPadNames[] __attribute__((section(".data"))) =
1982 #else
1983 static const char* aRowPadNames[] =
1984 #endif
1986 OOO_STRING_SVTOOLS_RTF_TRPADDT, OOO_STRING_SVTOOLS_RTF_TRPADDL, OOO_STRING_SVTOOLS_RTF_TRPADDB, OOO_STRING_SVTOOLS_RTF_TRPADDR
1988 static const char* aRowPadUnits[] =
1990 OOO_STRING_SVTOOLS_RTF_TRPADDFT, OOO_STRING_SVTOOLS_RTF_TRPADDFL, OOO_STRING_SVTOOLS_RTF_TRPADDFB, OOO_STRING_SVTOOLS_RTF_TRPADDFR
1992 for (int i = 0; i < 4; ++i)
1994 rWrt.Strm() << aRowPadUnits[i];
1995 rWrt.OutULong(3);
1996 rWrt.Strm() << aRowPadNames[i];
1997 rWrt.OutULong(pDefaultBox->GetDistance(aBorders[i]));
2001 // Breite der Boxen ausgeben
2002 SwTwips nSz = 0, nCalc;
2003 for( nBox = 0; nBox < nColCnt; ++nBox )
2005 SwWriteTableCell* pCell = pBoxArr[ nBox ];
2006 if( (nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ]) || (pCell == NULL) )
2007 continue;
2009 const SwFrmFmt& rFmt = *pCell->GetBox()->GetFrmFmt();
2010 if( 1 < pCell->GetRowSpan() || 0 == pCell->GetRowSpan() )
2011 rWrt.Strm() << ( pCell->GetRowSpan() == pRowSpans[ nBox ]
2012 ? OOO_STRING_SVTOOLS_RTF_CLVMGF
2013 : OOO_STRING_SVTOOLS_RTF_CLVMRG );
2015 const SfxPoolItem* pItem;
2016 if (SFX_ITEM_SET == rFmt.GetAttrSet().GetItemState(RES_BOX, TRUE,
2017 &pItem))
2019 OutSwTblBorder(rRTFWrt, (SvxBoxItem&)*pItem, pDefaultBox);
2022 // RTF kennt Schattierung in unserem Sinne nicht!
2023 // if( SFX_ITEM_SET == pBoxFmt->GetAttrSet().GetItemState(
2024 // RES_SHADOW, TRUE, &pItem ) )
2025 // OutSwTblShadow( rRTFWrt, *pItem );
2027 if( SFX_ITEM_SET == rFmt.GetAttrSet().GetItemState(
2028 RES_BACKGROUND, TRUE, &pItem )
2029 || 0 != ( pItem = pCell->GetBackground() )
2030 || 0 != ( pItem = pRow->GetBackground() ) )
2031 OutSwTblBackground( rRTFWrt, (SvxBrushItem&)*pItem );
2033 if( SFX_ITEM_SET == rFmt.GetAttrSet().GetItemState(
2034 RES_VERT_ORIENT, TRUE, &pItem ) )
2035 switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
2037 case text::VertOrientation::CENTER: rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLVERTALC; break;
2038 case text::VertOrientation::BOTTOM: rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLVERTALB; break;
2039 default: rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLVERTALT; break;
2042 const SwFmtFrmSize& rLSz = rFmt.GetFrmSize();
2043 nSz += rLSz.GetWidth();
2044 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CELLX;
2046 nCalc = nSz;
2047 if( bRelBoxSize )
2049 nCalc *= nPageSize;
2050 nCalc /= nTblSz;
2052 rWrt.OutLong( nTblOffset + nCalc );
2055 // Inhalt der Boxen ausgeben
2056 rWrt.Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_INTBL;
2057 for( nBox = 0; nBox < nBoxes; ++nBox )
2059 SwWriteTableCell * pCell = pBoxArr[nBox];
2061 if( (nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ]) || pCell == NULL)
2062 continue;
2064 if( pCell->GetRowSpan() == pRowSpans[ nBox ] )
2066 // new Box
2067 const SwStartNode* pSttNd = pCell->GetBox()->GetSttNd();
2068 RTFSaveData aSaveData( rRTFWrt,
2069 pSttNd->GetIndex()+1, pSttNd->EndOfSectionIndex() );
2070 rRTFWrt.bOutTable = TRUE;
2071 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
2073 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CELL;
2076 // das wars mit der Line
2077 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ROW << OOO_STRING_SVTOOLS_RTF_PARD << ' ';
2079 for( nBox = 0; nBox < nColCnt; ++nBox )
2080 --pRowSpans[ nBox ];
2083 delete pTableWrt;
2084 delete[] pBoxArr;
2085 delete[] pRowSpans;
2087 // Pam hinter die Tabelle verschieben
2088 rRTFWrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();
2089 rRTFWrt.SetAttrSet( 0 );
2091 return rWrt;
2094 Writer& OutRTF_SwSectionNode( Writer& rWrt, SwSectionNode& rNode )
2096 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
2097 const SwSection& rSect = rNode.GetSection();
2099 // folgt dahinter noch ein SectionNode? Dann wird erst die innere
2100 // Section aktiv. Hier wird die Verschachtelung aufgebrochen, weil
2101 // RTF das nicht kennt
2102 BOOL bPgDscWrite = false;
2104 SwNodeIndex aIdx( rNode, 1 );
2105 const SwNode& rNd = aIdx.GetNode();
2106 if( rNd.IsSectionNode() /*&& CONTENT_SECTION ==
2107 aIdx.GetNode().GetSectionNode()->GetSection().GetType()*/ )
2108 return rWrt;
2110 // falls als erstes Position ein Content- oder Tabellen-Node steht,
2111 // dann kann dieser einen PageDesc gesetzt haben und der muss vor
2112 // der Bereichsbeschreibung geschrieben werden!
2113 // Umgekehrt muss im OutBreaks dann
2114 if( rNd.IsCntntNode() )
2116 bPgDscWrite = rRTFWrt.OutBreaks( ((SwCntntNode&)rNd).GetSwAttrSet() );
2117 rRTFWrt.bIgnoreNextPgBreak = TRUE;
2119 else if( rNd.IsTableNode() )
2121 bPgDscWrite = rRTFWrt.OutBreaks( ((SwTableNode&)rNd).GetTable().
2122 GetFrmFmt()->GetAttrSet() );
2123 rRTFWrt.bIgnoreNextPgBreak = TRUE;
2128 // if( CONTENT_SECTION == rSect.GetType() )
2130 // als fortlaufenden Abschnittwechsel heraus schreiben
2131 if( !bPgDscWrite )
2132 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SECT << OOO_STRING_SVTOOLS_RTF_SBKNONE;
2133 //JP 19.03.99 - es muss fuer den Import auf jedenfall das Cols
2134 // Token geschrieben werden. Sonst kann nicht erkannt
2135 // werden, wann ein PageDesc & eine Section gueltig ist
2136 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLS << '1';
2137 rRTFWrt.bOutFmtAttr = TRUE;
2138 const SfxPoolItem* pItem;
2139 const SwFrmFmt *pFmt = rSect.GetFmt();
2140 ASSERT(pFmt, "Impossible");
2141 const SfxItemSet& rSet = pFmt->GetAttrSet();
2142 if( SFX_ITEM_SET == rSet.GetItemState( RES_COL, false, &pItem ))
2143 OutRTF_SwFmtCol( rWrt, *pItem );
2144 else
2146 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLS << '1' << OOO_STRING_SVTOOLS_RTF_COLSX;
2147 rWrt.OutULong(709);
2150 if( SFX_ITEM_SET == rSet.GetItemState( RES_COLUMNBALANCE,
2151 false, &pItem ) && ((SwFmtNoBalancedColumns*)pItem)->GetValue() )
2152 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_BALANCEDCOLUMN ) << '}';
2154 if (FRMDIR_HORI_RIGHT_TOP == rRTFWrt.TrueFrameDirection(*pFmt))
2155 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLSECT;
2156 else
2157 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRSECT;
2159 rWrt.Strm() << SwRTFWriter::sNewLine;
2162 return rWrt;
2166 /* File CHRATR.HXX: */
2168 static Writer& OutRTF_SwFont( Writer& rWrt, const SfxPoolItem& rHt )
2170 /* trage den Font in die Font-Liste vom Writer ein und gebe hier nur
2171 * die entsprechende Nummer aus. Der Font wird spaeter ueber diese
2172 * Tabelle im RTF-Dokument referenziert.
2174 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2176 if( !rRTFWrt.bTxtAttr ||
2177 ( rRTFWrt.GetEndPosLst() &&
2178 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2180 rRTFWrt.bOutFmtAttr = true;
2181 const SvxFontItem&rFont = (const SvxFontItem&)rHt;
2182 bool bAssoc = rRTFWrt.IsAssociatedFlag();
2184 #109522#
2185 Word is a bit of a silly bugger of a program when its comes to symbol
2186 font useage. If a symbol font is actually being used, i.e. exported
2187 here with bTxtAttr true then both AF and F must be set to the same
2188 value
2190 if (rRTFWrt.bTxtAttr && (rFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL))
2192 const sal_Char* pCmd = !bAssoc ? OOO_STRING_SVTOOLS_RTF_AF : OOO_STRING_SVTOOLS_RTF_F;
2193 rWrt.Strm() << pCmd;
2195 const sal_Char* pCmd = bAssoc ? OOO_STRING_SVTOOLS_RTF_AF : OOO_STRING_SVTOOLS_RTF_F;
2196 rWrt.Strm() << pCmd;
2197 rWrt.OutULong(rRTFWrt.GetId(rFont));
2198 rRTFWrt.eCurrentEncoding = rtl_getTextEncodingFromWindowsCharset(sw::ms::rtl_TextEncodingToWinCharset(rFont.GetCharSet()));
2200 return rWrt;
2203 static Writer& OutRTF_SwPosture( Writer& rWrt, const SfxPoolItem& rHt )
2205 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2207 if( !rRTFWrt.bTxtAttr ||
2208 ( rRTFWrt.GetEndPosLst() &&
2209 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2211 if (rRTFWrt.IsAssociatedFlag() && rHt.Which() == RES_CHRATR_CJK_POSTURE)
2214 #i21422#
2215 Sadly in word rtf we can't retain CJK italic when we are not
2216 exporting asian text as it doesn't have a seperate italic for
2217 western and asian.
2219 return rWrt;
2222 const FontItalic nPosture = ((const SvxPostureItem&)rHt).GetPosture();
2223 int bTxtOut = rRTFWrt.bTxtAttr && ITALIC_NONE == nPosture;
2224 if( ITALIC_NORMAL == nPosture || bTxtOut )
2226 rRTFWrt.bOutFmtAttr = TRUE;
2227 const sal_Char* pCmd = rRTFWrt.IsAssociatedFlag() ? OOO_STRING_SVTOOLS_RTF_AI : OOO_STRING_SVTOOLS_RTF_I;
2228 rWrt.Strm() << pCmd;
2230 if( bTxtOut )
2231 rWrt.Strm() << '0'; // wieder abschalten
2233 return rWrt;
2237 static Writer& OutRTF_SwWeight( Writer& rWrt, const SfxPoolItem& rHt )
2239 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2240 if( !rRTFWrt.bTxtAttr ||
2241 ( rRTFWrt.GetEndPosLst() &&
2242 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2244 if (rRTFWrt.IsAssociatedFlag() && rHt.Which() == RES_CHRATR_CJK_WEIGHT)
2247 #i21422#
2248 Sadly in word rtf we can't retain CJK bold when we are not
2249 exporting asian text as it doesn't have a seperate bold for western
2250 and asian.
2252 return rWrt;
2255 const FontWeight nBold = ((const SvxWeightItem&)rHt).GetWeight();
2256 int bTxtOut = rRTFWrt.bTxtAttr && WEIGHT_NORMAL == nBold;
2257 if( WEIGHT_BOLD == nBold || bTxtOut )
2259 rRTFWrt.bOutFmtAttr = TRUE;
2260 const sal_Char* pCmd = rRTFWrt.IsAssociatedFlag() ? OOO_STRING_SVTOOLS_RTF_AB : OOO_STRING_SVTOOLS_RTF_B;
2261 rWrt.Strm() << pCmd;
2263 if( bTxtOut )
2264 rWrt.Strm() << '0';
2266 return rWrt;
2269 static Writer& OutRTF_SwEmphasisMark( Writer& rWrt, const SfxPoolItem& rHt )
2271 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2272 const sal_Char* pStr;
2273 switch( ((const SvxEmphasisMarkItem&)rHt).GetEmphasisMark())
2275 case EMPHASISMARK_NONE: pStr = OOO_STRING_SVTOOLS_RTF_ACCNONE; break;
2276 case EMPHASISMARK_SIDE_DOTS: pStr = OOO_STRING_SVTOOLS_RTF_ACCCOMMA; break;
2277 default: pStr = OOO_STRING_SVTOOLS_RTF_ACCDOT; break;
2280 rRTFWrt.bOutFmtAttr = TRUE;
2281 rWrt.Strm() << pStr;
2282 return rWrt;
2285 static Writer& OutRTF_SwTwoInOne( Writer& rWrt, const SfxPoolItem& rHt )
2287 if( ((SvxTwoLinesItem&)rHt).GetValue() )
2289 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2291 sal_Unicode cStart = ((SvxTwoLinesItem&)rHt).GetStartBracket();
2292 sal_Unicode cEnd = ((SvxTwoLinesItem&)rHt).GetStartBracket();
2294 USHORT nType;
2295 if( !cStart && !cEnd )
2296 nType = 0;
2297 else if( '{' == cStart || '}' == cEnd )
2298 nType = 4;
2299 else if( '<' == cStart || '>' == cEnd )
2300 nType = 3;
2301 else if( '[' == cStart || ']' == cEnd )
2302 nType = 2;
2303 else // all other kind of brackets
2304 nType = 1;
2306 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TWOINONE;
2307 rWrt.OutULong( nType );
2308 rRTFWrt.bOutFmtAttr = TRUE;
2310 return rWrt;
2313 static Writer& OutRTF_SwCharRotate( Writer& rWrt, const SfxPoolItem& rHt )
2315 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2316 rRTFWrt.bOutFmtAttr = TRUE;
2317 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_HORZVERT;
2318 rWrt.OutLong( ((SvxCharRotateItem&)rHt).IsFitToLine() ? 1 : 0 );
2319 return rWrt;
2321 static Writer& OutRTF_SwCharScaleW( Writer& rWrt, const SfxPoolItem& rHt )
2323 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2324 rRTFWrt.bOutFmtAttr = TRUE;
2325 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CHARSCALEX;
2326 rWrt.OutLong( ((SvxCharScaleWidthItem&)rHt).GetValue() );
2327 return rWrt;
2330 static Writer& OutRTF_SwCharRelief(Writer& rWrt, const SfxPoolItem& rHt)
2332 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2333 const SvxCharReliefItem& rAttr = (const SvxCharReliefItem&)rHt;
2334 const sal_Char* pStr;
2335 switch (rAttr.GetValue())
2337 case RELIEF_EMBOSSED:
2338 pStr = OOO_STRING_SVTOOLS_RTF_EMBO;
2339 break;
2340 case RELIEF_ENGRAVED:
2341 pStr = OOO_STRING_SVTOOLS_RTF_IMPR;
2342 break;
2343 default:
2344 pStr = 0;
2345 break;
2348 if (pStr)
2350 rRTFWrt.bOutFmtAttr = TRUE;
2351 rWrt.Strm() << pStr;
2353 return rWrt;
2357 static Writer& OutRTF_SwChrBckgrnd( Writer& rWrt, const SfxPoolItem& rHt )
2359 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2360 const SvxBrushItem& rBack = (const SvxBrushItem&)rHt;
2361 if( !rBack.GetColor().GetTransparency() )
2363 ByteString sOut( OOO_STRING_SVTOOLS_RTF_CHCBPAT );
2364 sOut += ByteString::CreateFromInt32(
2365 rRTFWrt.GetId( rBack.GetColor() ));
2367 rRTFWrt.bOutFmtAttr = TRUE;
2368 rWrt.Strm() << sOut.GetBuffer();
2370 return rWrt;
2373 static Writer& OutRTF_SwShadowed( Writer& rWrt, const SfxPoolItem& rHt )
2375 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2376 const BOOL bShadow = ((const SvxShadowedItem&)rHt).GetValue();
2377 int bTxtOut = rRTFWrt.bTxtAttr && !bShadow;
2378 if( bShadow || bTxtOut )
2380 rRTFWrt.bOutFmtAttr = TRUE;
2381 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SHAD;
2383 if( bTxtOut )
2384 rWrt.Strm() << '0';
2385 return rWrt;
2390 static Writer& OutRTF_SwContour( Writer& rWrt, const SfxPoolItem& rHt )
2392 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2393 const BOOL bContour = ((const SvxContourItem&)rHt).GetValue();
2394 int bTxtOut = rRTFWrt.bTxtAttr && !bContour;
2395 if( bContour || bTxtOut )
2397 rRTFWrt.bOutFmtAttr = TRUE;
2398 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_OUTL;
2400 if( bTxtOut )
2401 rWrt.Strm() << '0';
2402 return rWrt;
2405 static Writer& OutRTF_SwCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
2407 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2408 const FontStrikeout nStrike = ((const SvxCrossedOutItem&)rHt).GetStrikeout();
2409 int bTxtOut = rRTFWrt.bTxtAttr && STRIKEOUT_NONE == nStrike;
2411 if( (STRIKEOUT_NONE != nStrike && STRIKEOUT_DONTKNOW != nStrike) || bTxtOut )
2413 rRTFWrt.bOutFmtAttr = TRUE;
2414 if( STRIKEOUT_DOUBLE == nStrike )
2416 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_STRIKED;
2417 if( !bTxtOut )
2418 rWrt.Strm() << '1';
2420 else
2421 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_STRIKE;
2423 if( bTxtOut )
2424 rWrt.Strm() << '0';
2425 return rWrt;
2430 static Writer& OutRTF_SwCaseMap( Writer& rWrt, const SfxPoolItem& rHt )
2432 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2433 switch( ((const SvxCaseMapItem&)rHt).GetValue() )
2435 case SVX_CASEMAP_KAPITAELCHEN:
2436 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SCAPS;
2437 break;
2439 case SVX_CASEMAP_VERSALIEN:
2440 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CAPS;
2441 break;
2443 case SVX_CASEMAP_NOT_MAPPED:
2444 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CAPS << '0' << OOO_STRING_SVTOOLS_RTF_SCAPS << '0'; // beide aus !!
2445 break;
2447 default:
2448 return rWrt;
2451 rRTFWrt.bOutFmtAttr = TRUE;
2452 return rWrt;
2456 static Writer& OutRTF_SwUnderline( Writer& rWrt, const SfxPoolItem& rHt )
2458 const char* pStr = 0;
2459 switch( ((const SvxUnderlineItem&)rHt).GetLineStyle() )
2461 case UNDERLINE_SINGLE:
2462 pStr = OOO_STRING_SVTOOLS_RTF_UL;
2463 break;
2464 case UNDERLINE_DOUBLE:
2465 pStr = OOO_STRING_SVTOOLS_RTF_ULDB;
2466 break;
2467 case UNDERLINE_NONE:
2468 pStr = OOO_STRING_SVTOOLS_RTF_ULNONE;
2469 break;
2470 case UNDERLINE_DOTTED:
2471 pStr = OOO_STRING_SVTOOLS_RTF_ULD;
2472 break;
2473 case UNDERLINE_DASH:
2474 pStr = OOO_STRING_SVTOOLS_RTF_ULDASH;
2475 break;
2476 case UNDERLINE_DASHDOT:
2477 pStr = OOO_STRING_SVTOOLS_RTF_ULDASHD;
2478 break;
2479 case UNDERLINE_DASHDOTDOT:
2480 pStr = OOO_STRING_SVTOOLS_RTF_ULDASHDD;
2481 break;
2482 case UNDERLINE_BOLD:
2483 pStr = OOO_STRING_SVTOOLS_RTF_ULTH;
2484 break;
2485 case UNDERLINE_WAVE:
2486 pStr = OOO_STRING_SVTOOLS_RTF_ULWAVE;
2487 break;
2488 case UNDERLINE_BOLDDOTTED:
2489 pStr = OOO_STRING_SVTOOLS_RTF_ULTHD;
2490 break;
2491 case UNDERLINE_BOLDDASH:
2492 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASH;
2493 break;
2494 case UNDERLINE_LONGDASH:
2495 pStr = OOO_STRING_SVTOOLS_RTF_ULLDASH;
2496 break;
2497 case UNDERLINE_BOLDLONGDASH:
2498 pStr = OOO_STRING_SVTOOLS_RTF_ULTHLDASH;
2499 break;
2500 case UNDERLINE_BOLDDASHDOT:
2501 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHD;
2502 break;
2503 case UNDERLINE_BOLDDASHDOTDOT:
2504 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHDD;
2505 break;
2506 case UNDERLINE_BOLDWAVE:
2507 pStr = OOO_STRING_SVTOOLS_RTF_ULHWAVE;
2508 break;
2509 case UNDERLINE_DOUBLEWAVE:
2510 pStr = OOO_STRING_SVTOOLS_RTF_ULULDBWAVE;
2511 break;
2512 default:
2513 break;
2516 if( pStr )
2518 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2520 if( UNDERLINE_SINGLE == ((const SvxUnderlineItem&)rHt).GetLineStyle()
2521 && ((SvxWordLineModeItem&)rRTFWrt.GetItem(
2522 RES_CHRATR_WORDLINEMODE )).GetValue() )
2523 pStr = OOO_STRING_SVTOOLS_RTF_ULW;
2525 rRTFWrt.Strm() << pStr;
2526 rRTFWrt.bOutFmtAttr = TRUE;
2528 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ULC;
2529 rWrt.OutULong( rRTFWrt.GetId(((const SvxUnderlineItem&)rHt).GetColor()) );
2533 return rWrt;
2538 static Writer& OutRTF_SwOverline( Writer& rWrt, const SfxPoolItem& rHt )
2540 const char* pStr = 0;
2541 switch( ((const SvxOverlineItem&)rHt).GetLineStyle() )
2543 case UNDERLINE_SINGLE:
2544 pStr = OOO_STRING_SVTOOLS_RTF_OL;
2545 break;
2546 case UNDERLINE_DOUBLE:
2547 pStr = OOO_STRING_SVTOOLS_RTF_OLDB;
2548 break;
2549 case UNDERLINE_NONE:
2550 pStr = OOO_STRING_SVTOOLS_RTF_OLNONE;
2551 break;
2552 case UNDERLINE_DOTTED:
2553 pStr = OOO_STRING_SVTOOLS_RTF_OLD;
2554 break;
2555 case UNDERLINE_DASH:
2556 pStr = OOO_STRING_SVTOOLS_RTF_OLDASH;
2557 break;
2558 case UNDERLINE_DASHDOT:
2559 pStr = OOO_STRING_SVTOOLS_RTF_OLDASHD;
2560 break;
2561 case UNDERLINE_DASHDOTDOT:
2562 pStr = OOO_STRING_SVTOOLS_RTF_OLDASHDD;
2563 break;
2564 case UNDERLINE_BOLD:
2565 pStr = OOO_STRING_SVTOOLS_RTF_OLTH;
2566 break;
2567 case UNDERLINE_WAVE:
2568 pStr = OOO_STRING_SVTOOLS_RTF_OLWAVE;
2569 break;
2570 case UNDERLINE_BOLDDOTTED:
2571 pStr = OOO_STRING_SVTOOLS_RTF_OLTHD;
2572 break;
2573 case UNDERLINE_BOLDDASH:
2574 pStr = OOO_STRING_SVTOOLS_RTF_OLTHDASH;
2575 break;
2576 case UNDERLINE_LONGDASH:
2577 pStr = OOO_STRING_SVTOOLS_RTF_OLLDASH;
2578 break;
2579 case UNDERLINE_BOLDLONGDASH:
2580 pStr = OOO_STRING_SVTOOLS_RTF_OLTHLDASH;
2581 break;
2582 case UNDERLINE_BOLDDASHDOT:
2583 pStr = OOO_STRING_SVTOOLS_RTF_OLTHDASHD;
2584 break;
2585 case UNDERLINE_BOLDDASHDOTDOT:
2586 pStr = OOO_STRING_SVTOOLS_RTF_OLTHDASHDD;
2587 break;
2588 case UNDERLINE_BOLDWAVE:
2589 pStr = OOO_STRING_SVTOOLS_RTF_OLHWAVE;
2590 break;
2591 case UNDERLINE_DOUBLEWAVE:
2592 pStr = OOO_STRING_SVTOOLS_RTF_OLOLDBWAVE;
2593 break;
2594 default:
2595 break;
2598 if( pStr )
2600 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2601 if ( rRTFWrt.bNonStandard )
2603 if( UNDERLINE_SINGLE == ((const SvxOverlineItem&)rHt).GetLineStyle()
2604 && ((SvxWordLineModeItem&)rRTFWrt.GetItem(
2605 RES_CHRATR_WORDLINEMODE )).GetValue() )
2606 pStr = OOO_STRING_SVTOOLS_RTF_OLW;
2608 rRTFWrt.Strm() << pStr;
2609 rRTFWrt.bOutFmtAttr = TRUE;
2611 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_OLC;
2612 rWrt.OutULong( rRTFWrt.GetId(((const SvxOverlineItem&)rHt).GetColor()) );
2617 return rWrt;
2622 static Writer& OutRTF_SwLanguage( Writer& rWrt, const SfxPoolItem& rHt )
2624 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2625 if( !rRTFWrt.bTxtAttr ||
2626 ( rRTFWrt.GetEndPosLst() &&
2627 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2630 rRTFWrt.bOutFmtAttr = TRUE;
2631 const sal_Char* p = RES_CHRATR_CJK_LANGUAGE == rHt.Which()
2632 ? OOO_STRING_SVTOOLS_RTF_LANGFE : OOO_STRING_SVTOOLS_RTF_LANG;
2633 rWrt.Strm() << p;
2634 rWrt.OutULong( ((const SvxLanguageItem&)rHt).GetLanguage() );
2636 return rWrt;
2641 static Writer& OutRTF_SwEscapement( Writer& rWrt, const SfxPoolItem& rHt )
2643 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2644 const SvxEscapementItem& rEsc = (const SvxEscapementItem&)rHt;
2645 const char * pUpDn;
2647 SwTwips nH = ((SvxFontHeightItem&)rRTFWrt.GetItem(
2648 RES_CHRATR_FONTSIZE )).GetHeight();
2650 if( 0 < rEsc.GetEsc() )
2651 pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
2652 else if( 0 > rEsc.GetEsc() )
2654 pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
2655 nH = -nH; // den negativen Wert herrausrechnen
2657 else
2658 return rWrt;
2660 // prozentuale Veraenderung speichern !
2661 short nEsc = rEsc.GetEsc();
2662 short nProp = rEsc.GetProp() * 100;
2663 if( DFLT_ESC_AUTO_SUPER == nEsc )
2665 nEsc = 100 - rEsc.GetProp();
2666 ++nProp;
2668 else if( DFLT_ESC_AUTO_SUB == nEsc )
2670 nEsc = - 100 + rEsc.GetProp();
2671 ++nProp;
2674 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_UPDNPROP, TRUE );
2675 rWrt.OutULong( nProp ) << '}' << pUpDn;
2678 * berechne aus der akt. FontSize und dem ProzentWert die Verschiebung,
2679 * wobei im RTF File 1/2 Points stehen muessen, waehrend intern
2680 * mit Twips gerechnet wird.
2681 * Formel : (FontSize * 1/20 ) pts x * 2
2682 * ----------------------- = ------------
2683 * 100% Escapement
2686 rWrt.OutULong( ( (long( nEsc ) * nH) + 500L ) / 1000L );
2687 // 500L zum Aufrunden !!
2688 return rWrt;
2693 static Writer& OutRTF_SwSize( Writer& rWrt, const SfxPoolItem& rHt )
2695 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2696 if( !rRTFWrt.bTxtAttr ||
2697 ( rRTFWrt.GetEndPosLst() &&
2698 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2700 if (
2701 rRTFWrt.IsAssociatedFlag() &&
2702 rHt.Which() == RES_CHRATR_CJK_FONTSIZE
2706 #i21422#
2707 Sadly in word rtf we can't retain CJK fontsize when we are not
2708 exporting asian text as it doesn't have a seperate fontsize for
2709 western and asian.
2711 return rWrt;
2714 rRTFWrt.bOutFmtAttr = TRUE;
2716 const sal_Char* pCmd = rRTFWrt.IsAssociatedFlag() ? OOO_STRING_SVTOOLS_RTF_AFS : OOO_STRING_SVTOOLS_RTF_FS;
2717 rWrt.Strm() << pCmd;
2718 rWrt.OutULong( ((const SvxFontHeightItem&)rHt).GetHeight() / 10 );
2720 return rWrt;
2725 static Writer& OutRTF_SwColor( Writer& rWrt, const SfxPoolItem& rHt )
2727 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2728 /* trage die Color in die Color-Liste vom Writer ein und gebe hier nur
2729 * die entsprechende Nummer aus. Die Color wird spaeter ueber diese
2730 * Tabelle im RTF-Dokument referenziert.
2732 rRTFWrt.bOutFmtAttr = TRUE;
2733 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CF;
2734 rWrt.OutULong( rRTFWrt.GetId( ((const SvxColorItem&)rHt).GetValue() ));
2735 return rWrt;
2738 static Writer& OutRTF_SvxCharHiddenItem(Writer& rWrt, const SfxPoolItem& rHt)
2740 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2741 rRTFWrt.bOutFmtAttr = true;
2742 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_V;
2743 if (!((const SvxCharHiddenItem&)rHt).GetValue())
2744 rWrt.OutULong(0);
2745 return rWrt;
2748 extern void sw3io_ConvertToOldField( const SwField* pFld, USHORT& rWhich,
2749 ULONG& rFmt, ULONG nFFVersion );
2751 static Writer& OutRTF_SwField( Writer& rWrt, const SfxPoolItem& rHt )
2753 SwFmtFld & rFld = (SwFmtFld&)rHt;
2754 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2756 const SwField* pFld = rFld.GetFld();
2758 ByteString aFldStt( '{' );
2759 ((((aFldStt += OOO_STRING_SVTOOLS_RTF_FIELD) += '{' ) += OOO_STRING_SVTOOLS_RTF_IGNORE) += OOO_STRING_SVTOOLS_RTF_FLDINST) += ' ';
2760 switch( pFld->GetTyp()->Which() )
2762 case RES_COMBINED_CHARS:
2765 We need a font size to fill in the defaults, if these are overridden
2766 (as they generally are) by character properties then those properties
2767 win.
2769 The fontsize that is used in MS for determing the defaults is always
2770 the CJK fontsize even if the text is not in that language, in OOo the
2771 largest fontsize used in the field is the one we should take, but
2772 whatever we do, word will actually render using the fontsize set for
2773 CJK text. Nevertheless we attempt to guess whether the script is in
2774 asian or western text based up on the first character and use the
2775 font size of that script as our default.
2777 const String& rFldPar1 = pFld->GetPar1();
2778 USHORT nScript;
2779 if( pBreakIt->GetBreakIter().is() )
2780 nScript = pBreakIt->GetBreakIter()->getScriptType( rFldPar1, 0);
2781 else
2782 nScript = i18n::ScriptType::ASIAN;
2784 long nHeight = ((SvxFontHeightItem&)rRTFWrt.GetItem(
2785 GetWhichOfScript(RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
2786 nHeight = (nHeight + 10) / 20; //Font Size in points;
2789 Divide the combined char string into its up and down part. Get the
2790 font size and fill in the defaults as up == half the font size and
2791 down == a fifth the font size
2793 xub_StrLen nAbove = (rFldPar1.Len()+1)/2;
2794 rWrt.Strm() << aFldStt.GetBuffer() << "EQ \\\\o (\\\\s\\\\up ";
2795 rWrt.OutLong( nHeight/2 ) << '(';
2796 RTFOutFuncs::Out_String( rWrt.Strm(), rFldPar1.Copy(0,nAbove),
2797 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2798 rWrt.Strm() << "), \\\\s\\\\do ";
2799 rWrt.OutLong( nHeight/5 ) << '(';
2800 RTFOutFuncs::Out_String( rWrt.Strm(), rFldPar1.Copy( nAbove ),
2801 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt )
2802 << "))";
2804 break;
2806 case RES_DBFLD:
2807 aFldStt += "MERGEFIELD ";
2808 // kein break !!
2809 case RES_USERFLD:
2810 rWrt.Strm() << aFldStt.GetBuffer();
2811 RTFOutFuncs::Out_String( rWrt.Strm(), pFld->GetTyp()->GetName(),
2812 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2813 break;
2814 case RES_GETREFFLD:
2816 BYTE nFldTyp = 0;
2817 rWrt.Strm() << aFldStt.GetBuffer() << " REF ";
2818 const SwGetRefField& rRFld = *(SwGetRefField*)pFld;
2819 switch( pFld->GetSubType() )
2821 case REF_SETREFATTR:
2822 case REF_BOOKMARK:
2823 RTFOutFuncs::Out_String( rWrt.Strm(), rRFld.GetSetRefName(),
2824 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2825 nFldTyp = 3;
2826 break;
2829 if( nFldTyp )
2831 switch( pFld->GetFormat() )
2833 case REF_PAGE_PGDESC:
2834 case REF_PAGE:
2835 rWrt.Strm() << "SEITEN";
2836 nFldTyp = 37;
2837 break;
2838 case REF_UPDOWN:
2839 rWrt.Strm() << " \\p";
2840 nFldTyp = 3;
2841 break;
2842 case REF_CHAPTER:
2843 rWrt.Strm() << " \\n";
2844 break;
2845 case REF_ONLYNUMBER:
2846 case REF_ONLYCAPTION:
2847 case REF_ONLYSEQNO:
2848 break;
2849 // default:
2850 // case REF_CONTENT:
2852 rWrt.Strm() << " \\\\h "; // insert hyperlink
2855 break;
2856 // case RES_CHAPTERFLD:
2857 // rWrt.Strm() << ' ';
2858 // break;
2859 case RES_PAGENUMBERFLD:
2860 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\page";
2862 char __READONLY_DATA
2863 sNType0[] = "ALPHABETIC", /* CHARS_UPPER_LETTER*/
2864 sNType1[] = "alphabetic", /* CHARS_LOWER_LETTER*/
2865 sNType2[] = "ROMAN", /* ROMAN_UPPER */
2866 sNType3[] = "roman", /* ROMAN_LOWER */
2867 sNType4[] = "ARABIC"; /* ARABIC */
2869 const char* pFmtStr = 0;
2870 switch( pFld->GetFormat() )
2872 case SVX_NUM_CHARS_UPPER_LETTER:
2873 case SVX_NUM_CHARS_UPPER_LETTER_N: pFmtStr = sNType0; break;
2874 case SVX_NUM_CHARS_LOWER_LETTER:
2875 case SVX_NUM_CHARS_LOWER_LETTER_N: pFmtStr = sNType1; break;
2876 case SVX_NUM_ROMAN_UPPER: pFmtStr = sNType2; break;
2877 case SVX_NUM_ROMAN_LOWER: pFmtStr = sNType3; break;
2878 case SVX_NUM_ARABIC: pFmtStr = sNType4; break;
2881 if( pFmtStr )
2882 rWrt.Strm() << "\\\\* " << pFmtStr;
2884 break;
2885 case RES_FILENAMEFLD:
2886 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\filename ";
2887 break;
2888 case RES_DBNAMEFLD:
2890 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\data ";
2891 SwDBData aData = rWrt.pDoc->GetDBData();
2892 String sOut(aData.sDataSource);
2893 sOut += DB_DELIM;
2894 sOut += (String)aData.sCommand;
2895 RTFOutFuncs::Out_String( rWrt.Strm(), sOut,
2896 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2898 break;
2899 case RES_AUTHORFLD:
2900 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\author ";
2901 break;
2903 case RES_HIDDENTXTFLD:
2904 if( TYP_CONDTXTFLD == ((SwHiddenTxtField*)pFld)->GetSubType() )
2905 RTFOutFuncs::Out_String( rWrt.Strm(),
2906 pFld->ExpandField(rWrt.pDoc->IsClipBoard()),
2907 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2908 else
2910 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_V << ' ';
2911 OutRTF_AsByteString( rWrt, pFld->GetPar2(), rRTFWrt.eDefaultEncoding ).Strm()
2912 << '}' << SwRTFWriter::sNewLine;
2914 return rWrt; // nicht bis zum Ende, kein RTF-Feld !!
2916 case RES_DATETIMEFLD:
2917 if (!(pFld->GetSubType() & FIXEDFLD))
2919 USHORT nWhich = RES_DATETIMEFLD;
2920 ULONG nFmt = pFld->GetFormat();
2921 sw3io_ConvertToOldField(pFld, nWhich, nFmt, SOFFICE_FILEFORMAT_40 );
2922 if (pFld->GetSubType() & DATEFLD)
2924 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\date \\\\@\"";
2925 switch( nFmt )
2927 case DF_SSYS: rWrt.Strm() << "tt.MM.yy"; break;
2928 case DF_LSYS: rWrt.Strm() << "tttt, t. MMMM yyyy"; break;
2929 case DF_SHORT: rWrt.Strm() << "tt.MM.yy"; break;
2930 case DF_SCENT: rWrt.Strm() << "tt.MM.yyyy"; break;
2931 case DF_LMON: rWrt.Strm() << "t. MMM yyyy"; break;
2932 case DF_LMONTH: rWrt.Strm() << "t. MMMM yyyy"; break;
2933 case DF_LDAYMON: rWrt.Strm() << "ttt, t. MMMM yyyy"; break;
2934 case DF_LDAYMONTH: rWrt.Strm() << "tttt, t. MMMM yyyy"; break;
2937 else
2939 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\date \\\\@\"";
2940 switch( nFmt )
2942 case TF_SSMM_24: rWrt.Strm() << "HH:mm"; break;
2943 case TF_SSMM_12: rWrt.Strm() << "hh:mm"; break; // ???
2944 case TF_SYSTEM: rWrt.Strm() << "HH:mm"; break;
2947 rWrt.Strm() << '\"';
2948 break;
2950 // Kein break: in default-Zweig laufen!
2952 default:
2954 aFldStt.Erase();
2956 // JP 20.07.95: warum nicht das Expandierte rausschreiben ?
2957 sal_Char cCh;
2958 rWrt.Strm().SeekRel(-1);
2959 rWrt.Strm() >> cCh;
2960 if( ' ' != cCh ) // vorweg immer einen Trenner
2961 rWrt.Strm() << ' ';
2962 RTFOutFuncs::Out_String( rWrt.Strm(),
2963 pFld->ExpandField(rWrt.pDoc->IsClipBoard()),
2964 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2966 break;
2969 if( aFldStt.Len() )
2971 rWrt.Strm() << "}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << ' ';
2972 RTFOutFuncs::Out_String( rWrt.Strm(),
2973 pFld->ExpandField(rWrt.pDoc->IsClipBoard()),
2974 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2975 rWrt.Strm() << "}}";
2976 rRTFWrt.bOutFmtAttr = FALSE;
2979 return rWrt;
2982 static Writer& OutRTF_SwFlyCntnt( Writer& rWrt, const SfxPoolItem& rHt )
2984 SwFrmFmt* pFmt = ((SwFmtFlyCnt&)rHt).GetFrmFmt();
2985 if (RES_DRAWFRMFMT != pFmt->Which())
2987 ((SwRTFWriter&)rWrt).OutRTFFlyFrms( *((SwFlyFrmFmt*)pFmt) );
2988 ((SwRTFWriter&)rWrt).bOutFmtAttr = false;
2990 return rWrt;
2993 static Writer& OutRTF_SwFtn( Writer& rWrt, const SfxPoolItem& rHt )
2995 const SwFmtFtn& rFtn = (const SwFmtFtn&)rHt;
2996 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2998 do { // middle-check-loop
2999 if( !rFtn.GetTxtFtn() || !rFtn.GetTxtFtn()->GetStartNode() )
3000 break; // es gibt keine Kopf-/Fusszeile/Fussnote
3002 // Hole vom Node und vom letzten Node die Position in der Section
3003 ULONG nStart = rFtn.GetTxtFtn()->GetStartNode()->GetIndex()+1,
3004 nEnd = rWrt.pDoc->GetNodes()[ nStart-1 ]->EndOfSectionIndex();
3006 // kein Bereich also kein gueltiger Node
3007 if( nStart >= nEnd )
3008 break;
3010 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_SUPER << ' ';
3011 if( !rFtn.GetNumStr().Len() )
3013 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CHFTN;
3014 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_FOOTNOTE );
3015 if( rFtn.IsEndNote() )
3016 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FTNALT;
3017 rWrt.Strm() << ' ' << OOO_STRING_SVTOOLS_RTF_CHFTN;
3019 else
3021 OutRTF_AsByteString( rWrt, rFtn.GetNumStr(), rRTFWrt.eDefaultEncoding );
3022 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_FOOTNOTE );
3023 if( rFtn.IsEndNote() )
3024 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FTNALT;
3025 rWrt.Strm() << ' ';
3026 OutRTF_AsByteString( rWrt, rFtn.GetNumStr(), rRTFWrt.eDefaultEncoding );
3028 RTFSaveData aSaveData( rRTFWrt, nStart, nEnd );
3029 // damit kein \par ausgegeben wird !!
3030 rRTFWrt.pCurPam->GetMark()->nContent++;
3031 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
3033 rWrt.Strm() << "}}" << SwRTFWriter::sNewLine;
3034 rRTFWrt.bOutFmtAttr = FALSE;
3036 } while( FALSE );
3037 return rWrt;
3040 static Writer& OutRTF_SwTxtCharFmt( Writer& rWrt, const SfxPoolItem& rHt )
3042 const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rHt;
3043 const SwCharFmt* pFmt = rChrFmt.GetCharFmt();
3045 if( pFmt )
3046 OutRTF_SwFmt( rWrt, *pFmt );
3047 return rWrt;
3050 static Writer& OutRTF_SwTxtAutoFmt( Writer& rWrt, const SfxPoolItem& rHt )
3052 const SwFmtAutoFmt& rAutoFmt = (const SwFmtAutoFmt&)rHt;
3053 const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
3055 if( pSet.get() )
3057 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
3058 OutRTF_SfxItemSet( rRTFWrt, *pSet.get(), FALSE );
3060 return rWrt;
3063 static Writer& OutRTF_SwTxtRuby( Writer& rWrt, const SfxPoolItem& rHt )
3065 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3066 const SwFmtRuby& rRuby = (const SwFmtRuby&)rHt;
3067 const SwTxtRuby* pRubyTxt = rRuby.GetTxtRuby();
3068 const SwTxtNode* pNd;
3070 if( !pRubyTxt || 0 == (pNd = pRubyTxt->GetpTxtNode() ))
3071 return rWrt;
3073 sal_Char cDirective = 0, cJC = '0';
3074 switch( rRuby.GetAdjustment() )
3076 case 0: cJC = '3'; cDirective = 'l'; break;
3077 case 2: cJC = '4'; cDirective = 'r'; break;
3078 case 3: cJC = '1'; cDirective = 'd'; break;
3079 case 4: cJC = '2'; cDirective = 'd'; break;
3080 case 1: break; //defaults to 0
3081 default:
3082 ASSERT( FALSE, "Unhandled Ruby justication code" );
3083 break;
3087 MS needs to know the name and size of the font used in the ruby item,
3088 but we coud have written it in a mixture of asian and western
3089 scripts, and each of these can be a different font and size than the
3090 other, so we make a guess based upon the first character of the text,
3091 defaulting to asian.
3093 USHORT nScript;
3094 if( pBreakIt->GetBreakIter().is() )
3095 nScript = pBreakIt->GetBreakIter()->getScriptType( rRuby.GetText(), 0);
3096 else
3097 nScript = i18n::ScriptType::ASIAN;
3099 const SwCharFmt* pFmt = pRubyTxt->GetCharFmt();
3100 const SvxFontItem *pFont;
3101 long nHeight;
3103 if( pFmt )
3105 const SwAttrSet& rSet = pFmt->GetAttrSet();
3106 pFont = &(const SvxFontItem&)rSet.Get( GetWhichOfScript(
3107 RES_CHRATR_FONT, nScript ));
3109 nHeight = ((SvxFontHeightItem&)rSet.Get(
3110 GetWhichOfScript( RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
3112 else
3114 /*Get document defaults if no formatting on ruby text*/
3115 const SfxItemPool *pPool = pNd->GetSwAttrSet().GetPool();
3116 pFont = &(const SvxFontItem&)pPool->GetDefaultItem(
3117 GetWhichOfScript( RES_CHRATR_FONT, nScript ));
3119 nHeight = ((SvxFontHeightItem&)pPool->GetDefaultItem(
3120 GetWhichOfScript( RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
3122 ( nHeight += 5 ) /= 10;
3124 // don't change " EQ " to any other without changing the code in RTFFLD.CXX
3125 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_FIELD << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_FLDINST
3126 << " EQ \\\\* jc" << cJC
3127 << " \\\\* \"Font:";
3128 RTFOutFuncs::Out_String( rWrt.Strm(), pFont->GetFamilyName(),
3129 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
3130 rWrt.Strm() << "\" \\\\* hps";
3131 rWrt.OutLong( nHeight );
3132 rWrt.Strm() << " \\\\o";
3133 if( cDirective )
3134 rWrt.Strm() << "\\\\a" << cDirective;
3135 rWrt.Strm() << "(\\\\s\\\\up ";
3137 if( pBreakIt->GetBreakIter().is() )
3138 nScript = pBreakIt->GetBreakIter()->getScriptType( pNd->GetTxt(),
3139 *pRubyTxt->GetStart() );
3140 else
3141 nScript = i18n::ScriptType::ASIAN;
3143 const SwAttrSet& rSet = pNd->GetSwAttrSet();
3144 nHeight = ((SvxFontHeightItem&)rSet.Get(
3145 GetWhichOfScript( RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
3146 (nHeight += 10) /= 20-1;
3147 rWrt.OutLong( nHeight ) << '(';
3149 if( pFmt )
3151 rWrt.Strm() << '{';
3152 OutRTF_SwFmt( rWrt, *pFmt );
3153 if( rRTFWrt.bOutFmtAttr )
3154 rWrt.Strm() << ' ';
3156 RTFOutFuncs::Out_String( rWrt.Strm(), rRuby.GetText(),
3157 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
3158 if( pFmt )
3159 rWrt.Strm() << '}';
3161 rWrt.Strm() << "),";
3162 rRTFWrt.bOutFmtAttr = FALSE;
3164 return rWrt;
3168 /* File FRMATR.HXX */
3170 static Writer& OutRTF_SwFrmSize( Writer& rWrt, const SfxPoolItem& rHt )
3172 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3173 const SwFmtFrmSize& rSz = (const SwFmtFrmSize&)rHt;
3174 if( rRTFWrt.pFlyFmt ) // wird das FlyFrmFmt ausgegeben ?
3176 if( !rRTFWrt.bRTFFlySyntax )
3177 return rWrt;
3179 if( rSz.GetWidth() )
3181 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ABSW;
3182 rWrt.OutLong( rSz.GetWidth() );
3183 rRTFWrt.bOutFmtAttr = TRUE;
3186 if( rSz.GetHeight() )
3188 long nH = rSz.GetHeight();
3189 if( ATT_FIX_SIZE == rSz.GetHeightSizeType() )
3190 nH = -nH;
3191 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ABSH;
3192 rWrt.OutLong( nH );
3193 rRTFWrt.bOutFmtAttr = TRUE;
3196 else if( rRTFWrt.bOutPageDesc )
3198 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PGWSXN;
3199 rWrt.OutLong( rSz.GetWidth() );
3200 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PGHSXN;
3201 rWrt.OutLong( rSz.GetHeight() );
3202 rRTFWrt.bOutFmtAttr = TRUE;
3204 return rWrt;
3207 static Writer& OutRTF_SwFmtLRSpace( Writer& rWrt, const SfxPoolItem& rHt )
3209 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3210 const SvxLRSpaceItem & rLR = (const SvxLRSpaceItem&) rHt;
3211 if( !rRTFWrt.pFlyFmt )
3213 if( rRTFWrt.bOutPageDesc )
3215 if( rLR.GetLeft() )
3217 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_MARGLSXN;
3218 rWrt.OutLong( rLR.GetLeft() );
3219 rRTFWrt.bOutFmtAttr = TRUE;
3221 if( rLR.GetRight() )
3223 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_MARGRSXN;
3224 rWrt.OutLong( rLR.GetRight() );
3225 rRTFWrt.bOutFmtAttr = TRUE;
3228 else
3230 rRTFWrt.bOutFmtAttr = TRUE;
3231 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LI;
3232 rWrt.OutLong( rLR.GetTxtLeft() ) << OOO_STRING_SVTOOLS_RTF_RI;
3233 rWrt.OutLong( rLR.GetRight() );
3234 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LIN;
3235 rWrt.OutLong( rLR.GetTxtLeft() ) << OOO_STRING_SVTOOLS_RTF_RIN;
3236 rWrt.OutLong( rLR.GetRight() );
3237 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FI;
3238 rWrt.OutLong( rLR.GetTxtFirstLineOfst() );
3241 else if( rLR.GetLeft() == rLR.GetRight() && rRTFWrt.bRTFFlySyntax )
3243 rRTFWrt.bOutFmtAttr = TRUE;
3244 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DFRMTXTX;
3245 rWrt.OutLong( rLR.GetLeft() );
3247 return rWrt;
3250 static Writer& OutRTF_SwFmtULSpace( Writer& rWrt, const SfxPoolItem& rHt )
3252 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3253 const SvxULSpaceItem & rUL = (const SvxULSpaceItem&) rHt;
3254 if( rRTFWrt.pFlyFmt )
3256 if( rUL.GetUpper() == rUL.GetLower() && rRTFWrt.bRTFFlySyntax )
3258 rRTFWrt.bOutFmtAttr = TRUE;
3259 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DFRMTXTY;
3260 rWrt.OutLong( rUL.GetLower() );
3263 else
3265 const char* p;
3266 USHORT nValue = rUL.GetUpper();
3267 if( rRTFWrt.bOutPageDesc )
3269 p = OOO_STRING_SVTOOLS_RTF_MARGTSXN;
3270 if( !rRTFWrt.bOutPageDescTbl )
3272 SwRect aRect;
3273 const SwFmtHeader* pHdr;
3274 if( SFX_ITEM_SET == rRTFWrt.pAktPageDesc->GetMaster().
3275 GetItemState( RES_HEADER, FALSE,
3276 (const SfxPoolItem**)&pHdr ) && pHdr->IsActive() )
3278 aRect = pHdr->GetHeaderFmt()->FindLayoutRect( FALSE );
3279 if( aRect.Height() )
3280 nValue = nValue + static_cast< USHORT >(aRect.Height());
3281 else
3283 const SwFmtFrmSize& rSz = pHdr->GetHeaderFmt()->GetFrmSize();
3284 if( ATT_VAR_SIZE != rSz.GetHeightSizeType() )
3285 nValue = nValue + static_cast< USHORT >(rSz.GetHeight());
3286 else
3287 nValue = nValue + 274; // defaulten fuer 12pt Schrift
3288 nValue = nValue + pHdr->GetHeaderFmt()->GetULSpace().GetLower();
3293 else
3294 p = OOO_STRING_SVTOOLS_RTF_SB;
3296 if( rRTFWrt.bOutPageDesc || nValue )
3298 rRTFWrt.bOutFmtAttr = TRUE;
3299 rWrt.Strm() << p;
3300 rWrt.OutLong( nValue );
3304 nValue = rUL.GetLower();
3305 if( rRTFWrt.bOutPageDesc )
3307 p = OOO_STRING_SVTOOLS_RTF_MARGBSXN;
3308 if( !rRTFWrt.bOutPageDescTbl )
3310 SwRect aRect;
3311 const SwFmtFooter* pFtr;
3312 if( SFX_ITEM_SET == rRTFWrt.pAktPageDesc->GetMaster().
3313 GetItemState( RES_FOOTER, FALSE,
3314 (const SfxPoolItem**)&pFtr ) && pFtr->IsActive() )
3316 aRect = pFtr->GetFooterFmt()->FindLayoutRect( FALSE );
3317 if( aRect.Height() )
3318 nValue = nValue + static_cast< USHORT >(aRect.Height());
3319 else
3321 const SwFmtFrmSize& rSz = pFtr->GetFooterFmt()->GetFrmSize();
3322 if( ATT_VAR_SIZE != rSz.GetHeightSizeType() )
3323 nValue = nValue + static_cast< USHORT >(rSz.GetHeight());
3324 else
3325 nValue += 274; // defaulten fuer 12pt Schrift
3326 nValue = nValue + pFtr->GetFooterFmt()->GetULSpace().GetUpper();
3331 else
3332 p = OOO_STRING_SVTOOLS_RTF_SA;
3334 if( rRTFWrt.bOutPageDesc || nValue )
3336 rRTFWrt.bOutFmtAttr = TRUE;
3337 rWrt.Strm() << p;
3338 rWrt.OutLong( nValue );
3341 return rWrt;
3344 // Header-Footer werden auch vom RTF-Writer direkt gerufen, also kein static!
3347 Writer& OutRTF_SwFmtHeader( Writer& rWrt, const SfxPoolItem& rHt )
3349 const SwFmtHeader& rHd = (const SwFmtHeader&)rHt;
3350 if( !rHd.IsActive() ) // nicht aktiv, dann nichts weiter ausgeben
3351 return rWrt;
3353 // hole einen Node zu dem Request
3354 SwStartNode *pSttNode = 0;
3355 const SwFmtCntnt& rCntnt = rHd.GetHeaderFmt()->GetCntnt();
3356 if( rCntnt.GetCntntIdx() )
3357 pSttNode = rCntnt.GetCntntIdx()->GetNode().GetStartNode();
3359 do { // middle-check-loop
3360 if( !pSttNode )
3361 break; // es gibt keine Kopf-/Fusszeile/Fussnote
3363 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3365 // Hole vom Node und vom letzten Node die Position in der Section
3366 ULONG nStart = pSttNode->GetIndex() + 1,
3367 nEnd = pSttNode->EndOfSectionIndex();
3369 // kein Bereich also kein gueltiger Node
3370 if( nStart >= nEnd )
3371 break;
3372 ASSERT( rRTFWrt.pAktPageDesc, "Header-Attribut ohne PageDesc" );
3374 const sal_Char * pHdNm = OOO_STRING_SVTOOLS_RTF_HEADER;
3375 rWrt.Strm() << pHdNm << 'y';
3376 if( rRTFWrt.bOutPageDescTbl )
3378 // hole die Ober-/Unterkanten vom Header
3379 const SvxULSpaceItem& rUL = rHd.GetHeaderFmt()->GetULSpace();
3380 const SvxLRSpaceItem& rLR = rHd.GetHeaderFmt()->GetLRSpace();
3381 const SwFmtFrmSize& rSz = rHd.GetHeaderFmt()->GetFrmSize();
3383 rWrt.OutLong( rUL.GetUpper() );
3384 OutComment( rWrt, pHdNm ) << "yb";
3385 rWrt.OutLong( rUL.GetLower() ) << pHdNm << "xl";
3386 rWrt.OutLong( rLR.GetLeft() ) << pHdNm << "xr";
3387 rWrt.OutLong( rLR.GetRight() ) << pHdNm << "yh";
3388 rWrt.OutLong( ATT_FIX_SIZE == rSz.GetHeightSizeType()
3389 ? -rSz.GetHeight()
3390 : rSz.GetHeight() ) << '}';
3392 else
3393 rWrt.OutLong( rRTFWrt.pAktPageDesc->GetMaster().
3394 GetULSpace().GetUpper() );
3396 // wird nicht die PageDesc-Tabelle ausgegeben und gibt es einen
3397 // Nachfolger, dann handelt es sich um die "1.Seite" nach RTF.
3398 sal_Char cTyp = 0;
3399 if( rRTFWrt.pAktPageDesc->GetFollow() &&
3400 rRTFWrt.pAktPageDesc->GetFollow() != rRTFWrt.pAktPageDesc )
3402 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG; //i13107
3403 cTyp = 'f'; // dann FirstPage-Header
3405 else if( !rRTFWrt.pAktPageDesc->IsHeaderShared() )
3407 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FACINGP; //i13107
3408 cTyp = rRTFWrt.bOutLeftHeadFoot ? 'l' : 'r';
3411 rWrt.Strm() << '{'<< pHdNm;
3412 if( cTyp ) rWrt.Strm() << cTyp;
3413 rWrt.Strm() << ' ';
3416 RTFSaveData aSaveData( rRTFWrt, nStart, nEnd );
3417 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
3420 rWrt.Strm() << '}' << SwRTFWriter::sNewLine;
3422 } while( FALSE );
3423 return rWrt;
3425 // Header-Footer werden auch vom RTF-Writer direkt gerufen, also kein static!
3428 Writer& OutRTF_SwFmtFooter( Writer& rWrt, const SfxPoolItem& rHt )
3430 const SwFmtFooter& rFt = (const SwFmtFooter&)rHt;
3431 if( !rFt.IsActive() ) // nicht aktiv, dann nichts weiter ausgeben
3432 return rWrt;
3434 SwStartNode *pSttNode = 0;
3435 const SwFmtCntnt& rCntnt = rFt.GetFooterFmt()->GetCntnt();
3436 if( rCntnt.GetCntntIdx() )
3437 pSttNode = rCntnt.GetCntntIdx()->GetNode().GetStartNode();
3439 do { // middle-check-loop
3440 if( !pSttNode )
3441 break; // es gibt keine Kopf-/Fusszeile/Fussnote
3443 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3445 // Hole vom Node und vom letzten Node die Position in der Section
3446 ULONG nStart = pSttNode->GetIndex()+1,
3447 nEnd = pSttNode->EndOfSectionIndex();
3449 // kein Bereich also kein gueltiger Node
3450 if( nStart >= nEnd )
3451 break;
3452 ASSERT( rRTFWrt.pAktPageDesc, "Footer-Attribut ohne PageDesc" );
3454 const sal_Char * pFtNm = OOO_STRING_SVTOOLS_RTF_FOOTER;
3455 rWrt.Strm() << pFtNm << 'y';
3456 if( rRTFWrt.bOutPageDescTbl )
3458 // hole die Ober-/Unterkanten vom Footer
3459 const SvxULSpaceItem& rUL = rFt.GetFooterFmt()->GetULSpace();
3460 const SvxLRSpaceItem& rLR = rFt.GetFooterFmt()->GetLRSpace();
3461 const SwFmtFrmSize& rSz = rFt.GetFooterFmt()->GetFrmSize();
3463 rWrt.OutLong( rUL.GetLower() );
3464 OutComment( rWrt, pFtNm ) << "yt";
3465 rWrt.OutLong( rUL.GetUpper() ) << pFtNm << "xl";
3466 rWrt.OutLong( rLR.GetLeft() ) << pFtNm << "xr";
3467 rWrt.OutLong( rLR.GetRight() ) << pFtNm << "yh";
3468 rWrt.OutLong( ATT_FIX_SIZE == rSz.GetHeightSizeType()
3469 ? -rSz.GetHeight()
3470 : rSz.GetHeight() ) << '}';
3472 else
3473 rWrt.OutLong( rRTFWrt.pAktPageDesc->GetMaster().
3474 GetULSpace().GetLower() );
3476 // wird nicht die PageDesc-Tabelle ausgegeben und gibt es einen
3477 // Nachfolger, dann handelt es sich um die "1.Seite" nach RTF.
3478 sal_Char cTyp = 0;
3479 if( !rRTFWrt.bOutPageDesc && rRTFWrt.pAktPageDesc->GetFollow() &&
3480 rRTFWrt.pAktPageDesc->GetFollow() != rRTFWrt.pAktPageDesc )
3482 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG; //i13107
3483 cTyp = 'f'; // dann FirstPage-Header
3485 else if( !rRTFWrt.pAktPageDesc->IsFooterShared() )
3487 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FACINGP; //i13107
3488 cTyp = rRTFWrt.bOutLeftHeadFoot ? 'l' : 'r';
3491 rWrt.Strm() << '{'<< pFtNm;
3492 if( cTyp ) rWrt.Strm() << cTyp;
3493 rWrt.Strm() << ' ';
3496 RTFSaveData aSaveData( rRTFWrt, nStart, nEnd );
3497 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
3500 rWrt.Strm() << '}' << SwRTFWriter::sNewLine;
3502 } while( FALSE );
3503 return rWrt;
3506 static Writer& OutRTF_SwFmtPrint( Writer& rWrt, const SfxPoolItem& rHt )
3508 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3509 if( !rRTFWrt.bRTFFlySyntax && !((const SvxPrintItem&)rHt).GetValue() )
3511 rRTFWrt.bOutFmtAttr = TRUE;
3512 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYPRINT;
3514 return rWrt;
3518 static Writer& OutRTF_SwFmtOpaque( Writer& rWrt, const SfxPoolItem& rHt )
3520 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3521 if( !rRTFWrt.bRTFFlySyntax && !((const SvxOpaqueItem&)rHt).GetValue() )
3523 rRTFWrt.bOutFmtAttr = TRUE;
3524 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYOPAQUE;
3526 return rWrt;
3530 static Writer& OutRTF_SwFmtProtect( Writer& rWrt, const SfxPoolItem& rHt )
3532 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3533 if( !rRTFWrt.bRTFFlySyntax )
3535 const SvxProtectItem & rFlyProtect = (const SvxProtectItem&) rHt;
3536 RTFProtect aP( rFlyProtect.IsCntntProtected(),
3537 rFlyProtect.IsSizeProtected(),
3538 rFlyProtect.IsPosProtected() );
3539 rRTFWrt.bOutFmtAttr = TRUE;
3540 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYPRTCTD;
3541 rWrt.OutULong( aP.GetValue() );
3543 return rWrt;
3547 static Writer& OutRTF_SwFmtSurround( Writer& rWrt, const SfxPoolItem& rHt )
3549 const SwFmtSurround& rFlySurround = (const SwFmtSurround&) rHt;
3550 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3551 if( rRTFWrt.bRTFFlySyntax )
3553 if( SURROUND_NONE == rFlySurround.GetSurround() )
3555 rRTFWrt.bOutFmtAttr = TRUE;
3556 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_NOWRAP;
3559 else
3561 SwSurround eSurround = rFlySurround.GetSurround();
3562 BOOL bGold = SURROUND_IDEAL == eSurround;
3563 if( bGold )
3564 eSurround = SURROUND_PARALLEL;
3565 RTFSurround aMC( bGold, static_cast< BYTE >(eSurround) );
3566 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYMAINCNT;
3567 rWrt.OutULong( aMC.GetValue() );
3568 rRTFWrt.bOutFmtAttr = TRUE;
3570 return rWrt;
3573 static Writer& OutRTF_SwFmtVertOrient ( Writer& rWrt, const SfxPoolItem& rHt )
3575 const SwFmtVertOrient& rFlyVert = (const SwFmtVertOrient&) rHt;
3576 RTFVertOrient aVO( static_cast< USHORT >(rFlyVert.GetVertOrient()), static_cast< USHORT >(rFlyVert.GetRelationOrient()) );
3577 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3579 if( rRTFWrt.bRTFFlySyntax && rRTFWrt.pFlyFmt )
3581 rRTFWrt.bOutFmtAttr = TRUE;
3582 const char* pOrient;
3583 RndStdIds eAnchor = rRTFWrt.pFlyFmt->GetAnchor().GetAnchorId();
3584 sal_Int16 eOrient = rFlyVert.GetRelationOrient();
3585 if (FLY_AT_PAGE == eAnchor)
3587 if( text::RelOrientation::PAGE_FRAME == eOrient || text::RelOrientation::FRAME == eOrient )
3588 pOrient = OOO_STRING_SVTOOLS_RTF_PVPG;
3589 else
3590 pOrient = OOO_STRING_SVTOOLS_RTF_PVMRG;
3592 else
3593 pOrient = OOO_STRING_SVTOOLS_RTF_PVPARA;
3594 rWrt.Strm() << pOrient;
3596 switch (rFlyVert.GetVertOrient())
3598 case text::VertOrientation::TOP:
3599 case text::VertOrientation::LINE_TOP:
3600 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSYT;
3601 break;
3602 case text::VertOrientation::BOTTOM:
3603 case text::VertOrientation::LINE_BOTTOM:
3604 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSYB;
3605 break;
3606 case text::VertOrientation::CENTER:
3607 case text::VertOrientation::LINE_CENTER:
3608 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSYC;
3609 break;
3610 case text::VertOrientation::NONE:
3611 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSY;
3612 rWrt.OutULong(rFlyVert.GetPos());
3613 break;
3614 default:
3615 break;
3618 else if( !rRTFWrt.bRTFFlySyntax )
3620 rRTFWrt.bOutFmtAttr = TRUE;
3621 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYVERT;
3622 rWrt.OutULong( aVO.GetValue() );
3625 return rWrt;
3628 static Writer& OutRTF_SwFmtHoriOrient( Writer& rWrt, const SfxPoolItem& rHt )
3630 const SwFmtHoriOrient& rFlyHori = (const SwFmtHoriOrient&) rHt;
3631 RTFHoriOrient aHO( static_cast< USHORT >(rFlyHori.GetHoriOrient()),
3632 static_cast< USHORT >(rFlyHori.GetRelationOrient()) );
3634 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3635 if( rRTFWrt.bRTFFlySyntax && rRTFWrt.pFlyFmt )
3637 rRTFWrt.bOutFmtAttr = TRUE;
3638 const char* pS;
3639 RndStdIds eAnchor = rRTFWrt.pFlyFmt->GetAnchor().GetAnchorId();
3640 sal_Int16 eOrient = rFlyHori.GetRelationOrient();
3641 if (FLY_AT_PAGE == eAnchor)
3643 if( text::RelOrientation::PAGE_FRAME == eOrient || text::RelOrientation::FRAME == eOrient )
3644 pS = OOO_STRING_SVTOOLS_RTF_PHPG;
3645 else
3646 pS = OOO_STRING_SVTOOLS_RTF_PHMRG;
3648 else
3649 pS = OOO_STRING_SVTOOLS_RTF_PHCOL;
3650 rWrt.Strm() << pS;
3652 pS = 0;
3653 switch(rFlyHori.GetHoriOrient())
3655 case text::HoriOrientation::RIGHT:
3656 pS = rFlyHori.IsPosToggle() ? OOO_STRING_SVTOOLS_RTF_POSXO : OOO_STRING_SVTOOLS_RTF_POSXR;
3657 break;
3658 case text::HoriOrientation::LEFT:
3659 pS = rFlyHori.IsPosToggle() ? OOO_STRING_SVTOOLS_RTF_POSXI : OOO_STRING_SVTOOLS_RTF_POSXL;
3660 break;
3661 case text::HoriOrientation::CENTER:
3662 pS = OOO_STRING_SVTOOLS_RTF_POSXC;
3663 break;
3664 case text::HoriOrientation::NONE:
3665 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSX;
3666 rWrt.OutULong( rFlyHori.GetPos() );
3667 break;
3668 default:
3669 break;
3671 if (pS)
3672 rWrt.Strm() << pS;
3674 else
3676 rRTFWrt.bOutFmtAttr = TRUE;
3677 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYHORZ;
3678 rWrt.OutULong( aHO.GetValue() );
3680 return rWrt;
3683 static Writer& OutRTF_SwFmtAnchor( Writer& rWrt, const SfxPoolItem& rHt )
3685 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3686 if( !rRTFWrt.bRTFFlySyntax )
3688 const SwFmtAnchor& rAnchor = (const SwFmtAnchor&) rHt;
3689 USHORT nId = static_cast< USHORT >(rAnchor.GetAnchorId());
3690 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYANCHOR;
3691 rWrt.OutULong( nId );
3692 rRTFWrt.bOutFmtAttr = TRUE;
3693 switch( nId )
3695 case FLY_AT_PAGE:
3696 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYPAGE;
3697 rWrt.OutULong( rAnchor.GetPageNum() );
3698 break;
3699 case FLY_AT_PARA:
3700 case FLY_AS_CHAR:
3701 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYCNTNT;
3702 break;
3705 return rWrt;
3710 static Writer& OutRTF_SwFmtBackground( Writer& rWrt, const SfxPoolItem& rHt )
3712 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3713 // wird das FlyFrmFmt ausgegeben, dann Background nur ausgeben, wenn
3714 // RTF-Syntax gesetzt ist !
3715 if( !rRTFWrt.pFlyFmt || !rRTFWrt.bRTFFlySyntax )
3717 const SvxBrushItem& rBack = (const SvxBrushItem&)rHt;
3718 if( !rBack.GetColor().GetTransparency() )
3720 ByteString sOut( OOO_STRING_SVTOOLS_RTF_CBPAT );
3721 sOut += ByteString::CreateFromInt32(
3722 rRTFWrt.GetId( rBack.GetColor() ));
3724 if( rRTFWrt.pFlyFmt || rRTFWrt.bOutPageDesc )
3726 rWrt.Strm() << '{' << sOut.GetBuffer() << '}';
3728 else
3730 rRTFWrt.bOutFmtAttr = TRUE;
3731 rWrt.Strm() << sOut.GetBuffer();
3735 return rWrt;
3739 static Writer& OutRTF_SwFmtShadow( Writer& rWrt, const SfxPoolItem& rHt )
3741 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3742 // wird das FlyFrmFmt ausgegeben, dann Schatten nur ausgeben, wenn
3743 // nicht RTF-Syntax gesetzt ist !
3744 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax )
3745 return rWrt;
3747 const SvxShadowItem& rShadow = (const SvxShadowItem&)rHt;
3748 // FALSE wegen schliessender Klammer !!
3749 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_SHADOW, FALSE );
3750 rWrt.OutULong( rShadow.GetLocation() ) << OOO_STRING_SVTOOLS_RTF_SHDWDIST;
3751 rWrt.OutULong( rShadow.GetWidth() ) << OOO_STRING_SVTOOLS_RTF_SHDWSTYLE;
3752 const Color& rColor = rShadow.GetColor();
3753 rWrt.OutULong( rColor.GetTransparency() ? SW_SV_BRUSH_NULL : SW_SV_BRUSH_SOLID );
3754 rWrt.OutULong( rRTFWrt.GetId( rColor ) ) << OOO_STRING_SVTOOLS_RTF_SHDWFCOL;
3755 rWrt.OutULong( 0 ) << '}';
3756 return rWrt;
3760 static void OutBorderLine( SwRTFWriter& rWrt, const SvxBorderLine* pLine,
3761 const char* pStr )
3763 rWrt.Strm() << pStr << OOO_STRING_SVTOOLS_RTF_BRDLNCOL;
3764 rWrt.OutULong( rWrt.GetId( pLine->GetColor() ) ) << OOO_STRING_SVTOOLS_RTF_BRDLNIN;
3765 rWrt.OutULong( pLine->GetInWidth() ) << OOO_STRING_SVTOOLS_RTF_BRDLNOUT;
3766 rWrt.OutULong( pLine->GetOutWidth() ) << OOO_STRING_SVTOOLS_RTF_BRDLNDIST;
3767 rWrt.OutULong( pLine->GetDistance() );
3771 static Writer& OutRTF_SwFmtBox( Writer& rWrt, const SfxPoolItem& rHt )
3773 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3775 const SvxBoxItem& rBox = (const SvxBoxItem&)rHt;
3777 static USHORT __READONLY_DATA aBorders[] = {
3778 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT };
3779 static const sal_Char* __READONLY_DATA aBorderNames[] = {
3780 OOO_STRING_SVTOOLS_RTF_BRDRT, OOO_STRING_SVTOOLS_RTF_BRDRL, OOO_STRING_SVTOOLS_RTF_BRDRB, OOO_STRING_SVTOOLS_RTF_BRDRR };
3782 USHORT nDist = rBox.GetDistance();
3784 // wird das FlyFrmFmt ausgegeben, dann Border nur ausgeben, wenn
3785 // nicht RTF-Syntax gesetzt ist!
3786 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax )
3789 RTF kennt keine Rahmen Umrandung!
3790 // die normale RTF-Definition
3791 if( rBox.GetTop() && rBox.GetBottom() &&
3792 rBox.GetLeft() && rBox.GetRight() &&
3793 *rBox.GetTop() == *rBox.GetBottom() &&
3794 *rBox.GetTop() == *rBox.GetLeft() &&
3795 *rBox.GetTop() == *rBox.GetRight() )
3796 OutBorderLine( rRTFWrt, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist );
3797 else
3799 OUT_BRDLINE( rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BRDRT, nDist );
3800 OUT_BRDLINE( rBox.GetBottom(), OOO_STRING_SVTOOLS_RTF_BRDRB, nDist );
3801 OUT_BRDLINE( rBox.GetLeft(), OOO_STRING_SVTOOLS_RTF_BRDRL, nDist );
3802 OUT_BRDLINE( rBox.GetRight(), OOO_STRING_SVTOOLS_RTF_BRDRR, nDist );
3805 return rWrt;
3807 else if( !rRTFWrt.pFlyFmt )
3809 // erst die normale RTF-Definition, dann unsere eigene
3810 if( rBox.GetTop() && rBox.GetBottom() &&
3811 rBox.GetLeft() && rBox.GetRight() &&
3812 *rBox.GetTop() == *rBox.GetBottom() &&
3813 *rBox.GetTop() == *rBox.GetLeft() &&
3814 *rBox.GetTop() == *rBox.GetRight() &&
3815 nDist == rBox.GetDistance( BOX_LINE_TOP ) &&
3816 nDist == rBox.GetDistance( BOX_LINE_LEFT ) &&
3817 nDist == rBox.GetDistance( BOX_LINE_BOTTOM ) &&
3818 nDist == rBox.GetDistance( BOX_LINE_RIGHT ))
3819 OutBorderLine( rRTFWrt, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist );
3820 else
3822 const USHORT* pBrd = aBorders;
3823 const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
3824 for(int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
3826 if (const SvxBorderLine* pLn = rBox.GetLine(*pBrd))
3828 OutBorderLine(rRTFWrt, pLn, *pBrdNms,
3829 rBox.GetDistance(*pBrd));
3835 const USHORT* pBrd = aBorders;
3836 const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
3837 for( int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms )
3839 const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
3840 if( pLn )
3842 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE;
3843 OutBorderLine( rRTFWrt, pLn, *pBrdNms );
3844 rWrt.Strm() << '}' << OOO_STRING_SVTOOLS_RTF_BRSP;
3845 rWrt.OutULong( rBox.GetDistance( *pBrd ));
3849 rRTFWrt.bOutFmtAttr = FALSE;
3850 return rWrt;
3853 static Writer& OutRTF_SwFmtCol( Writer& rWrt, const SfxPoolItem& rHt )
3855 SwRTFWriter& rRTFWrt = ((SwRTFWriter&)rWrt);
3856 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax )
3857 return rWrt;
3859 const SwFmtCol& rCol = (const SwFmtCol&)rHt;
3860 const SwColumns& rColumns = rCol.GetColumns();
3862 USHORT nCols = rColumns.Count();
3863 if( 1 < nCols )
3865 // dann besorge mal die Seitenbreite ohne Raender !!
3866 const SwFrmFmt* pFmt;
3868 if( rRTFWrt.pFlyFmt )
3869 pFmt = rRTFWrt.pFlyFmt;
3870 else if( rRTFWrt.pAktPageDesc )
3871 pFmt = &rRTFWrt.pAktPageDesc->GetMaster();
3872 else
3873 pFmt = &const_cast<const SwDoc *>(rWrt.pDoc)
3874 ->GetPageDesc(0).GetMaster();
3876 const SvxLRSpaceItem& rLR = pFmt->GetLRSpace();
3878 USHORT nPageSize = static_cast< USHORT >( pFmt->GetFrmSize().GetWidth() -
3879 rLR.GetLeft() - rLR.GetRight() );
3881 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLS;
3882 rWrt.OutLong( nCols );
3884 if( rCol.IsOrtho() )
3886 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLSX;
3887 rWrt.OutLong( rCol.GetGutterWidth( TRUE ) );
3889 else
3890 for( USHORT n = 0; n < nCols; )
3892 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLNO;
3893 rWrt.OutLong( n+1 );
3895 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLW;
3896 rWrt.OutLong( rCol.CalcPrtColWidth( n, nPageSize ) );
3897 if( ++n != nCols )
3899 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLSR;
3900 rWrt.OutLong( rColumns[ n-1 ]->GetRight() +
3901 rColumns[ n ]->GetLeft() );
3904 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3906 return rWrt;
3909 static Writer& OutRTF_SvxFmtKeep( Writer& rWrt, const SfxPoolItem& rHt )
3911 const SvxFmtKeepItem& rItem = (const SvxFmtKeepItem&)rHt;
3912 if( rItem.GetValue() )
3914 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_KEEPN;
3915 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3917 return rWrt;
3920 static Writer& OutRTF_SvxFrmDir( Writer& rWrt, const SfxPoolItem& rHt )
3922 SwRTFWriter& rRTFWrt = ((SwRTFWriter&)rWrt);
3923 if (rRTFWrt.pFlyFmt || rRTFWrt.bOutPageDesc)
3924 OutSvxFrmDir(rRTFWrt, rHt);
3925 return rWrt;
3928 /* File GRFATR.HXX */
3930 static Writer& OutRTF_SwMirrorGrf( Writer& rWrt, const SfxPoolItem& rHt )
3932 const SwMirrorGrf & rMirror = (const SwMirrorGrf&)rHt;
3933 if( RES_MIRROR_GRAPH_DONT == rMirror.GetValue() )
3934 return rWrt;
3936 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3937 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_GRFMIRROR;
3938 rWrt.OutULong( rMirror.GetValue() );
3939 return rWrt;
3942 static Writer& OutRTF_SwCropGrf( Writer& rWrt, const SfxPoolItem& rHt )
3944 const SwCropGrf & rCrop = (const SwCropGrf&)rHt;
3945 ByteString aStr;
3946 if( rCrop.GetLeft() )
3947 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPL ) +=
3948 ByteString::CreateFromInt32( (short)rCrop.GetLeft() );
3949 if( rCrop.GetRight() )
3950 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPR ) +=
3951 ByteString::CreateFromInt32( (short)rCrop.GetRight() );
3952 if( rCrop.GetTop() )
3953 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPT ) +=
3954 ByteString::CreateFromInt32( (short)rCrop.GetTop() );
3955 if( rCrop.GetBottom() )
3956 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPB ) +=
3957 ByteString::CreateFromInt32( (short)rCrop.GetBottom() );
3958 if( aStr.Len() )
3960 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3961 rWrt.Strm() << aStr.GetBuffer();
3963 return rWrt;
3968 /* File PARATR.HXX */
3970 static Writer& OutRTF_SwLineSpacing( Writer& rWrt, const SfxPoolItem& rHt )
3972 const SvxLineSpacingItem &rLs = (const SvxLineSpacingItem&)rHt;
3974 switch (rLs.GetLineSpaceRule())
3976 default:
3977 break;
3978 case SVX_LINE_SPACE_AUTO:
3979 case SVX_LINE_SPACE_FIX:
3980 case SVX_LINE_SPACE_MIN:
3982 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3983 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SL;
3984 sal_Char cMult = '0';
3985 switch (rLs.GetInterLineSpaceRule())
3987 case SVX_INTER_LINE_SPACE_FIX:
3988 // unser Durchschuss gibt es aber nicht in WW - also wie
3989 // kommt man an die MaxLineHeight heran?
3990 rWrt.OutLong((short)rLs.GetInterLineSpace());
3991 break;
3992 case SVX_INTER_LINE_SPACE_PROP:
3993 rWrt.OutLong((240L * rLs.GetPropLineSpace()) / 100L);
3994 cMult = '1';
3995 break;
3996 default:
3997 if (SVX_LINE_SPACE_FIX == rLs.GetLineSpaceRule())
3998 rWrt.Strm() << '-';
3999 rWrt.OutLong( rLs.GetLineHeight() );
4000 break;
4002 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SLMULT << cMult;
4004 break;
4006 return rWrt;
4009 static Writer& OutRTF_SwAdjust( Writer& rWrt, const SfxPoolItem& rHt )
4011 const SvxAdjustItem & rAdjust = ((const SvxAdjustItem&)rHt);
4012 ByteString aAttr( "\\q" );
4013 switch( rAdjust.GetAdjust() )
4015 case SVX_ADJUST_LEFT: aAttr += 'l'; break;
4016 case SVX_ADJUST_RIGHT: aAttr += 'r'; break;
4017 case SVX_ADJUST_BLOCKLINE:
4018 case SVX_ADJUST_BLOCK: aAttr += 'j'; break;
4019 case SVX_ADJUST_CENTER: aAttr += 'c'; break;
4021 default:
4022 return rWrt; // kein gueltiges Attriut, also returnen
4024 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4025 rWrt.Strm() << aAttr.GetBuffer();
4026 return rWrt;
4029 static Writer& OutRTF_SvxFmtSplit( Writer& rWrt, const SfxPoolItem& rHt )
4031 const SvxFmtSplitItem& rItem = (const SvxFmtSplitItem&)rHt;
4032 if( !rItem.GetValue() )
4034 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_KEEP;
4035 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4037 return rWrt;
4040 static Writer& OutRTF_SwTabStop( Writer& rWrt, const SfxPoolItem& rHt )
4042 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
4043 const SvxTabStopItem & rTStops = (const SvxTabStopItem&)rHt;
4044 long nOffset = ((SvxLRSpaceItem&)rRTFWrt.GetItem( RES_LR_SPACE )).GetTxtLeft();
4045 for( USHORT n = 0; n < rTStops.Count(); n++ )
4047 const SvxTabStop & rTS = rTStops[ n ];
4048 if( SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment() )
4050 BOOL bOutDecimal = TRUE;
4051 const char* pFill = 0;
4052 switch( rTS.GetFill() )
4054 case cDfltFillChar:
4055 break;
4057 case '.': pFill = OOO_STRING_SVTOOLS_RTF_TLDOT; break;
4058 case '_': pFill = OOO_STRING_SVTOOLS_RTF_TLUL; break;
4059 case '-': pFill = OOO_STRING_SVTOOLS_RTF_TLTH; break;
4060 case '=': pFill = OOO_STRING_SVTOOLS_RTF_TLEQ; break;
4061 default:
4062 if( !rRTFWrt.bWriteHelpFmt )
4064 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_TLSWG, FALSE );
4065 rWrt.OutULong( (((USHORT)rTS.GetFill()) << 8 ) +
4066 rTS.GetDecimal() )
4067 << '}';
4068 bOutDecimal = FALSE;
4071 if( pFill )
4072 rWrt.Strm() << pFill;
4074 if( !rRTFWrt.bWriteHelpFmt && bOutDecimal &&
4075 rTS.GetDecimal() != ((SvxTabStopItem&)*GetDfltAttr(
4076 RES_PARATR_TABSTOP ))[ 0 ].GetDecimal() )
4078 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_TLSWG, FALSE );
4079 rWrt.OutULong( (((USHORT)rTS.GetFill()) << 8 ) +
4080 rTS.GetDecimal() ) << '}';
4083 const sal_Char* pAdjStr = 0;
4084 switch (rTS.GetAdjustment())
4086 case SVX_TAB_ADJUST_RIGHT:
4087 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
4088 break;
4089 case SVX_TAB_ADJUST_DECIMAL:
4090 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
4091 break;
4092 case SVX_TAB_ADJUST_CENTER:
4093 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
4094 break;
4095 default:
4096 break;
4098 if (pAdjStr)
4099 rWrt.Strm() << pAdjStr;
4100 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TX;
4101 rWrt.OutLong(rTS.GetTabPos() + nOffset);
4104 rRTFWrt.bOutFmtAttr = TRUE;
4105 return rWrt;
4108 static Writer& OutRTF_SwHypenZone( Writer& rWrt, const SfxPoolItem& rHt )
4110 if( !((SwRTFWriter&)rWrt).bWriteHelpFmt )
4112 const SvxHyphenZoneItem& rAttr = (const SvxHyphenZoneItem&)rHt;
4113 USHORT nFlags = rAttr.IsHyphen() ? 1 : 0;
4114 if( rAttr.IsPageEnd() ) nFlags += 2;
4116 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_HYPHEN, FALSE );
4117 rWrt.OutULong( nFlags ) << OOO_STRING_SVTOOLS_RTF_HYPHLEAD;
4118 rWrt.OutULong( rAttr.GetMinLead() ) << OOO_STRING_SVTOOLS_RTF_HYPHTRAIL;
4119 rWrt.OutULong( rAttr.GetMinTrail() ) << OOO_STRING_SVTOOLS_RTF_HYPHMAX;
4120 rWrt.OutULong( rAttr.GetMaxHyphens() ) << '}';
4122 return rWrt;
4125 static Writer& OutRTF_SwNumRule( Writer& rWrt, const SfxPoolItem& rHt )
4127 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
4128 if( !rRTFWrt.bOutListNumTxt )
4130 const SwNumRuleItem& rAttr = (const SwNumRuleItem&)rHt;
4131 USHORT nId;
4132 if( rAttr.GetValue().Len() &&
4133 USHRT_MAX != (nId = rRTFWrt.GetId( rAttr ) ))
4135 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LS;
4136 rWrt.OutULong( nId );
4137 rRTFWrt.bOutFmtAttr = TRUE;
4140 return rWrt;
4143 static Writer& OutRTF_SwScriptSpace( Writer& rWrt, const SfxPoolItem& rHt )
4145 if( ((const SvxScriptSpaceItem&)rHt).GetValue() )
4147 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ASPALPHA;
4148 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4150 return rWrt;
4152 static Writer& OutRTF_SwHangPunctuation( Writer& rWrt, const SfxPoolItem& rHt )
4154 if( !((const SvxHangingPunctuationItem&)rHt).GetValue() )
4156 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_NOOVERFLOW;
4157 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4159 return rWrt;
4161 static Writer& OutRTF_SwForbiddenRule( Writer& rWrt, const SfxPoolItem& rHt )
4163 if( !((const SvxForbiddenRuleItem&)rHt).GetValue() )
4165 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_NOCWRAP;
4166 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4168 return rWrt;
4171 static Writer& OutRTF_SwFontAlign( Writer& rWrt, const SfxPoolItem& rHt )
4173 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
4174 const SvxParaVertAlignItem & rAttr = (const SvxParaVertAlignItem &)rHt;
4175 const char* pStr;
4176 switch ( rAttr.GetValue() )
4178 case SvxParaVertAlignItem::TOP: pStr = OOO_STRING_SVTOOLS_RTF_FAHANG; break;
4179 case SvxParaVertAlignItem::BOTTOM: pStr = OOO_STRING_SVTOOLS_RTF_FAVAR; break;
4180 case SvxParaVertAlignItem::CENTER: pStr = OOO_STRING_SVTOOLS_RTF_FACENTER; break;
4181 case SvxParaVertAlignItem::BASELINE: pStr = OOO_STRING_SVTOOLS_RTF_FAROMAN; break;
4183 // case SvxParaVertAlignItem::AUTOMATIC:
4184 default: pStr = OOO_STRING_SVTOOLS_RTF_FAAUTO; break;
4186 rWrt.Strm() << pStr;
4187 rRTFWrt.bOutFmtAttr = TRUE;
4188 return rWrt;
4192 * lege hier die Tabellen fuer die RTF-Funktions-Pointer auf
4193 * die Ausgabe-Funktionen an.
4194 * Es sind lokale Strukturen, die nur innerhalb der RTF-DLL
4195 * bekannt sein muessen.
4198 SwAttrFnTab aRTFAttrFnTab = {
4199 /* RES_CHRATR_CASEMAP */ OutRTF_SwCaseMap,
4200 /* RES_CHRATR_CHARSETCOLOR */ 0,
4201 /* RES_CHRATR_COLOR */ OutRTF_SwColor,
4202 /* RES_CHRATR_CONTOUR */ OutRTF_SwContour,
4203 /* RES_CHRATR_CROSSEDOUT */ OutRTF_SwCrossedOut,
4204 /* RES_CHRATR_ESCAPEMENT */ OutRTF_SwEscapement,
4205 /* RES_CHRATR_FONT */ OutRTF_SwFont,
4206 /* RES_CHRATR_FONTSIZE */ OutRTF_SwSize,
4207 /* RES_CHRATR_KERNING */ 0, // NOT USED!! OutRTF_SwKerning,
4208 /* RES_CHRATR_LANGUAGE */ OutRTF_SwLanguage,
4209 /* RES_CHRATR_POSTURE */ OutRTF_SwPosture,
4210 /* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
4211 /* RES_CHRATR_SHADOWED */ OutRTF_SwShadowed,
4212 /* RES_CHRATR_UNDERLINE */ OutRTF_SwUnderline,
4213 /* RES_CHRATR_WEIGHT */ OutRTF_SwWeight,
4214 /* RES_CHRATR_WORDLINEMODE */ 0, // Neu: Wortweises Unter-/Durchstreichen
4215 /* RES_CHRATR_AUTOKERN */ 0, // Neu: Automatisches Pairkerning
4216 /* RES_CHRATR_BLINK */ 0, // Neu: Blinkender Text
4217 /* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen
4218 /* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen
4219 /* RES_CHRATR_BACKGROUND */ OutRTF_SwChrBckgrnd, // Neu: Zeichenhintergrund
4220 /* RES_CHRATR_CJK_FONT */ OutRTF_SwFont,
4221 /* RES_CHRATR_CJK_FONTSIZE */ OutRTF_SwSize,
4222 /* RES_CHRATR_CJK_LANGUAGE */ OutRTF_SwLanguage,
4223 /* RES_CHRATR_CJK_POSTURE */ OutRTF_SwPosture,
4224 /* RES_CHRATR_CJK_WEIGHT */ OutRTF_SwWeight,
4225 /* RES_CHRATR_CTL_FONT */ OutRTF_SwFont,
4226 /* RES_CHRATR_CTL_FONTSIZE */ OutRTF_SwSize,
4227 /* RES_CHRATR_CTL_LANGUAGE */ OutRTF_SwLanguage,
4228 /* RES_CHRATR_CTL_POSTURE */ OutRTF_SwPosture,
4229 /* RES_CHRATR_CTL_WEIGHT */ OutRTF_SwWeight,
4230 /* RES_CHRATR_ROTATE */ OutRTF_SwCharRotate,
4231 /* RES_CHRATR_EMPHASIS_MARK */ OutRTF_SwEmphasisMark,
4232 /* RES_CHRATR_TWO_LINES */ OutRTF_SwTwoInOne,
4233 /* RES_CHRATR_SCALEW */ OutRTF_SwCharScaleW,
4234 /* RES_CHRATR_RELIEF */ OutRTF_SwCharRelief,
4235 /* RES_CHRATR_HIDDEN */ OutRTF_SvxCharHiddenItem,
4236 /* RES_CHRATR_OVERLINE */ OutRTF_SwOverline,
4237 /* RES_CHRATR_DUMMY1 */ 0,
4238 /* RES_CHRATR_DUMMY2 */ 0,
4240 /* RES_TXTATR_REFMARK */ 0, // NOT USED!! OutRTF_SwRefMark,
4241 /* RES_TXTATR_TOXMARK */ 0, // NOT USED!! OutRTF_SwTOXMark,
4242 /* RES_TXTATR_META */ 0,
4243 /* RES_TXTATR_METAFIELD */ 0,
4244 /* RES_TXTATR_AUTOFMT */ OutRTF_SwTxtAutoFmt,
4245 /* RES_TXTATR_INETFMT */ OutRTF_SwTxtINetFmt,
4246 /* RES_TXTATR_CHARFMT */ OutRTF_SwTxtCharFmt,
4247 /* RES_TXTATR_CJK_RUBY */ OutRTF_SwTxtRuby,
4248 /* RES_TXTATR_UNKNOWN_CONTAINER */ 0,
4249 /* RES_TXTATR_DUMMY5 */ 0,
4251 /* RES_TXTATR_FIELD */ OutRTF_SwField,
4252 /* RES_TXTATR_FLYCNT */ OutRTF_SwFlyCntnt,
4253 /* RES_TXTATR_FTN */ OutRTF_SwFtn,
4254 /* RES_TXTATR_DUMMY4 */ 0,
4255 /* RES_TXTATR_DUMMY3 */ 0,
4256 /* RES_TXTATR_DUMMY1 */ 0, // Dummy:
4257 /* RES_TXTATR_DUMMY2 */ 0, // Dummy:
4259 /* RES_PARATR_LINESPACING */ OutRTF_SwLineSpacing,
4260 /* RES_PARATR_ADJUST */ OutRTF_SwAdjust,
4261 /* RES_PARATR_SPLIT */ OutRTF_SvxFmtSplit,
4262 /* RES_PARATR_WIDOWS */ 0, // NOT USED!! OutRTF_SwWidows,
4263 /* RES_PARATR_ORPHANS */ 0, // NOT USED!! OutRTF_SwOrphans,
4264 /* RES_PARATR_TABSTOP */ OutRTF_SwTabStop,
4265 /* RES_PARATR_HYPHENZONE*/ OutRTF_SwHypenZone,
4266 /* RES_PARATR_DROP */ 0,
4267 /* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit
4268 /* RES_PARATR_NUMRULE */ OutRTF_SwNumRule,
4269 /* RES_PARATR_SCRIPTSPACE */ OutRTF_SwScriptSpace,
4270 /* RES_PARATR_HANGINGPUNCTUATION */ OutRTF_SwHangPunctuation,
4271 /* RES_PARATR_FORBIDDEN_RULE*/ OutRTF_SwForbiddenRule,
4272 /* RES_PARATR_VERTALIGN */ OutRTF_SwFontAlign,
4273 /* RES_PARATR_SNAPTOGRID*/ 0, // new
4274 /* RES_PARATR_CONNECT_TO_BORDER */ 0, // new
4275 /* RES_PARATR_OUTLINELEVEL */ 0, // new - outlinelevel
4277 /* RES_PARATR_LIST_ID */ 0, // new
4278 /* RES_PARATR_LIST_LEVEL */ 0, // new
4279 /* RES_PARATR_LIST_ISRESTART */ 0, // new
4280 /* RES_PARATR_LIST_RESTARTVALUE */ 0, // new
4281 /* RES_PARATR_LIST_ISCOUNTED */ 0, // new
4283 /* RES_FILL_ORDER */ 0, // NOT USED!! OutRTF_SwFillOrder,
4284 /* RES_FRM_SIZE */ OutRTF_SwFrmSize,
4285 /* RES_PAPER_BIN */ 0, // NOT USED!! OutRTF_SwFmtPaperBin,
4286 /* RES_LR_SPACE */ OutRTF_SwFmtLRSpace,
4287 /* RES_UL_SPACE */ OutRTF_SwFmtULSpace,
4288 /* RES_PAGEDESC */ 0,
4289 /* RES_BREAK */ 0,
4290 /* RES_CNTNT */ 0,
4291 /* RES_HEADER */ OutRTF_SwFmtHeader,
4292 /* RES_FOOTER */ OutRTF_SwFmtFooter,
4293 /* RES_PRINT */ OutRTF_SwFmtPrint,
4294 /* RES_OPAQUE */ OutRTF_SwFmtOpaque,
4295 /* RES_PROTECT */ OutRTF_SwFmtProtect,
4296 /* RES_SURROUND */ OutRTF_SwFmtSurround,
4297 /* RES_VERT_ORIENT */ OutRTF_SwFmtVertOrient,
4298 /* RES_HORI_ORIENT */ OutRTF_SwFmtHoriOrient,
4299 /* RES_ANCHOR */ OutRTF_SwFmtAnchor,
4300 /* RES_BACKGROUND */ OutRTF_SwFmtBackground,
4301 /* RES_BOX */ OutRTF_SwFmtBox,
4302 /* RES_SHADOW */ OutRTF_SwFmtShadow,
4303 /* RES_FRMMACRO */ 0, // NOT USED!! OutRTF_SwFmtFrmMacro,
4304 /* RES_COL */ OutRTF_SwFmtCol,
4305 /* RES_KEEP */ OutRTF_SvxFmtKeep,
4306 /* RES_URL */ 0, // URL
4307 /* RES_EDIT_IN_READONLY */ 0,
4308 /* RES_LAYOUT_SPLIT */ 0,
4309 /* RES_FRMATR_DUMMY1 */ 0, // Dummy:
4310 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
4311 /* RES_AUTO_STYLE */ 0, // Dummy:
4312 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
4313 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
4314 /* RES_FRMATR_DUMMY6 */ 0, // Dummy:
4315 /* RES_FRAMEDIR*/ OutRTF_SvxFrmDir,
4316 /* RES_FRMATR_DUMMY8 */ 0, // Dummy:
4317 /* RES_FRMATR_DUMMY9 */ 0, // Dummy:
4318 /* RES_FOLLOW_TEXT_FLOW */ 0,
4319 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ 0,
4320 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
4321 /* RES_AUTO_STYLE */ 0, // Dummy:
4322 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
4323 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
4325 /* RES_GRFATR_MIRRORGRF */ OutRTF_SwMirrorGrf,
4326 /* RES_GRFATR_CROPGRF */ OutRTF_SwCropGrf,
4327 /* RES_GRFATR_ROTATION */ 0,
4328 /* RES_GRFATR_LUMINANCE */ 0,
4329 /* RES_GRFATR_CONTRAST */ 0,
4330 /* RES_GRFATR_CHANNELR */ 0,
4331 /* RES_GRFATR_CHANNELG */ 0,
4332 /* RES_GRFATR_CHANNELB */ 0,
4333 /* RES_GRFATR_GAMMA */ 0,
4334 /* RES_GRFATR_INVERT */ 0,
4335 /* RES_GRFATR_TRANSPARENCY */ 0,
4336 /* RES_GRFATR_DRWAMODE */ 0,
4337 /* RES_GRFATR_DUMMY1 */ 0,
4338 /* RES_GRFATR_DUMMY2 */ 0,
4339 /* RES_GRFATR_DUMMY3 */ 0,
4340 /* RES_GRFATR_DUMMY4 */ 0,
4341 /* RES_GRFATR_DUMMY5 */ 0,
4343 /* RES_BOXATR_FORMAT */ 0,
4344 /* RES_BOXATR_FORMULA */ 0,
4345 /* RES_BOXATR_VALUE */ 0,
4347 /* RES_UNKNOWNATR_CONTAINER */ 0
4350 SwNodeFnTab aRTFNodeFnTab = {
4351 /* RES_TXTNODE */ OutRTF_SwTxtNode,
4352 /* RES_GRFNODE */ OutRTF_SwGrfNode,
4353 /* RES_OLENODE */ OutRTF_SwOLENode
4356 /* vi:set tabstop=4 shiftwidth=4 expandtab: */