1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ww8atr.cxx,v $
10 * $Revision: 1.113.40.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
36 * Dieses File enthaelt alle Ausgabe-Funktionen des WW8-Writers;
37 * fuer alle Nodes, Attribute, Formate und Chars.
41 #include <hintids.hxx>
43 #ifndef _APP_HXX //autogen
44 #include <vcl/svapp.hxx>
46 #include <vcl/salbtype.hxx>
47 #include <svtools/zformat.hxx>
48 #include <svtools/itemiter.hxx>
49 #include <svx/fontitem.hxx>
50 #ifndef _SVX_TSTPITEM_HXX //autogen
51 #include <svx/tstpitem.hxx>
53 #include <svx/adjitem.hxx>
54 #include <svx/spltitem.hxx>
55 #include <svx/widwitem.hxx>
56 #include <svx/lspcitem.hxx>
57 #include <svx/keepitem.hxx>
58 #include <svx/shaditem.hxx>
59 #include <svx/brshitem.hxx>
60 #include <svx/postitem.hxx>
61 #include <svx/wghtitem.hxx>
62 #include <svx/kernitem.hxx>
63 #include <svx/crsditem.hxx>
64 #include <svx/cmapitem.hxx>
65 #include <svx/wrlmitem.hxx>
66 #include <svx/udlnitem.hxx>
67 #include <svx/langitem.hxx>
68 #include <svx/escpitem.hxx>
69 #include <svx/fhgtitem.hxx>
70 #include <svx/colritem.hxx>
71 #include <svx/hyznitem.hxx>
72 #include <svx/brkitem.hxx>
73 #include <svx/lrspitem.hxx>
74 #include <svx/ulspitem.hxx>
75 #include <svx/boxitem.hxx>
76 #include <svx/cntritem.hxx>
77 #include <svx/shdditem.hxx>
78 #include <svx/akrnitem.hxx>
79 #include <svx/pbinitem.hxx>
80 #ifndef _SVX_EMPHITEM_HXX
81 #include <svx/emphitem.hxx>
83 #include <svx/twolinesitem.hxx>
84 #include <svx/charscaleitem.hxx>
85 #include <svx/charrotateitem.hxx>
86 #include <svx/charreliefitem.hxx>
87 #include <svx/paravertalignitem.hxx>
88 #include <svx/pgrditem.hxx>
89 #include <svx/frmdiritem.hxx>
90 #include <svx/blnkitem.hxx>
91 #include <svx/charhiddenitem.hxx>
93 #include <fchrfmt.hxx>
94 #include <fmtfsize.hxx>
95 #include <fmtpdsc.hxx>
96 #include <fmtornt.hxx>
97 #include <fmtanchr.hxx>
98 #include <fmtclds.hxx>
99 #include <fmtsrnd.hxx>
100 #include <fmtftn.hxx>
101 #include <fmtflcnt.hxx>
102 #include <frmatr.hxx>
103 #include <swtable.hxx>
104 #include <fmtinfmt.hxx>
105 #include <txtfld.hxx>
106 #include <txtftn.hxx>
107 #include <poolfmt.hxx>
108 #include <doc.hxx> // Doc fuer Fussnoten
110 #include <paratr.hxx>
111 #include <fldbas.hxx> // fuer SwField ...
112 #include <docufld.hxx> // fuer SwField ...
113 #include <expfld.hxx>
114 #include <pagedesc.hxx> // fuer SwPageDesc...
115 #include <flddat.hxx> // fuer Datum-Felder
116 #include <ndtxt.hxx> // fuer Numrules
117 #include <fmthbsh.hxx>
118 #include <swrect.hxx>
119 #include <reffld.hxx>
120 #include <ftninfo.hxx>
121 #include <charfmt.hxx>
122 #include <section.hxx>
123 #include <lineinfo.hxx>
124 #include <fmtline.hxx>
126 #include <fmtftntx.hxx>
127 #include <breakit.hxx>
128 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
129 #include <com/sun/star/i18n/ScriptType.hdl>
131 #include <unotools/localedatawrapper.hxx>
132 #include <tgrditem.hxx>
133 #include <flddropdown.hxx>
134 #include <chpfld.hxx>
135 #include <fmthdft.hxx>
137 #if OSL_DEBUG_LEVEL > 1
138 # include <fmtcntnt.hxx>
140 #include "writerhelper.hxx"
141 #include "writerwordglue.hxx"
142 #include "wrtww8.hxx"
143 #include "ww8par.hxx"
144 #include "fields.hxx"
145 #include <vcl/outdev.hxx>
146 #include <i18npool/mslangid.hxx>
148 using namespace ::com::sun::star
;
149 using namespace nsFieldFlags
;
150 using namespace nsSwDocInfoSubType
;
154 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
155 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
156 * definiert und mit der akt. verglichen. Bei unterschieden wird der
157 * Compiler schon meckern.
159 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
160 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
163 #if !defined(MSC) && !defined(UNX) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
165 #define ATTRFNTAB_SIZE 130
166 #if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
167 # error "Attribut-Tabelle ist ungueltigt. Wurden neue Hint-ID's zugefuegt ??"
170 #define NODETAB_SIZE 3
171 #if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
172 # error "Node-Tabelle ist ungueltigt. Wurden neue Hint-ID's zugefuegt ??"
177 using namespace sw::util
;
178 using namespace sw::types
;
179 //------------------------------------------------------------
180 // Forward-Declarationen
181 //------------------------------------------------------------
182 static Writer
& OutWW8_SwFmtBreak( Writer
& rWrt
, const SfxPoolItem
& rHt
);
183 static Writer
& OutWW8_SwNumRuleItem( Writer
& rWrt
, const SfxPoolItem
& rHt
);
186 Sadly word does not have two different sizes for asian font size and western
187 font size, it has to different fonts, but not sizes, so we have to use our
188 guess as to the script used and disable the export of one type. The same
189 occurs for font weight and posture (bold and italic)
191 In addition WW7- has only one character language identifier while WW8+ has two
193 bool SwWW8Writer::CollapseScriptsforWordOk(USHORT nScript
, USHORT nWhich
)
196 if (nScript
== i18n::ScriptType::ASIAN
)
198 //for asian in ww8, there is only one fontsize
199 //and one fontstyle (posture/weight) for ww6
200 //there is the additional problem that there
201 //is only one font setting for all three scripts
204 case RES_CHRATR_FONTSIZE
:
205 case RES_CHRATR_POSTURE
:
206 case RES_CHRATR_WEIGHT
:
209 case RES_CHRATR_LANGUAGE
:
210 case RES_CHRATR_CTL_FONT
:
211 case RES_CHRATR_CTL_FONTSIZE
:
212 case RES_CHRATR_CTL_LANGUAGE
:
213 case RES_CHRATR_CTL_POSTURE
:
214 case RES_CHRATR_CTL_WEIGHT
:
221 else if (nScript
== i18n::ScriptType::COMPLEX
)
223 //Complex is ok in ww8, but for ww6 there is only
224 //one font, one fontsize, one fontsize (weight/posture)
225 //and only one language
230 case RES_CHRATR_CJK_FONT
:
231 case RES_CHRATR_CJK_FONTSIZE
:
232 case RES_CHRATR_CJK_POSTURE
:
233 case RES_CHRATR_CJK_WEIGHT
:
234 case RES_CHRATR_CJK_LANGUAGE
:
235 case RES_CHRATR_FONT
:
236 case RES_CHRATR_FONTSIZE
:
237 case RES_CHRATR_POSTURE
:
238 case RES_CHRATR_WEIGHT
:
239 case RES_CHRATR_LANGUAGE
:
249 //for western in ww8, there is only one fontsize
250 //and one fontstyle (posture/weight) for ww6
251 //there is the additional problem that there
252 //is only one font setting for all three scripts
255 case RES_CHRATR_CJK_FONTSIZE
:
256 case RES_CHRATR_CJK_POSTURE
:
257 case RES_CHRATR_CJK_WEIGHT
:
260 case RES_CHRATR_CJK_LANGUAGE
:
261 case RES_CHRATR_CTL_FONT
:
262 case RES_CHRATR_CTL_FONTSIZE
:
263 case RES_CHRATR_CTL_LANGUAGE
:
264 case RES_CHRATR_CTL_POSTURE
:
265 case RES_CHRATR_CTL_WEIGHT
:
275 //------------------------------------------------------------
276 // Hilfsroutinen fuer Styles
277 //------------------------------------------------------------
279 void SwWW8Writer::ExportPoolItemsToCHP(sw::PoolItems
&rItems
, USHORT nScript
)
281 sw::cPoolItemIter aEnd
= rItems
.end();
282 for (sw::cPoolItemIter aI
= rItems
.begin(); aI
!= aEnd
; ++aI
)
284 const SfxPoolItem
*pItem
= aI
->second
;
285 USHORT nWhich
= pItem
->Which();
286 if (FnAttrOut pOut
= aWW8AttrFnTab
[nWhich
- RES_CHRATR_BEGIN
])
288 if (nWhich
< RES_CHRATR_BEGIN
|| nWhich
>= RES_TXTATR_END
)
290 if (SwWW8Writer::CollapseScriptsforWordOk(nScript
, nWhich
))
291 (*pOut
)(*this, *pItem
);
297 * Format wie folgt ausgeben:
298 * - gebe die Attribute aus; ohne Parents!
301 void SwWW8Writer::Out_SfxItemSet(const SfxItemSet
& rSet
, bool bPapFmt
,
302 bool bChpFmt
, USHORT nScript
)
306 const SfxPoolItem
* pItem
;
309 pISet
= &rSet
; // fuer Doppel-Attribute
311 //If frame dir is set, but not adjust, then force adjust as well
312 if (bPapFmt
&& SFX_ITEM_SET
== rSet
.GetItemState(RES_FRAMEDIR
, false))
314 //No explicit adjust set ?
315 if (SFX_ITEM_SET
!= rSet
.GetItemState(RES_PARATR_ADJUST
, false))
317 if (0 != (pItem
= rSet
.GetItem(RES_PARATR_ADJUST
)))
319 // then set the adjust used by the parent format
320 pOut
= aWW8AttrFnTab
[ static_cast< USHORT
>(RES_PARATR_ADJUST
) - RES_CHRATR_BEGIN
];
321 (*pOut
)( *this, *pItem
);
326 if (bPapFmt
&& SFX_ITEM_SET
== rSet
.GetItemState(RES_PARATR_NUMRULE
,
329 pOut
= aWW8AttrFnTab
[ static_cast< USHORT
>(RES_PARATR_NUMRULE
) - RES_CHRATR_BEGIN
];
330 (*pOut
)( *this, *pItem
);
331 // switch off the numerbering?
332 if( !((SwNumRuleItem
*)pItem
)->GetValue().Len() && SFX_ITEM_SET
333 != rSet
.GetItemState( RES_LR_SPACE
, false) && SFX_ITEM_SET
334 == rSet
.GetItemState( RES_LR_SPACE
, true, &pItem
) )
336 // the set the LR-Space of the parentformat!
337 pOut
= aWW8AttrFnTab
[ static_cast< USHORT
>(RES_LR_SPACE
) - RES_CHRATR_BEGIN
];
338 (*pOut
)( *this, *pItem
);
342 sw::PoolItems aItems
;
343 GetPoolItems(rSet
, aItems
);
345 ExportPoolItemsToCHP(aItems
, nScript
);
347 sw::cPoolItemIter aEnd
= aItems
.end();
348 for (sw::cPoolItemIter aI
= aItems
.begin(); aI
!= aEnd
; ++aI
)
351 USHORT nWhich
= pItem
->Which();
352 pOut
= aWW8AttrFnTab
[nWhich
- RES_CHRATR_BEGIN
];
353 if( 0 != pOut
&& (!bPapFmt
|| RES_PARATR_NUMRULE
!= nWhich
))
355 bool bPap
= nWhich
>= RES_PARATR_BEGIN
356 && nWhich
< RES_FRMATR_END
;
358 (*pOut
)(*this, *pItem
);
361 pISet
= 0; // fuer Doppel-Attribute
365 void SwWW8Writer::GatherChapterFields()
367 //If the header/footer contains a chapter field
368 SwClientIter
aIter(*pDoc
->GetSysFldType(RES_CHAPTERFLD
));
369 const SwClient
*pField
= aIter
.First(TYPE(SwFmtFld
));
372 const SwFmtFld
* pFld
= (const SwFmtFld
*)(pField
);
373 if (const SwTxtFld
*pTxtFld
= pFld
->GetTxtFld())
375 const SwTxtNode
&rTxtNode
= pTxtFld
->GetTxtNode();
376 maChapterFieldLocs
.push_back(rTxtNode
.GetIndex());
378 pField
= aIter
.Next();
382 bool SwWW8Writer::CntntContainsChapterField(const SwFmtCntnt
&rCntnt
) const
385 if (const SwNodeIndex
* pSttIdx
= rCntnt
.GetCntntIdx())
387 SwNodeIndex
aIdx(*pSttIdx
, 1);
388 SwNodeIndex
aEnd(*pSttIdx
->GetNode().EndOfSectionNode());
389 ULONG nStart
= aIdx
.GetIndex();
390 ULONG nEnd
= aEnd
.GetIndex();
391 //If the header/footer contains a chapter field
392 mycCFIter aIEnd
= maChapterFieldLocs
.end();
393 for (mycCFIter aI
= maChapterFieldLocs
.begin(); aI
!= aIEnd
; ++aI
)
395 if ((nStart
<= *aI
) && (*aI
<= nEnd
))
405 bool SwWW8Writer::FmtHdFtContainsChapterField(const SwFrmFmt
&rFmt
) const
407 if (maChapterFieldLocs
.empty())
411 const SwFrmFmt
*pFmt
= 0;
412 if (0 != (pFmt
= rFmt
.GetHeader().GetHeaderFmt()))
413 bRet
= CntntContainsChapterField(pFmt
->GetCntnt());
414 if (!bRet
&& 0 != (pFmt
= rFmt
.GetFooter().GetFooterFmt()))
415 bRet
= CntntContainsChapterField(pFmt
->GetCntnt());
420 bool SwWW8Writer::SetAktPageDescFromNode(const SwNode
&rNd
)
422 bool bNewPageDesc
= false;
423 const SwPageDesc
* pCurrent
= SwPageDesc::GetPageDescOfNode(rNd
);
424 ASSERT(pCurrent
&& pAktPageDesc
, "Not possible surely");
425 if (pAktPageDesc
&& pCurrent
)
427 if (pCurrent
!= pAktPageDesc
)
429 if (pAktPageDesc
->GetFollow() != pCurrent
)
433 const SwFrmFmt
& rTitleFmt
= pAktPageDesc
->GetMaster();
434 const SwFrmFmt
& rFollowFmt
= pCurrent
->GetMaster();
436 bNewPageDesc
= !IsPlausableSingleWordSection(rTitleFmt
,
439 pAktPageDesc
= pCurrent
;
443 const SwFrmFmt
&rFmt
= pCurrent
->GetMaster();
444 bNewPageDesc
= FmtHdFtContainsChapterField(rFmt
);
450 // Da WW nur Break-After ( Pagebreak und Sectionbreaks ) kennt, im SW aber
451 // Bagebreaks "vor" und "nach" und Pagedescs nur "vor" existieren, werden
452 // die Breaks 2* durchgeklimpert, naemlich vor und hinter jeder Zeile.
453 // Je nach BreakTyp werden sie vor oder nach der Zeile gesetzt.
454 // Es duerfen nur Funktionen gerufen werden, die nicht in den
455 // Ausgabebereich pO schreiben, da dieser nur einmal fuer CHP und PAP existiert
456 // und damit im falschen landen wuerden.
457 void SwWW8Writer::Out_SfxBreakItems(const SfxItemSet
*pSet
, const SwNode
& rNd
)
459 bool bAllowOutputPageDesc
= false;
460 if (!bStyDef
&& !bOutKF
&& !bInWriteEscher
&& !bOutPageDescs
)
461 bAllowOutputPageDesc
= true;
463 if (!bAllowOutputPageDesc
)
468 bool bNewPageDesc
= false;
469 const SfxPoolItem
* pItem
=0;
470 const SwFmtPageDesc
*pPgDesc
=0;
472 //Output a sectionbreak if theres a new pagedesciptor. otherwise output a
473 //pagebreak if there is a pagebreak here, unless the new page (follow
474 //style) is different to the current one, in which case plump for a
476 bool bBreakSet
= false;
478 if (pSet
&& pSet
->Count())
480 if (SFX_ITEM_SET
== pSet
->GetItemState(RES_PAGEDESC
, false, &pItem
)
481 && ((SwFmtPageDesc
*)pItem
)->GetRegisteredIn())
485 pPgDesc
= (const SwFmtPageDesc
*)pItem
;
486 pAktPageDesc
= pPgDesc
->GetPageDesc();
488 else if (SFX_ITEM_SET
== pSet
->GetItemState(RES_BREAK
, false, &pItem
))
490 // --> FME 2007-05-30 #146867# Word does not like hard break attributes in some table cells
491 bool bRemoveHardBreakInsideTable
= false;
494 const SwTableNode
* pTableNode
= rNd
.FindTableNode();
497 const SwTableBox
* pBox
= rNd
.GetTblBox();
498 const SwTableLine
* pLine
= pBox
? pBox
->GetUpper() : 0;
499 // but only for non-complex tables
500 if ( pLine
&& !pLine
->GetUpper() )
502 // check if box is not first in that line:
503 if ( 0 < pLine
->GetTabBoxes().GetPos( pBox
) && pBox
->GetSttNd() )
505 bRemoveHardBreakInsideTable
= true;
514 if ( !bRemoveHardBreakInsideTable
)
516 ASSERT(pAktPageDesc
, "should not be possible");
518 If because of this pagebreak the page desc following the page
519 break is the follow style of the current page desc then output a
520 section break using that style instead. At least in those cases
521 we end up with the same style in word and writer, nothing can be
522 done when it happens when we get a new pagedesc because we
523 overflow from the first page style.
527 // --> OD 2007-05-30 #i76301#
528 // assure that there is a page break before set at the node.
529 const SvxFmtBreakItem
* pBreak
= dynamic_cast<const SvxFmtBreakItem
*>(pItem
);
531 pBreak
->GetBreak() == SVX_BREAK_PAGE_BEFORE
)
533 bNewPageDesc
= SetAktPageDescFromNode(rNd
);
538 OutWW8_SwFmtBreak( *this, *pItem
);
545 No explicit page break, lets see if the style had one and we've moved to a
546 new page style because of it, if we have to then we take the opportunity to
547 set the equivalent word section here. We *could* do it for every paragraph
548 that moves onto a new page because of layout, but that would be insane.
550 bool bHackInBreak
= false;
553 if (const SwCntntNode
*pNd
= rNd
.GetCntntNode())
555 const SvxFmtBreakItem
&rBreak
=
556 ItemGet
<SvxFmtBreakItem
>(*pNd
, RES_BREAK
);
557 if (rBreak
.GetBreak() == SVX_BREAK_PAGE_BEFORE
)
560 { // Even a pagedesc item is set, the break item can be set 'NONE',
561 // but a pagedesc item is an implicit page break before...
562 const SwFmtPageDesc
&rPageDesc
=
563 ItemGet
<SwFmtPageDesc
>( *pNd
, RES_PAGEDESC
);
564 if( rPageDesc
.GetRegisteredIn() )
572 ASSERT(pAktPageDesc
, "should not be possible");
574 bNewPageDesc
= SetAktPageDescFromNode(rNd
);
577 if (bNewPageDesc
&& pAktPageDesc
)
579 // --> OD 2007-05-29 #i76300#
580 // code moved code to method <SwWW8Writer::PrepareNewPageDesc(..)>
581 // // Die PageDescs werden beim Auftreten von PageDesc-Attributen nur in
582 // // WW8Writer::pSepx mit der entsprechenden Position eingetragen. Das
583 // // Aufbauen und die Ausgabe der am PageDesc haengenden Attribute und
584 // // Kopf/Fusszeilen passiert nach dem Haupttext und seinen Attributen.
586 // ULONG nFcPos = ReplaceCr(0x0c); // Page/Section-Break
588 // const SwSectionFmt *pFmt = 0;
589 // const SwSectionNode* pSect = rNd.FindSectionNode();
590 // if (pSect && CONTENT_SECTION == pSect->GetSection().GetType())
591 // pFmt = pSect->GetSection().GetFmt();
593 // // tatsaechlich wird hier NOCH NICHTS ausgegeben, sondern
594 // // nur die Merk-Arrays aCps, aSects entsprechend ergaenzt
597 // const SwFmtLineNumber *pNItem = 0;
599 // pNItem = &(ItemGet<SwFmtLineNumber>(*pSet,RES_LINENUMBER));
600 // else if (const SwCntntNode *pNd = rNd.GetCntntNode())
601 // pNItem = &(ItemGet<SwFmtLineNumber>(*pNd,RES_LINENUMBER));
602 // ULONG nLnNm = pNItem ? pNItem->GetStartValue() : 0;
605 // pSepx->AppendSep(Fc2Cp(nFcPos), *pPgDesc, rNd, pFmt, nLnNm);
607 // pSepx->AppendSep(Fc2Cp(nFcPos), pAktPageDesc, rNd, pFmt, nLnNm);
609 PrepareNewPageDesc( pSet
, rNd
, pPgDesc
, pAktPageDesc
);
611 bBreakBefore
= false;
614 // --> OD 2007-05-29 #i76300#
615 bool SwWW8Writer::Out_FollowPageDesc( const SfxItemSet
* pSet
,
616 const SwTxtNode
* pNd
)
622 pAktPageDesc
!= pAktPageDesc
->GetFollow() )
624 PrepareNewPageDesc( pSet
, *pNd
, 0, pAktPageDesc
->GetFollow() );
631 // initial version by extracting corresponding code from method <SwWW8Writer::Out_SfxBreakItems(..)>
632 void SwWW8Writer::PrepareNewPageDesc( const SfxItemSet
*pSet
,
634 const SwFmtPageDesc
* pNewPgDescFmt
,
635 const SwPageDesc
* pNewPgDesc
)
637 // Die PageDescs werden beim Auftreten von PageDesc-Attributen nur in
638 // WW8Writer::pSepx mit der entsprechenden Position eingetragen. Das
639 // Aufbauen und die Ausgabe der am PageDesc haengenden Attribute und
640 // Kopf/Fusszeilen passiert nach dem Haupttext und seinen Attributen.
642 ULONG nFcPos
= ReplaceCr(0x0c); // Page/Section-Break
644 const SwSectionFmt
* pFmt
= 0;
645 const SwSectionNode
* pSect
= rNd
.FindSectionNode();
647 CONTENT_SECTION
== pSect
->GetSection().GetType() )
649 pFmt
= pSect
->GetSection().GetFmt();
652 // tatsaechlich wird hier NOCH NICHTS ausgegeben, sondern
653 // nur die Merk-Arrays aCps, aSects entsprechend ergaenzt
656 const SwFmtLineNumber
* pNItem
= 0;
659 pNItem
= &(ItemGet
<SwFmtLineNumber
>(*pSet
,RES_LINENUMBER
));
661 else if (const SwCntntNode
*pNd
= rNd
.GetCntntNode())
663 pNItem
= &(ItemGet
<SwFmtLineNumber
>(*pNd
,RES_LINENUMBER
));
665 const ULONG nLnNm
= pNItem
? pNItem
->GetStartValue() : 0;
669 pSepx
->AppendSep(Fc2Cp(nFcPos
), *pNewPgDescFmt
, rNd
, pFmt
, nLnNm
);
671 else if ( pNewPgDesc
)
673 pSepx
->AppendSep(Fc2Cp(nFcPos
), pNewPgDesc
, rNd
, pFmt
, nLnNm
);
677 ASSERT( false, "<SwWW8Writer::PrepareNewPageDesc(..)> - misusage: neither page desc format nor page desc provided." );
684 void SwWW8Writer::CorrTabStopInSet(SfxItemSet
& rSet
, USHORT nAbsLeft
)
686 const SvxTabStopItem
*pItem
=
687 sw::util::HasItem
<SvxTabStopItem
>(rSet
, RES_PARATR_TABSTOP
);
691 // dann muss das fuer die Ausgabe korrigiert werden
692 SvxTabStopItem
aTStop(*pItem
);
693 for(USHORT nCnt
= 0; nCnt
< aTStop
.Count(); ++nCnt
)
695 SvxTabStop
& rTab
= (SvxTabStop
&)aTStop
[ nCnt
];
696 if( SVX_TAB_ADJUST_DEFAULT
!= rTab
.GetAdjustment() &&
697 rTab
.GetTabPos() >= nAbsLeft
)
698 rTab
.GetTabPos() -= nAbsLeft
;
701 aTStop
.Remove( nCnt
);
709 BYTE
SwWW8Writer::GetNumId( USHORT eNumType
)
714 case SVX_NUM_CHARS_UPPER_LETTER
:
715 case SVX_NUM_CHARS_UPPER_LETTER_N
: nRet
= 3; break;
716 case SVX_NUM_CHARS_LOWER_LETTER
:
717 case SVX_NUM_CHARS_LOWER_LETTER_N
: nRet
= 4; break;
718 case SVX_NUM_ROMAN_UPPER
: nRet
= 1; break;
719 case SVX_NUM_ROMAN_LOWER
: nRet
= 2; break;
722 case SVX_NUM_CHAR_SPECIAL
: nRet
= 23; break;
724 // nix, macht WW undokumentiert auch so
725 case SVX_NUM_NUMBER_NONE
: nRet
= 0xff; break;
730 void SwWW8Writer::ExportOutlineNumbering(BYTE nLvl
, const SwNumFmt
&rNFmt
,
733 if (nLvl
>= WW8ListManager::nMaxLevel
)
734 nLvl
= WW8ListManager::nMaxLevel
-1;
738 // write sprmPOutLvl sprmPIlvl and sprmPIlfo
739 SwWW8Writer::InsUInt16( *pO
, 0x2640 );
740 pO
->Insert( nLvl
, pO
->Count() );
741 SwWW8Writer::InsUInt16( *pO
, 0x260a );
742 pO
->Insert( nLvl
, pO
->Count() );
743 SwWW8Writer::InsUInt16( *pO
, 0x460b );
744 SwWW8Writer::InsUInt16( *pO
, 1 + GetId(
745 *pDoc
->GetOutlineNumRule() ) );
749 Out_SwNumLvl( nLvl
);
750 // --> OD 2008-06-03 #i86652#
751 // if (rNFmt.GetAbsLSpace())
752 if ( rNFmt
.GetPositionAndSpaceMode() ==
753 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
&&
754 rNFmt
.GetAbsLSpace() )
757 SwNumFmt
aNumFmt(rNFmt
);
758 const SvxLRSpaceItem
& rLR
=
759 ItemGet
<SvxLRSpaceItem
>(rFmt
, RES_LR_SPACE
);
760 aNumFmt
.SetAbsLSpace(writer_cast
<short>(
761 aNumFmt
.GetAbsLSpace() + rLR
.GetLeft()));
762 Out_NumRuleAnld( *pDoc
->GetOutlineNumRule(),
766 Out_NumRuleAnld( *pDoc
->GetOutlineNumRule(),
771 // --> OD 2007-06-04 #i77805#
772 bool SwWW8Writer::DisallowInheritingOutlineNumbering(const SwFmt
&rFmt
)
776 //If there is no numbering on this fmt, but its parent was outline
777 //numbered, then in writer this is no inheritied, but in word it would
778 //be, so we must export "no numbering" and "body level" to make word
779 //behave like writer (see #i25755)
780 if (SFX_ITEM_SET
!= rFmt
.GetItemState(RES_PARATR_NUMRULE
, false))
782 if (const SwFmt
*pParent
= rFmt
.DerivedFrom())
784 //BYTE nLvl = ((const SwTxtFmtColl*)pParent)->GetOutlineLevel(); //#outline level,removed by zhaojianwei
785 //if (MAXLEVEL > nLvl)
786 //{ //<-end, ->add by zhaojianwei
787 if (((const SwTxtFmtColl
*)pParent
)->IsAssignedToListLevelOfOutlineStyle())
788 { //<-end,zhaojianwei
791 SwWW8Writer::InsUInt16(*pO
, 0x2640);
792 pO
->Insert(BYTE(9), pO
->Count());
793 SwWW8Writer::InsUInt16(*pO
, 0x460b);
794 SwWW8Writer::InsUInt16(*pO
, 0);
798 /*whats the winword 6 way to do this ?*/
807 void SwWW8Writer::Out_SwFmt(const SwFmt
& rFmt
, bool bPapFmt
, bool bChpFmt
,
810 bool bCallOutSet
= true;
811 const SwModify
* pOldMod
= pOutFmtNode
;
814 switch( rFmt
.Which() )
816 case RES_CONDTXTFMTCOLL
:
820 //BYTE nLvl = ((const SwTxtFmtColl&)rFmt).GetOutlineLevel(); //#outline level,removed by zhaojianwei
821 //if (MAXLEVEL > nLvl)
822 //{ //<-end, ->add by zhaojianwei
823 if (((const SwTxtFmtColl
&)rFmt
).IsAssignedToListLevelOfOutlineStyle())
825 int nLvl
= ((const SwTxtFmtColl
&)rFmt
).GetAssignedOutlineStyleLevel(); //<-end,zhaojianwei
827 //if outline numbered
828 // if Write StyleDefinition then write the OutlineRule
829 const SwNumFmt
& rNFmt
= pDoc
->GetOutlineNumRule()->Get(static_cast<USHORT
>(nLvl
));
831 ExportOutlineNumbering(static_cast<BYTE
>(nLvl
), rNFmt
, rFmt
);
833 // --> OD 2008-06-03 #i86652#
834 // if (rNFmt.GetAbsLSpace())
835 if ( rNFmt
.GetPositionAndSpaceMode() ==
836 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
&&
837 rNFmt
.GetAbsLSpace() )
840 SfxItemSet
aSet( rFmt
.GetAttrSet() );
842 ItemGet
<SvxLRSpaceItem
>(aSet
, RES_LR_SPACE
));
844 aLR
.SetTxtLeft( aLR
.GetTxtLeft() + rNFmt
.GetAbsLSpace() );
845 aLR
.SetTxtFirstLineOfst( GetWordFirstLineOffset(rNFmt
));
848 SwWW8Writer::CorrTabStopInSet( aSet
, rNFmt
.GetAbsLSpace() );
849 Out_SfxItemSet( aSet
, bPapFmt
, bChpFmt
,
850 i18n::ScriptType::LATIN
);
856 //otherwise we might have to remove outline numbering from
857 //what gets exported if the parent style was outline numbered
858 // --> OD 2007-06-04 #i77805#
859 // If inherited outline numbering is suppress, the left/right
860 // margins has to be exported explicitly.
861 if ( bStyDef
&& DisallowInheritingOutlineNumbering(rFmt
) )
863 SfxItemSet
aSet( rFmt
.GetAttrSet() );
865 ItemGet
<SvxLRSpaceItem
>(aSet
, RES_LR_SPACE
));
867 Out_SfxItemSet( aSet
, bPapFmt
, bChpFmt
,
868 com::sun::star::i18n::ScriptType::LATIN
);
881 ASSERT(mpParentFrame
, "No parent frame, all broken");
885 const SwFrmFmt
&rFrmFmt
= mpParentFrame
->GetFrmFmt();
887 SfxItemSet
aSet(pDoc
->GetAttrPool(), RES_FRMATR_BEGIN
,
889 aSet
.Set(rFrmFmt
.GetAttrSet());
891 // Fly als Zeichen werden bei uns zu Absatz-gebundenen
892 // jetzt den Abstand vom Absatz-Rand setzen
895 aSet
.Put(SwFmtHoriOrient(pFlyOffset
->X()));
896 aSet
.Put(SwFmtVertOrient(pFlyOffset
->Y()));
897 SwFmtAnchor
aAnchor(rFrmFmt
.GetAnchor());
898 aAnchor
.SetType(eNewAnchorType
);
902 if (SFX_ITEM_SET
!= aSet
.GetItemState(RES_SURROUND
))
903 aSet
.Put(SwFmtSurround(SURROUND_NONE
));
905 bOutFlyFrmAttrs
= true;
906 //script doesn't matter if not exporting chp
907 Out_SfxItemSet(aSet
, true, false,
908 i18n::ScriptType::LATIN
);
909 bOutFlyFrmAttrs
= false;
916 ASSERT( !this, "Was wird hier ausgegeben ??? " );
921 Out_SfxItemSet( rFmt
.GetAttrSet(), bPapFmt
, bChpFmt
,
922 i18n::ScriptType::LATIN
);
923 pOutFmtNode
= pOldMod
;
926 bool SwWW8Writer::HasRefToObject(USHORT nTyp
, const String
* pNm
, USHORT nSeqNo
)
929 const SwTxtNode
* pNd
;
930 SwClientIter
aIter( *pDoc
->GetSysFldType( RES_GETREFFLD
));
931 for( SwFmtFld
* pFld
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
));
932 pFld
&& !bFnd
; pFld
= (SwFmtFld
*)aIter
.Next() )
933 if( pFld
->GetTxtFld() && nTyp
== pFld
->GetFld()->GetSubType() &&
934 0 != ( pNd
= pFld
->GetTxtFld()->GetpTxtNode() ) &&
935 pNd
->GetNodes().IsDocNodes() )
937 const SwGetRefField
& rRFld
= *(SwGetRefField
*)pFld
->GetFld();
942 bFnd
= (*pNm
== rRFld
.GetSetRefName()) ? true : false;
946 bFnd
= (nSeqNo
== rRFld
.GetSeqNo()) ? true : false;
948 case REF_SEQUENCEFLD
: break; // ???
949 case REF_OUTLINE
: break; // ???
956 String
SwWW8Writer::GetBookmarkName( USHORT nTyp
, const String
* pNm
,
963 sRet
.APPEND_CONST_ASC( "Ref_" );
966 case REF_SEQUENCEFLD
:
974 sRet
.APPEND_CONST_ASC( "_RefF" );
975 sRet
+= String::CreateFromInt32( nSeqNo
);
978 sRet
.APPEND_CONST_ASC( "_RefE" );
979 sRet
+= String::CreateFromInt32( nSeqNo
);
982 // --> OD 2005-06-08 #i43956# - encode bookmark accordingly
983 return BookmarkToWord( sRet
);
987 //-----------------------------------------------------------------------
989 /* File CHRATR.HXX: */
991 static Writer
& OutWW8_SwBoldUSW(Writer
& rWrt
, BYTE nId
, bool bVal
)
993 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
994 if( rWrtWW8
.bWrtWW8
)
995 rWrtWW8
.InsUInt16(8 == nId
? 0x2a53 : 0x0835 + nId
);
997 return rWrt
; // das Attribut gibt es im WW6 nicht
999 rWrtWW8
.pO
->Insert( 85 + nId
, rWrtWW8
.pO
->Count() );
1000 rWrtWW8
.pO
->Insert( bVal
? 1 : 0, rWrtWW8
.pO
->Count() );
1004 static Writer
& OutWW8_SwBoldBiDiUSW(Writer
& rWrt
, BYTE nId
, bool bVal
)
1006 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1007 ASSERT(nId
<= 1, "out of range");
1008 if (!rWrtWW8
.bWrtWW8
|| nId
> 1)
1011 rWrtWW8
.InsUInt16(0x085C + nId
);
1012 rWrtWW8
.pO
->Insert(bVal
? 1 : 0, rWrtWW8
.pO
->Count());
1016 static Writer
& OutWW8_SwFont( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1018 const SvxFontItem
& rAttr
= (const SvxFontItem
&)rHt
;
1019 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1020 USHORT nFontID
= rWrtWW8
.GetId(rAttr
);
1022 if( rWrtWW8
.bWrtWW8
)
1024 rWrtWW8
.InsUInt16( 0x4a4f );
1025 rWrtWW8
.InsUInt16( nFontID
);
1026 rWrtWW8
.InsUInt16( 0x4a51 );
1029 rWrtWW8
.pO
->Insert( 93, rWrtWW8
.pO
->Count() );
1030 rWrtWW8
.InsUInt16( nFontID
);
1034 static Writer
& OutWW8_SwCTLFont(Writer
& rWrt
, const SfxPoolItem
& rHt
)
1036 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1037 if (rWrtWW8
.bWrtWW8
)
1039 rWrtWW8
.InsUInt16(0x4A5E);
1040 rWrtWW8
.InsUInt16(rWrtWW8
.GetId((const SvxFontItem
&)rHt
));
1045 static Writer
& OutWW8_SwCJKFont( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1047 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1048 if( rWrtWW8
.bWrtWW8
)
1050 rWrtWW8
.InsUInt16( 0x4a50 );
1051 rWrtWW8
.InsUInt16(rWrtWW8
.GetId((const SvxFontItem
&)rHt
));
1056 static Writer
& OutWW8_SwBiDiWeight( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1058 //Can only export in 8+, in 7- export as normal varient and expect that
1059 //upperlevel code has blocked exporting clobbering attributes
1060 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1061 if (rWrtWW8
.bWrtWW8
)
1063 OutWW8_SwBoldBiDiUSW(rWrt
, 0,
1064 WEIGHT_BOLD
== ((const SvxWeightItem
&)rHt
).GetWeight());
1068 OutWW8_SwBoldUSW(rWrt
, 0,
1069 WEIGHT_BOLD
== ((const SvxWeightItem
&)rHt
).GetWeight());
1074 static Writer
& OutWW8_SwBiDiPosture( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1076 //Can only export in 8+, in 7- export as normal varient and expect that
1077 //upperlevel code has blocked exporting clobbering attributes
1078 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1079 if (rWrtWW8
.bWrtWW8
)
1081 OutWW8_SwBoldBiDiUSW( rWrt
, 1,
1082 ITALIC_NONE
!= ((const SvxPostureItem
&)rHt
).GetPosture() );
1086 OutWW8_SwBoldUSW( rWrt
, 1,
1087 ITALIC_NONE
!= ((const SvxPostureItem
&)rHt
).GetPosture() );
1092 static Writer
& OutWW8_SwPosture( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1094 return OutWW8_SwBoldUSW( rWrt
, 1,
1095 ITALIC_NONE
!= ((const SvxPostureItem
&)rHt
).GetPosture() );
1098 static Writer
& OutWW8_SwWeight( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1100 return OutWW8_SwBoldUSW( rWrt
, 0,
1101 WEIGHT_BOLD
== ((const SvxWeightItem
&)rHt
).GetWeight() );
1104 // Shadowed und Contour gibts in WW-UI nicht. JP: ??
1105 static Writer
& OutWW8_SwContour( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1107 return OutWW8_SwBoldUSW(rWrt
, 3,
1108 ((const SvxContourItem
&)rHt
).GetValue() ? true : false);
1111 static Writer
& OutWW8_SwShadow( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1113 return OutWW8_SwBoldUSW(rWrt
, 4,
1114 ((const SvxShadowedItem
&)rHt
).GetValue() ? true : false);
1117 static Writer
& OutWW8_SwKerning( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1119 const SvxKerningItem
& rAttr
= (const SvxKerningItem
&)rHt
;
1120 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1121 if( rWrtWW8
.bWrtWW8
)
1122 rWrtWW8
.InsUInt16( 0x8840 );
1124 rWrtWW8
.pO
->Insert( 96, rWrtWW8
.pO
->Count() );
1125 rWrtWW8
.InsUInt16( rAttr
.GetValue() );
1129 static Writer
& OutWW8_SvxAutoKern( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1131 const SvxAutoKernItem
& rAttr
= (const SvxAutoKernItem
&)rHt
;
1132 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1133 if( rWrtWW8
.bWrtWW8
)
1134 rWrtWW8
.InsUInt16( 0x484B );
1136 rWrtWW8
.pO
->Insert( 107, rWrtWW8
.pO
->Count() );
1137 rWrtWW8
.InsUInt16( rAttr
.GetValue() ? 1 : 0 );
1141 static Writer
& OutWW8_SwAnimatedText( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1143 const SvxBlinkItem
& rAttr
= (const SvxBlinkItem
&)rHt
;
1144 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1145 if( rWrtWW8
.bWrtWW8
)
1147 rWrtWW8
.InsUInt16( 0x2859 );
1148 // At the moment the only animated text effect we support is blinking
1149 rWrtWW8
.InsUInt16( rAttr
.GetValue() ? 2 : 0 );
1155 static Writer
& OutWW8_SwCrossedOut( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1157 FontStrikeout eSt
= ((const SvxCrossedOutItem
&)rHt
).GetStrikeout();
1158 if( STRIKEOUT_DOUBLE
== eSt
)
1159 return OutWW8_SwBoldUSW(rWrt
, 8, true);
1160 if( STRIKEOUT_NONE
!= eSt
)
1161 return OutWW8_SwBoldUSW(rWrt
, 2, true);
1163 // dann auch beide ausschalten!
1164 OutWW8_SwBoldUSW(rWrt
, 8, false);
1165 return OutWW8_SwBoldUSW(rWrt
, 2, false);
1168 static Writer
& OutWW8_SwCaseMap( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1170 USHORT eSt
= ((const SvxCaseMapItem
&)rHt
).GetValue();
1173 case SVX_CASEMAP_KAPITAELCHEN
:
1174 return OutWW8_SwBoldUSW(rWrt
, 5, true);
1175 case SVX_CASEMAP_VERSALIEN
:
1176 return OutWW8_SwBoldUSW(rWrt
, 6, true);
1177 case SVX_CASEMAP_TITEL
:
1178 //NO such feature in word
1181 // dann auch beide ausschalten!
1182 OutWW8_SwBoldUSW(rWrt
, 5, false);
1183 return OutWW8_SwBoldUSW(rWrt
, 6, false);
1188 static Writer
& OutWW8_SvxCharHidden(Writer
& rWrt
, const SfxPoolItem
& rHt
)
1190 OutWW8_SwBoldUSW(rWrt
, 7, (item_cast
<SvxCharHiddenItem
>(rHt
)).GetValue());
1194 static Writer
& OutWW8_SwUnderline( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1196 const SvxUnderlineItem
& rAttr
= (const SvxUnderlineItem
&)rHt
;
1197 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1198 if( rWrtWW8
.bWrtWW8
)
1199 rWrtWW8
.InsUInt16( 0x2A3E );
1201 rWrtWW8
.pO
->Insert( 94, rWrtWW8
.pO
->Count() );
1203 const SfxPoolItem
* pItem
= ((SwWW8Writer
&)rWrt
).HasItem(
1204 RES_CHRATR_WORDLINEMODE
);
1207 bWord
= ((const SvxWordLineModeItem
*)pItem
)->GetValue() ? true : false;
1209 // WW95 - parameters: 0 = none, 1 = single, 2 = by Word,
1210 // 3 = double, 4 = dotted, 5 = hidden
1211 // WW97 - additional parameters:
1212 // 6 = thick, 7 = dash, 8 = dot(not used)
1213 // 9 = dotdash 10 = dotdotdash, 11 = wave
1215 switch (rAttr
.GetLineStyle())
1217 case UNDERLINE_SINGLE
:
1218 b
= ( bWord
) ? 2 : 1;
1220 case UNDERLINE_BOLD
:
1221 b
= rWrtWW8
.bWrtWW8
? 6 : 1;
1223 case UNDERLINE_DOUBLE
:
1226 case UNDERLINE_DOTTED
:
1229 case UNDERLINE_DASH
:
1230 b
= rWrtWW8
.bWrtWW8
? 7 : 4;
1232 case UNDERLINE_DASHDOT
:
1233 b
= rWrtWW8
.bWrtWW8
? 9 : 4;
1235 case UNDERLINE_DASHDOTDOT
:
1236 b
= rWrtWW8
.bWrtWW8
? 10 : 4;
1238 case UNDERLINE_WAVE
:
1239 b
= rWrtWW8
.bWrtWW8
? 11 : 3;
1241 // ------------ new in WW2000 -------------------------------------
1242 case UNDERLINE_BOLDDOTTED
:
1243 b
= rWrtWW8
.bWrtWW8
? 20 : 4;
1245 case UNDERLINE_BOLDDASH
:
1246 b
= rWrtWW8
.bWrtWW8
? 23 : 4;
1248 case UNDERLINE_LONGDASH
:
1249 b
= rWrtWW8
.bWrtWW8
? 39 : 4;
1251 case UNDERLINE_BOLDLONGDASH
:
1252 b
= rWrtWW8
.bWrtWW8
? 55 : 4;
1254 case UNDERLINE_BOLDDASHDOT
:
1255 b
= rWrtWW8
.bWrtWW8
? 25 : 4;
1257 case UNDERLINE_BOLDDASHDOTDOT
:
1258 b
= rWrtWW8
.bWrtWW8
? 26 : 4;
1260 case UNDERLINE_BOLDWAVE
:
1261 b
= rWrtWW8
.bWrtWW8
? 27 : 3;
1263 case UNDERLINE_DOUBLEWAVE
:
1264 b
= rWrtWW8
.bWrtWW8
? 43 : 3;
1266 case UNDERLINE_NONE
:
1270 ASSERT(rAttr
.GetLineStyle() == UNDERLINE_NONE
, "Unhandled underline type");
1274 rWrtWW8
.pO
->Insert(b
, rWrtWW8
.pO
->Count());
1278 static Writer
& OutWW8_SwLanguage( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1281 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1282 if (rWrtWW8
.bWrtWW8
)
1284 switch (rHt
.Which())
1286 case RES_CHRATR_LANGUAGE
:
1289 case RES_CHRATR_CJK_LANGUAGE
:
1292 case RES_CHRATR_CTL_LANGUAGE
:
1302 if (rWrtWW8
.bWrtWW8
) // use sprmCRgLid0 rather than sprmCLid
1303 rWrtWW8
.InsUInt16(nId
);
1305 rWrtWW8
.pO
->Insert((BYTE
)nId
, rWrtWW8
.pO
->Count());
1306 rWrtWW8
.InsUInt16(((const SvxLanguageItem
&)rHt
).GetLanguage());
1308 //unknown as to exactly why, but this seems to shadow the other
1309 //paramater in word 2000 and without it spellchecking doesn't work
1312 rWrtWW8
.InsUInt16(0x4873);
1313 rWrtWW8
.InsUInt16(((const SvxLanguageItem
&)rHt
).GetLanguage());
1315 else if (nId
== 0x485F)
1317 rWrtWW8
.InsUInt16(0x4874);
1318 rWrtWW8
.InsUInt16(((const SvxLanguageItem
&)rHt
).GetLanguage());
1325 static Writer
& OutWW8_SwEscapement( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1327 const SvxEscapementItem
& rAttr
= (const SvxEscapementItem
&)rHt
;
1328 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1331 short nEsc
= rAttr
.GetEsc(), nProp
= rAttr
.GetProp();
1338 else if( DFLT_ESC_PROP
== nProp
)
1340 if( DFLT_ESC_SUB
== nEsc
|| DFLT_ESC_AUTO_SUB
== nEsc
)
1342 else if( DFLT_ESC_SUPER
== nEsc
|| DFLT_ESC_AUTO_SUPER
== nEsc
)
1348 if( rWrtWW8
.bWrtWW8
)
1349 rWrtWW8
.InsUInt16( 0x2A48 );
1351 rWrtWW8
.pO
->Insert( 104, rWrtWW8
.pO
->Count() );
1352 rWrtWW8
.pO
->Insert( b
, rWrtWW8
.pO
->Count() );
1355 if( 0 == b
|| 0xFF == b
)
1357 long nHeight
= ((SvxFontHeightItem
&)rWrtWW8
.GetItem(
1358 RES_CHRATR_FONTSIZE
)).GetHeight();
1359 if( rWrtWW8
.bWrtWW8
)
1360 rWrtWW8
.InsUInt16( 0x4845 );
1362 rWrtWW8
.pO
->Insert( 101, rWrtWW8
.pO
->Count() );
1363 rWrtWW8
.InsUInt16( (short)(( nHeight
* nEsc
+ 500 ) / 1000 ));
1365 if( 100 != nProp
|| !b
)
1367 if( rWrtWW8
.bWrtWW8
)
1368 rWrtWW8
.InsUInt16( 0x4A43 );
1370 rWrtWW8
.pO
->Insert( 99, rWrtWW8
.pO
->Count() );
1372 msword_cast
<sal_uInt16
>((nHeight
* nProp
+ 500 ) / 1000));
1379 static Writer
& OutWW8_SwSize( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1381 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1383 if (rWrtWW8
.bWrtWW8
)
1385 switch (rHt
.Which())
1387 case RES_CHRATR_FONTSIZE
:
1388 case RES_CHRATR_CJK_FONTSIZE
:
1391 case RES_CHRATR_CTL_FONTSIZE
:
1401 if( rWrtWW8
.bWrtWW8
)
1402 rWrtWW8
.InsUInt16( nId
);
1404 rWrtWW8
.pO
->Insert( (BYTE
)nId
, rWrtWW8
.pO
->Count() );
1406 const SvxFontHeightItem
& rAttr
= (const SvxFontHeightItem
&)rHt
;
1407 rWrtWW8
.InsUInt16( (UINT16
)(( rAttr
.GetHeight() + 5 ) / 10 ) );
1412 static Writer
& OutWW8_ScaleWidth( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1414 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1415 if( rWrtWW8
.bWrtWW8
)
1417 rWrtWW8
.InsUInt16( 0x4852 );
1418 rWrtWW8
.InsUInt16( ((SvxCharScaleWidthItem
&)rHt
).GetValue() );
1423 static Writer
& OutWW8_Relief( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1425 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1426 if( rWrtWW8
.bWrtWW8
)
1428 const SvxCharReliefItem
& rAttr
= (const SvxCharReliefItem
&)rHt
;
1430 switch ( rAttr
.GetValue() )
1432 case RELIEF_EMBOSSED
: nId
= 0x858; break;
1433 case RELIEF_ENGRAVED
: nId
= 0x854; break;
1434 default: nId
= 0; break;
1439 rWrtWW8
.InsUInt16( nId
);
1440 rWrtWW8
.pO
->Insert( (BYTE
)0x81, rWrtWW8
.pO
->Count() );
1444 // switch both flags off
1445 rWrtWW8
.InsUInt16( 0x858 );
1446 rWrtWW8
.pO
->Insert( (BYTE
)0x0, rWrtWW8
.pO
->Count() );
1447 rWrtWW8
.InsUInt16( 0x854 );
1448 rWrtWW8
.pO
->Insert( (BYTE
)0x0, rWrtWW8
.pO
->Count() );
1455 static Writer
& OutWW8_CharRotate( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1457 // #i28331# - check that a Value is set
1458 if((static_cast<const SvxCharRotateItem
&>(rHt
)).GetValue())
1460 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1461 if( rWrtWW8
.bWrtWW8
&& !rWrtWW8
.bIsInTable
)
1463 // #i36867 In word the text in a table is rotated via the TC or 0x7629
1464 // This means you can only rotate all or none of the text adding 0xCA78
1465 // here corrupts the table, hence !rWrtWW8.bIsInTable
1466 const SvxCharRotateItem
& rAttr
= (const SvxCharRotateItem
&)rHt
;
1468 rWrtWW8
.InsUInt16( 0xCA78 );
1469 rWrtWW8
.pO
->Insert( (BYTE
)0x06, rWrtWW8
.pO
->Count() ); //len 6
1470 rWrtWW8
.pO
->Insert( (BYTE
)0x01, rWrtWW8
.pO
->Count() );
1472 rWrtWW8
.InsUInt16( rAttr
.IsFitToLine() ? 1 : 0 );
1473 static const BYTE aZeroArr
[ 3 ] = { 0, 0, 0 };
1474 rWrtWW8
.pO
->Insert( aZeroArr
, 3, rWrtWW8
.pO
->Count() );
1481 static Writer
& OutWW8_EmphasisMark( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1483 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1484 if( rWrtWW8
.bWrtWW8
)
1487 switch ( ((const SvxEmphasisMarkItem
&)rHt
).GetValue() )
1489 case EMPHASISMARK_NONE
: nVal
= 0; break;
1490 case EMPHASISMARK_SIDE_DOTS
: nVal
= 2; break;
1491 case EMPHASISMARK_CIRCLE_ABOVE
: nVal
= 3; break;
1492 case EMPHASISMARK_DOTS_BELOW
: nVal
= 4; break;
1494 default: nVal
= 1; break;
1497 rWrtWW8
.InsUInt16( 0x2A34 );
1498 rWrtWW8
.pO
->Insert( nVal
, rWrtWW8
.pO
->Count() );
1504 // TransCol uebersetzt SW-Farben in WW. Heraus kommt die bei WW fuer
1505 // Text- und Hintergrundfarbe benutzte Codierung.
1506 // Gibt es keine direkte Entsprechung, dann wird versucht, eine moeglichst
1507 // aehnliche WW-Farbe zu finden.
1508 // return: 5-Bit-Wert ( 0..16 )
1509 BYTE
SwWW8Writer::TransCol( const Color
& rCol
)
1511 BYTE nCol
= 0; // ->Auto
1512 switch( rCol
.GetColor() )
1514 case COL_BLACK
: nCol
= 1; break;
1515 case COL_BLUE
: nCol
= 9; break;
1516 case COL_GREEN
: nCol
= 11; break;
1517 case COL_CYAN
: nCol
= 10; break;
1518 case COL_RED
: nCol
= 13; break;
1519 case COL_MAGENTA
: nCol
= 12; break;
1520 case COL_BROWN
: nCol
= 14; break;
1521 case COL_GRAY
: nCol
= 15; break;
1522 case COL_LIGHTGRAY
: nCol
= 16; break;
1523 case COL_LIGHTBLUE
: nCol
= 2; break;
1524 case COL_LIGHTGREEN
: nCol
= 4; break;
1525 case COL_LIGHTCYAN
: nCol
= 3; break;
1526 case COL_LIGHTRED
: nCol
= 6; break;
1527 case COL_LIGHTMAGENTA
: nCol
= 5; break;
1528 case COL_YELLOW
: nCol
= 7; break;
1529 case COL_WHITE
: nCol
= 8; break;
1530 case COL_AUTO
: nCol
= 0; break;
1535 pBmpPal
= new BitmapPalette( 16 );
1536 static const ColorData aColArr
[ 16 ] = {
1537 COL_BLACK
, COL_LIGHTBLUE
, COL_LIGHTCYAN
, COL_LIGHTGREEN
,
1538 COL_LIGHTMAGENTA
,COL_LIGHTRED
, COL_YELLOW
, COL_WHITE
,
1539 COL_BLUE
, COL_CYAN
, COL_GREEN
, COL_MAGENTA
,
1540 COL_RED
, COL_BROWN
, COL_GRAY
, COL_LIGHTGRAY
1543 for( USHORT i
= 0; i
< 16; ++i
)
1544 pBmpPal
->operator[]( i
) = Color( aColArr
[ i
] );
1546 nCol
= static_cast< BYTE
>(pBmpPal
->GetBestIndex( rCol
) + 1);
1552 // TransBrush uebersetzt SW-Brushes in WW. Heraus kommt WW8_SHD.
1553 // Nicht-Standardfarben des SW werden noch nicht in die
1554 // Misch-Werte ( 0 .. 95% ) vom WW uebersetzt.
1555 // Return: Echte Brush ( nicht transparent )
1556 // auch bei Transparent wird z.B. fuer Tabellen eine transparente Brush
1558 bool SwWW8Writer::TransBrush(const Color
& rCol
, WW8_SHD
& rShd
)
1560 if( rCol
.GetTransparency() )
1561 rShd
= WW8_SHD(); // alles Nullen : transparent
1565 rShd
.SetBack( TransCol( rCol
) );
1566 rShd
.SetStyle( bWrtWW8
, 0 );
1568 return !rCol
.GetTransparency();
1571 sal_uInt32
SuitableBGColor(sal_uInt32 nIn
)
1573 if (nIn
== COL_AUTO
)
1575 return wwUtility::RGBToBGR(nIn
);
1578 static Writer
& OutWW8_SwColor( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1580 const SvxColorItem
& rAttr
= (const SvxColorItem
&)rHt
;
1581 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1582 if (rWrtWW8
.bWrtWW8
)
1583 rWrtWW8
.InsUInt16(0x2A42);
1585 rWrtWW8
.pO
->Insert(98, rWrtWW8
.pO
->Count());
1587 BYTE nColour
= rWrtWW8
.TransCol(rAttr
.GetValue());
1588 rWrtWW8
.pO
->Insert(nColour
, rWrtWW8
.pO
->Count());
1590 if (rWrtWW8
.bWrtWW8
&& nColour
)
1592 rWrtWW8
.InsUInt16(0x6870);
1593 rWrtWW8
.InsUInt32(wwUtility::RGBToBGR(rAttr
.GetValue().GetColor()));
1598 static Writer
& OutWW8_SwFmtCharBackground( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1600 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
1602 if( rWW8Wrt
.bWrtWW8
) // nur WW8 kann ZeichenHintergrund
1604 const SvxBrushItem
& rBack
= (const SvxBrushItem
&)rHt
;
1607 rWW8Wrt
.TransBrush(rBack
.GetColor(), aSHD
);
1609 rWW8Wrt
.InsUInt16( 0x4866 );
1610 rWW8Wrt
.InsUInt16( aSHD
.GetValue() );
1612 //Quite a few unknowns, some might be transparency or something
1614 rWW8Wrt
.InsUInt16(0xCA71);
1615 rWW8Wrt
.pO
->Insert(10, rWW8Wrt
.pO
->Count());
1616 rWW8Wrt
.InsUInt32(0xFF000000);
1617 rWW8Wrt
.InsUInt32(SuitableBGColor(rBack
.GetColor().GetColor()));
1618 rWW8Wrt
.InsUInt16(0x0000);
1623 static Writer
& OutSwFmtINetFmt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
1625 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
1626 const SwFmtINetFmt
& rINet
= (SwFmtINetFmt
&)rHt
;
1628 if( rINet
.GetValue().Len() )
1631 const String
& rStr
= rINet
.GetINetFmt();
1633 nId
= rINet
.GetINetFmtId();
1635 nId
= RES_POOLCHR_INET_NORMAL
;
1637 const SwCharFmt
* pFmt
= IsPoolUserFmt( nId
)
1638 ? rWrt
.pDoc
->FindCharFmtByName( rStr
)
1639 : rWrt
.pDoc
->GetCharFmtFromPool( nId
);
1641 if( rWrtWW8
.bWrtWW8
)
1642 rWrtWW8
.InsUInt16( 0x4A30 );
1644 rWrtWW8
.pO
->Insert( 80, rWrtWW8
.pO
->Count() );
1646 rWrtWW8
.InsUInt16( rWrtWW8
.GetId( *pFmt
) );
1651 // --> OD 2005-06-08 #i43956# - add optional parameter <pLinkStr>
1652 // It's needed to write the hyperlink data for a certain cross-reference
1653 // - it contains the name of the link target, which is a bookmark.
1654 // --> OD 2008-08-14 #158418# - add optional parameter <bIncludeEmptyPicLocation>
1655 // It is needed to write an empty picture location for page number field separators
1656 static void InsertSpecialChar( SwWW8Writer
& rWrt
, BYTE c
,
1657 String
* pLinkStr
= 0L,
1658 bool bIncludeEmptyPicLocation
= false )
1661 rWrt
.GetCurrentItems(aItems
);
1664 rWrt
.pChpPlc
->AppendFkpEntry(rWrt
.Strm().Tell());
1666 rWrt
.pChpPlc
->AppendFkpEntry(rWrt
.Strm().Tell(), aItems
.Count(),
1671 // --> OD 2008-08-14 #158418#
1672 // store empty sprmCPicLocation for field separator
1673 if ( bIncludeEmptyPicLocation
&&
1674 ( c
== 0x13 || c
== 0x14 || c
== 0x15 ) )
1676 SwWW8Writer::InsUInt16( aItems
, 0x6a03 );
1677 SwWW8Writer::InsUInt32( aItems
, 0x00000000 );
1681 // --> OD 2005-06-08 #i43956# - write hyperlink data and attributes
1682 if ( rWrt
.bWrtWW8
&& c
== 0x01 && pLinkStr
)
1684 // write hyperlink data to data stream
1685 SvStream
& rStrm
= *rWrt
.pDataStrm
;
1686 // position of hyperlink data
1687 const UINT32 nLinkPosInDataStrm
= rStrm
.Tell();
1688 // write empty header
1689 const UINT16 nEmptyHdrLen
= 0x44;
1690 BYTE aEmptyHeader
[ nEmptyHdrLen
] = { 0 };
1691 aEmptyHeader
[ 4 ] = 0x44;
1692 rStrm
.Write( aEmptyHeader
, nEmptyHdrLen
);
1693 // writer fixed header
1694 const UINT16 nFixHdrLen
= 0x19;
1695 BYTE aFixHeader
[ nFixHdrLen
] =
1697 0x08, 0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE,
1698 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9,
1699 0x0B, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
1702 rStrm
.Write( aFixHeader
, nFixHdrLen
);
1703 // write reference string including length+1
1704 UINT32
nStrLen( pLinkStr
->Len() + 1 );
1705 SwWW8Writer::WriteLong( rStrm
, nStrLen
);
1706 SwWW8Writer::WriteString16( rStrm
, *(pLinkStr
), false );
1707 // write additional two NULL Bytes
1708 SwWW8Writer::WriteLong( rStrm
, 0 );
1709 // write length of hyperlink data
1710 const UINT32 nCurrPos
= rStrm
.Tell();
1711 rStrm
.Seek( nLinkPosInDataStrm
);
1713 UInt32ToSVBT32( nCurrPos
- nLinkPosInDataStrm
, nLen
);
1714 rStrm
.Write( nLen
, 4 );
1715 rStrm
.Seek( nCurrPos
);
1717 // write attributes of hyperlink character 0x01
1718 SwWW8Writer::InsUInt16( aItems
, 0x0802 ); //sprmCFFldVanish
1719 aItems
.Insert( (BYTE
)0x81, aItems
.Count() );
1720 SwWW8Writer::InsUInt16( aItems
, 0x6a03 );
1721 SwWW8Writer::InsUInt32( aItems
, nLinkPosInDataStrm
);
1722 SwWW8Writer::InsUInt16( aItems
, 0x0806 );
1723 aItems
.Insert( (BYTE
)0x01, aItems
.Count() );
1726 //Technically we should probably Remove all attribs
1727 //here for the 0x13, 0x14, 0x15, but our import
1728 //is slightly lacking
1729 //aItems.Remove(0, aItems.Count());
1730 // fSpec-Attribute true
1733 SwWW8Writer::InsUInt16( aItems
, 0x855 ); //sprmCFSpec
1734 aItems
.Insert( 1, aItems
.Count() );
1738 aItems
.Insert( 117, aItems
.Count() ); //sprmCFSpec
1739 aItems
.Insert( 1, aItems
.Count() );
1742 rWrt
.pChpPlc
->AppendFkpEntry(rWrt
.Strm().Tell(), aItems
.Count(),
1746 String
lcl_GetExpandedField(const SwField
&rFld
)
1748 String
sRet(rFld
.Expand());
1750 //replace LF 0x0A with VT 0x0B
1751 sRet
.SearchAndReplaceAll(0x0A, 0x0B);
1756 WW8_WrPlcFld
* SwWW8Writer::CurrentFieldPlc() const
1758 WW8_WrPlcFld
* pFldP
= NULL
;
1780 pFldP
= pFldHFTxtBxs
;
1783 ASSERT( !this, "was ist das fuer ein SubDoc-Type?" );
1788 void SwWW8Writer::OutField(const SwField
* pFld
, ww::eField eFldType
,
1789 const String
& rFldCmd
, BYTE nMode
)
1791 bool bUnicode
= IsUnicode();
1792 WW8_WrPlcFld
* pFldP
= CurrentFieldPlc();
1794 // --> OD 2008-08-14 #158418#
1795 const bool bIncludeEmptyPicLocation
= ( eFldType
== ww::ePAGE
);
1797 if (WRITEFIELD_START
& nMode
)
1799 BYTE aFld13
[2] = { 0x13, 0x00 }; // will change
1800 //#i3958#, Needed to make this field work correctly in Word 2000
1801 if (eFldType
== ww::eSHAPE
)
1803 aFld13
[1] = static_cast< BYTE
>(eFldType
); // Typ nachtragen
1804 pFldP
->Append( Fc2Cp( Strm().Tell() ), aFld13
);
1805 // --> OD 2008-08-14 #158418#
1806 InsertSpecialChar( *this, 0x13, 0, bIncludeEmptyPicLocation
);
1809 if (WRITEFIELD_CMD_START
& nMode
)
1812 SwWW8Writer::WriteString16(Strm(), rFldCmd
, false);
1815 SwWW8Writer::WriteString8(Strm(), rFldCmd
, false,
1816 RTL_TEXTENCODING_MS_1252
);
1818 // --> OD 2005-06-08 #i43956# - write hyperlink character including
1819 // attributes and corresponding binary data for certain reference fields.
1820 bool bHandleBookmark
= false;
1824 if (pFld
->GetTyp()->Which() == RES_GETREFFLD
&&
1825 ( eFldType
== ww::ePAGEREF
|| eFldType
== ww::eREF
||
1826 eFldType
== ww::eNOTEREF
|| eFldType
== ww::eFOOTREF
))
1827 bHandleBookmark
= true;
1830 if (pFld
->GetTyp()->Which() == RES_INPUTFLD
&&
1831 eFldType
== ww::eFORMTEXT
)
1832 bHandleBookmark
= true;
1836 if ( bHandleBookmark
)
1838 // retrieve reference destionation - the name of the bookmark
1840 const USHORT nSubType
= pFld
->GetSubType();
1841 const SwGetRefField
& rRFld
= *(static_cast<const SwGetRefField
*>(pFld
));
1842 if ( nSubType
== REF_SETREFATTR
||
1843 nSubType
== REF_BOOKMARK
)
1845 aLinkStr
= GetBookmarkName( nSubType
, &rRFld
.GetSetRefName(), 0 );
1847 else if ( nSubType
== REF_FOOTNOTE
||
1848 nSubType
== REF_ENDNOTE
)
1850 aLinkStr
= GetBookmarkName( nSubType
, 0, rRFld
.GetSeqNo() );
1852 else if ( nSubType
== REF_SEQUENCEFLD
)
1854 aLinkStr
= pFld
->GetPar2();
1856 // insert hyperlink character including attributes and data.
1857 InsertSpecialChar( *this, 0x01, &aLinkStr
);
1861 if (WRITEFIELD_CMD_END
& nMode
)
1863 static const BYTE aFld14
[2] = { 0x14, 0xff };
1864 pFldP
->Append( Fc2Cp( Strm().Tell() ), aFld14
);
1865 pFldP
->ResultAdded();
1866 // --> OD 2008-08-14 #158418#
1867 InsertSpecialChar( *this, 0x14, 0, bIncludeEmptyPicLocation
);
1870 if (WRITEFIELD_END
& nMode
)
1874 sOut
= lcl_GetExpandedField(*pFld
);
1880 SwWW8Writer::WriteString16(Strm(), sOut
, false);
1883 SwWW8Writer::WriteString8(Strm(), sOut
, false,
1884 RTL_TEXTENCODING_MS_1252
);
1889 if (pFld
->GetTyp()->Which() == RES_INPUTFLD
&&
1890 eFldType
== ww::eFORMTEXT
)
1897 Set_UInt16(pArr
, 0x6a03); //sprmCPicLocation
1898 Set_UInt32(pArr
, 0x0);
1900 Set_UInt16( pArr
, 0x855 );//sprmCFSpec
1901 Set_UInt8( pArr
, 1 );
1903 Set_UInt16( pArr
, 0x875 );//sprmCFNoProof
1908 Set_UInt8(pArr
, 0x68); //sprmCPicLocation
1909 Set_UInt32(pArr
, 0x0);
1911 Set_UInt8( pArr
, 117 ); //sprmCFSpec
1912 Set_UInt8( pArr
, 1 );
1914 pChpPlc
->AppendFkpEntry( pStrm
->Tell(), static_cast< short >(pArr
- aArr
), aArr
);
1919 if (WRITEFIELD_CLOSE
& nMode
)
1921 BYTE aFld15
[2] = { 0x15, 0x80 };
1925 if (pFld
->GetTyp()->Which() == RES_INPUTFLD
&&
1926 eFldType
== ww::eFORMTEXT
)
1928 USHORT nSubType
= pFld
->GetSubType();
1930 if (nSubType
== REF_SEQUENCEFLD
)
1931 aFld15
[0] |= (0x4 << 5);
1935 pFldP
->Append( Fc2Cp( Strm().Tell() ), aFld15
);
1936 // --> OD 2008-08-14 #158418#
1937 InsertSpecialChar( *this, 0x15, 0, bIncludeEmptyPicLocation
);
1942 void SwWW8Writer::StartCommentOutput(const String
& rName
)
1944 String
sStr(FieldString(ww::eQUOTE
));
1945 sStr
.APPEND_CONST_ASC("[");
1947 sStr
.APPEND_CONST_ASC("] ");
1948 OutField(0, ww::eQUOTE
, sStr
, WRITEFIELD_START
| WRITEFIELD_CMD_START
);
1951 void SwWW8Writer::EndCommentOutput(const String
& rName
)
1953 String
sStr(CREATE_CONST_ASC(" ["));
1955 sStr
.APPEND_CONST_ASC("] ");
1956 OutField(0, ww::eQUOTE
, sStr
, WRITEFIELD_CMD_END
| WRITEFIELD_END
|
1960 USHORT
SwWW8Writer::GetId( const SwTOXType
& rTOXType
)
1962 void* p
= (void*)&rTOXType
;
1963 USHORT nRet
= aTOXArr
.GetPos( p
);
1964 if( USHRT_MAX
== nRet
)
1965 aTOXArr
.Insert( p
, nRet
= aTOXArr
.Count() );
1969 // return values: 1 - no PageNum,
1970 // 2 - TabStop before PageNum,
1971 // 3 - Text before PageNum - rTxt hold the text
1972 // 4 - no Text and no TabStop before PageNum
1973 int lcl_CheckForm( const SwForm
& rForm
, BYTE nLvl
, String
& rText
)
1979 SwFormTokens aPattern
= rForm
.GetPattern(nLvl
);
1980 SwFormTokens::iterator aIt
= aPattern
.begin();
1981 bool bPgNumFnd
= false;
1982 FormTokenType eTType
;
1985 if (! aPattern
.empty())
1988 while( ++aIt
!= aPattern
.end() && !bPgNumFnd
)
1990 eTType
= aIt
->eTokenType
;
1994 case TOKEN_PAGE_NUMS
:
1998 case TOKEN_TAB_STOP
:
2003 rText
= aIt
->sText
.Copy( 0, 5 ); // #i21237#
2006 case TOKEN_LINK_START
:
2007 case TOKEN_LINK_END
:
2023 bool lcl_IsHyperlinked(const SwForm
& rForm
, USHORT nTOXLvl
)
2026 for (USHORT nI
= 1; nI
< nTOXLvl
; ++nI
)
2029 SwFormTokens aPattern
= rForm
.GetPattern(nI
);
2031 if ( !aPattern
.empty() )
2033 SwFormTokens::iterator aIt
= aPattern
.begin();
2035 FormTokenType eTType
;
2038 while ( ++aIt
!= aPattern
.end() )
2040 eTType
= aIt
->eTokenType
;
2043 case TOKEN_LINK_START
:
2044 case TOKEN_LINK_END
:
2056 void SwWW8Writer::StartTOX( const SwSection
& rSect
)
2058 if (const SwTOXBase
* pTOX
= rSect
.GetTOXBase())
2060 static const sal_Char sEntryEnd
[] = "\" ";
2062 ww::eField eCode
= ww::eTOC
;
2064 switch (pTOX
->GetType())
2068 sStr
= FieldString(eCode
);
2070 if (pTOX
->GetTOXForm().IsCommaSeparated())
2071 sStr
.APPEND_CONST_ASC("\\r ");
2073 if (nsSwTOIOptions::TOI_ALPHA_DELIMITTER
& pTOX
->GetOptions())
2074 sStr
.APPEND_CONST_ASC("\\h \"A\" ");
2078 for (BYTE n
= 1; n
<= 3; ++n
)
2081 int nRet
= ::lcl_CheckForm(pTOX
->GetTOXForm(), n
, aTxt
);
2085 else if ((4 == nRet
) || (2 == nRet
)) //#109414#
2090 sStr
.APPEND_CONST_ASC("\\e \"");
2092 sStr
.AppendAscii(sEntryEnd
);
2096 // case TOX_AUTHORITIES: eCode = eTOA; sStr = ???; break;
2098 case TOX_ILLUSTRATIONS
:
2101 if (!pTOX
->IsFromObjectNames())
2103 sStr
= FieldString(eCode
);
2105 sStr
.APPEND_CONST_ASC("\\c \"");
2106 sStr
+= pTOX
->GetSequenceName();
2107 sStr
.AppendAscii(sEntryEnd
);
2110 int nRet
= ::lcl_CheckForm( pTOX
->GetTOXForm(), 1, aTxt
);
2112 sStr
.APPEND_CONST_ASC("\\n ");
2113 else if( 3 == nRet
|| 4 == nRet
)
2115 sStr
.APPEND_CONST_ASC("\\p \"");
2117 sStr
.AppendAscii(sEntryEnd
);
2123 // case TOX_CONTENT:
2126 sStr
= FieldString(eCode
);
2129 USHORT n
, nTOXLvl
= pTOX
->GetLevel();
2133 if( nsSwTOXElement::TOX_MARK
& pTOX
->GetCreateType() )
2135 sStr
.APPEND_CONST_ASC( "\\f " );
2137 if( TOX_USER
== pTOX
->GetType() )
2140 sStr
+= (sal_Char
)('A' + GetId( *pTOX
->GetTOXType()));
2141 sStr
.AppendAscii( sEntryEnd
);
2145 if( nsSwTOXElement::TOX_OUTLINELEVEL
& pTOX
->GetCreateType() )
2147 // --> OD 2009-02-27 #i99641#
2148 // The following code does not determine the minimum outline
2149 // level for the TOC
2150 // // Search over all the outline styles used and figure out
2151 // // what is the minimum outline level we need to display
2152 // // (ignoring headline styles 1-9)
2153 // //BYTE nLvl = 0, nMinLvl = 0; //#outline level, removed by zhaojianwei
2154 // int nLvl = 0, nMinLvl = 0; //<-end,add by zhaojianwei
2155 // const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
2156 // const SwTxtFmtColl* pColl;
2157 // for( n = rColls.Count(); n; )
2159 // pColl = rColls[ --n ];
2160 // //nLvl = pColl->GetOutlineLevel(); //#outline level,zhaojianwei
2161 // //USHORT nPoolId = pColl->GetPoolFmtId();
2162 // //if( MAXLEVEL > nLvl && nMinLvl < nLvl && //<-end, ->add by zhaojianwei
2163 // USHORT nPoolId = pColl->GetPoolFmtId();
2164 // if( pColl->IsAssignedToListLevelOfOutlineStyle() &&
2165 // nMinLvl < (nLvl = pColl->GetAssignedOutlineStyleLevel()) && //<-end,zhaojianwei
2166 // ( RES_POOLCOLL_HEADLINE1 > nPoolId ||
2167 // RES_POOLCOLL_HEADLINE9 < nPoolId ))
2169 // // If we are using the default heading styles then use nTOXLvl
2173 // nLvl = nMinLvl < nTOXLvl ? nMinLvl : (BYTE)nTOXLvl;
2177 const int nMinLvl
= nTOXLvl
;
2182 int nTmpLvl
= nMinLvl
;
2183 if (nTmpLvl
> WW8ListManager::nMaxLevel
)
2184 nTmpLvl
= WW8ListManager::nMaxLevel
;
2186 sStr
.APPEND_CONST_ASC( "\\o \"1-" );
2187 sStr
+= String::CreateFromInt32( nTmpLvl
);
2188 sStr
.AppendAscii(sEntryEnd
);
2193 // --> OD 2009-02-27 #i99641#
2194 // not needed to additional export paragraph style with
2195 // an outline level to the /t option
2196 // if( nMinLvl > 0 )
2199 // // collect this templates into the \t otion
2200 // const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
2201 // const SwTxtFmtColl* pColl;
2203 // for( n = rColls.Count(); n;)
2205 // pColl = rColls[--n];
2206 // //nLvl = pColl->GetOutlineLevel(); //#outline level, removed by zhaojianwei
2207 // //if (MAXLEVEL > nLvl && nMinLvl <= nLvl)
2208 // //{ //<-end, ->add by zhaojianwei
2209 // if( pColl->IsAssignedToListLevelOfOutlineStyle() &&
2210 // nMinLvl <= ( nLvl = pColl->GetAssignedOutlineStyleLevel()))
2211 // { //<-end,zhaojianwei
2212 // if( sTOption.Len() )
2214 // (( sTOption += pColl->GetName() ) += ';' )
2215 // += String::CreateFromInt32( nLvl + 1 );
2221 if( nsSwTOXElement::TOX_TEMPLATE
& pTOX
->GetCreateType() )
2222 // --> OD 2009-02-27 #i99641#
2223 // Consider additional styles regardless of TOX-outlinelevel
2224 for( n
= 0; n
< MAXLEVEL
; ++n
)
2227 const String
& rStyles
= pTOX
->GetStyleNames( n
);
2230 xub_StrLen nPos
= 0;
2232 sLvl
+= String::CreateFromInt32( n
+ 1 );
2234 String
sStyle( rStyles
.GetToken( 0,
2235 TOX_STYLE_DELIMITER
, nPos
));
2238 if( sTOption
.Len() )
2240 ( sTOption
+= sStyle
) += sLvl
;
2242 } while( STRING_NOTFOUND
!= nPos
);
2248 BYTE nNoPgStt
= MAXLEVEL
, nNoPgEnd
= MAXLEVEL
;
2249 bool bFirstFillTxt
= true, bOnlyText
= true;
2250 for( n
= 0; n
< nTOXLvl
; ++n
)
2253 int nRet
= ::lcl_CheckForm( pTOX
->GetTOXForm(),
2254 static_cast< BYTE
>(n
+1), aTxt
);
2258 if( MAXLEVEL
== nNoPgStt
)
2259 nNoPgStt
= static_cast< BYTE
>(n
+1);
2263 if( MAXLEVEL
!= nNoPgStt
&&
2264 MAXLEVEL
== nNoPgEnd
)
2267 bOnlyText
= bOnlyText
&& 3 == nRet
;
2268 if( 3 == nRet
|| 4 == nRet
)
2272 else if( aFillTxt
!= aTxt
)
2274 bFirstFillTxt
= false;
2278 if( MAXLEVEL
!= nNoPgStt
)
2280 if (WW8ListManager::nMaxLevel
< nNoPgEnd
)
2281 nNoPgEnd
= WW8ListManager::nMaxLevel
;
2282 sStr
.APPEND_CONST_ASC( "\\n " );
2283 sStr
+= String::CreateFromInt32( nNoPgStt
);
2285 sStr
+= String::CreateFromInt32( nNoPgEnd
);
2290 sStr
.APPEND_CONST_ASC( "\\p \"" );
2292 sStr
.AppendAscii(sEntryEnd
);
2296 if( sTOption
.Len() )
2298 sStr
.APPEND_CONST_ASC( "\\t \"" );
2300 sStr
.AppendAscii(sEntryEnd
);
2303 if (lcl_IsHyperlinked(pTOX
->GetTOXForm(), nTOXLvl
))
2304 sStr
.APPEND_CONST_ASC("\\h");
2312 OutField(0, eCode
, sStr
, WRITEFIELD_START
| WRITEFIELD_CMD_START
|
2313 WRITEFIELD_CMD_END
);
2319 void SwWW8Writer::EndTOX( const SwSection
& rSect
)
2321 const SwTOXBase
* pTOX
= rSect
.GetTOXBase();
2324 ww::eField eCode
= TOX_INDEX
== pTOX
->GetType() ? ww::eINDEX
: ww::eTOC
;
2325 OutField(0, eCode
, aEmptyStr
, WRITEFIELD_CLOSE
);
2327 bInWriteTOX
= false;
2330 bool SwWW8Writer::GetNumberFmt(const SwField
& rFld
, String
& rStr
)
2332 // Returns a date or time format string by using the US NfKeywordTable
2333 bool bHasFmt
= false;
2334 SvNumberFormatter
* pNFmtr
= pDoc
->GetNumberFormatter();
2335 UINT32 nFmtIdx
= rFld
.GetFormat();
2336 const SvNumberformat
* pNumFmt
= pNFmtr
->GetEntry( nFmtIdx
);
2339 //USHORT nLng = rFld.GetLanguage();
2340 LocaleDataWrapper
aLocDat( pNFmtr
->GetServiceManager(),
2341 MsLangId::convertLanguageToLocale( LANGUAGE_ENGLISH_US
) );
2345 pKeyMap
= new NfKeywordTable
;
2346 NfKeywordTable
& rKeyMap
= *(NfKeywordTable
*)pKeyMap
;
2347 pNFmtr
->FillKeywordTable( rKeyMap
, LANGUAGE_ENGLISH_US
);
2350 String
sFmt(pNumFmt
->GetMappedFormatstring(*(NfKeywordTable
*)pKeyMap
,
2354 sw::ms::SwapQuotesInField(sFmt
);
2356 rStr
.APPEND_CONST_ASC( "\\@\"" );
2358 rStr
.APPEND_CONST_ASC( "\" " );
2365 void WW8_GetNumberPara( String
& rStr
, const SwField
& rFld
)
2367 switch(rFld
.GetFormat())
2369 case SVX_NUM_CHARS_UPPER_LETTER
:
2370 case SVX_NUM_CHARS_UPPER_LETTER_N
:
2371 rStr
.APPEND_CONST_ASC( "\\*ALPHABETIC ");
2373 case SVX_NUM_CHARS_LOWER_LETTER
:
2374 case SVX_NUM_CHARS_LOWER_LETTER_N
:
2375 rStr
.APPEND_CONST_ASC("\\*alphabetic ");
2377 case SVX_NUM_ROMAN_UPPER
:
2378 rStr
.APPEND_CONST_ASC("\\*ROMAN ");
2380 case SVX_NUM_ROMAN_LOWER
:
2381 rStr
.APPEND_CONST_ASC("\\*roman ");
2384 ASSERT(rFld
.GetFormat() == SVX_NUM_ARABIC
,
2385 "Unknown numbering type exported as default\n");
2386 case SVX_NUM_ARABIC
:
2387 rStr
.APPEND_CONST_ASC("\\*Arabic ");
2389 case SVX_NUM_PAGEDESC
:
2390 //Nothing, use word's default
2395 void SwWW8Writer::WritePostItBegin( WW8Bytes
* pOut
)
2402 Set_UInt16( pArr
, 0x855 ); //sprmCFSpec
2404 Set_UInt8( pArr
, 117 ); //sprmCFSpec
2405 Set_UInt8( pArr
, 1 );
2407 pChpPlc
->AppendFkpEntry( Strm().Tell() );
2408 WriteChar( 0x05 ); // Annotation reference
2411 pOut
->Insert( aArr
, static_cast< USHORT
>(pArr
- aArr
), pOut
->Count() );
2413 pChpPlc
->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr
- aArr
), aArr
);
2416 String
FieldString(ww::eField eIndex
)
2418 String
sRet(CREATE_CONST_ASC(" "));
2419 if (const char *pField
= ww::GetEnglishFieldName(eIndex
))
2420 sRet
.InsertAscii(pField
, 1);
2424 void OutWW8_RefField(SwWW8Writer
& rWW8Wrt
, const SwField
&rFld
,
2427 String
sStr(FieldString(ww::eREF
));
2428 sStr
.APPEND_CONST_ASC("\"");
2430 sStr
.APPEND_CONST_ASC( "\" " );
2431 rWW8Wrt
.OutField(&rFld
, ww::eREF
, sStr
, WRITEFIELD_START
|
2432 WRITEFIELD_CMD_START
| WRITEFIELD_CMD_END
);
2433 String sVar
= lcl_GetExpandedField(rFld
);
2436 if (rWW8Wrt
.IsUnicode())
2437 SwWW8Writer::WriteString16(rWW8Wrt
.Strm(), sVar
, false);
2440 SwWW8Writer::WriteString8(rWW8Wrt
.Strm(), sVar
, false,
2441 RTL_TEXTENCODING_MS_1252
);
2444 rWW8Wrt
.OutField(&rFld
, ww::eREF
, sStr
, WRITEFIELD_CLOSE
);
2447 void WriteExpand(SwWW8Writer
& rWW8Wrt
, const SwField
&rFld
)
2449 String
sExpand(lcl_GetExpandedField(rFld
));
2450 if (rWW8Wrt
.IsUnicode())
2451 SwWW8Writer::WriteString16(rWW8Wrt
.Strm(), sExpand
, false);
2454 SwWW8Writer::WriteString8(rWW8Wrt
.Strm(), sExpand
, false,
2455 RTL_TEXTENCODING_MS_1252
);
2459 static Writer
& OutWW8_SwField( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2461 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
2462 const SwFmtFld
& rFld
= (SwFmtFld
&)rHt
;
2463 const SwField
* pFld
= rFld
.GetFld();
2464 String sStr
; // fuer optionale Parameter
2465 bool bWriteExpand
= false;
2466 USHORT nSubType
= pFld
->GetSubType();
2468 switch (pFld
->GetTyp()->Which())
2471 if (nSubType
== nsSwGetSetExpType::GSE_STRING
)
2473 const SwGetExpField
*pGet
=(const SwGetExpField
*)(pFld
);
2474 OutWW8_RefField(rWW8Wrt
, *pGet
, pGet
->GetFormula());
2477 bWriteExpand
= true;
2480 if (nsSwGetSetExpType::GSE_SEQ
== nSubType
)
2482 sStr
= FieldString(ww::eSEQ
);
2483 sStr
.APPEND_CONST_ASC("\"");
2484 sStr
+= pFld
->GetTyp()->GetName();
2485 sStr
.APPEND_CONST_ASC( "\" " );
2487 ::WW8_GetNumberPara( sStr
, *pFld
);
2488 rWW8Wrt
.OutField(pFld
, ww::eSEQ
, sStr
);
2490 else if (nSubType
& nsSwGetSetExpType::GSE_STRING
)
2492 bool bShowAsWell
= false;
2493 ww::eField eFieldNo
;
2494 const SwSetExpField
*pSet
=(const SwSetExpField
*)(pFld
);
2495 const String
&rVar
= pSet
->GetPar2();
2496 if (pSet
->GetInputFlag())
2498 sStr
= FieldString(ww::eASK
);
2499 sStr
.APPEND_CONST_ASC("\"");
2500 sStr
+= pSet
->GetPar1();
2501 sStr
.APPEND_CONST_ASC( "\" " );
2502 sStr
+= pSet
->GetPromptText();
2503 sStr
.APPEND_CONST_ASC( " \\d " );
2505 eFieldNo
= ww::eASK
;
2509 sStr
= FieldString(ww::eSET
);
2510 sStr
+= pSet
->GetPar1();
2511 sStr
.APPEND_CONST_ASC(" \"");
2513 sStr
.APPEND_CONST_ASC("\" ");
2514 eFieldNo
= ww::eSET
;
2515 bShowAsWell
= (nSubType
& nsSwExtendedSubType::SUB_INVISIBLE
) ? false : true;
2518 ULONG nFrom
= rWW8Wrt
.Fc2Cp(rWrt
.Strm().Tell());
2520 rWW8Wrt
.OutField(pFld
, eFieldNo
, sStr
, WRITEFIELD_START
|
2521 WRITEFIELD_CMD_START
| WRITEFIELD_CMD_END
);
2524 Is there a bookmark at the start position of this field, if so
2525 move it to the 0x14 of the result of the field. This is what word
2526 does. MoveFieldBookmarks moves any bookmarks at this position to
2527 the beginning of the field result, and marks the bookmark as a
2528 fieldbookmark which is to be ended before the field end mark
2529 instead of after it like a normal bookmark.
2531 rWW8Wrt
.MoveFieldBookmarks(nFrom
,rWW8Wrt
.Fc2Cp(rWrt
.Strm().Tell()));
2535 if (rWW8Wrt
.IsUnicode())
2536 SwWW8Writer::WriteString16(rWrt
.Strm(), rVar
, false);
2539 SwWW8Writer::WriteString8(rWrt
.Strm(), rVar
, false,
2540 RTL_TEXTENCODING_MS_1252
);
2543 rWW8Wrt
.OutField(pFld
, eFieldNo
, sStr
, WRITEFIELD_CLOSE
);
2546 OutWW8_RefField(rWW8Wrt
, *pSet
, pSet
->GetPar1());
2549 bWriteExpand
= true;
2551 case RES_PAGENUMBERFLD
:
2552 sStr
= FieldString(ww::ePAGE
);
2553 ::WW8_GetNumberPara(sStr
, *pFld
);
2554 rWW8Wrt
.OutField(pFld
, ww::ePAGE
, sStr
);
2556 case RES_FILENAMEFLD
:
2557 sStr
= FieldString(ww::eFILENAME
);
2558 if (pFld
->GetFormat() == FF_PATHNAME
)
2559 sStr
.APPEND_CONST_ASC("\\p ");
2560 rWW8Wrt
.OutField(pFld
, ww::eFILENAME
, sStr
);
2564 sStr
= FieldString(ww::eDATABASE
);
2565 SwDBData aData
= rWrt
.pDoc
->GetDBData();
2566 sStr
+= String(aData
.sDataSource
);
2568 sStr
+= String(aData
.sCommand
);
2569 rWW8Wrt
.OutField(pFld
, ww::eDATABASE
, sStr
);
2575 (AF_SHORTCUT
& nSubType
? ww::eUSERINITIALS
: ww::eUSERNAME
);
2576 rWW8Wrt
.OutField(pFld
, eFld
, FieldString(eFld
));
2579 case RES_TEMPLNAMEFLD
:
2580 rWW8Wrt
.OutField(pFld
, ww::eTEMPLATE
, FieldString(ww::eTEMPLATE
));
2582 case RES_DOCINFOFLD
: // Last printed, last edited,...
2583 if( DI_SUB_FIXED
& nSubType
)
2584 bWriteExpand
= true;
2587 ww::eField
eFld(ww::eNONE
);
2588 switch (0xff & nSubType
)
2594 eFld
= ww::eSUBJECT
;
2597 eFld
= ww::eKEYWORDS
;
2600 eFld
= ww::eCOMMENTS
;
2606 if (DI_SUB_AUTHOR
== (nSubType
& DI_SUB_MASK
))
2608 else if (rWW8Wrt
.GetNumberFmt(*pFld
, sStr
))
2609 eFld
= ww::eCREATEDATE
;
2613 if (DI_SUB_AUTHOR
== (nSubType
& DI_SUB_MASK
))
2614 eFld
= ww::eLASTSAVEDBY
;
2615 else if (rWW8Wrt
.GetNumberFmt(*pFld
, sStr
))
2616 eFld
= ww::eSAVEDATE
;
2620 if (DI_SUB_AUTHOR
!= (nSubType
& DI_SUB_MASK
) &&
2621 rWW8Wrt
.GetNumberFmt(*pFld
, sStr
))
2622 eFld
= ww::ePRINTDATE
;
2625 if( DI_SUB_AUTHOR
!= (nSubType
& DI_SUB_MASK
) &&
2626 rWW8Wrt
.GetNumberFmt( *pFld
, sStr
))
2627 eFld
= ww::eSAVEDATE
;
2630 eFld
= ww::eDOCPROPERTY
;
2632 static String
sQuotes('\"');
2633 const SwDocInfoField
* pDocInfoField
=
2634 dynamic_cast<const SwDocInfoField
*> (pFld
);
2636 if (pDocInfoField
!= NULL
)
2638 String sFieldname
= pDocInfoField
->GetCntnt(TRUE
);
2639 xub_StrLen nIndex
= sFieldname
.Search(':');
2641 if (nIndex
!= sFieldname
.Len())
2642 sFieldname
= sFieldname
.Copy(nIndex
+ 1);
2644 sStr
.Insert(sQuotes
);
2645 sStr
.Insert(sFieldname
);
2646 sStr
.Insert(sQuotes
);
2654 if (eFld
!= ww::eNONE
)
2656 sStr
.Insert(FieldString(eFld
), 0);
2657 rWW8Wrt
.OutField(pFld
, eFld
, sStr
);
2660 bWriteExpand
= true;
2663 case RES_DATETIMEFLD
:
2664 if (FIXEDFLD
& nSubType
|| !rWW8Wrt
.GetNumberFmt(*pFld
, sStr
))
2665 bWriteExpand
= true;
2668 ww::eField eFld
= (DATEFLD
& nSubType
) ? ww::eDATE
: ww::eTIME
;
2669 sStr
.Insert(FieldString(eFld
), 0);
2670 rWW8Wrt
.OutField(pFld
, eFld
, sStr
);
2673 case RES_DOCSTATFLD
:
2675 ww::eField eFld
= ww::eNONE
;
2680 eFld
= ww::eNUMPAGE
;
2683 eFld
= ww::eNUMWORDS
;
2686 eFld
= ww::eNUMCHARS
;
2690 if (eFld
!= ww::eNONE
)
2692 sStr
= FieldString(eFld
);
2693 ::WW8_GetNumberPara(sStr
, *pFld
);
2694 rWW8Wrt
.OutField(pFld
, eFld
, sStr
);
2697 bWriteExpand
= true;
2700 case RES_EXTUSERFLD
:
2702 ww::eField eFld
= ww::eNONE
;
2703 switch (0xFF & nSubType
)
2707 eFld
= ww::eUSERNAME
;
2710 eFld
= ww::eUSERINITIALS
;
2716 eFld
= ww::eUSERADDRESS
;
2720 if (eFld
!= ww::eNONE
)
2722 sStr
= FieldString(eFld
);
2723 rWW8Wrt
.OutField(pFld
, eFld
, sStr
);
2726 bWriteExpand
= true;
2730 //Sadly only possible for word in main document text
2731 if (rWW8Wrt
.nTxtTyp
== TXT_MAINTEXT
)
2733 const SwPostItField
& rPFld
= *(SwPostItField
*)pFld
;
2734 rWW8Wrt
.pAtn
->Append( rWW8Wrt
.Fc2Cp( rWrt
.Strm().Tell() ), rPFld
);
2735 rWW8Wrt
.WritePostItBegin( rWW8Wrt
.pO
);
2740 const SwInputField
* pInputField
=
2741 dynamic_cast<const SwInputField
*>(pFld
);
2743 if (pInputField
->isFormField())
2744 rWW8Wrt
.DoFormText(pInputField
);
2747 sStr
= FieldString(ww::eFILLIN
);
2749 sStr
.ASSIGN_CONST_ASC("\"");
2750 sStr
+= pFld
->GetPar2();
2753 rWW8Wrt
.OutField(pFld
, ww::eFILLIN
, sStr
);
2759 ww::eField eFld
= ww::eNONE
;
2760 const SwGetRefField
& rRFld
= *(SwGetRefField
*)pFld
;
2763 case REF_SETREFATTR
:
2765 switch (pFld
->GetFormat())
2767 case REF_PAGE_PGDESC
:
2769 eFld
= ww::ePAGEREF
;
2775 sStr
= FieldString(eFld
);
2776 sStr
+= rWW8Wrt
.GetBookmarkName(nSubType
,
2777 &rRFld
.GetSetRefName(), 0);
2781 switch (pFld
->GetFormat())
2783 case REF_PAGE_PGDESC
:
2785 eFld
= ww::ePAGEREF
;
2792 REF_ENDNOTE
== nSubType
? ww::eNOTEREF
: ww::eFOOTREF
;
2795 sStr
= FieldString(eFld
);
2796 sStr
+= rWW8Wrt
.GetBookmarkName(nSubType
, 0,
2801 if (eFld
!= ww::eNONE
)
2803 switch (pFld
->GetFormat())
2806 sStr
.APPEND_CONST_ASC(" \\p");
2809 sStr
.APPEND_CONST_ASC(" \\n");
2814 sStr
.APPEND_CONST_ASC(" \\h "); // insert hyperlink
2815 rWW8Wrt
.OutField(pFld
, eFld
, sStr
);
2818 bWriteExpand
= true;
2821 case RES_COMBINED_CHARS
:
2824 We need a font size to fill in the defaults, if these are overridden
2825 (as they generally are) by character properties then those properties
2828 The fontsize that is used in MS for determing the defaults is always
2829 the CJK fontsize even if the text is not in that language, in OOo the
2830 largest fontsize used in the field is the one we should take, but
2831 whatever we do, word will actually render using the fontsize set for
2832 CJK text. Nevertheless we attempt to guess whether the script is in
2833 asian or western text based up on the first character and use the
2834 font size of that script as our default.
2837 if( pBreakIt
->xBreak
.is() )
2838 nScript
= pBreakIt
->xBreak
->getScriptType( pFld
->GetPar1(), 0);
2840 nScript
= i18n::ScriptType::ASIAN
;
2842 long nHeight
= ((SvxFontHeightItem
&)(((SwWW8Writer
&)rWrt
).GetItem(
2843 GetWhichOfScript(RES_CHRATR_FONTSIZE
,nScript
)))).GetHeight();;
2845 nHeight
= (nHeight
+ 10) / 20; //Font Size in points;
2848 Divide the combined char string into its up and down part. Get the
2849 font size and fill in the defaults as up == half the font size and
2850 down == a fifth the font size
2852 xub_StrLen nAbove
= (pFld
->GetPar1().Len()+1)/2;
2853 sStr
= FieldString(ww::eEQ
);
2854 sStr
.APPEND_CONST_ASC("\\o (\\s\\up ");
2855 sStr
+= String::CreateFromInt32(nHeight
/2);
2858 sStr
+= String(pFld
->GetPar1(),0,nAbove
);
2859 sStr
.APPEND_CONST_ASC("), \\s\\do ");
2860 sStr
+= String::CreateFromInt32(nHeight
/5);
2863 sStr
+= String(pFld
->GetPar1(),nAbove
,pFld
->GetPar1().Len()-nAbove
);
2864 sStr
.APPEND_CONST_ASC("))");
2865 rWW8Wrt
.OutField(pFld
, ww::eEQ
, sStr
);
2869 if (rWW8Wrt
.bWrtWW8
)
2871 const SwDropDownField
& rFld2
= *(SwDropDownField
*)pFld
;
2872 uno::Sequence
<rtl::OUString
> aItems
=
2873 rFld2
.GetItemSequence();
2874 rWW8Wrt
.DoComboBox(rFld2
.GetName(),
2877 rFld2
.GetSelectedItem(), aItems
);
2880 bWriteExpand
= true;
2882 case RES_CHAPTERFLD
:
2883 bWriteExpand
= true;
2884 if (rWW8Wrt
.bOutKF
&& rFld
.GetTxtFld())
2886 const SwTxtNode
*pTxtNd
= rWW8Wrt
.GetHdFtPageRoot();
2889 if (const SwNode
*pNd
= rWW8Wrt
.pCurPam
->GetNode())
2890 pTxtNd
= pNd
->GetTxtNode();
2895 SwChapterField
aCopy(*(const SwChapterField
*)pFld
);
2896 aCopy
.ChangeExpansion(*pTxtNd
, false);
2897 WriteExpand(rWW8Wrt
, aCopy
);
2898 bWriteExpand
= false;
2902 case RES_HIDDENTXTFLD
:
2904 String
sExpand(pFld
->GetPar2());
2907 //replace LF 0x0A with VT 0x0B
2908 sExpand
.SearchAndReplaceAll(0x0A, 0x0B);
2909 rWW8Wrt
.pChpPlc
->AppendFkpEntry(rWW8Wrt
.Strm().Tell());
2910 if (rWW8Wrt
.IsUnicode())
2912 SwWW8Writer::WriteString16(rWW8Wrt
.Strm(), sExpand
, false);
2913 static BYTE aArr
[] =
2917 rWW8Wrt
.pChpPlc
->AppendFkpEntry(rWW8Wrt
.Strm().Tell(), sizeof(aArr
), aArr
);
2921 SwWW8Writer::WriteString8(rWW8Wrt
.Strm(), sExpand
, false,
2922 RTL_TEXTENCODING_MS_1252
);
2923 static BYTE aArr
[] =
2927 rWW8Wrt
.pChpPlc
->AppendFkpEntry(rWW8Wrt
.Strm().Tell(), sizeof(aArr
), aArr
);
2933 bWriteExpand
= true;
2938 WriteExpand(rWW8Wrt
, *pFld
);
2943 static Writer
& OutWW8_SwFlyCntnt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2945 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
2946 if (rWrtWW8
.pOutFmtNode
&& rWrtWW8
.pOutFmtNode
->ISA(SwCntntNode
))
2948 SwTxtNode
* pTxtNd
= (SwTxtNode
*)rWrtWW8
.pOutFmtNode
;
2951 aLayPos
= pTxtNd
->FindLayoutRect(false, &aLayPos
).Pos();
2953 SwPosition
aPos(*pTxtNd
);
2954 sw::Frame
aFrm(*((const SwFmtFlyCnt
&)rHt
).GetFrmFmt(), aPos
);
2956 rWrtWW8
.OutWW8FlyFrm(aFrm
, aLayPos
);
2961 // TOXMarks fehlen noch
2963 // Detaillierte Einstellungen zur Trennung erlaubt WW nur dokumentenweise.
2964 // Man koennte folgende Mimik einbauen: Die Werte des Style "Standard" werden,
2965 // falls vorhanden, in die Document Properties ( DOP ) gesetzt.
2967 // ACK. Dieser Vorschlag passt exakt zu unserer Implementierung des Import,
2968 // daher setze ich das gleich mal um. (KHZ, 07/15/2000)
2969 static Writer
& OutWW8_SvxHyphenZone( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2972 const SvxHyphenZoneItem
& rAttr
= (const SvxHyphenZoneItem
&)rHt
;
2973 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
2974 if( rWrtWW8
.bWrtWW8
)
2975 rWrtWW8
.InsUInt16( 0x242A );
2977 rWrtWW8
.pO
->Insert( 44, rWrtWW8
.pO
->Count() );
2979 rWrtWW8
.pO
->Insert( rAttr
.IsHyphen() ? 0 : 1, rWrtWW8
.pO
->Count() );
2983 static Writer
& OutWW8_SfxBoolItem( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2986 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
2987 if( rWrtWW8
.bWrtWW8
)
2988 switch ( rHt
.Which() )
2990 case RES_PARATR_SCRIPTSPACE
: nId
= 0x2437; break;
2991 case RES_PARATR_HANGINGPUNCTUATION
: nId
= 0x2435; break;
2992 case RES_PARATR_FORBIDDEN_RULES
: nId
= 0x2433; break;
2997 if( rWrtWW8
.bWrtWW8
)
2998 rWrtWW8
.InsUInt16( nId
);
3000 rWrtWW8
.pO
->Insert( (BYTE
)nId
, rWrtWW8
.pO
->Count() );
3002 rWrtWW8
.pO
->Insert( ((SfxBoolItem
&)rHt
).GetValue() ? 1 : 0,
3003 rWrtWW8
.pO
->Count() );
3008 static Writer
& OutWW8_SvxParaGridItem(Writer
& rWrt
, const SfxPoolItem
& rHt
)
3010 // sprmPFUsePgsuSettings
3012 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
3014 if (!rWrtWW8
.bWrtWW8
)
3017 rWrtWW8
.InsUInt16(0x2447);
3018 const SvxParaGridItem
& rAttr
= (const SvxParaGridItem
&)rHt
;
3019 rWrtWW8
.pO
->Insert( rAttr
.GetValue(), rWrtWW8
.pO
->Count() );
3023 static Writer
& OutWW8_SvxParaVertAlignItem(Writer
& rWrt
, const SfxPoolItem
& rHt
)
3027 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
3029 if( !rWrtWW8
.bWrtWW8
)
3032 rWrtWW8
.InsUInt16( 0x4439 );
3033 const SvxParaVertAlignItem
& rAttr
= (const SvxParaVertAlignItem
&)rHt
;
3035 INT16 nVal
= rAttr
.GetValue();
3038 case SvxParaVertAlignItem::BASELINE
:
3041 case SvxParaVertAlignItem::TOP
:
3044 case SvxParaVertAlignItem::CENTER
:
3047 case SvxParaVertAlignItem::BOTTOM
:
3050 case SvxParaVertAlignItem::AUTOMATIC
:
3055 ASSERT(!(&rWrt
), "Unknown vert alignment");
3058 rWrtWW8
.InsUInt16( nVal
);
3063 // NoHyphen: ich habe keine Entsprechung in der SW-UI und WW-UI gefunden
3065 static Writer
& OutWW8_SwHardBlank( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3067 ((SwWW8Writer
&)rWrt
).WriteChar( ((SwFmtHardBlank
&)rHt
).GetChar() );
3071 // RefMark, NoLineBreakHere fehlen noch
3073 void SwWW8Writer::WriteFtnBegin( const SwFmtFtn
& rFtn
, WW8Bytes
* pOutArr
)
3076 bool bAutoNum
= !rFtn
.GetNumStr().Len(); // Auto-Nummer
3081 static const BYTE aSpec
[] =
3083 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
3084 0x55, 0x08, 1 // sprmCFSpec
3087 aAttrArr
.Insert(aSpec
, sizeof(aSpec
), aAttrArr
.Count());
3091 static BYTE
const aSpec
[] =
3093 117, 1, // sprmCFSpec
3094 68, 4, 0, 0, 0, 0 // sprmCObjLocation
3097 aAttrArr
.Insert(aSpec
, sizeof(aSpec
), aAttrArr
.Count());
3102 const SwEndNoteInfo
* pInfo
;
3103 if( rFtn
.IsEndNote() )
3104 pInfo
= &pDoc
->GetEndNoteInfo();
3106 pInfo
= &pDoc
->GetFtnInfo();
3107 const SwCharFmt
* pCFmt
= pOutArr
3108 ? pInfo
->GetAnchorCharFmt( *pDoc
)
3109 : pInfo
->GetCharFmt( *pDoc
);
3111 SwWW8Writer::InsUInt16( aAttrArr
, 0x4a30 );
3113 aAttrArr
.Insert( 80, aAttrArr
.Count() );
3114 SwWW8Writer::InsUInt16( aAttrArr
, GetId( *pCFmt
) );
3116 // fSpec-Attribut true
3117 // Fuer Auto-Nummer muss ein Spezial-Zeichen
3118 // in den Text und darum ein fSpec-Attribut
3119 pChpPlc
->AppendFkpEntry( Strm().Tell() );
3121 WriteChar( 0x02 ); // Auto-Nummer-Zeichen
3123 // User-Nummerierung
3124 OutSwString( rFtn
.GetNumStr(), 0, rFtn
.GetNumStr().Len(),
3125 IsUnicode(), RTL_TEXTENCODING_MS_1252
);
3129 // insert at start of array, so the "hard" attribute overrule the
3130 // attributes of the character template
3131 pOutArr
->Insert( &aAttrArr
, 0 );
3137 // insert at start of array, so the "hard" attribute overrule the
3138 // attributes of the character template
3139 aOutArr
.Insert( &aAttrArr
, 0 );
3141 // write for the ftn number in the content, the font of the anchor
3142 const SwTxtFtn
* pTxtFtn
= rFtn
.GetTxtFtn();
3145 WW8Bytes
* pOld
= pO
;
3147 SfxItemSet
aSet( pDoc
->GetAttrPool(), RES_CHRATR_FONT
,
3150 pCFmt
= pInfo
->GetCharFmt( *pDoc
);
3151 aSet
.Set( pCFmt
->GetAttrSet() );
3153 pTxtFtn
->GetTxtNode().GetAttr( aSet
, *pTxtFtn
->GetStart(),
3154 (*pTxtFtn
->GetStart()) + 1 );
3155 ::OutWW8_SwFont( *this, aSet
.Get( RES_CHRATR_FONT
));
3158 pChpPlc
->AppendFkpEntry( Strm().Tell(), aOutArr
.Count(),
3159 aOutArr
.GetData() );
3163 static bool lcl_IsAtTxtEnd(const SwFmtFtn
& rFtn
)
3166 if( rFtn
.GetTxtFtn() )
3168 USHORT nWh
= static_cast< USHORT
>(rFtn
.IsEndNote() ? RES_END_AT_TXTEND
3169 : RES_FTN_AT_TXTEND
);
3170 const SwSectionNode
* pSectNd
= rFtn
.GetTxtFtn()->GetTxtNode().
3172 while( pSectNd
&& FTNEND_ATPGORDOCEND
==
3173 ((const SwFmtFtnAtTxtEnd
&)pSectNd
->GetSection().GetFmt()->
3174 GetFmtAttr( nWh
, true)).GetValue() )
3175 pSectNd
= pSectNd
->StartOfSectionNode()->FindSectionNode();
3178 bRet
= false; // the is ftn/end collected at Page- or Doc-End
3184 static Writer
& OutWW8_SwFtn( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3186 const SwFmtFtn
& rFtn
= (const SwFmtFtn
&)rHt
;
3187 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3190 WW8_WrPlcFtnEdn
* pFtnEnd
;
3191 if( rFtn
.IsEndNote() )
3193 pFtnEnd
= rWW8Wrt
.pEdn
;
3195 if( rWW8Wrt
.bEndAtTxtEnd
)
3196 rWW8Wrt
.bEndAtTxtEnd
= lcl_IsAtTxtEnd( rFtn
);
3200 pFtnEnd
= rWW8Wrt
.pFtn
;
3201 nTyp
= REF_FOOTNOTE
;
3202 if( rWW8Wrt
.bFtnAtTxtEnd
)
3203 rWW8Wrt
.bFtnAtTxtEnd
= lcl_IsAtTxtEnd( rFtn
);
3206 // if any reference to this footnote/endnote then insert an internal
3209 if( rWW8Wrt
.HasRefToObject( nTyp
, 0, rFtn
.GetTxtFtn()->GetSeqRefNo() ))
3211 sBkmkNm
= rWW8Wrt
.GetBookmarkName( nTyp
, 0,
3212 rFtn
.GetTxtFtn()->GetSeqRefNo() );
3213 rWW8Wrt
.AppendBookmark( sBkmkNm
);
3217 pFtnEnd
->Append( rWW8Wrt
.Fc2Cp( rWrt
.Strm().Tell() ), rFtn
);
3218 rWW8Wrt
.WriteFtnBegin( rFtn
, rWW8Wrt
.pO
);
3221 rWW8Wrt
.AppendBookmark( sBkmkNm
);
3226 static Writer
& OutWW8_SwTxtCharFmt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3228 const SwFmtCharFmt
& rAttr
= (const SwFmtCharFmt
&)rHt
;
3229 if( rAttr
.GetCharFmt() )
3231 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
3232 if( rWrtWW8
.bWrtWW8
)
3233 rWrtWW8
.InsUInt16( 0x4A30 );
3235 rWrtWW8
.pO
->Insert( 80, rWrtWW8
.pO
->Count() );
3237 rWrtWW8
.InsUInt16( rWrtWW8
.GetId( *rAttr
.GetCharFmt() ) );
3243 See ww8par6.cxx Read_DoubleLine for some more info
3245 static Writer
& OutWW8_SvxTwoLinesItem( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3247 // #i28331# - check that bOn is set
3248 if((static_cast<const SvxTwoLinesItem
&>(rHt
)).GetValue())
3250 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
3252 if( !rWrtWW8
.bWrtWW8
)
3255 const SvxTwoLinesItem
& rAttr
= (const SvxTwoLinesItem
&)rHt
;
3256 rWrtWW8
.InsUInt16( 0xCA78 );
3257 rWrtWW8
.pO
->Insert( (BYTE
)0x06, rWrtWW8
.pO
->Count() ); //len 6
3258 rWrtWW8
.pO
->Insert( (BYTE
)0x02, rWrtWW8
.pO
->Count() );
3260 sal_Unicode cStart
= rAttr
.GetStartBracket();
3261 sal_Unicode cEnd
= rAttr
.GetStartBracket();
3264 As per usual we have problems. We can have seperate left and right brackets
3265 in OOo, it doesn't appear that you can in word. Also in word there appear
3266 to only be a limited number of possibilities, we can use pretty much
3269 So if we have none, we export none, if either bracket is set to a known
3270 word type we export both as that type (with the bracket winning out in
3271 the case of a conflict simply being the order of test here.
3273 Upshot being a documented created in word will be reexported with no
3278 if (!cStart
&& !cEnd
)
3280 else if ((cStart
== '{') || (cEnd
== '}'))
3282 else if ((cStart
== '<') || (cEnd
== '>'))
3284 else if ((cStart
== '[') || (cEnd
== ']'))
3288 rWrtWW8
.InsUInt16( nType
);
3289 static const BYTE aZeroArr
[ 3 ] = { 0, 0, 0 };
3290 rWrtWW8
.pO
->Insert( aZeroArr
, 3, rWrtWW8
.pO
->Count() );
3295 static Writer
& OutWW8_SwNumRuleItem( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3297 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3298 const SwNumRuleItem
& rNumRule
= (const SwNumRuleItem
&)rHt
;
3300 const SwTxtNode
* pTxtNd
= 0;
3303 if( rNumRule
.GetValue().Len() )
3305 const SwNumRule
* pRule
= rWrt
.pDoc
->FindNumRulePtr(
3306 rNumRule
.GetValue() );
3307 if( pRule
&& USHRT_MAX
!= ( nNumId
= rWW8Wrt
.GetId( *pRule
)) )
3310 if( rWW8Wrt
.pOutFmtNode
)
3312 if( rWW8Wrt
.pOutFmtNode
->ISA( SwCntntNode
))
3314 pTxtNd
= (SwTxtNode
*)rWW8Wrt
.pOutFmtNode
;
3316 if( pTxtNd
->IsCountedInList())
3318 nLvl
= static_cast< BYTE
>(pTxtNd
->GetActualListLevel());
3320 if (pTxtNd
->IsListRestart())
3322 USHORT nStartWith
= static_cast< USHORT
>(pTxtNd
->GetActualListStartValue());
3323 nNumId
= rWW8Wrt
.DupNumRuleWithLvlStart(pRule
,nLvl
,nStartWith
);
3324 if (USHRT_MAX
!= nNumId
)
3330 // #i44815# adjust numbering for numbered paragraphs
3331 // without number (NO_NUMLEVEL). These paragaphs
3332 // will receive a list id 0, which WW interprets as
3337 else if( rWW8Wrt
.pOutFmtNode
->ISA( SwTxtFmtColl
))
3339 const SwTxtFmtColl
* pC
= (SwTxtFmtColl
*)rWW8Wrt
.pOutFmtNode
;
3340 //if( pC && MAXLEVEL > pC->GetOutlineLevel() ) //#outline level,removed by zhaojianwei
3341 // nLvl = pC->GetOutlineLevel(); //<-end, ->add by zhaojianwei
3342 if( pC
&& pC
->IsAssignedToListLevelOfOutlineStyle() )
3343 nLvl
= static_cast<BYTE
>(pC
->GetAssignedOutlineStyleLevel()); //<-end,zhaojianwei
3353 if (USHRT_MAX
!= nNumId
)
3355 if (nLvl
>= WW8ListManager::nMaxLevel
)
3356 nLvl
= WW8ListManager::nMaxLevel
-1;
3357 if( rWW8Wrt
.bWrtWW8
)
3359 // write sprmPIlvl and sprmPIlfo
3360 SwWW8Writer::InsUInt16( *rWW8Wrt
.pO
, 0x260a );
3361 rWW8Wrt
.pO
->Insert( nLvl
, rWW8Wrt
.pO
->Count() );
3362 SwWW8Writer::InsUInt16( *rWW8Wrt
.pO
, 0x460b );
3363 SwWW8Writer::InsUInt16( *rWW8Wrt
.pO
, nNumId
);
3365 else if( pTxtNd
&& rWW8Wrt
.Out_SwNum( pTxtNd
) ) // NumRules
3366 rWW8Wrt
.pSepx
->SetNum( pTxtNd
);
3371 /* File FRMATR.HXX */
3373 static Writer
& OutWW8_SwFrmSize( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3375 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3376 const SwFmtFrmSize
& rSz
= (const SwFmtFrmSize
&)rHt
;
3378 if( rWW8Wrt
.bOutFlyFrmAttrs
) // Flys
3380 if( rWW8Wrt
.bOutGrf
)
3381 return rWrt
; // Fly um Grafik -> Auto-Groesse
3383 //???? was ist bei Prozentangaben ???
3384 if( rSz
.GetWidth() && rSz
.GetWidthSizeType() == ATT_FIX_SIZE
)
3387 if( rWW8Wrt
.bWrtWW8
)
3388 rWW8Wrt
.InsUInt16( 0x841A );
3390 rWW8Wrt
.pO
->Insert( 28, rWW8Wrt
.pO
->Count() );
3391 rWW8Wrt
.InsUInt16( (USHORT
)rSz
.GetWidth() );
3394 if( rSz
.GetHeight() )
3397 if( rWW8Wrt
.bWrtWW8
)
3398 rWW8Wrt
.InsUInt16( 0x442B );
3400 rWW8Wrt
.pO
->Insert( 45, rWW8Wrt
.pO
->Count() );
3403 switch( rSz
.GetHeightSizeType() )
3405 case ATT_VAR_SIZE
: break;
3406 case ATT_FIX_SIZE
: nH
= (USHORT
)rSz
.GetHeight() & 0x7fff; break;
3407 default: nH
= (USHORT
)rSz
.GetHeight() | 0x8000; break;
3409 rWW8Wrt
.InsUInt16( nH
);
3412 else if( rWW8Wrt
.bOutPageDescs
) // PageDesc : Breite + Hoehe
3414 if( rWW8Wrt
.pAktPageDesc
->GetLandscape() )
3416 /*sprmSBOrientation*/
3417 if( rWW8Wrt
.bWrtWW8
)
3418 rWW8Wrt
.InsUInt16( 0x301d );
3420 rWW8Wrt
.pO
->Insert( 162, rWW8Wrt
.pO
->Count() );
3421 rWW8Wrt
.pO
->Insert( 2, rWW8Wrt
.pO
->Count() );
3425 if( rWW8Wrt
.bWrtWW8
)
3426 rWW8Wrt
.InsUInt16( 0xB01F );
3428 rWW8Wrt
.pO
->Insert( 164, rWW8Wrt
.pO
->Count() );
3430 msword_cast
<sal_uInt16
>(SnapPageDimension(rSz
.GetWidth())));
3433 if( rWW8Wrt
.bWrtWW8
)
3434 rWW8Wrt
.InsUInt16( 0xB020 );
3436 rWW8Wrt
.pO
->Insert( 165, rWW8Wrt
.pO
->Count() );
3438 msword_cast
<sal_uInt16
>(SnapPageDimension(rSz
.GetHeight())));
3443 // FillOrder fehlt noch
3445 // ReplaceCr() wird fuer Pagebreaks und Pagedescs gebraucht. Es wird ein
3446 // bereits geschriebenes CR durch ein Break-Zeichen ersetzt. Replace muss
3447 // direkt nach Schreiben des CR gerufen werden.
3448 // Rueckgabe: FilePos des ersetzten CRs + 1 oder 0 fuer nicht ersetzt
3450 ULONG
SwWW8Writer::ReplaceCr( BYTE nChar
)
3453 ASSERT( nChar
, "gegen 0 ersetzt bringt WW97/95 zum Absturz" );
3455 bool bReplaced
= false;
3456 SvStream
& rStrm
= Strm();
3457 ULONG nRetPos
= 0, nPos
= rStrm
.Tell();
3460 //If there is at least two characters already output
3461 if (nPos
- (IsUnicode() ? 2 : 1) >= ULONG(pFib
->fcMin
))
3463 rStrm
.SeekRel(IsUnicode() ? -2 : -1);
3471 //If the last char was a cr
3472 if (nUCode
== 0x0d) // CR ?
3474 if ((nChar
== 0x0c) &&
3475 (nPos
- (IsUnicode() ? 4 : 2) >= ULONG(pFib
->fcMin
)))
3477 rStrm
.SeekRel( IsUnicode() ? -4 : -2 );
3488 rStrm
.SeekRel( IsUnicode() ? -2 : -1 );
3491 //And the para is not of len 0, then replace this cr with the mark
3492 if( nChar
== 0x0e || nUCode
== 0x0d )
3501 else if ((nUCode
== 0x0c) && (nChar
== 0x0e))
3503 //#108854# a column break after a section has
3504 //no effect in writer
3514 // then write as normal char
3516 pPiece
->SetParaBreak();
3517 pPapPlc
->AppendFkpEntry(rStrm
.Tell());
3518 pChpPlc
->AppendFkpEntry(rStrm
.Tell());
3519 nRetPos
= rStrm
.Tell();
3524 ASSERT( nRetPos
|| nPos
== (ULONG
)pFib
->fcMin
,
3525 "WW8_ReplaceCr an falscher FilePos gerufen" );
3531 void SwWW8Writer::WriteRowEnd(sal_uInt32 nDepth
)
3534 WriteChar( (BYTE
)0x07 );
3535 else if (nDepth
> 1)
3536 WriteChar( (BYTE
)0x0d );
3538 //Technically in a word document this is a different value for a row ends
3539 //that are not row ends directly after a cell with a graphic. But it
3540 //doesn't seem to make a difference
3541 //pMagicTable->Append(Fc2Cp(Strm().Tell()),0x1B6);
3544 static Writer
& OutWW8_SwFmtPageDesc(Writer
& rWrt
, const SfxPoolItem
& rHt
)
3546 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3547 if (rWW8Wrt
.bStyDef
&& rWW8Wrt
.pOutFmtNode
&& rWW8Wrt
.pOutFmtNode
->ISA(SwTxtFmtColl
))
3549 const SwFmtPageDesc
&rPgDesc
= (const SwFmtPageDesc
&)rHt
;
3550 const SwTxtFmtColl
* pC
= (SwTxtFmtColl
*)rWW8Wrt
.pOutFmtNode
;
3551 if ((SFX_ITEM_SET
!= pC
->GetItemState(RES_BREAK
, false)) && rPgDesc
.GetRegisteredIn())
3552 OutWW8_SwFmtBreak(rWrt
, SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE
, RES_BREAK
));
3557 // Breaks schreiben nichts in das Ausgabe-Feld rWrt.pO,
3558 // sondern nur in den Text-Stream ( Bedingung dafuer, dass sie von Out_Break...
3559 // gerufen werden duerfen )
3560 static Writer
& OutWW8_SwFmtBreak( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3563 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3564 const SvxFmtBreakItem
&rBreak
= (const SvxFmtBreakItem
&)rHt
;
3566 if( rWW8Wrt
.bStyDef
)
3568 switch( rBreak
.GetBreak() )
3570 //JP 21.06.99: column breaks does never change to pagebreaks
3571 // case SVX_BREAK_COLUMN_BEFORE:
3572 // case SVX_BREAK_COLUMN_BOTH:
3573 case SVX_BREAK_NONE
:
3574 case SVX_BREAK_PAGE_BEFORE
:
3575 case SVX_BREAK_PAGE_BOTH
:
3576 // sprmPPageBreakBefore/sprmPFPageBreakBefore
3577 if (rWW8Wrt
.bWrtWW8
)
3578 rWW8Wrt
.InsUInt16(0x2407);
3580 rWW8Wrt
.pO
->Insert(9, rWW8Wrt
.pO
->Count());
3581 rWW8Wrt
.pO
->Insert(rBreak
.GetValue() ? 1 : 0,
3582 rWW8Wrt
.pO
->Count());
3588 else if (!rWW8Wrt
.mpParentFrame
)
3590 static const BYTE cColBreak
= 0xe;
3591 static const BYTE cPageBreak
= 0xc;
3594 bool bBefore
= false;
3595 // --> OD 2007-05-29 #i76300#
3596 // Note: Can only be <true>, if <bBefore> equals <false>.
3597 bool bCheckForFollowPageDesc
= false;
3600 switch( rBreak
.GetBreak() )
3602 case SVX_BREAK_NONE
: // Ausgeschaltet
3603 if( !rWW8Wrt
.bBreakBefore
)
3605 // sprmPPageBreakBefore/sprmPFPageBreakBefore
3606 if( rWW8Wrt
.bWrtWW8
)
3607 rWW8Wrt
.InsUInt16( 0x2407 );
3609 rWW8Wrt
.pO
->Insert( 9, rWW8Wrt
.pO
->Count() );
3610 rWW8Wrt
.pO
->Insert( (BYTE
)0, rWW8Wrt
.pO
->Count() );
3614 case SVX_BREAK_COLUMN_BEFORE
: // ColumnBreak
3617 case SVX_BREAK_COLUMN_AFTER
:
3618 case SVX_BREAK_COLUMN_BOTH
:
3619 ASSERT (rWW8Wrt
.pSepx
, "how come this is 0");
3620 if (rWW8Wrt
.pSepx
&&
3621 rWW8Wrt
.pSepx
->CurrentNoColumns(*rWW8Wrt
.pDoc
) > 1)
3627 case SVX_BREAK_PAGE_BEFORE
: // PageBreak
3628 // From now on(fix for #i77900#) we prefer to save a page break as
3629 // paragraph attribute, this has to be done after the export of the
3630 // paragraph ( => !rWW8Wrt.bBreakBefore )
3631 if( !rWW8Wrt
.bBreakBefore
)
3633 // sprmPPageBreakBefore/sprmPFPageBreakBefore
3634 if( rWW8Wrt
.bWrtWW8
)
3635 rWW8Wrt
.InsUInt16( 0x2407 );
3637 rWW8Wrt
.pO
->Insert( 9, rWW8Wrt
.pO
->Count() );
3638 rWW8Wrt
.pO
->Insert( (BYTE
)1, rWW8Wrt
.pO
->Count() );
3641 case SVX_BREAK_PAGE_AFTER
:
3642 case SVX_BREAK_PAGE_BOTH
:
3644 // --> OD 2007-05-29 #i76300#
3645 // check for follow page description, if current writing attributes
3647 if ( dynamic_cast<const SwTxtNode
*>(rWW8Wrt
.pOutFmtNode
) &&
3648 rWW8Wrt
.GetCurItemSet() )
3650 bCheckForFollowPageDesc
= true;
3658 if ( (bBefore
== rWW8Wrt
.bBreakBefore
) && nC
) // #49917#
3660 // --> OD 2007-05-29 #i76300#
3661 bool bFollowPageDescWritten( false );
3662 if ( bCheckForFollowPageDesc
&& !bBefore
)
3664 bFollowPageDescWritten
=
3665 rWW8Wrt
.Out_FollowPageDesc( rWW8Wrt
.GetCurItemSet(),
3666 dynamic_cast<const SwTxtNode
*>(rWW8Wrt
.pOutFmtNode
) );
3668 if ( !bFollowPageDescWritten
)
3670 rWW8Wrt
.ReplaceCr( nC
);
3678 static Writer
& OutWW8_SwTextGrid( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3680 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
3681 if (rWrtWW8
.bOutPageDescs
&& rWrtWW8
.bWrtWW8
)
3683 const SwTextGridItem
& rItem
= (const SwTextGridItem
&)rHt
;
3685 switch (rItem
.GetGridType())
3688 ASSERT(!(&rWrt
), "Unknown grid type");
3692 case GRID_LINES_ONLY
:
3695 case GRID_LINES_CHARS
:
3697 if(rItem
.IsSnapToChars())
3708 rWrtWW8
.InsUInt16(0x5032);
3709 rWrtWW8
.InsUInt16(nGridType
);
3711 UINT16 nHeight
= rItem
.GetBaseHeight() + rItem
.GetRubyHeight();
3712 rWrtWW8
.InsUInt16(0x9031);
3713 rWrtWW8
.InsUInt16(nHeight
);
3714 sal_uInt32 nPageCharSize
= ItemGet
<SvxFontHeightItem
>(*(rWrtWW8
.pStyles
->GetSwFmt()),
3715 RES_CHRATR_CJK_FONTSIZE
).GetHeight();
3717 INT32 nCharWidth
= rItem
.GetBaseWidth() - nPageCharSize
;
3718 INT32 nFraction
= 0;
3719 nFraction
= nCharWidth
%20;
3720 if( nCharWidth
< 0 )
3721 nFraction
= 20 + nFraction
;
3722 nFraction
= ((nFraction
)*0xFFF)/20;
3723 nFraction
= (nFraction
& 0x00000FFF);
3726 nMain
= nCharWidth
/20;
3727 if( nCharWidth
< 0 )
3729 nMain
= nMain
* 0x1000;
3730 nMain
= (nMain
& 0xFFFFF000);
3732 UINT32 nCharSpace
= nFraction
+ nMain
;
3733 rWrtWW8
.InsUInt16(0x7030);
3734 rWrtWW8
.InsUInt32(nCharSpace
);
3739 static Writer
& OutWW8_SvxPaperBin( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3741 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
3742 const SvxPaperBinItem
& rItem
= (const SvxPaperBinItem
&)rHt
;
3744 if( rWrtWW8
.bOutPageDescs
)
3747 switch( rItem
.GetValue() )
3749 case 0: nVal
= 15; break; // Automatically select
3750 case 1: nVal
= 1; break; // Upper paper tray
3751 case 2: nVal
= 4; break; // Manual paper feed
3752 default: nVal
= 0; break;
3757 // sprmSDmBinFirst 0x5007 word
3758 // sprmSDmBinOther 0x5008 word
3759 BYTE nOff
= rWrtWW8
.bOutFirstPage
? 0 : 1;
3760 if( rWrtWW8
.bWrtWW8
)
3761 rWrtWW8
.InsUInt16( 0x5007 + nOff
);
3763 rWrtWW8
.pO
->Insert( 140 + nOff
, rWrtWW8
.pO
->Count() );
3764 rWrtWW8
.InsUInt16( nVal
);
3770 static Writer
& OutWW8_SwFmtLRSpace( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3772 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3773 const SvxLRSpaceItem
& rLR
= (const SvxLRSpaceItem
&) rHt
;
3776 // Flys fehlen noch ( siehe RTF )
3778 if( rWW8Wrt
.bOutFlyFrmAttrs
) // Flys
3780 // sprmPDxaFromText10
3781 if( rWW8Wrt
.bWrtWW8
)
3782 rWW8Wrt
.InsUInt16( 0x4622 );
3784 rWW8Wrt
.pO
->Insert( 49, rWW8Wrt
.pO
->Count() );
3785 // Mittelwert nehmen, da WW nur 1 Wert kennt
3786 rWW8Wrt
.InsUInt16( (USHORT
) ( ( rLR
.GetLeft() + rLR
.GetRight() ) / 2 ) );
3788 else if( rWW8Wrt
.bOutPageDescs
) // PageDescs
3790 USHORT nLDist
, nRDist
;
3791 const SfxPoolItem
* pItem
= ((SwWW8Writer
&)rWrt
).HasItem( RES_BOX
);
3794 nRDist
= ((SvxBoxItem
*)pItem
)->CalcLineSpace( BOX_LINE_LEFT
);
3795 nLDist
= ((SvxBoxItem
*)pItem
)->CalcLineSpace( BOX_LINE_RIGHT
);
3798 nLDist
= nRDist
= 0;
3799 nLDist
= nLDist
+ (USHORT
)rLR
.GetLeft();
3800 nRDist
= nRDist
+ (USHORT
)rLR
.GetRight();
3803 if( rWW8Wrt
.bWrtWW8
)
3804 rWW8Wrt
.InsUInt16( 0xB021 );
3806 rWW8Wrt
.pO
->Insert( 166, rWW8Wrt
.pO
->Count() );
3807 rWW8Wrt
.InsUInt16( nLDist
);
3809 if( rWW8Wrt
.bWrtWW8
)
3810 rWW8Wrt
.InsUInt16( 0xB022 );
3812 rWW8Wrt
.pO
->Insert( 167, rWW8Wrt
.pO
->Count() );
3813 rWW8Wrt
.InsUInt16( nRDist
);
3816 { // normale Absaetze
3818 if( rWW8Wrt
.bWrtWW8
)
3820 rWW8Wrt
.InsUInt16( 0x845E ); //asian version ?
3821 rWW8Wrt
.InsUInt16( (USHORT
)rLR
.GetTxtLeft() );
3826 rWW8Wrt
.pO
->Insert( 17, rWW8Wrt
.pO
->Count() );
3827 rWW8Wrt
.InsUInt16( (USHORT
)rLR
.GetTxtLeft() );
3830 if( rWW8Wrt
.bWrtWW8
)
3832 rWW8Wrt
.InsUInt16( 0x845D ); //asian version ?
3833 rWW8Wrt
.InsUInt16( (USHORT
)rLR
.GetRight() );
3837 rWW8Wrt
.pO
->Insert( 16, rWW8Wrt
.pO
->Count() );
3838 rWW8Wrt
.InsUInt16( (USHORT
)rLR
.GetRight() );
3841 if( rWW8Wrt
.bWrtWW8
)
3843 rWW8Wrt
.InsUInt16( 0x8460 ); //asian version ?
3844 rWW8Wrt
.InsUInt16( rLR
.GetTxtFirstLineOfst() );
3848 rWW8Wrt
.pO
->Insert( 19, rWW8Wrt
.pO
->Count() );
3849 rWW8Wrt
.InsUInt16( rLR
.GetTxtFirstLineOfst() );
3855 static Writer
& OutWW8_SwFmtULSpace( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3857 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3858 const SvxULSpaceItem
& rUL
= (const SvxULSpaceItem
&) rHt
;
3860 // Flys fehlen noch ( siehe RTF )
3862 if( rWW8Wrt
.bOutFlyFrmAttrs
) // Flys
3865 if( rWW8Wrt
.bWrtWW8
)
3866 rWW8Wrt
.InsUInt16( 0x842E );
3868 rWW8Wrt
.pO
->Insert( 48, rWW8Wrt
.pO
->Count() );
3869 // Mittelwert nehmen, da WW nur 1 Wert kennt
3870 rWW8Wrt
.InsUInt16( (USHORT
) ( ( rUL
.GetUpper() + rUL
.GetLower() ) / 2 ) );
3872 else if( rWW8Wrt
.bOutPageDescs
) // Page-UL
3874 ASSERT(rWW8Wrt
.GetCurItemSet(), "Impossible");
3875 if (!rWW8Wrt
.GetCurItemSet())
3878 HdFtDistanceGlue
aDistances(*rWW8Wrt
.GetCurItemSet());
3880 if (aDistances
.HasHeader())
3883 if (rWW8Wrt
.bWrtWW8
)
3884 rWW8Wrt
.InsUInt16(0xB017);
3886 rWW8Wrt
.pO
->Insert(156, rWW8Wrt
.pO
->Count());
3887 rWW8Wrt
.InsUInt16(aDistances
.dyaHdrTop
);
3891 if (rWW8Wrt
.bWrtWW8
)
3892 rWW8Wrt
.InsUInt16(0x9023);
3894 rWW8Wrt
.pO
->Insert(168, rWW8Wrt
.pO
->Count());
3895 rWW8Wrt
.InsUInt16(aDistances
.dyaTop
);
3897 if (aDistances
.HasFooter())
3900 if (rWW8Wrt
.bWrtWW8
)
3901 rWW8Wrt
.InsUInt16(0xB018);
3903 rWW8Wrt
.pO
->Insert(157, rWW8Wrt
.pO
->Count());
3904 rWW8Wrt
.InsUInt16(aDistances
.dyaHdrBottom
);
3908 if (rWW8Wrt
.bWrtWW8
)
3909 rWW8Wrt
.InsUInt16(0x9024);
3911 rWW8Wrt
.pO
->Insert(169, rWW8Wrt
.pO
->Count());
3912 rWW8Wrt
.InsUInt16(aDistances
.dyaBottom
);
3917 if( rWW8Wrt
.bWrtWW8
)
3918 rWW8Wrt
.InsUInt16( 0xA413 );
3920 rWW8Wrt
.pO
->Insert( 21, rWW8Wrt
.pO
->Count() );
3921 rWW8Wrt
.InsUInt16( rUL
.GetUpper() );
3923 if( rWW8Wrt
.bWrtWW8
)
3924 rWW8Wrt
.InsUInt16( 0xA414 );
3926 rWW8Wrt
.pO
->Insert( 22, rWW8Wrt
.pO
->Count() );
3927 rWW8Wrt
.InsUInt16( rUL
.GetLower() );
3932 // Print, Opaque, Protect fehlen noch
3934 static Writer
& OutWW8_SwFmtSurround( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3936 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3937 if( rWW8Wrt
.bOutFlyFrmAttrs
)
3939 if( rWW8Wrt
.bWrtWW8
)
3940 rWW8Wrt
.InsUInt16( 0x2423 );
3942 rWW8Wrt
.pO
->Insert( 37, rWW8Wrt
.pO
->Count() );
3944 rWW8Wrt
.pO
->Insert( (SURROUND_NONE
!=
3945 ((const SwFmtSurround
&) rHt
).GetSurround() )
3946 ? 2 : 1, rWW8Wrt
.pO
->Count() );
3951 Writer
& OutWW8_SwFmtVertOrient( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3953 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3955 //!!!! Ankertyp und entsprechende Umrechnung fehlt noch
3957 if( rWW8Wrt
.bOutFlyFrmAttrs
)
3959 const SwFmtVertOrient
& rFlyVert
= (const SwFmtVertOrient
&) rHt
;
3962 switch( rFlyVert
.GetVertOrient() )
3964 case text::VertOrientation::NONE
:
3965 nPos
= (short)rFlyVert
.GetPos();
3967 case text::VertOrientation::CENTER
:
3968 case text::VertOrientation::LINE_CENTER
:
3971 case text::VertOrientation::BOTTOM
:
3972 case text::VertOrientation::LINE_BOTTOM
:
3975 case text::VertOrientation::TOP
:
3976 case text::VertOrientation::LINE_TOP
:
3983 if( rWW8Wrt
.bWrtWW8
)
3984 rWW8Wrt
.InsUInt16( 0x8419 );
3986 rWW8Wrt
.pO
->Insert( 27, rWW8Wrt
.pO
->Count() );
3987 rWW8Wrt
.InsUInt16( nPos
);
3993 Writer
& OutWW8_SwFmtHoriOrient( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3995 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
3996 if (!rWW8Wrt
.mpParentFrame
)
3998 ASSERT(rWW8Wrt
.mpParentFrame
, "HoriOrient without mpParentFrame !!");
4002 //!!!! Ankertyp und entsprechende Umrechnung fehlt noch
4003 if( rWW8Wrt
.bOutFlyFrmAttrs
)
4005 const SwFmtHoriOrient
& rFlyHori
= (const SwFmtHoriOrient
&) rHt
;
4008 switch( rFlyHori
.GetHoriOrient() )
4010 case text::HoriOrientation::NONE
: {
4011 nPos
= (short)rFlyHori
.GetPos();
4013 nPos
= 1; // WW: 0 ist reserviert
4017 case text::HoriOrientation::LEFT
: nPos
= rFlyHori
.IsPosToggle() ? -12 : 0;
4019 case text::HoriOrientation::RIGHT
: nPos
= rFlyHori
.IsPosToggle() ? -16 : -8;
4021 case text::HoriOrientation::CENTER
:
4022 case text::HoriOrientation::FULL
: // FULL nur fuer Tabellen
4023 default: nPos
= -4; break;
4027 if( rWW8Wrt
.bWrtWW8
)
4028 rWW8Wrt
.InsUInt16( 0x8418 );
4030 rWW8Wrt
.pO
->Insert( 26, rWW8Wrt
.pO
->Count() );
4031 rWW8Wrt
.InsUInt16( nPos
);
4036 static Writer
& OutWW8_SwFmtAnchor( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4038 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
4039 ASSERT(rWW8Wrt
.mpParentFrame
, "Anchor without mpParentFrame !!");
4041 if( rWW8Wrt
.bOutFlyFrmAttrs
)
4043 const SwFmtAnchor
& rAnchor
= (const SwFmtAnchor
&) rHt
;
4045 switch( rAnchor
.GetAnchorId() )
4048 // Vert: Page | Horz: Page
4049 nP
|= (1 << 4) | (2 << 6);
4051 // Im Fall eine Flys als Zeichen: Absatz-gebunden setzen!!!
4053 case FLY_AUTO_CNTNT
:
4056 // Vert: Page | Horz: Page
4057 nP
|= (2 << 4) | (0 << 6);
4064 if( rWW8Wrt
.bWrtWW8
)
4065 rWW8Wrt
.InsUInt16( 0x261B );
4067 rWW8Wrt
.pO
->Insert( 29, rWW8Wrt
.pO
->Count() );
4068 rWW8Wrt
.pO
->Insert( nP
, rWW8Wrt
.pO
->Count() );
4073 static Writer
& OutWW8_SwFmtBackground( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4075 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
4077 if( !rWW8Wrt
.bOutPageDescs
) // WW kann keinen Hintergrund
4079 const SvxBrushItem
& rBack
= (const SvxBrushItem
&)rHt
;
4082 rWW8Wrt
.TransBrush(rBack
.GetColor(), aSHD
);
4084 if (rWW8Wrt
.bWrtWW8
)
4085 rWW8Wrt
.InsUInt16(0x442D);
4087 rWW8Wrt
.pO
->Insert(47, rWW8Wrt
.pO
->Count());
4088 rWW8Wrt
.InsUInt16( aSHD
.GetValue() );
4090 //Quite a few unknowns, some might be transparency or something
4092 if (rWW8Wrt
.bWrtWW8
)
4094 rWW8Wrt
.InsUInt16(0xC64D);
4095 rWW8Wrt
.pO
->Insert(10, rWW8Wrt
.pO
->Count());
4096 rWW8Wrt
.InsUInt32(0xFF000000);
4097 rWW8Wrt
.InsUInt32(SuitableBGColor(
4098 rBack
.GetColor().GetColor()));
4099 rWW8Wrt
.InsUInt16(0x0000);
4105 WW8_BRC
SwWW8Writer::TranslateBorderLine(const SvxBorderLine
& rLine
,
4106 USHORT nDist
, bool bShadow
)
4108 // M.M. This function writes out border lines to the word format similar to
4109 // what SwRTFWriter::OutRTFBorder does in the RTF filter Eventually it
4110 // would be nice if all this functionality was in the one place
4112 UINT16 nWidth
= rLine
.GetInWidth() + rLine
.GetOutWidth();
4113 BYTE brcType
= 0, nColCode
= 0;
4115 if( nWidth
) // Linie ?
4118 bool bDouble
= 0 != rLine
.GetInWidth() && 0 != rLine
.GetOutWidth();
4119 bool bThick
= !bDouble
&& !bWrtWW8
&& nWidth
> 75;
4133 // Angabe in 8tel Punkten, also durch 2.5, da 1 Punkt = 20 Twips
4134 nWidth
= (( nWidth
* 8 ) + 10 ) / 20;
4140 // Angabe in 0.75 pt
4141 nWidth
= ( nWidth
+ 7 ) / 15;
4146 if( 0 == nWidth
) // ganz duenne Linie
4147 nWidth
= 1; // nicht weglassen
4150 nColCode
= TransCol( rLine
.GetColor() );
4154 USHORT nLDist
= nDist
;
4155 nLDist
/= 20; // Masseinheit : pt
4161 aBrc
.aBits1
[0] = BYTE(nWidth
);
4162 aBrc
.aBits1
[1] = brcType
;
4163 aBrc
.aBits2
[0] = nColCode
;
4164 aBrc
.aBits2
[1] = BYTE(nLDist
);
4166 // fShadow, keine weiteren Einstellungen im WW moeglich
4168 aBrc
.aBits2
[1] |= 0x20;
4172 USHORT aBits
= nWidth
+ ( brcType
<< 3 );
4173 aBits
|= (nColCode
& 0x1f) << 6;
4174 aBits
|= nLDist
<< 11;
4175 // fShadow, keine weiteren Einstellungen im WW moeglich
4178 ShortToSVBT16( aBits
, aBrc
.aBits1
);
4184 // MakeBorderLine() bekommt einen WW8Bytes* uebergeben, um die Funktion
4185 // auch fuer die Tabellen-Umrandungen zu benutzen.
4186 // Wenn nSprmNo == 0, dann wird der Opcode nicht ausgegeben.
4187 // bShadow darf bei Tabellenzellen *nicht* gesetzt sein !
4188 void SwWW8Writer::Out_BorderLine(WW8Bytes
& rO
, const SvxBorderLine
* pLine
,
4189 USHORT nDist
, USHORT nOffset
, bool bShadow
)
4191 ASSERT( (nOffset
<= 3) || USHRT_MAX
== nOffset
||
4192 ((0x702b - 0x6424) <= nOffset
&& nOffset
<= (0x702e - 0x6424)),
4193 "SprmOffset ausserhalb des Bereichs" );
4198 aBrc
= TranslateBorderLine( *pLine
, nDist
, bShadow
);
4203 // 0x6424, sprmPBrcTop pap.brcTop;BRC;long; !!!!
4204 // 0x6425, sprmPBrcLeft
4205 // 0x6426, sprmPBrcBottom
4206 // 0x6427, sprmPBrcRight
4207 if( USHRT_MAX
!= nOffset
) // mit OpCode-Ausgabe ?
4208 SwWW8Writer::InsUInt16( rO
, 0x6424 + nOffset
);
4210 rO
.Insert( aBrc
.aBits1
, 2, rO
.Count() );
4211 rO
.Insert( aBrc
.aBits2
, 2, rO
.Count() );
4216 // 38, sprmPBrcTop - pap.brcTop BRC short !!!
4218 // 40, sprmPBrcBottom
4219 // 41, sprmPBrcRight
4220 if( USHRT_MAX
!= nOffset
) // mit OpCode-Ausgabe ?
4221 rO
.Insert( (BYTE
)( 38 + nOffset
), rO
.Count() );
4222 rO
.Insert( aBrc
.aBits1
, 2, rO
.Count() );
4226 // OutWW8_SwFmtBox1() ist fuer alle Boxen ausser in Tabellen.
4227 // es wird pO des WW8Writers genommen
4228 void SwWW8Writer::Out_SwFmtBox(const SvxBoxItem
& rBox
, bool bShadow
)
4234 return ; // WW95 kennt keine Seitenumrandung
4237 // 0x702b, sprmSBrcTop pap.brcTop;BRC;long; !!!!
4238 // 0x702c, sprmSBrcLeft
4239 // 0x702d, sprmSBrcBottom
4240 // 0x702e, sprmSBrcRight
4241 nOffset
= (0x702b - 0x6424);
4244 static const USHORT aBorders
[] =
4246 BOX_LINE_TOP
, BOX_LINE_LEFT
, BOX_LINE_BOTTOM
, BOX_LINE_RIGHT
4248 const USHORT
* pBrd
= aBorders
;
4249 for( USHORT i
= 0; i
< 4; ++i
, ++pBrd
)
4251 const SvxBorderLine
* pLn
= rBox
.GetLine( *pBrd
);
4252 Out_BorderLine( *pO
, pLn
, rBox
.GetDistance( *pBrd
), nOffset
+i
,
4257 // OutWW8_SwFmtBox2() ist fuer TC-Strukturen in Tabellen. Der Sprm-Opcode
4258 // wird nicht geschrieben, da es in der TC-Structur ohne Opcode gepackt ist.
4259 // dxpSpace wird immer 0, da WW das in Tabellen so verlangt
4260 // ( Tabellenumrandungen fransen sonst aus )
4261 // Ein WW8Bytes-Ptr wird als Ausgabe-Parameter uebergeben
4263 void SwWW8Writer::Out_SwFmtTableBox( WW8Bytes
& rO
, const SvxBoxItem
& rBox
)
4265 // moeglich und vielleicht besser waere 0xffff
4266 static const USHORT aBorders
[] =
4268 BOX_LINE_TOP
, BOX_LINE_LEFT
, BOX_LINE_BOTTOM
, BOX_LINE_RIGHT
4270 const USHORT
* pBrd
= aBorders
;
4271 for( int i
= 0; i
< 4; ++i
, ++pBrd
)
4273 const SvxBorderLine
* pLn
= rBox
.GetLine( *pBrd
);
4274 Out_BorderLine(rO
, pLn
, 0, USHRT_MAX
, false);
4278 static Writer
& OutWW8_SwFmtBox( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4280 // Fly um Grafik-> keine Umrandung hier, da
4281 // der GrafikHeader bereits die Umrandung hat
4282 SwWW8Writer
& rWW8Wrt
= ((SwWW8Writer
&)rWrt
);
4283 if( !rWW8Wrt
.bOutGrf
)
4285 bool bShadow
= false;
4286 const SfxPoolItem
* pItem
= ((SwWW8Writer
&)rWrt
).HasItem( RES_SHADOW
);
4289 const SvxShadowItem
* p
= (const SvxShadowItem
*)pItem
;
4290 bShadow
= ( p
->GetLocation() != SVX_SHADOW_NONE
)
4291 && ( p
->GetWidth() != 0 );
4294 rWW8Wrt
.Out_SwFmtBox( (SvxBoxItem
&)rHt
, bShadow
);
4299 SwTwips
SwWW8Writer::CurrentPageWidth(SwTwips
&rLeft
, SwTwips
&rRight
) const
4301 const SwFrmFmt
* pFmt
= pAktPageDesc
? &pAktPageDesc
->GetMaster()
4302 : &const_cast<const SwDoc
*>(pDoc
)->GetPageDesc(0).GetMaster();
4304 const SvxLRSpaceItem
& rLR
= pFmt
->GetLRSpace();
4305 SwTwips nPageSize
= pFmt
->GetFrmSize().GetWidth();
4306 rLeft
= rLR
.GetLeft();
4307 rRight
= rLR
.GetRight();
4311 static Writer
& OutWW8_SwFmtCol( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4313 const SwFmtCol
& rCol
= (const SwFmtCol
&)rHt
;
4314 const SwColumns
& rColumns
= rCol
.GetColumns();
4315 SwWW8Writer
& rWW8Wrt
= ((SwWW8Writer
&)rWrt
);
4317 USHORT nCols
= rColumns
.Count();
4318 if (1 < nCols
&& !rWW8Wrt
.bOutFlyFrmAttrs
)
4320 // dann besorge mal die Seitenbreite ohne Raender !!
4322 const SwFrmFmt
* pFmt
= rWW8Wrt
.pAktPageDesc
? &rWW8Wrt
.pAktPageDesc
->GetMaster() : &const_cast<const SwDoc
*>(rWW8Wrt
.pDoc
)->GetPageDesc(0).GetMaster();
4323 const SvxFrameDirectionItem
&frameDirection
= pFmt
->GetFrmDir();
4325 if (frameDirection
.GetValue() == FRMDIR_VERT_TOP_RIGHT
|| frameDirection
.GetValue() == FRMDIR_VERT_TOP_LEFT
)
4327 const SvxULSpaceItem
&rUL
= pFmt
->GetULSpace();
4328 nPageSize
= pFmt
->GetFrmSize().GetHeight();
4329 nPageSize
-= rUL
.GetUpper() + rUL
.GetLower();
4331 const SwFmtHeader
*header
= dynamic_cast<const SwFmtHeader
*>(pFmt
->GetAttrSet().GetItem(RES_HEADER
));
4334 const SwFrmFmt
*headerFmt
= header
->GetHeaderFmt();
4337 nPageSize
-= headerFmt
->GetFrmSize().GetHeight();
4340 const SwFmtFooter
*footer
= dynamic_cast<const SwFmtFooter
*>(pFmt
->GetAttrSet().GetItem(RES_FOOTER
));
4343 const SwFrmFmt
*footerFmt
= footer
->GetFooterFmt();
4346 nPageSize
-= footerFmt
->GetFrmSize().GetHeight();
4352 const SvxLRSpaceItem
&rLR
= pFmt
->GetLRSpace();
4353 nPageSize
= pFmt
->GetFrmSize().GetWidth();
4354 nPageSize
-= rLR
.GetLeft() + rLR
.GetRight();
4358 if( rWW8Wrt
.bWrtWW8
)
4359 rWW8Wrt
.InsUInt16( 0x500b );
4361 rWW8Wrt
.pO
->Insert( 144, rWW8Wrt
.pO
->Count() );
4362 rWW8Wrt
.InsUInt16( nCols
- 1 );
4365 if( rWW8Wrt
.bWrtWW8
)
4366 rWW8Wrt
.InsUInt16( 0x900c );
4368 rWW8Wrt
.pO
->Insert( 145, rWW8Wrt
.pO
->Count() );
4369 rWW8Wrt
.InsUInt16(rCol
.GetGutterWidth(true));
4372 if( rWW8Wrt
.bWrtWW8
)
4373 rWW8Wrt
.InsUInt16( 0x3019 );
4375 rWW8Wrt
.pO
->Insert( 158, rWW8Wrt
.pO
->Count() );
4376 rWW8Wrt
.pO
->Insert( COLADJ_NONE
== rCol
.GetLineAdj() ? 0 : 1,
4377 rWW8Wrt
.pO
->Count() );
4379 // Nachsehen, ob alle Spalten gleich sind
4382 USHORT nColWidth
= rCol
.CalcPrtColWidth( 0, (USHORT
)nPageSize
);
4383 for (n
= 1; n
< nCols
; n
++)
4385 short nDiff
= nColWidth
-
4386 rCol
.CalcPrtColWidth( n
, (USHORT
)nPageSize
);
4388 if( nDiff
> 10 || nDiff
< -10 ) // Toleranz: 10 tw
4396 USHORT nSpace
= rColumns
[0]->GetRight() + rColumns
[1]->GetLeft();
4397 for( n
= 2; n
< nCols
; n
++ )
4399 short nDiff
= nSpace
- ( rColumns
[n
- 1]->GetRight()
4400 + rColumns
[n
]->GetLeft() );
4401 if (nDiff
> 10 || nDiff
< -10)
4411 if( rWW8Wrt
.bWrtWW8
)
4412 rWW8Wrt
.InsUInt16( 0x3005 );
4414 rWW8Wrt
.pO
->Insert( 138, rWW8Wrt
.pO
->Count() );
4415 rWW8Wrt
.pO
->Insert( bEven
? 1 : 0, rWW8Wrt
.pO
->Count() );
4419 for (n
= 0; n
< nCols
; ++n
)
4422 if( rWW8Wrt
.bWrtWW8
)
4423 rWW8Wrt
.InsUInt16( 0xF203 );
4425 rWW8Wrt
.pO
->Insert( 136, rWW8Wrt
.pO
->Count() );
4426 rWW8Wrt
.pO
->Insert( (BYTE
)n
, rWW8Wrt
.pO
->Count() );
4427 rWW8Wrt
.InsUInt16(rCol
.CalcPrtColWidth(n
, (USHORT
)nPageSize
));
4431 //sprmSDxaColSpacing
4432 if( rWW8Wrt
.bWrtWW8
)
4433 rWW8Wrt
.InsUInt16( 0xF204 );
4435 rWW8Wrt
.pO
->Insert( 137, rWW8Wrt
.pO
->Count() );
4436 rWW8Wrt
.pO
->Insert( (BYTE
)n
, rWW8Wrt
.pO
->Count() );
4437 rWW8Wrt
.InsUInt16( rColumns
[ n
]->GetRight() +
4438 rColumns
[ n
+ 1 ]->GetLeft() );
4446 // "Absaetze zusammenhalten"
4447 static Writer
& OutWW8_SvxFmtKeep( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4450 const SvxFmtKeepItem
& rAttr
= (const SvxFmtKeepItem
&)rHt
;
4451 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
4452 if( rWrtWW8
.bWrtWW8
)
4453 rWrtWW8
.InsUInt16( 0x2406 );
4455 rWrtWW8
.pO
->Insert( 8, rWrtWW8
.pO
->Count() );
4457 rWrtWW8
.pO
->Insert( rAttr
.GetValue() ? 1 : 0, rWrtWW8
.pO
->Count() );
4462 // exclude a paragraph from Line Numbering
4463 static Writer
& OutWW8_SwFmtLineNumber( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4466 const SwFmtLineNumber
& rAttr
= (const SwFmtLineNumber
&)rHt
;
4468 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
4469 if( rWrtWW8
.bWrtWW8
)
4470 rWrtWW8
.InsUInt16( 0x240C );
4472 rWrtWW8
.pO
->Insert( 14, rWrtWW8
.pO
->Count() );
4474 rWrtWW8
.pO
->Insert( rAttr
.IsCount() ? 0 : 1, rWrtWW8
.pO
->Count() );
4480 /* File PARATR.HXX */
4482 static Writer
& OutWW8_SvxLineSpacing( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4485 const SvxLineSpacingItem
& rAttr
= (const SvxLineSpacingItem
&)rHt
;
4486 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
4487 if( rWrtWW8
.bWrtWW8
)
4488 rWrtWW8
.InsUInt16( 0x6412 );
4490 rWrtWW8
.pO
->Insert( 20, rWrtWW8
.pO
->Count() );
4492 short nSpace
= 240, nMulti
= 0;
4494 switch (rAttr
.GetLineSpaceRule())
4498 case SVX_LINE_SPACE_AUTO
:
4499 case SVX_LINE_SPACE_FIX
:
4500 case SVX_LINE_SPACE_MIN
:
4502 switch (rAttr
.GetInterLineSpaceRule())
4504 case SVX_INTER_LINE_SPACE_FIX
: // unser Durchschuss
4506 // gibt es aber nicht in WW - also wie kommt man an
4507 // die MaxLineHeight heran?
4508 nSpace
= (short)rAttr
.GetInterLineSpace();
4509 sal_uInt16 nScript
=
4510 i18n::ScriptType::LATIN
;
4511 const SwAttrSet
*pSet
= 0;
4512 if (rWrtWW8
.pOutFmtNode
&& rWrtWW8
.pOutFmtNode
->ISA(SwFmt
))
4514 const SwFmt
*pFmt
= (const SwFmt
*)(rWrtWW8
.pOutFmtNode
);
4515 pSet
= &pFmt
->GetAttrSet();
4517 else if (rWrtWW8
.pOutFmtNode
&&
4518 rWrtWW8
.pOutFmtNode
->ISA(SwTxtNode
))
4520 const SwTxtNode
* pNd
=
4521 (const SwTxtNode
*)rWrtWW8
.pOutFmtNode
;
4522 pSet
= &pNd
->GetSwAttrSet();
4523 if (pBreakIt
->xBreak
.is())
4525 nScript
= pBreakIt
->xBreak
->
4526 getScriptType(pNd
->GetTxt(), 0);
4529 ASSERT(pSet
, "No attrset for lineheight :-(");
4532 nSpace
= nSpace
+ (short)(AttrSetToLineHeight(*rWrtWW8
.pDoc
,
4533 *pSet
, *Application::GetDefaultDevice(), nScript
));
4537 case SVX_INTER_LINE_SPACE_PROP
:
4538 nSpace
= (short)(( 240L * rAttr
.GetPropLineSpace() ) / 100L );
4541 default: // z.B. Minimum oder FIX?
4542 if( SVX_LINE_SPACE_FIX
== rAttr
.GetLineSpaceRule() )
4543 nSpace
= -(short)rAttr
.GetLineHeight();
4545 nSpace
= (short)rAttr
.GetLineHeight();
4552 rWrtWW8
.InsUInt16(nSpace
);
4553 rWrtWW8
.InsUInt16(nMulti
);
4557 static Writer
& OutWW8_SvxAdjust(Writer
& rWrt
, const SfxPoolItem
& rHt
)
4560 const SvxAdjustItem
& rAttr
= (const SvxAdjustItem
&)rHt
;
4562 BYTE nAdjBiDi
= 255;
4563 switch(rAttr
.GetAdjust())
4565 case SVX_ADJUST_LEFT
:
4569 case SVX_ADJUST_RIGHT
:
4573 case SVX_ADJUST_BLOCKLINE
:
4574 case SVX_ADJUST_BLOCK
:
4575 nAdj
= nAdjBiDi
= 3;
4577 case SVX_ADJUST_CENTER
:
4578 nAdj
= nAdjBiDi
= 1;
4581 return rWrt
; // not a supported Attribut
4584 if (255 != nAdj
) // supported Attribut?
4586 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
4587 if (rWrtWW8
.bWrtWW8
)
4589 rWrtWW8
.InsUInt16(0x2403);
4590 rWrtWW8
.pO
->Insert(nAdj
, rWrtWW8
.pO
->Count());
4593 Sadly for left to right paragraphs both these values are the same,
4594 for right to left paragraphs the bidi one is the reverse of the
4597 rWrtWW8
.InsUInt16(0x2461); //bidi version ?
4598 bool bBiDiSwap
=false;
4599 if (rWrtWW8
.pOutFmtNode
)
4601 short nDirection
= FRMDIR_HORI_LEFT_TOP
;
4602 if (rWrtWW8
.pOutFmtNode
->ISA(SwTxtNode
))
4604 SwPosition
aPos(*(const SwCntntNode
*)rWrtWW8
.pOutFmtNode
);
4605 nDirection
= rWrtWW8
.pDoc
->GetTextDirection(aPos
);
4607 else if (rWrtWW8
.pOutFmtNode
->ISA(SwTxtFmtColl
))
4609 const SwTxtFmtColl
* pC
=
4610 (const SwTxtFmtColl
*)rWrtWW8
.pOutFmtNode
;
4611 const SvxFrameDirectionItem
&rItem
=
4612 ItemGet
<SvxFrameDirectionItem
>(*pC
, RES_FRAMEDIR
);
4613 nDirection
= rItem
.GetValue();
4615 if ((nDirection
== FRMDIR_HORI_RIGHT_TOP
)
4616 || (nDirection
== FRMDIR_ENVIRONMENT
&& Application::GetSettings().GetLayoutRTL()))
4621 rWrtWW8
.pO
->Insert(nAdjBiDi
, rWrtWW8
.pO
->Count());
4623 rWrtWW8
.pO
->Insert(nAdj
, rWrtWW8
.pO
->Count());
4627 rWrtWW8
.pO
->Insert(5, rWrtWW8
.pO
->Count());
4628 rWrtWW8
.pO
->Insert(nAdj
, rWrtWW8
.pO
->Count());
4634 static Writer
& OutWW8_SvxFrameDirection( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4636 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
4637 if (!rWrtWW8
.bWrtWW8
) //8+ only
4640 const SvxFrameDirectionItem
& rItem
= (const SvxFrameDirectionItem
&)rHt
;
4643 short nDir
= rItem
.GetValue();
4645 if (nDir
== FRMDIR_ENVIRONMENT
)
4647 if (rWrtWW8
.bOutPageDescs
)
4648 nDir
= rWrtWW8
.GetCurrentPageDirection();
4649 else if (rWrtWW8
.pOutFmtNode
)
4651 if (rWrtWW8
.bOutFlyFrmAttrs
) //frame
4653 nDir
= rWrtWW8
.TrueFrameDirection(
4654 *(const SwFrmFmt
*)rWrtWW8
.pOutFmtNode
);
4656 else if (rWrtWW8
.pOutFmtNode
->ISA(SwCntntNode
)) //pagagraph
4658 const SwCntntNode
* pNd
=
4659 (const SwCntntNode
*)rWrtWW8
.pOutFmtNode
;
4660 SwPosition
aPos(*pNd
);
4661 nDir
= rWrt
.pDoc
->GetTextDirection(aPos
);
4663 else if (rWrtWW8
.pOutFmtNode
->ISA(SwTxtFmtColl
))
4664 nDir
= FRMDIR_HORI_LEFT_TOP
; //what else can we do :-(
4667 if (nDir
== FRMDIR_ENVIRONMENT
)
4668 nDir
= FRMDIR_HORI_LEFT_TOP
; //Set something
4674 //Can't get an unknown type here
4675 ASSERT(!(&rWrt
), "Unknown frame direction");
4676 case FRMDIR_HORI_LEFT_TOP
:
4679 case FRMDIR_HORI_RIGHT_TOP
:
4683 case FRMDIR_VERT_TOP_LEFT
: //word doesn't have this
4684 case FRMDIR_VERT_TOP_RIGHT
:
4689 if (rWrtWW8
.bOutPageDescs
)
4691 rWrtWW8
.InsUInt16(0x5033);
4692 rWrtWW8
.InsUInt16(nTextFlow
);
4693 rWrtWW8
.InsUInt16(0x3228);
4694 rWrtWW8
.pO
->Insert(bBiDi
, rWrtWW8
.pO
->Count() );
4696 else if (!rWrtWW8
.bOutFlyFrmAttrs
) //paragraph/style
4698 rWrtWW8
.InsUInt16(0x2441);
4699 rWrtWW8
.pO
->Insert(bBiDi
, rWrtWW8
.pO
->Count() );
4704 // "Absaetze trennen"
4705 static Writer
& OutWW8_SvxFmtSplit( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4708 const SvxFmtSplitItem
& rAttr
= (const SvxFmtSplitItem
&)rHt
;
4709 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
4710 if( rWrtWW8
.bWrtWW8
)
4711 rWrtWW8
.InsUInt16( 0x2405 );
4713 rWrtWW8
.pO
->Insert( 7, rWrtWW8
.pO
->Count() );
4714 rWrtWW8
.pO
->Insert( rAttr
.GetValue() ? 0 : 1, rWrtWW8
.pO
->Count() );
4718 // Es wird nur das Item "SvxWidowItem" und nicht die Orphans uebersetzt,
4719 // da es fuer beides im WW nur ein Attribut "Absatzkontrolle" gibt und
4720 // im SW wahrscheinlich vom Anwender immer Beide oder keiner gesetzt werden.
4721 static Writer
& OutWW8_SvxWidows( Writer
& rWrt
, const SfxPoolItem
& rHt
)
4723 // sprmPFWidowControl
4724 const SvxWidowsItem
& rAttr
= (const SvxWidowsItem
&)rHt
;
4725 SwWW8Writer
& rWrtWW8
= (SwWW8Writer
&)rWrt
;
4726 if( rWrtWW8
.bWrtWW8
)
4727 rWrtWW8
.InsUInt16( 0x2431 );
4729 rWrtWW8
.pO
->Insert( 51, rWrtWW8
.pO
->Count() );
4730 rWrtWW8
.pO
->Insert( rAttr
.GetValue() ? 1 : 0, rWrtWW8
.pO
->Count() );
4737 BYTE
* pDel
; // DelArray
4738 BYTE
* pAddPos
; // AddPos-Array
4739 BYTE
* pAddTyp
; // AddTyp-Array
4740 sal_uInt16 nAdd
; // so viele Tabs kommen hinzu
4741 sal_uInt16 nDel
; // so viele Tabs fallen weg
4743 SwWW8WrTabu(sal_uInt16 nDelMax
, sal_uInt16 nAddMax
);
4746 void Add(const SvxTabStop
&rTS
, long nAdjustment
);
4747 void Del(const SvxTabStop
&rTS
, long nAdjustment
);
4748 void PutAll(SwWW8Writer
& rWW8Wrt
);
4751 SwWW8WrTabu::SwWW8WrTabu(sal_uInt16 nDelMax
, sal_uInt16 nAddMax
)
4754 pDel
= nDelMax
? new BYTE
[nDelMax
* 2] : 0;
4755 pAddPos
= new BYTE
[nAddMax
* 2];
4756 pAddTyp
= new BYTE
[nAddMax
];
4759 SwWW8WrTabu::~SwWW8WrTabu()
4766 // Add( const SvxTabStop & rTS ) fuegt einen Tab in die WW-Struktur ein
4767 void SwWW8WrTabu::Add(const SvxTabStop
& rTS
, long nAdjustment
)
4769 // Tab-Position eintragen
4770 ShortToSVBT16(msword_cast
<sal_Int16
>(rTS
.GetTabPos() + nAdjustment
),
4771 pAddPos
+ (nAdd
* 2));
4773 // Tab-Typ eintragen
4775 switch (rTS
.GetAdjustment())
4777 case SVX_TAB_ADJUST_RIGHT
:
4780 case SVX_TAB_ADJUST_CENTER
:
4783 case SVX_TAB_ADJUST_DECIMAL
:
4785 Theres nothing we can do btw the the decimal seperator has been
4786 customized, but if you think different remember that different
4787 locales have different seperators, i.e. german is a , while english
4796 switch( rTS
.GetFill() )
4798 case '.': // dotted leader
4801 case '_': // Single line leader
4804 case '-': // hyphenated leader
4807 case '=': // heavy line leader
4812 ByteToSVBT8(nPara
, pAddTyp
+ nAdd
);
4816 // Del( const SvxTabStop & rTS ) fuegt einen zu loeschenden Tab
4817 // in die WW-Struktur ein
4818 void SwWW8WrTabu::Del(const SvxTabStop
&rTS
, long nAdjustment
)
4820 // Tab-Position eintragen
4821 ShortToSVBT16(msword_cast
<sal_Int16
>(rTS
.GetTabPos() + nAdjustment
),
4826 // PutAll( SwWW8Writer& rWW8Wrt ) schreibt das Attribut nach rWrt.pO
4827 void SwWW8WrTabu::PutAll(SwWW8Writer
& rWrt
)
4829 if (!nAdd
&& !nDel
) //It its a no-op
4831 ASSERT(nAdd
<= 255, "more than 255 added tabstops ?");
4832 ASSERT(nDel
<= 255, "more than 244 removed tabstops ?");
4838 sal_uInt16 nSiz
= 2 * nDel
+ 3 * nAdd
+ 2;
4843 rWrt
.InsUInt16(0xC60D);
4845 rWrt
.pO
->Insert(15, rWrt
.pO
->Count());
4847 rWrt
.pO
->Insert(msword_cast
<sal_uInt8
>(nSiz
), rWrt
.pO
->Count());
4849 rWrt
.pO
->Insert(msword_cast
<sal_uInt8
>(nDel
), rWrt
.pO
->Count());
4850 rWrt
.OutSprmBytes(pDel
, nDel
* 2);
4852 rWrt
.pO
->Insert(msword_cast
<sal_uInt8
>(nAdd
), rWrt
.pO
->Count());
4853 rWrt
.OutSprmBytes(pAddPos
, 2 * nAdd
); // AddPosArray
4854 rWrt
.OutSprmBytes(pAddTyp
, nAdd
); // AddTypArray
4858 static void OutWW8_SwTabStopAdd(Writer
& rWrt
, const SvxTabStopItem
& rTStops
,
4861 SwWW8WrTabu
aTab( 0, rTStops
.Count());
4863 for( USHORT n
= 0; n
< rTStops
.Count(); n
++ )
4865 const SvxTabStop
& rTS
= rTStops
[n
];
4866 // Def-Tabs ignorieren
4867 if (SVX_TAB_ADJUST_DEFAULT
!= rTS
.GetAdjustment())
4868 aTab
.Add(rTS
, nLParaMgn
);
4870 aTab
.PutAll( (SwWW8Writer
&)rWrt
);
4873 bool lcl_IsEqual(long nOneLeft
, const SvxTabStop
&rOne
,
4874 long nTwoLeft
, const SvxTabStop
&rTwo
)
4877 nOneLeft
== nTwoLeft
&&
4878 rOne
.GetAdjustment() == rTwo
.GetAdjustment() &&
4879 rOne
.GetDecimal() == rTwo
.GetDecimal() &&
4880 rOne
.GetFill() == rTwo
.GetFill()
4884 static void OutWW8_SwTabStopDelAdd(Writer
& rWrt
, const SvxTabStopItem
& rTStyle
,
4885 long nLStypeMgn
, const SvxTabStopItem
& rTNew
, long nLParaMgn
)
4887 SwWW8WrTabu
aTab(rTStyle
.Count(), rTNew
.Count());
4889 USHORT nO
= 0; // rTStyle Index
4890 USHORT nN
= 0; // rTNew Index
4893 const SvxTabStop
* pTO
;
4895 if( nO
< rTStyle
.Count() ) // alt noch nicht am Ende ?
4897 pTO
= &rTStyle
[ nO
];
4898 nOP
= pTO
->GetTabPos() + nLStypeMgn
;
4899 if( SVX_TAB_ADJUST_DEFAULT
== pTO
->GetAdjustment() )
4901 nO
++; // Default-Tab ignorieren
4911 const SvxTabStop
* pTN
;
4913 if( nN
< rTNew
.Count() ) // neu noch nicht am Ende
4916 nNP
= pTN
->GetTabPos() + nLParaMgn
;
4917 if( SVX_TAB_ADJUST_DEFAULT
== pTN
->GetAdjustment() )
4919 nN
++; // Default-Tab ignorieren
4929 if( nOP
== LONG_MAX
&& nNP
== LONG_MAX
)
4930 break; // alles fertig
4932 if( nOP
< nNP
) // naechster Tab ist alt
4934 aTab
.Del(*pTO
, nLStypeMgn
); // muss geloescht werden
4937 else if( nNP
< nOP
) // naechster Tab ist neu
4939 aTab
.Add(*pTN
, nLParaMgn
); // muss eigefuegt werden
4942 else if (lcl_IsEqual(nOP
, *pTO
, nNP
, *pTN
)) // Tabs sind gleich:
4944 nO
++; // nichts zu tun
4947 else // Tabs selbe Pos, diff Typ
4949 aTab
.Del(*pTO
, nLStypeMgn
); // alten loeschen
4950 aTab
.Add(*pTN
, nLParaMgn
); // neuen einfuegen
4956 aTab
.PutAll( (SwWW8Writer
&)rWrt
);
4959 static Writer
& OutWW8_SwTabStop(Writer
& rWrt
, const SfxPoolItem
& rHt
)
4961 SwWW8Writer
& rWW8Wrt
= (SwWW8Writer
&)rWrt
;
4962 const SvxTabStopItem
& rTStops
= (const SvxTabStopItem
&)rHt
;
4963 bool bTabsRelativeToIndex
= rWW8Wrt
.pCurPam
->GetDoc()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT
);
4964 long nCurrentLeft
= 0;
4966 if (bTabsRelativeToIndex
)
4968 const SfxPoolItem
* pLR
= rWW8Wrt
.HasItem( RES_LR_SPACE
);
4971 nCurrentLeft
= ((const SvxLRSpaceItem
*)pLR
)->GetTxtLeft();
4975 // --> FLR 2009-03-17 #i100264#
4977 && rWW8Wrt
.pCurrentStyle
!=NULL
4978 && rWW8Wrt
.pCurrentStyle
->DerivedFrom()!=NULL
) {
4979 SvxTabStopItem
aTabs(0, 0, SVX_TAB_ADJUST_DEFAULT
, RES_PARATR_TABSTOP
);
4980 const SwFmt
*pParentStyle
=rWW8Wrt
.pCurrentStyle
->DerivedFrom();
4981 const SvxTabStopItem
* pParentTabs
=HasItem
<SvxTabStopItem
>(pParentStyle
->GetAttrSet(), RES_PARATR_TABSTOP
);
4983 aTabs
.Insert(pParentTabs
);
4986 OutWW8_SwTabStopDelAdd(rWW8Wrt
, aTabs
, 0, rTStops
, 0);
4992 // StyleDef -> "einfach" eintragen || keine Style-Attrs -> dito
4993 const SvxTabStopItem
* pStyleTabs
= 0;
4994 if (!rWW8Wrt
.bStyDef
&& rWW8Wrt
.pStyAttr
)
4997 HasItem
<SvxTabStopItem
>(*rWW8Wrt
.pStyAttr
, RES_PARATR_TABSTOP
);
5001 OutWW8_SwTabStopAdd(rWW8Wrt
, rTStops
, nCurrentLeft
);
5004 long nStyleLeft
= 0;
5006 if (bTabsRelativeToIndex
)
5008 const SvxLRSpaceItem
&rStyleLR
=
5009 ItemGet
<SvxLRSpaceItem
>(*rWW8Wrt
.pStyAttr
, RES_LR_SPACE
);
5010 nStyleLeft
= rStyleLR
.GetTxtLeft();
5013 OutWW8_SwTabStopDelAdd(rWW8Wrt
, *pStyleTabs
, nStyleLeft
, rTStops
,
5019 //-----------------------------------------------------------------------
5022 * lege hier die Tabellen fuer die WW-Funktions-Pointer auf
5023 * die Ausgabe-Funktionen an.
5024 * Es sind lokale Strukturen, die nur innerhalb
5025 * bekannt sein muessen.
5028 SwAttrFnTab aWW8AttrFnTab
= {
5029 /* RES_CHRATR_CASEMAP */ OutWW8_SwCaseMap
,
5030 /* RES_CHRATR_CHARSETCOLOR */ 0,
5031 /* RES_CHRATR_COLOR */ OutWW8_SwColor
,
5032 /* RES_CHRATR_CONTOUR */ OutWW8_SwContour
,
5033 /* RES_CHRATR_CROSSEDOUT */ OutWW8_SwCrossedOut
,
5034 /* RES_CHRATR_ESCAPEMENT */ OutWW8_SwEscapement
,
5035 /* RES_CHRATR_FONT */ OutWW8_SwFont
,
5036 /* RES_CHRATR_FONTSIZE */ OutWW8_SwSize
,
5037 /* RES_CHRATR_KERNING */ OutWW8_SwKerning
,
5038 /* RES_CHRATR_LANGUAGE */ OutWW8_SwLanguage
,
5039 /* RES_CHRATR_POSTURE */ OutWW8_SwPosture
,
5040 /* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
5041 /* RES_CHRATR_SHADOWED */ OutWW8_SwShadow
,
5042 /* RES_CHRATR_UNDERLINE */ OutWW8_SwUnderline
,
5043 /* RES_CHRATR_WEIGHT */ OutWW8_SwWeight
,
5044 /* RES_CHRATR_WORDLINEMODE */ 0, // Wird bei Underline mitbehandelt
5045 /* RES_CHRATR_AUTOKERN */ OutWW8_SvxAutoKern
,
5046 /* RES_CHRATR_BLINK */ OutWW8_SwAnimatedText
, // neu: blinkender Text
5047 /* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen
5048 /* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen
5049 /* RES_CHRATR_BACKGROUND */ OutWW8_SwFmtCharBackground
,
5050 /* RES_CHRATR_CJK_FONT */ OutWW8_SwCJKFont
,
5051 /* RES_CHRATR_CJK_FONTSIZE */ OutWW8_SwSize
,
5052 /* RES_CHRATR_CJK_LANGUAGE */ OutWW8_SwLanguage
,
5053 /* RES_CHRATR_CJK_POSTURE */ OutWW8_SwPosture
,
5054 /* RES_CHRATR_CJK_WEIGHT */ OutWW8_SwWeight
,
5055 /* RES_CHRATR_CTL_FONT */ OutWW8_SwCTLFont
,
5056 /* RES_CHRATR_CTL_FONTSIZE */ OutWW8_SwSize
,
5057 /* RES_CHRATR_CTL_LANGUAGE */ OutWW8_SwLanguage
,
5058 /* RES_CHRATR_CTL_POSTURE */ OutWW8_SwBiDiPosture
,
5059 /* RES_CHRATR_CTL_WEIGHT */ OutWW8_SwBiDiWeight
,
5060 /* RES_CHRATR_WRITING_DIRECTION */ OutWW8_CharRotate
,
5061 /* RES_CHRATR_EMPHASIS_MARK*/ OutWW8_EmphasisMark
,
5062 /* RES_TXTATR_TWO_LINES */ OutWW8_SvxTwoLinesItem
,
5063 /* RES_CHRATR_DUMMY4 */ OutWW8_ScaleWidth
,
5064 /* RES_CHRATR_RELIEF*/ OutWW8_Relief
,
5065 /* RES_CHRATR_HIDDEN */ OutWW8_SvxCharHidden
,
5066 /* RES_CHRATR_OVERLINE */ 0,
5067 /* RES_CHRATR_DUMMY1 */ 0,
5068 /* RES_CHRATR_DUMMY2 */ 0,
5070 /* RES_TXTATR_DUMMY4 */ 0,
5071 /* RES_TXTATR_INETFMT */ OutSwFmtINetFmt
,
5072 /* RES_TXTATR_REFMARK */ 0, // handled by SwAttrIter
5073 /* RES_TXTATR_TOXMARK */ 0, // handled by SwAttrIter
5074 /* RES_TXTATR_CHARFMT */ OutWW8_SwTxtCharFmt
,
5075 /* RES_TXTATR_DUMMY5*/ 0,
5076 /* RES_TXTATR_CJK_RUBY */ 0, // handled by SwAttrIter
5077 /* RES_TXTATR_UNKNOWN_CONTAINER */ 0,
5078 /* RES_TXTATR_DUMMY6 */ 0,
5079 /* RES_TXTATR_DUMMY7 */ 0,
5081 /* RES_TXTATR_FIELD */ OutWW8_SwField
,
5082 /* RES_TXTATR_FLYCNT */ OutWW8_SwFlyCntnt
,
5083 /* RES_TXTATR_FTN */ OutWW8_SwFtn
,
5084 /* RES_TXTATR_SOFTHYPH */ 0, // old attr. - coded now by character
5085 /* RES_TXTATR_HARDBLANK */ OutWW8_SwHardBlank
,
5086 /* RES_TXTATR_DUMMY1 */ 0, // Dummy:
5087 /* RES_TXTATR_DUMMY2 */ 0, // Dummy:
5089 /* RES_PARATR_LINESPACING */ OutWW8_SvxLineSpacing
,
5090 /* RES_PARATR_ADJUST */ OutWW8_SvxAdjust
,
5091 /* RES_PARATR_SPLIT */ OutWW8_SvxFmtSplit
,
5092 /* RES_PARATR_ORPHANS */ 0, // OutW4W_SwOrphans, // kann WW nicht unabhaengig von Widows
5093 /* RES_PARATR_WIDOWS */ OutWW8_SvxWidows
,
5094 /* RES_PARATR_TABSTOP */ OutWW8_SwTabStop
,
5095 /* RES_PARATR_HYPHENZONE*/ OutWW8_SvxHyphenZone
,
5096 /* RES_PARATR_DROP */ 0,
5097 /* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit
5098 /* RES_PARATR_NUMRULE */ OutWW8_SwNumRuleItem
,
5099 /* RES_PARATR_SCRIPTSPACE */ OutWW8_SfxBoolItem
,
5100 /* RES_PARATR_HANGINGPUNCTUATION */ OutWW8_SfxBoolItem
,
5101 /* RES_PARATR_FORBIDDEN_RULES */ OutWW8_SfxBoolItem
,
5102 /* RES_PARATR_VERTALIGN */ OutWW8_SvxParaVertAlignItem
,
5103 /* RES_PARATR_SNAPTOGRID*/ OutWW8_SvxParaGridItem
,
5104 /* RES_PARATR_CONNECT_TO_BORDER */ 0, // new
5105 /* RES_PARATR_OUTLINELEVEL */ 0, // new - outlinelevel
5107 /* RES_PARATR_LIST_ID */ 0, // new
5108 /* RES_PARATR_LIST_LEVEL */ 0, // new
5109 /* RES_PARATR_LIST_ISRESTART */ 0, // new
5110 /* RES_PARATR_LIST_RESTARTVALUE */ 0, // new
5111 /* RES_PARATR_LIST_ISCOUNTED */ 0, // new
5113 /* RES_FILL_ORDER */ 0, // OutW4W_SwFillOrder,
5114 /* RES_FRM_SIZE */ OutWW8_SwFrmSize
,
5115 /* RES_PAPER_BIN */ OutWW8_SvxPaperBin
,
5116 /* RES_LR_SPACE */ OutWW8_SwFmtLRSpace
,
5117 /* RES_UL_SPACE */ OutWW8_SwFmtULSpace
,
5118 /* RES_PAGEDESC */ OutWW8_SwFmtPageDesc
,
5119 /* RES_BREAK */ OutWW8_SwFmtBreak
,
5120 /* RES_CNTNT */ 0, /* 0, // OutW4W_??? */
5121 /* RES_HEADER */ 0, // wird bei der PageDesc ausgabe beachtet
5122 /* RES_FOOTER */ 0, // wird bei der PageDesc ausgabe beachtet
5123 /* RES_PRINT */ 0, // OutW4W_SwFmtPrint,
5124 /* RES_OPAQUE */ 0, // OutW4W_SwFmtOpaque, // kann WW nicht
5125 /* RES_PROTECT */ 0, // OutW4W_SwFmtProtect,
5126 /* RES_SURROUND */ OutWW8_SwFmtSurround
,
5127 /* RES_VERT_ORIENT */ OutWW8_SwFmtVertOrient
,
5128 /* RES_HORI_ORIENT */ OutWW8_SwFmtHoriOrient
,
5129 /* RES_ANCHOR */ OutWW8_SwFmtAnchor
,
5130 /* RES_BACKGROUND */ OutWW8_SwFmtBackground
,
5131 /* RES_BOX */ OutWW8_SwFmtBox
,
5132 /* RES_SHADOW */ 0, // Wird bei SwFmtBox mitbehandelt
5133 /* RES_FRMMACRO */ 0, /* 0, // OutW4W_??? */
5134 /* RES_COL */ OutWW8_SwFmtCol
,
5135 /* RES_KEEP */ OutWW8_SvxFmtKeep
,
5136 /* RES_URL */ 0, // URL
5137 /* RES_EDIT_IN_READONLY */ 0,
5138 /* RES_LAYOUT_SPLIT */ 0,
5140 /* RES_TEXTGRID*/ OutWW8_SwTextGrid
,
5141 /* RES_LINENUMBER */ OutWW8_SwFmtLineNumber
, // Line Numbering
5142 /* RES_FTN_AT_TXTEND*/ 0, // Dummy:
5143 /* RES_END_AT_TXTEND*/ 0, // Dummy:
5144 /* RES_COLUMNBALANCE*/ 0, // Dummy:
5145 /* RES_FRAMEDIR*/ OutWW8_SvxFrameDirection
,
5146 /* RES_FRMATR_DUMMY8 */ 0, // Dummy:
5147 /* RES_FRMATR_DUMMY9 */ 0, // Dummy:
5148 /* RES_FOLLOW_TEXT_FLOW */ 0,
5149 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ 0,
5150 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
5151 /* RES_AUTO_STYLE */ 0, // Dummy:
5152 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
5153 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
5155 /* RES_GRFATR_MIRRORGRF */ 0, // OutW4W_SwMirrorGrf,
5156 /* RES_GRFATR_CROPGRF */ 0, // OutW4W_SwCropGrf
5157 /* RES_GRFATR_ROTATION */ 0,
5158 /* RES_GRFATR_LUMINANCE */ 0,
5159 /* RES_GRFATR_CONTRAST */ 0,
5160 /* RES_GRFATR_CHANNELR */ 0,
5161 /* RES_GRFATR_CHANNELG */ 0,
5162 /* RES_GRFATR_CHANNELB */ 0,
5163 /* RES_GRFATR_GAMMA */ 0,
5164 /* RES_GRFATR_INVERT */ 0,
5165 /* RES_GRFATR_TRANSPARENCY */ 0,
5166 /* RES_GRFATR_DRWAMODE */ 0,
5167 /* RES_GRFATR_DUMMY1 */ 0,
5168 /* RES_GRFATR_DUMMY2 */ 0,
5169 /* RES_GRFATR_DUMMY3 */ 0,
5170 /* RES_GRFATR_DUMMY4 */ 0,
5171 /* RES_GRFATR_DUMMY5 */ 0,
5173 /* RES_BOXATR_FORMAT */ 0,
5174 /* RES_BOXATR_FORMULA */ 0,
5175 /* RES_BOXATR_VALUE */ 0,
5177 /* RES_UNKNOWNATR_CONTAINER */ 0
5180 /* vi:set tabstop=4 shiftwidth=4 expandtab: */