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: htmlatr.cxx,v $
10 * $Revision: 1.41.140.1 $
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"
35 #include <hintids.hxx>
36 #include <com/sun/star/i18n/ScriptType.hpp>
37 #include <vcl/svapp.hxx>
38 #ifndef _WRKWIN_HXX //autogen
39 #include <vcl/wrkwin.hxx>
41 #include <tools/urlobj.hxx>
43 #if !defined _SVSTDARR_XUB_STRLEN_DECL || !defined _SVSTDARR_USHORTS_DECL
44 #define _SVSTDARR_XUB_STRLEN
45 #define _SVSTDARR_USHORTS
46 #include <svtools/svstdarr.hxx>
48 #include <svtools/htmlout.hxx>
49 #include <svtools/htmlkywd.hxx>
50 #include <svtools/htmltokn.h>
51 #include <svtools/whiter.hxx>
52 #include <svx/htmlmode.hxx>
53 #include <svx/escpitem.hxx>
54 #include <svx/brkitem.hxx>
55 #include <svx/boxitem.hxx>
56 #include <svx/ulspitem.hxx>
57 #include <svx/udlnitem.hxx>
58 #include <svx/crsditem.hxx>
59 #include <svx/blnkitem.hxx>
60 #include <svx/cmapitem.hxx>
61 #include <svx/colritem.hxx>
62 #include <svx/fontitem.hxx>
63 #include <svx/fhgtitem.hxx>
64 #include <svx/postitem.hxx>
65 #include <svx/kernitem.hxx>
66 #include <svx/wghtitem.hxx>
67 #include <svx/lspcitem.hxx>
68 #include <svx/adjitem.hxx>
69 #include <svx/lrspitem.hxx>
70 #include <svx/brshitem.hxx>
71 #include <svx/langitem.hxx>
72 #include <svx/frmdiritem.hxx>
73 #include <fchrfmt.hxx>
74 #include <fmtautofmt.hxx>
75 #include <fmtfsize.hxx>
76 #include <fmtclds.hxx>
77 #include <fmtpdsc.hxx>
78 #include <fmtflcnt.hxx>
79 #include <fmtinfmt.hxx>
81 #include <txatbase.hxx>
83 #include <charfmt.hxx>
84 #include <fmthbsh.hxx>
90 #include <poolfmt.hxx>
91 #include <pagedesc.hxx>
92 #include <swtable.hxx>
94 #include <breakit.hxx>
95 #include <htmlnum.hxx>
96 #include <wrthtml.hxx>
97 #include <htmlfly.hxx>
98 #include <numrule.hxx>
100 using namespace ::com::sun::star
;
103 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
104 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
105 * definiert und mit der akt. verglichen. Bei unterschieden wird der
106 * Compiler schon meckern.
108 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
109 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
111 #if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
113 #define ATTRFNTAB_SIZE 130
114 #if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
115 #error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
118 #ifdef FORMAT_TABELLE
119 // da sie nicht benutzt wird!
120 #define FORMATTAB_SIZE 7
121 #if FORMATTAB_SIZE != RES_FMT_END - RES_FMT_BEGIN
122 #error Format-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
126 #define NODETAB_SIZE 3
127 #if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
128 #error Node-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
133 #define HTML_BULLETCHAR_DISC 34
134 #define HTML_BULLETCHAR_CIRCLE 38
135 #define HTML_BULLETCHAR_SQUARE 36
139 //-----------------------------------------------------------------------
141 HTMLOutEvent __FAR_DATA aAnchorEventTable
[] =
143 { OOO_STRING_SVTOOLS_HTML_O_SDonclick
, OOO_STRING_SVTOOLS_HTML_O_onclick
, SFX_EVENT_MOUSECLICK_OBJECT
},
144 { OOO_STRING_SVTOOLS_HTML_O_SDonmouseover
, OOO_STRING_SVTOOLS_HTML_O_onmouseover
, SFX_EVENT_MOUSEOVER_OBJECT
},
145 { OOO_STRING_SVTOOLS_HTML_O_SDonmouseout
, OOO_STRING_SVTOOLS_HTML_O_onmouseout
, SFX_EVENT_MOUSEOUT_OBJECT
},
149 static Writer
& OutHTML_SvxAdjust( Writer
& rWrt
, const SfxPoolItem
& rHt
);
151 static Writer
& OutHTML_HoriSpacer( Writer
& rWrt
, INT16 nSize
)
153 ASSERT( nSize
>0, "horizontaler SPACER mit negativem Wert?" )
157 if( Application::GetDefaultDevice() )
159 nSize
= (INT16
)Application::GetDefaultDevice()
160 ->LogicToPixel( Size(nSize
,0), MapMode(MAP_TWIP
) ).Width();
163 ByteString
sOut( '<' );
164 (((((((((sOut
+= OOO_STRING_SVTOOLS_HTML_spacer
)
165 += ' ') += OOO_STRING_SVTOOLS_HTML_O_type
) += '=') += OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal
)
166 += ' ') += OOO_STRING_SVTOOLS_HTML_O_size
) += '=')
167 +=ByteString::CreateFromInt32(nSize
)) += '>';
169 rWrt
.Strm() << sOut
.GetBuffer();
174 USHORT
SwHTMLWriter::GetDefListLvl( const String
& rNm
, USHORT nPoolId
)
176 if( nPoolId
== RES_POOLCOLL_HTML_DD
)
178 return 1 | HTML_DLCOLL_DD
;
180 else if( nPoolId
== RES_POOLCOLL_HTML_DT
)
182 return 1 | HTML_DLCOLL_DT
;
185 String
sDTDD( String::CreateFromAscii(OOO_STRING_SVTOOLS_HTML_dt
) );
187 if( COMPARE_EQUAL
== sDTDD
.CompareTo( rNm
, sDTDD
.Len() ) )
188 // DefinitionList - term
189 return (USHORT
)rNm
.Copy( sDTDD
.Len() ).ToInt32() | HTML_DLCOLL_DT
;
191 sDTDD
.AssignAscii( OOO_STRING_SVTOOLS_HTML_dd
);
193 if( COMPARE_EQUAL
== sDTDD
.CompareTo( rNm
, sDTDD
.Len() ) )
194 // DefinitionList - definition
195 return (USHORT
)rNm
.Copy( sDTDD
.Len() ).ToInt32() | HTML_DLCOLL_DD
;
200 void SwHTMLWriter::OutAndSetDefList( USHORT nNewLvl
)
202 // eventuell muss erst mal eine Liste aufgemacht werden
203 if( nDefListLvl
< nNewLvl
)
205 // output </pre> for the previous(!) pararagraph, if required.
206 // Preferable, the <pre> is exported by OutHTML_SwFmtOff for the
207 // previous paragraph already, but that's not possible, because a very
208 // deep look at the next paragraph (this one) is required to figure
209 // out that a def list starts here.
211 ChangeParaToken( 0 );
213 // entsprechend dem Level-Unterschied schreiben!
214 for( USHORT i
=nDefListLvl
; i
<nNewLvl
; i
++ )
218 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist
, TRUE
);
223 else if( nDefListLvl
> nNewLvl
)
225 for( USHORT i
=nNewLvl
; i
< nDefListLvl
; i
++ )
230 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist
, FALSE
);
235 nDefListLvl
= nNewLvl
;
239 void SwHTMLWriter::ChangeParaToken( USHORT nNew
)
241 if( nNew
!= nLastParaToken
&& HTML_PREFORMTXT_ON
== nLastParaToken
)
243 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_preformtxt
, FALSE
);
246 nLastParaToken
= nNew
;
249 sal_uInt16
SwHTMLWriter::GetCSS1ScriptForScriptType( sal_uInt16 nScriptType
)
251 sal_uInt16 nRet
= CSS1_OUTMODE_ANY_SCRIPT
;
253 switch( nScriptType
)
255 case i18n::ScriptType::LATIN
:
256 nRet
= CSS1_OUTMODE_WESTERN
;
258 case i18n::ScriptType::ASIAN
:
259 nRet
= CSS1_OUTMODE_CJK
;
261 case i18n::ScriptType::COMPLEX
:
262 nRet
= CSS1_OUTMODE_CTL
;
269 // fuer die Formate muesste eine einzige Ausgabe-Funktion genuegen !
271 * Formate wie folgt ausgeben:
272 * - fuer Formate, fuer die es entsprechende HTML-Tags gibt wird das
274 * - fuer alle anderen wird ein Absatz-Tag <P> ausgegeben und bUserFmt
276 * - Wenn eine Absatz-Ausrichtung am uebergebenen Item-Set des Nodes
277 * oder im Item-Set des Format gesetzt ist, wird ein ALIGN=xxx ausgegeben,
278 * sofern HTML es zulaesst
279 * - in jedem Fall wird harte Attributierung als STYLE-Option geschrieben.
280 * Wenn bUserFmt nicht gesetzt ist, wird nur der uebergebene Item-Set
281 * betrachtet. Sonst werden auch Attribute des Formats ausgegeben.
284 struct SwHTMLTxtCollOutputInfo
286 ByteString aToken
; // auszugendens End-Token
287 SfxItemSet
*pItemSet
; // harte Attributierung
289 BOOL bInNumBulList
; // in einer Aufzaehlungs-Liste;
290 BOOL bParaPossible
; // ein </P> darf zusaetzlich ausgegeben werden
291 BOOL bOutPara
; // ein </P> soll ausgegeben werden
292 BOOL bOutDiv
; // write a </DIV>
294 SwHTMLTxtCollOutputInfo() :
296 bInNumBulList( FALSE
),
297 bParaPossible( FALSE
),
302 ~SwHTMLTxtCollOutputInfo();
304 BOOL
HasParaToken() const { return aToken
.Len()==1 && aToken
.GetChar(0)=='P'; }
305 BOOL
ShouldOutputToken() const { return bOutPara
|| !HasParaToken(); }
308 SwHTMLTxtCollOutputInfo::~SwHTMLTxtCollOutputInfo()
315 const SwFmt
*pFmt
; // das Format selbst
316 const SwFmt
*pRefFmt
; // das Vergleichs-Format
318 ByteString aToken
; // das auszugebende Token
319 String aClass
; // die auszugebende Klasse
321 SfxItemSet
*pItemSet
; // der auszugebende Attribut-Set
323 sal_Int32 nLeftMargin
; // ein par default-Werte fuer
324 sal_Int32 nRightMargin
; // Absatz-Vorlagen
325 short nFirstLineIndent
;
328 USHORT nBottomMargin
;
330 sal_Bool bScriptDependent
;
332 // Konstruktor fuer einen Dummy zum Suchen
333 SwHTMLFmtInfo( const SwFmt
*pF
) :
334 pFmt( pF
), pItemSet( 0 )
338 // Konstruktor zum Erstellen der Format-Info
339 SwHTMLFmtInfo( const SwFmt
*pFmt
, SwDoc
*pDoc
, SwDoc
*pTemlate
,
340 BOOL bOutStyles
, LanguageType eDfltLang
=LANGUAGE_DONTKNOW
,
341 sal_uInt16 nScript
=CSS1_OUTMODE_ANY_SCRIPT
,
342 BOOL bHardDrop
=FALSE
);
345 friend BOOL
operator==( const SwHTMLFmtInfo
& rInfo1
,
346 const SwHTMLFmtInfo
& rInfo2
)
348 return (long)rInfo1
.pFmt
== (long)rInfo2
.pFmt
;
351 friend BOOL
operator<( const SwHTMLFmtInfo
& rInfo1
,
352 const SwHTMLFmtInfo
& rInfo2
)
354 return (long)rInfo1
.pFmt
< (long)rInfo2
.pFmt
;
359 SV_IMPL_OP_PTRARR_SORT( SwHTMLFmtInfos
, SwHTMLFmtInfo
* )
361 SwHTMLFmtInfo::SwHTMLFmtInfo( const SwFmt
*pF
, SwDoc
*pDoc
, SwDoc
*pTemplate
,
363 LanguageType eDfltLang
,
364 sal_uInt16 nCSS1Script
, BOOL bHardDrop
) :
365 pFmt( pF
), pItemSet( 0 ), bScriptDependent( sal_False
)
367 USHORT nRefPoolId
= 0;
368 // Den Selektor des Formats holen
369 USHORT nDeep
= SwHTMLWriter::GetCSS1Selector( pFmt
, aToken
, aClass
,
371 ASSERT( nDeep
? aToken
.Len()>0 : aToken
.Len()==0,
372 "Hier stimmt doch was mit dem Token nicht!" );
373 ASSERT( nDeep
? nRefPoolId
: !nRefPoolId
,
374 "Hier stimmt doch was mit der Vergleichs-Vorlage nicht!" );
376 BOOL bTxtColl
= pFmt
->Which() == RES_TXTFMTCOLL
||
377 pFmt
->Which() == RES_CONDTXTFMTCOLL
;
379 const SwFmt
*pReferenceFmt
= 0; // Vergleichs-Format
380 sal_Bool bSetDefaults
= sal_True
, bClearSame
= sal_True
;
383 // Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
384 // solchen abgeleitet
387 // wenn keine Styles exportiert werden, muss evtl. zusaetlich
388 // harte Attributierung geschrieben werden
392 case CSS1_FMT_CMPREF
:
393 // fuer HTML-Tag-Vorlagen die Unterscheide zum Original
394 // (sofern verfuegbar)
395 pReferenceFmt
= SwHTMLWriter::GetTemplateFmt( nRefPoolId
,
400 // sonst die zur HTML-Tag-Vorlage des Originals oder des
401 // aktuellen Doks, wenn die nicht verfuegbar ist
403 pReferenceFmt
= SwHTMLWriter::GetTemplateFmt( nRefPoolId
,
406 pReferenceFmt
= SwHTMLWriter::GetParentFmt( *pFmt
, nDeep
);
413 // Nicht von einer HTML-Tag-Vorlage abgeleitete Absatz-Vorlagen
414 // muessen als harte Attributierung relativ zur Textkoerper-Volage
415 // exportiert werden. Fuer Nicht-Styles-Export sollte die der
416 // HTML-Vorlage als Referenz dienen
417 if( !bOutStyles
&& pTemplate
)
418 pReferenceFmt
= pTemplate
->GetTxtCollFromPool( RES_POOLCOLL_TEXT
, false );
420 pReferenceFmt
= pDoc
->GetTxtCollFromPool( RES_POOLCOLL_TEXT
, false );
423 if( pReferenceFmt
|| nDeep
==0 )
425 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
426 pFmt
->GetAttrSet().GetRanges() );
427 // wenn Unterschiede zu einer anderen Vorlage geschrieben werden
428 // sollen ist harte Attributierung noetig. Fuer Vorlagen, die
429 // nicht von HTML-Tag-Vorlagen abgeleitet sind, gilt das immer
431 pItemSet
->Set( pFmt
->GetAttrSet(), TRUE
);
434 SwHTMLWriter::SubtractItemSet( *pItemSet
, pReferenceFmt
->GetAttrSet(),
435 bSetDefaults
, bClearSame
);
437 // einen leeren Item-Set gleich loeschen, das spart speater
439 if( !pItemSet
->Count() )
450 // We have to add hard attributes for any script dependent
451 // item that is not accessed by the style
452 static sal_uInt16 aWhichIds
[3][4] =
454 { RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
,
455 RES_CHRATR_POSTURE
, RES_CHRATR_WEIGHT
},
456 { RES_CHRATR_CJK_FONT
, RES_CHRATR_CJK_FONTSIZE
,
457 RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CJK_WEIGHT
},
458 { RES_CHRATR_CTL_FONT
, RES_CHRATR_CTL_FONTSIZE
,
459 RES_CHRATR_CTL_POSTURE
, RES_CHRATR_CTL_WEIGHT
}
463 sal_uInt16 aSets
[2] = {0,0};
464 switch( nCSS1Script
)
466 case CSS1_OUTMODE_WESTERN
:
471 case CSS1_OUTMODE_CJK
:
476 case CSS1_OUTMODE_CTL
:
482 for( sal_uInt16 i
=0; i
<4; i
++ )
484 const SfxPoolItem
& rRef
= pFmt
->GetFmtAttr( aWhichIds
[nRef
][i
] );
485 for( sal_uInt16 j
=0; j
<2; j
++ )
487 const SfxPoolItem
& rSet
= pFmt
->GetFmtAttr( aWhichIds
[aSets
[j
]][i
] );
491 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
492 pFmt
->GetAttrSet().GetRanges() );
493 pItemSet
->Put( rSet
);
499 // Ggf. noch ein DropCap-Attribut uebernehmen
500 if( bOutStyles
&& bHardDrop
&& nDeep
!= 0 )
502 const SfxPoolItem
*pItem
;
503 if( SFX_ITEM_SET
==pFmt
->GetAttrSet().GetItemState(
504 RES_PARATR_DROP
, TRUE
, &pItem
) )
509 pReferenceFmt
= SwHTMLWriter::GetTemplateFmt( nRefPoolId
, pTemplate
);
510 const SfxPoolItem
*pRefItem
;
512 SFX_ITEM_SET
==pReferenceFmt
->GetAttrSet().GetItemState(
513 RES_PARATR_DROP
, TRUE
, &pRefItem
);
514 bPut
= !bRefItemSet
|| *pItem
!=*pRefItem
;
519 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
520 pFmt
->GetAttrSet().GetRanges() );
521 pItemSet
->Put( *pItem
);
527 // Die diversen default-Abstaende aus der Vorlage oder der
528 // Vergleischs-Vorlage merken
529 const SvxLRSpaceItem
&rLRSpace
=
530 (pReferenceFmt
? pReferenceFmt
: pFmt
)->GetLRSpace();
531 nLeftMargin
= rLRSpace
.GetTxtLeft();
532 nRightMargin
= rLRSpace
.GetRight();
533 nFirstLineIndent
= rLRSpace
.GetTxtFirstLineOfst();
535 const SvxULSpaceItem
&rULSpace
=
536 (pReferenceFmt
? pReferenceFmt
: pFmt
)->GetULSpace();
537 nTopMargin
= rULSpace
.GetUpper();
538 nBottomMargin
= rULSpace
.GetLower();
540 // export language if it differs from the default language
541 sal_uInt16 nWhichId
=
542 SwHTMLWriter::GetLangWhichIdFromScript( nCSS1Script
);
543 const SvxLanguageItem
& rLang
=
544 (const SvxLanguageItem
&)pFmt
->GetFmtAttr( nWhichId
);
545 LanguageType eLang
= rLang
.GetLanguage();
546 if( eLang
!= eDfltLang
)
549 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
550 pFmt
->GetAttrSet().GetRanges() );
551 pItemSet
->Put( rLang
);
554 static sal_uInt16 aWhichIds
[3] =
555 { RES_CHRATR_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
,
556 RES_CHRATR_CTL_LANGUAGE
};
557 for( sal_uInt16 i
=0; i
<3; i
++ )
559 if( aWhichIds
[i
] != nWhichId
)
561 const SvxLanguageItem
& rTmpLang
=
562 (const SvxLanguageItem
&)pFmt
->GetFmtAttr(aWhichIds
[i
]);
563 if( rTmpLang
.GetLanguage() != eLang
)
566 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
567 pFmt
->GetAttrSet().GetRanges() );
568 pItemSet
->Put( rTmpLang
);
575 SwHTMLFmtInfo::~SwHTMLFmtInfo()
580 void OutHTML_SwFmt( Writer
& rWrt
, const SwFmt
& rFmt
,
581 const SfxItemSet
*pNodeItemSet
,
582 SwHTMLTxtCollOutputInfo
& rInfo
)
584 ASSERT( RES_CONDTXTFMTCOLL
==rFmt
.Which() || RES_TXTFMTCOLL
==rFmt
.Which(),
585 "keine Absatz-Vorlage" );
587 SwHTMLWriter
& rHWrt
= (SwHTMLWriter
&)rWrt
;
589 // Erstmal ein par Flags ...
590 USHORT nNewDefListLvl
= 0;
591 USHORT nNumStart
= USHRT_MAX
;
592 BOOL bForceDL
= FALSE
;
594 rInfo
.bInNumBulList
= FALSE
; // Wir sind in einer Liste?
595 BOOL bNumbered
= FALSE
; // Der aktuelle Absatz ist numeriert
596 BOOL bPara
= FALSE
; // das aktuelle Token ist <P>
597 rInfo
.bParaPossible
= FALSE
; // ein <P> darf zusaetzlich ausgegeben werden
598 BOOL bNoEndTag
= FALSE
; // kein End-Tag ausgeben
600 rHWrt
.bNoAlign
= FALSE
; // kein ALIGN=... moeglich
601 BOOL bNoStyle
= FALSE
; // kein STYLE=... moeglich
602 BYTE nBulletGrfLvl
= 255; // Die auszugebende Bullet-Grafik
604 // Sind wir in einer Aufzaehlungs- oder Numerierungliste?
605 const SwTxtNode
* pTxtNd
= rWrt
.pCurPam
->GetNode()->GetTxtNode();
607 SwHTMLNumRuleInfo aNumInfo
;
608 if( rHWrt
.GetNextNumInfo() )
610 aNumInfo
= *rHWrt
.GetNextNumInfo();
611 rHWrt
.ClearNextNumInfo();
615 aNumInfo
.Set( *pTxtNd
);
618 if( aNumInfo
.GetNumRule() )
620 rInfo
.bInNumBulList
= TRUE
;
623 // ist der aktuelle Absatz numeriert?
624 bNumbered
= aNumInfo
.IsNumbered();
625 BYTE nLvl
= aNumInfo
.GetLevel();
627 ASSERT( pTxtNd
->GetActualListLevel() == nLvl
,
628 "Gemerkter Num-Level ist falsch" );
629 ASSERT( bNumbered
== static_cast< BOOL
>(pTxtNd
->IsCountedInList()),
630 "Gemerkter Numerierungs-Zustand ist falsch" );
634 nBulletGrfLvl
= nLvl
; // nur veruebergehend!!!
635 // --> OD 2005-11-15 #i57919#
636 // correction of re-factoring done by cws swnumtree:
637 // - <nNumStart> has to contain the restart value, if the
638 // numbering is restarted at this text node. Value <USHRT_MAX>
639 // indicates, that no additional restart value has to be written.
640 if ( pTxtNd
->IsListRestart() )
642 nNumStart
= static_cast< USHORT
>(pTxtNd
->GetActualListStartValue());
645 DBG_ASSERT( rHWrt
.nLastParaToken
== 0,
646 "<PRE> wurde nicht vor <LI> beendet." );
650 // Jetzt holen wir das Token und ggf. die Klasse
651 SwHTMLFmtInfo
aFmtInfo( &rFmt
);
653 const SwHTMLFmtInfo
*pFmtInfo
;
654 if( rHWrt
.aTxtCollInfos
.Seek_Entry( &aFmtInfo
, &nArrayPos
) )
656 pFmtInfo
= rHWrt
.aTxtCollInfos
[nArrayPos
];
660 pFmtInfo
= new SwHTMLFmtInfo( &rFmt
, rWrt
.pDoc
, rHWrt
.pTemplate
,
661 rHWrt
.bCfgOutStyles
, rHWrt
.eLang
,
663 !rHWrt
.IsHTMLMode(HTMLMODE_DROPCAPS
) );
664 rHWrt
.aTxtCollInfos
.C40_PTR_INSERT( SwHTMLFmtInfo
, pFmtInfo
);
665 String
aName( rFmt
.GetName() );
666 if( rHWrt
.aScriptParaStyles
.Seek_Entry( &aName
) )
667 ((SwHTMLFmtInfo
*)pFmtInfo
)->bScriptDependent
= sal_True
;
670 // Jetzt wird festgelegt, was aufgrund des Tokens so moeglich ist
671 USHORT nToken
= 0; // Token fuer Tag-Wechsel
672 BOOL bOutNewLine
= FALSE
; // nur ein LF ausgeben?
673 if( pFmtInfo
->aToken
.Len() )
675 // Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
676 // solchen abgeleitet
677 rInfo
.aToken
= pFmtInfo
->aToken
;
679 // der erste Buchstabe reicht meistens
680 switch( rInfo
.aToken
.GetChar( 0 ) )
682 case 'A': ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_address
),
683 "Doch kein ADDRESS?" );
684 rInfo
.bParaPossible
= TRUE
;
685 rHWrt
.bNoAlign
= TRUE
;
688 case 'B': ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_blockquote
),
689 "Doch kein BLOCKQUOTE?" );
690 rInfo
.bParaPossible
= TRUE
;
691 rHWrt
.bNoAlign
= TRUE
;
694 case 'P': if( rInfo
.aToken
.Len() == 1 )
700 ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_preformtxt
),
702 if( HTML_PREFORMTXT_ON
== rHWrt
.nLastParaToken
)
708 nToken
= HTML_PREFORMTXT_ON
;
709 rHWrt
.bNoAlign
= TRUE
;
715 case 'D': ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_dt
) ||
716 rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_dd
),
717 "Doch kein DD/DT?" );
718 bDT
= rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_dt
);
719 rInfo
.bParaPossible
= !bDT
;
720 rHWrt
.bNoAlign
= TRUE
;
727 // alle Vorlagen, die nicht einem HTML-Tag entsprechen oder von
728 // diesem abgeleitet sind, werden als <P> exportiert
730 rInfo
.aToken
= OOO_STRING_SVTOOLS_HTML_parabreak
;
734 // Falls noetig, die harte Attributierung der Vorlage uebernehmen
735 if( pFmtInfo
->pItemSet
)
737 ASSERT( !rInfo
.pItemSet
, "Wo kommt der Item-Set her?" );
738 rInfo
.pItemSet
= new SfxItemSet( *pFmtInfo
->pItemSet
);
741 // und noch die harte Attributierung des Absatzes dazunehmen
745 rInfo
.pItemSet
->Put( *pNodeItemSet
);
747 rInfo
.pItemSet
= new SfxItemSet( *pNodeItemSet
);
750 // den unteren Absatz-Abstand brauchen wir noch
751 const SvxULSpaceItem
& rULSpace
=
752 pNodeItemSet
? ((const SvxULSpaceItem
&)pNodeItemSet
->Get(RES_UL_SPACE
))
756 if( (rHWrt
.bOutHeader
&&
757 rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() ==
758 rWrt
.pCurPam
->GetMark()->nNode
.GetIndex()) ||
761 if( rHWrt
.bCfgOutStyles
)
763 SvxULSpaceItem
aULSpaceItem( rULSpace
);
764 if( rHWrt
.bOutHeader
)
765 aULSpaceItem
.SetLower( rHWrt
.nHeaderFooterSpace
);
767 aULSpaceItem
.SetUpper( rHWrt
.nHeaderFooterSpace
);
769 if( !rInfo
.pItemSet
)
770 rInfo
.pItemSet
= new SfxItemSet(
771 *rFmt
.GetAttrSet().GetPool(),
772 RES_UL_SPACE
, RES_UL_SPACE
);
773 rInfo
.pItemSet
->Put( aULSpaceItem
);
775 rHWrt
.bOutHeader
= FALSE
;
776 rHWrt
.bOutFooter
= FALSE
;
781 // nur einen Zeilen-Umbruch (ohne Einrueckung) am Absatz-Anfang
783 rInfo
.aToken
.Erase(); // kein End-Tag ausgeben
784 rWrt
.Strm() << SwHTMLWriter::sNewLine
;
790 // soll ein ALIGN=... geschrieben werden?
791 const SfxPoolItem
* pAdjItem
= 0;
792 const SfxPoolItem
* pItem
;
794 if( rInfo
.pItemSet
&&
795 SFX_ITEM_SET
== rInfo
.pItemSet
->GetItemState( RES_PARATR_ADJUST
,
801 // Unteren Absatz-Abstand beachten ? (nie im letzen Absatz von
803 BOOL bUseParSpace
= !rHWrt
.bOutTable
||
804 (rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() !=
805 rWrt
.pCurPam
->GetMark()->nNode
.GetIndex());
806 // Wenn Styles exportiert werden, wird aus eingerueckten Absaetzen
807 // eine Definitions-Liste
808 const SvxLRSpaceItem
& rLRSpace
=
809 pNodeItemSet
? ((const SvxLRSpaceItem
&)pNodeItemSet
->Get(RES_LR_SPACE
))
811 if( (!rHWrt
.bCfgOutStyles
|| bForceDL
) && !rInfo
.bInNumBulList
)
813 sal_Int32 nLeftMargin
;
815 nLeftMargin
= rLRSpace
.GetTxtLeft();
817 nLeftMargin
= rLRSpace
.GetTxtLeft() > pFmtInfo
->nLeftMargin
818 ? rLRSpace
.GetTxtLeft() - pFmtInfo
->nLeftMargin
821 if( nLeftMargin
> 0 && rHWrt
.nDefListMargin
> 0 )
823 nNewDefListLvl
= static_cast< USHORT
>((nLeftMargin
+ (rHWrt
.nDefListMargin
/2)) /
824 rHWrt
.nDefListMargin
);
825 if( nNewDefListLvl
== 0 && bForceDL
&& !bDT
)
830 // If the left margin is 0 or negative, emulating indent
831 // with <dd> does not work. We then set a def list only if
832 // the dd style is used.
833 nNewDefListLvl
= (bForceDL
&& !bDT
) ? 1 : 0;
836 BOOL bIsNextTxtNode
=
837 rWrt
.pDoc
->GetNodes()[rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex()+1]
840 if( bForceDL
&& bDT
)
842 // Statt eines DD muessen wir hier auch ein DT der Ebene
846 else if( !nNewDefListLvl
&& !rHWrt
.bCfgOutStyles
&& bPara
&&
847 rULSpace
.GetLower()==0 &&
848 ((bUseParSpace
&& bIsNextTxtNode
) || rHWrt
.nDefListLvl
==1) &&
849 (!pAdjItem
|| SVX_ADJUST_LEFT
==
850 ((const SvxAdjustItem
*)pAdjItem
)->GetAdjust()) )
852 // Absaetze ohne unteren Abstand als DT exportieren
855 rInfo
.bParaPossible
= FALSE
;
856 rHWrt
.bNoAlign
= TRUE
;
860 if( nNewDefListLvl
!= rHWrt
.nDefListLvl
)
861 rHWrt
.OutAndSetDefList( nNewDefListLvl
);
863 // ggf. eine Aufzaehlung- oder Numerierungsliste beginnen
864 if( rInfo
.bInNumBulList
)
866 ASSERT( !rHWrt
.nDefListLvl
, "DL in OL geht nicht!" );
867 OutHTML_NumBulListStart( rHWrt
, aNumInfo
);
871 if( rHWrt
.aBulletGrfs
[nBulletGrfLvl
].Len() )
878 // Die Defaults aus der Vorlage merken, denn sie muessen nicht
880 rHWrt
.nDfltLeftMargin
= pFmtInfo
->nLeftMargin
;
881 rHWrt
.nDfltRightMargin
= pFmtInfo
->nRightMargin
;
882 rHWrt
.nDfltFirstLineIndent
= pFmtInfo
->nFirstLineIndent
;
884 if( rInfo
.bInNumBulList
)
886 if( !rHWrt
.IsHTMLMode( HTMLMODE_LSPACE_IN_NUMBUL
) )
887 rHWrt
.nDfltLeftMargin
= rLRSpace
.GetTxtLeft();
889 // In Numerierungs-Listen keinen Ertzeilen-Einzug ausgeben.
890 rHWrt
.nFirstLineIndent
= rLRSpace
.GetTxtFirstLineOfst();
893 if( rInfo
.bInNumBulList
&& bNumbered
&& bPara
&& !rHWrt
.bCfgOutStyles
)
895 // ein einzelnes LI hat keinen Abstand
896 rHWrt
.nDfltTopMargin
= 0;
897 rHWrt
.nDfltBottomMargin
= 0;
899 else if( rHWrt
.nDefListLvl
&& bPara
)
901 // ein einzelnes DD hat auch keinen Abstand
902 rHWrt
.nDfltTopMargin
= 0;
903 rHWrt
.nDfltBottomMargin
= 0;
907 rHWrt
.nDfltTopMargin
= pFmtInfo
->nTopMargin
;
908 // #60393#: Wenn im letzten Absatz einer Tabelle der
909 // untere Absatz-Abstand veraendert wird, vertut sich
910 // Netscape total. Deshalb exportieren wir hier erstmal
911 // nichts, indem wir den Abstand aus dem Absatz als Default
913 if( rHWrt
.bCfgNetscape4
&& !bUseParSpace
)
914 rHWrt
.nDfltBottomMargin
= rULSpace
.GetLower();
916 rHWrt
.nDfltBottomMargin
= pFmtInfo
->nBottomMargin
;
919 if( rHWrt
.nDefListLvl
)
922 (rHWrt
.nDefListLvl
-1) * rHWrt
.nDefListMargin
;
925 if( rHWrt
.bLFPossible
)
926 rHWrt
.OutNewLine(); // Absatz-Tag in neue Zeile
927 rInfo
.bOutPara
= FALSE
;
929 // das ist jetzt unser neues Token
930 rHWrt
.ChangeParaToken( nToken
);
932 BOOL bHasParSpace
= bUseParSpace
&& rULSpace
.GetLower() > 0;
934 // ggf ein List-Item aufmachen
935 if( rInfo
.bInNumBulList
&& bNumbered
)
937 ByteString
sOut( '<' );
938 sOut
+= OOO_STRING_SVTOOLS_HTML_li
;
939 if( USHRT_MAX
!= nNumStart
)
940 (((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_value
) += '=')
941 += ByteString::CreateFromInt32(nNumStart
);
943 rWrt
.Strm() << sOut
.GetBuffer();
946 if( rHWrt
.nDefListLvl
> 0 && !bForceDL
)
948 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), bDT
? OOO_STRING_SVTOOLS_HTML_dt
: OOO_STRING_SVTOOLS_HTML_dd
);
952 rHWrt
.IsHTMLMode( HTMLMODE_NO_CONTROL_CENTERING
) &&
953 rHWrt
.HasControls() )
955 // #64687#: The align=... attribute does behave strange in netscape
956 // if there are controls in a paragraph, because the control and
957 // all text behind the control does not recognize this attribute.
958 ByteString
sOut( '<' );
959 sOut
+= OOO_STRING_SVTOOLS_HTML_division
;
960 rWrt
.Strm() << sOut
.GetBuffer();
962 rHWrt
.bTxtAttr
= FALSE
;
963 rHWrt
.bOutOpts
= TRUE
;
964 OutHTML_SvxAdjust( rWrt
, *pAdjItem
);
967 rHWrt
.bNoAlign
= FALSE
;
968 rInfo
.bOutDiv
= TRUE
;
969 rHWrt
.IncIndentLevel();
970 rHWrt
.bLFPossible
= TRUE
;
974 // fuer BLOCKQUOTE, ADDRESS und DD wird noch ein Absatz-Token
976 // - keine Styles geschrieben werden, und
977 // - ein untere Abstand oder eine Absatz-Ausrichtung existiert
978 ByteString aToken
= rInfo
.aToken
;
979 if( !rHWrt
.bCfgOutStyles
&& rInfo
.bParaPossible
&& !bPara
&&
980 (bHasParSpace
|| pAdjItem
) )
982 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), rInfo
.aToken
.GetBuffer() );
983 aToken
= OOO_STRING_SVTOOLS_HTML_parabreak
;
985 rHWrt
.bNoAlign
= FALSE
;
989 LanguageType eLang
= rInfo
.pItemSet
990 ? ((const SvxLanguageItem
&)rInfo
.pItemSet
->Get(SwHTMLWriter::GetLangWhichIdFromScript(rHWrt
.nCSS1Script
))).GetLanguage()
995 static sal_uInt16 aWhichIds
[3] = { RES_CHRATR_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
, RES_CHRATR_CTL_LANGUAGE
};
997 for( sal_uInt16 i
=0; i
<3; i
++ )
999 // export language if it differs from the default language only.
1000 const SfxPoolItem
*pTmpItem
;
1001 if( SFX_ITEM_SET
== rInfo
.pItemSet
->GetItemState( aWhichIds
[i
],
1002 sal_True
, &pTmpItem
) &&
1003 ((const SvxLanguageItem
*)pTmpItem
)->GetLanguage() == eLang
)
1004 rInfo
.pItemSet
->ClearItem( aWhichIds
[i
] );
1008 // and the text direction
1009 sal_uInt16 nDir
= rHWrt
.GetHTMLDirection(
1010 (pNodeItemSet
? static_cast < const SvxFrameDirectionItem
& >(
1011 pNodeItemSet
->Get( RES_FRAMEDIR
) )
1012 : rFmt
.GetFrmDir() ).GetValue() );
1014 // Ein <P> wird nur geschrieben, wenn
1015 // - wir in keiner OL/UL/DL sind, oder
1016 // - der Absatz einer OL/UL nicht numeriert ist, oder
1017 // - keine Styles exportiert werden und
1018 // - ein unterer Abstand oder
1019 // - eine Absatz-Ausrichtung existiert, ode
1020 // - Styles exportiert werden und,
1021 // - die Textkoerper-Vorlage geaendert wurde, oder
1022 // - ein Benutzer-Format exportiert wird, oder
1023 // - Absatz-Attribute existieren
1025 (!rInfo
.bInNumBulList
&& !rHWrt
.nDefListLvl
) ||
1026 (rInfo
.bInNumBulList
&& !bNumbered
) ||
1027 (!rHWrt
.bCfgOutStyles
&&
1028 (bHasParSpace
|| pAdjItem
||
1029 (eLang
!= LANGUAGE_DONTKNOW
&& eLang
!= rHWrt
.eLang
))) ||
1030 nDir
!= rHWrt
.nDirection
||
1031 rHWrt
.bCfgOutStyles
)
1033 // jetzt werden Optionen ausgegeben
1034 rHWrt
.bTxtAttr
= FALSE
;
1035 rHWrt
.bOutOpts
= TRUE
;
1037 ByteString
sOut( '<' );
1040 if( eLang
!= LANGUAGE_DONTKNOW
&& eLang
!= rHWrt
.eLang
)
1042 rWrt
.Strm() << sOut
.GetBuffer();
1043 rHWrt
.OutLanguage( eLang
);
1047 if( nDir
!= rHWrt
.nDirection
)
1051 rWrt
.Strm() << sOut
.GetBuffer();
1054 rHWrt
.OutDirection( nDir
);
1057 if( rHWrt
.bCfgOutStyles
&&
1058 (pFmtInfo
->aClass
.Len() || pFmtInfo
->bScriptDependent
) )
1060 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
1061 rWrt
.Strm() << sOut
.GetBuffer();
1062 String
aClass( pFmtInfo
->aClass
);
1063 if( pFmtInfo
->bScriptDependent
)
1067 switch( rHWrt
.nCSS1Script
)
1069 case CSS1_OUTMODE_WESTERN
:
1070 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
1072 case CSS1_OUTMODE_CJK
:
1073 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
1075 case CSS1_OUTMODE_CTL
:
1076 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
1080 HTMLOutFuncs::Out_String( rWrt
.Strm(), aClass
,
1081 rHWrt
.eDestEnc
, &rHWrt
.aNonConvertableCharacters
);
1084 rWrt
.Strm() << sOut
.GetBuffer();
1086 // ggf. Ausrichtung ausgeben.
1087 if( !rHWrt
.bNoAlign
&& pAdjItem
)
1088 OutHTML_SvxAdjust( rWrt
, *pAdjItem
);
1090 // und nun ggf. noch die STYLE-Option
1091 if( rHWrt
.bCfgOutStyles
&& rInfo
.pItemSet
&& !bNoStyle
)
1093 OutCSS1_ParaTagStyleOpt( rWrt
, *rInfo
.pItemSet
);
1098 // Soll ein </P> geschrieben wenrden
1101 ( rHWrt
.bCfgOutStyles
||
1102 (!rHWrt
.bCfgOutStyles
&& bHasParSpace
) );
1104 // wenn kein End-Tag geschrieben werden soll, es loeschen
1106 rInfo
.aToken
.Erase();
1109 // ??? Warum nicht ueber den Hint-Mechanismus ???
1110 if( rHWrt
.IsHTMLMode(HTMLMODE_FIRSTLINE
) )
1112 const SvxLRSpaceItem
& rLRSpaceTmp
=
1113 pNodeItemSet
? ((const SvxLRSpaceItem
&)pNodeItemSet
->Get(RES_LR_SPACE
))
1114 : rFmt
.GetLRSpace();
1115 if( rLRSpaceTmp
.GetTxtFirstLineOfst() > 0 )
1117 OutHTML_HoriSpacer( rWrt
, rLRSpaceTmp
.GetTxtFirstLineOfst() );
1121 if( nBulletGrfLvl
!= 255 )
1123 ASSERT( aNumInfo
.GetNumRule(), "Wo ist die Numerierung geblieben???" );
1124 ASSERT( nBulletGrfLvl
< MAXLEVEL
, "So viele Ebenen gibt's nicht" );
1125 const SwNumFmt
& rNumFmt
= aNumInfo
.GetNumRule()->Get(nBulletGrfLvl
);
1127 OutHTML_BulletImage( rWrt
, OOO_STRING_SVTOOLS_HTML_image
, 0,
1128 rHWrt
.aBulletGrfs
[nBulletGrfLvl
],
1129 rNumFmt
.GetGraphicSize(), rNumFmt
.GetGraphicOrientation() );
1132 rHWrt
.GetNumInfo() = aNumInfo
;
1134 // die Defaults zuruecksetzen
1135 rHWrt
.nDfltLeftMargin
= 0;
1136 rHWrt
.nDfltRightMargin
= 0;
1137 rHWrt
.nDfltFirstLineIndent
= 0;
1138 rHWrt
.nDfltTopMargin
= 0;
1139 rHWrt
.nDfltBottomMargin
= 0;
1140 rHWrt
.nLeftMargin
= 0;
1141 rHWrt
.nFirstLineIndent
= 0;
1144 void OutHTML_SwFmtOff( Writer
& rWrt
, const SwHTMLTxtCollOutputInfo
& rInfo
)
1146 SwHTMLWriter
& rHWrt
= (SwHTMLWriter
&)rWrt
;
1148 // wenn es kein Token gibt haben wir auch nichts auszugeben
1149 if( !rInfo
.aToken
.Len() )
1151 rHWrt
.FillNextNumInfo();
1152 const SwHTMLNumRuleInfo
& rNextInfo
= *rHWrt
.GetNextNumInfo();
1153 // Auch in PRE muss eine Bullet-Liste beendet werden
1154 if( rInfo
.bInNumBulList
)
1157 const SwHTMLNumRuleInfo
& rNRInfo
= rHWrt
.GetNumInfo();
1158 if( rNextInfo
.GetNumRule() != rNRInfo
.GetNumRule() ||
1159 rNextInfo
.GetDepth() != rNRInfo
.GetDepth() ||
1160 rNextInfo
.IsNumbered() || rNextInfo
.IsRestart() )
1161 rHWrt
.ChangeParaToken( 0 );
1162 OutHTML_NumBulListEnd( rHWrt
, rNextInfo
);
1164 else if( rNextInfo
.GetNumRule() != 0 )
1165 rHWrt
.ChangeParaToken( 0 );
1170 if( rInfo
.ShouldOutputToken() )
1172 if( rHWrt
.bLFPossible
)
1173 rHWrt
.OutNewLine( TRUE
);
1175 // fuer BLOCKQUOTE, ADDRESS und DD wird ggf noch ein
1176 // Absatz-Token ausgegeben, wenn
1177 // - keine Styles geschrieben werden, und
1178 // - ein untere Abstand existiert
1179 if( rInfo
.bParaPossible
&& rInfo
.bOutPara
)
1180 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_parabreak
, FALSE
);
1182 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), rInfo
.aToken
.GetBuffer(),
1184 rHWrt
.bLFPossible
= !rInfo
.aToken
.Equals( OOO_STRING_SVTOOLS_HTML_dt
) &&
1185 !rInfo
.aToken
.Equals( OOO_STRING_SVTOOLS_HTML_dd
) &&
1186 !rInfo
.aToken
.Equals( OOO_STRING_SVTOOLS_HTML_li
);
1190 rHWrt
.DecIndentLevel();
1191 if( rHWrt
.bLFPossible
)
1193 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_division
, FALSE
);
1194 rHWrt
.bLFPossible
= TRUE
;
1197 // ggf. eine Aufzaehlung- oder Numerierungsliste beenden
1198 if( rInfo
.bInNumBulList
)
1200 rHWrt
.FillNextNumInfo();
1201 OutHTML_NumBulListEnd( rHWrt
, *rHWrt
.GetNextNumInfo() );
1214 HTMLSttEndPos( const SfxPoolItem
& rItem
, xub_StrLen nStt
, xub_StrLen nE
);
1217 const SfxPoolItem
*GetItem() const { return pItem
; }
1219 void SetStart( xub_StrLen nStt
) { nStart
= nStt
; }
1220 xub_StrLen
GetStart() const { return nStart
; }
1222 xub_StrLen
GetEnd() const { return nEnd
; }
1223 void SetEnd( xub_StrLen nE
) { nEnd
= nE
; }
1226 HTMLSttEndPos::HTMLSttEndPos( const SfxPoolItem
& rItem
, xub_StrLen nStt
,
1230 pItem( rItem
.Clone() )
1233 HTMLSttEndPos::~HTMLSttEndPos()
1238 typedef HTMLSttEndPos
*HTMLSttEndPosPtr
;
1239 SV_DECL_PTRARR( _HTMLEndLst
, HTMLSttEndPosPtr
, 5, 5 )
1241 enum HTMLOnOffState
{ HTML_NOT_SUPPORTED
, // nicht unterst. Attribut
1242 HTML_REAL_VALUE
, // Attribut mit Wert
1243 HTML_ON_VALUE
, // Attribut entspricht On-Tag
1244 HTML_OFF_VALUE
, // Attribut entspricht Off-Tag
1245 HTML_CHRFMT_VALUE
, // Attribut fuer Zeichenvorlage
1246 HTML_COLOR_VALUE
, // Attribut fuer Vordergrundfarbe
1247 HTML_STYLE_VALUE
, // Attribut muss als Style exp.
1248 HTML_DROPCAP_VALUE
, // DropCap-Attributs
1249 HTML_AUTOFMT_VALUE
}; // Attribute for automatic character styles
1254 _HTMLEndLst aStartLst
; // nach Anfangs-Psoitionen sortierte Liste
1255 _HTMLEndLst aEndLst
; // nach End-Psotionen sortierte Liste
1256 SvXub_StrLens aScriptChgLst
; // positions where script changes
1257 // 0 is not contained in this list,
1258 // but the text length
1259 SvUShorts aScriptLst
; // the script that is valif up to the position
1260 // contained in aScriptChgList at the same index
1262 SwDoc
*pDoc
; // das aktuelle Dokument
1263 SwDoc
* pTemplate
; // die HTML-Vorlage (oder 0)
1264 const Color
* pDfltColor
;// die Default-Vordergrund-Farbe
1265 SvStringsSortDtor
& rScriptTxtStyles
; //
1268 BOOL bOutStyles
: 1; // werden Styles exportiert
1271 // die Position eines Items in der Start-/Ende-Liste suchen
1272 USHORT
_FindStartPos( const HTMLSttEndPos
*pPos
) const;
1273 USHORT
_FindEndPos( const HTMLSttEndPos
*pPos
) const;
1275 // Eine SttEndPos in die Start- und Ende-Listen eintragen bzw. aus
1276 // ihnen loeschen, wobei die Ende-Position bekannt ist
1277 void _InsertItem( HTMLSttEndPos
*pPos
, USHORT nEndPos
);
1278 void _RemoveItem( USHORT nEndPos
);
1280 // die "Art" es Attributs ermitteln
1281 HTMLOnOffState
GetHTMLItemState( const SfxPoolItem
& rItem
);
1283 // Existiert ein bestimmtes On-Tag-Item
1284 BOOL
ExistsOnTagItem( USHORT nWhich
, xub_StrLen nPos
);
1286 // Existiert ein Item zum ausschalten eines Attributs, das genauso
1287 // exportiert wird wie das uebergebene Item im gleichen Bereich?
1288 BOOL
ExistsOffTagItem( USHORT nWhich
, xub_StrLen nStartPos
,
1289 xub_StrLen nEndPos
);
1292 // das Ende eines gesplitteten Items anpassen
1293 void FixSplittedItem( HTMLSttEndPos
*pPos
, USHORT nStartPos
,
1294 xub_StrLen nNewEnd
);
1296 // Ein Attribut in die Listen eintragen und ggf. aufteilen
1297 void InsertItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1300 // Ein bereits vorhandenes Attribut aufteilen
1301 void SplitItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1304 // Insert without taking care of script
1305 void InsertNoScript( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1306 xub_StrLen nEnd
, SwHTMLFmtInfos
& rFmtInfos
,
1307 BOOL bParaAttrs
=FALSE
);
1309 const SwHTMLFmtInfo
*GetFmtInfo( const SwFmt
& rFmt
,
1310 SwHTMLFmtInfos
& rFmtInfos
);
1314 HTMLEndPosLst( SwDoc
*pDoc
, SwDoc
* pTemplate
, const Color
* pDfltColor
,
1315 BOOL bOutStyles
, ULONG nHTMLMode
,
1316 const String
& rText
, SvStringsSortDtor
& rStyles
);
1319 // Ein Attribut einfuegen
1320 void Insert( const SfxPoolItem
& rItem
, xub_StrLen nStart
, xub_StrLen nEnd
,
1321 SwHTMLFmtInfos
& rFmtInfos
, BOOL bParaAttrs
=FALSE
);
1322 void Insert( const SfxItemSet
& rItemSet
, xub_StrLen nStart
, xub_StrLen nEnd
,
1323 SwHTMLFmtInfos
& rFmtInfos
, BOOL bDeep
,
1324 BOOL bParaAttrs
=FALSE
);
1325 void Insert( const SwDrawFrmFmt
& rFmt
, xub_StrLen nPos
,
1326 SwHTMLFmtInfos
& rFmtInfos
);
1328 sal_uInt16
GetScriptAtPos( xub_StrLen nPos
,
1329 sal_uInt16 nWeak
=CSS1_OUTMODE_ANY_SCRIPT
);
1331 void OutStartAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
1332 HTMLOutContext
*pContext
= 0 );
1333 void OutEndAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
1334 HTMLOutContext
*pContext
= 0 );
1336 USHORT
Count() const { return aEndLst
.Count(); }
1338 BOOL
IsHTMLMode( ULONG nMode
) const { return (nHTMLMode
& nMode
) != 0; }
1342 USHORT
HTMLEndPosLst::_FindStartPos( const HTMLSttEndPos
*pPos
) const
1345 for( i
= 0; i
< aStartLst
.Count() && aStartLst
[i
] != pPos
; i
++ )
1348 ASSERT( i
!= aStartLst
.Count(), "Item nicht in Start-Liste gefunden!" );
1350 return i
==aStartLst
.Count() ? USHRT_MAX
: i
;
1353 USHORT
HTMLEndPosLst::_FindEndPos( const HTMLSttEndPos
*pPos
) const
1357 for( i
= 0; i
< aEndLst
.Count() && aEndLst
[i
] != pPos
; i
++ )
1360 ASSERT( i
!= aEndLst
.Count(), "Item nicht in Ende-Liste gefunden" );
1362 return i
==aEndLst
.Count() ? USHRT_MAX
: i
;
1366 void HTMLEndPosLst::_InsertItem( HTMLSttEndPos
*pPos
, USHORT nEndPos
)
1368 // In der Start-Liste das Attribut hinter allen vorher und an
1369 // der gleichen Position gestarteten Attributen einfuegen
1370 xub_StrLen nStart
= pPos
->GetStart();
1373 for( i
= 0; i
< aStartLst
.Count() &&
1374 aStartLst
[i
]->GetStart() <= nStart
; i
++ )
1376 aStartLst
.Insert( pPos
, i
);
1378 // die Position in der Ende-Liste wurde uebergeben
1379 aEndLst
.Insert( pPos
, nEndPos
);
1382 void HTMLEndPosLst::_RemoveItem( USHORT nEndPos
)
1384 HTMLSttEndPos
*pPos
= aEndLst
[nEndPos
];
1386 // jetzt Suchen wir es in der Start-Liste
1387 USHORT nStartPos
= _FindStartPos( pPos
);
1388 if( nStartPos
!= USHRT_MAX
)
1389 aStartLst
.Remove( nStartPos
, 1 );
1391 aEndLst
.Remove( nEndPos
, 1 );
1396 HTMLOnOffState
HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem
& rItem
)
1398 HTMLOnOffState eState
= HTML_NOT_SUPPORTED
;
1399 switch( rItem
.Which() )
1401 case RES_CHRATR_POSTURE
:
1402 case RES_CHRATR_CJK_POSTURE
:
1403 case RES_CHRATR_CTL_POSTURE
:
1404 switch( ((const SvxPostureItem
&)rItem
).GetPosture() )
1407 eState
= HTML_ON_VALUE
;
1410 eState
= HTML_OFF_VALUE
;
1413 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1414 eState
= HTML_STYLE_VALUE
;
1419 case RES_CHRATR_CROSSEDOUT
:
1420 switch( ((const SvxCrossedOutItem
&)rItem
).GetStrikeout() )
1422 case STRIKEOUT_SINGLE
:
1423 case STRIKEOUT_DOUBLE
:
1424 eState
= HTML_ON_VALUE
;
1426 case STRIKEOUT_NONE
:
1427 eState
= HTML_OFF_VALUE
;
1434 case RES_CHRATR_ESCAPEMENT
:
1435 switch( (const SvxEscapement
)
1436 ((const SvxEscapementItem
&)rItem
).GetEnumValue() )
1438 case SVX_ESCAPEMENT_SUPERSCRIPT
:
1439 case SVX_ESCAPEMENT_SUBSCRIPT
:
1440 eState
= HTML_ON_VALUE
;
1442 case SVX_ESCAPEMENT_OFF
:
1443 eState
= HTML_OFF_VALUE
;
1450 case RES_CHRATR_UNDERLINE
:
1451 switch( ((const SvxUnderlineItem
&)rItem
).GetLineStyle() )
1453 case UNDERLINE_SINGLE
:
1454 eState
= HTML_ON_VALUE
;
1456 case UNDERLINE_NONE
:
1457 eState
= HTML_OFF_VALUE
;
1460 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1461 eState
= HTML_STYLE_VALUE
;
1466 case RES_CHRATR_OVERLINE
:
1467 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1468 eState
= HTML_STYLE_VALUE
;
1471 case RES_CHRATR_WEIGHT
:
1472 case RES_CHRATR_CJK_WEIGHT
:
1473 case RES_CHRATR_CTL_WEIGHT
:
1474 switch( ((const SvxWeightItem
&)rItem
).GetWeight() )
1477 eState
= HTML_ON_VALUE
;
1480 eState
= HTML_OFF_VALUE
;
1483 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1484 eState
= HTML_STYLE_VALUE
;
1489 case RES_CHRATR_BLINK
:
1490 if( IsHTMLMode(HTMLMODE_BLINK
) )
1491 eState
= ((const SvxBlinkItem
&)rItem
).GetValue() ? HTML_ON_VALUE
1495 case RES_CHRATR_COLOR
:
1496 eState
= HTML_COLOR_VALUE
;
1499 case RES_CHRATR_FONT
:
1500 case RES_CHRATR_FONTSIZE
:
1501 case RES_CHRATR_LANGUAGE
:
1502 case RES_CHRATR_CJK_FONT
:
1503 case RES_CHRATR_CJK_FONTSIZE
:
1504 case RES_CHRATR_CJK_LANGUAGE
:
1505 case RES_CHRATR_CTL_FONT
:
1506 case RES_CHRATR_CTL_FONTSIZE
:
1507 case RES_CHRATR_CTL_LANGUAGE
:
1508 case RES_TXTATR_INETFMT
:
1509 eState
= HTML_REAL_VALUE
;
1512 case RES_TXTATR_CHARFMT
:
1513 eState
= HTML_CHRFMT_VALUE
;
1516 case RES_TXTATR_AUTOFMT
:
1517 eState
= HTML_AUTOFMT_VALUE
;
1520 case RES_CHRATR_CASEMAP
:
1521 if( IsHTMLMode(HTMLMODE_SMALL_CAPS
) )
1522 eState
= HTML_STYLE_VALUE
;
1524 case RES_CHRATR_KERNING
:
1525 if( IsHTMLMode(HTMLMODE_FULL_STYLES
) )
1526 eState
= HTML_STYLE_VALUE
;
1529 case RES_CHRATR_BACKGROUND
:
1530 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1531 eState
= HTML_STYLE_VALUE
;
1534 case RES_PARATR_DROP
:
1535 eState
= HTML_DROPCAP_VALUE
;
1539 // eState = HTML_NOT_SUPPORTED;
1546 BOOL
HTMLEndPosLst::ExistsOnTagItem( USHORT nWhich
, xub_StrLen nPos
)
1548 for( USHORT i
=0; i
<aStartLst
.Count(); i
++ )
1550 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1552 if( pTest
->GetStart() > nPos
)
1554 // dieses uns alle folgenden Attribute beginnen spaeter
1557 else if( pTest
->GetEnd() > nPos
)
1559 // das Attribut beginnt vor oder an der aktuellen Position
1560 // und endet hinter ihr
1561 const SfxPoolItem
*pItem
= pTest
->GetItem();
1562 if( pItem
->Which() == nWhich
&&
1563 HTML_ON_VALUE
== GetHTMLItemState(*pItem
) )
1565 // ein On-Tag-Attibut wurde gefunden
1574 BOOL
HTMLEndPosLst::ExistsOffTagItem( USHORT nWhich
, xub_StrLen nStartPos
,
1575 xub_StrLen nEndPos
)
1577 if( nWhich
!= RES_CHRATR_CROSSEDOUT
&&
1578 nWhich
!= RES_CHRATR_UNDERLINE
&&
1579 nWhich
!= RES_CHRATR_BLINK
)
1584 for( USHORT i
=0; i
<aStartLst
.Count(); i
++ )
1586 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1588 if( pTest
->GetStart() > nStartPos
)
1590 // dieses uns alle folgenden Attribute beginnen spaeter
1593 else if( pTest
->GetStart()==nStartPos
&&
1594 pTest
->GetEnd()==nEndPos
)
1596 // das Attribut beginnt vor oder an der aktuellen Position
1597 // und endet hinter ihr
1598 const SfxPoolItem
*pItem
= pTest
->GetItem();
1599 USHORT nTstWhich
= pItem
->Which() ;
1600 if( (nTstWhich
== RES_CHRATR_CROSSEDOUT
||
1601 nTstWhich
== RES_CHRATR_UNDERLINE
||
1602 nTstWhich
== RES_CHRATR_BLINK
) &&
1603 HTML_OFF_VALUE
== GetHTMLItemState(*pItem
) )
1605 // Ein Off-Tag-Attibut wurde gefunden, das genauso
1606 // exportiert wird, wie das aktuelle Item
1615 void HTMLEndPosLst::FixSplittedItem( HTMLSttEndPos
*pPos
, xub_StrLen nNewEnd
,
1618 // die End-Position entsprechend fixen
1619 pPos
->SetEnd( nNewEnd
);
1621 // das Item aus der End-Liste entfernen
1622 USHORT nEndPos
= _FindEndPos( pPos
);
1623 if( nEndPos
!= USHRT_MAX
)
1624 aEndLst
.Remove( nEndPos
, 1 );
1626 // es wird von nun an als letztes an der entsprechenden Position
1628 for( nEndPos
=0; nEndPos
< aEndLst
.Count() &&
1629 aEndLst
[nEndPos
]->GetEnd() <= nNewEnd
; nEndPos
++ )
1631 aEndLst
.Insert( pPos
, nEndPos
);
1633 // jetzt noch die spaeter gestarteten Attribute anpassen
1634 for( USHORT i
=nStartPos
+1; i
<aStartLst
.Count(); i
++ )
1636 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1637 xub_StrLen nTestEnd
= pTest
->GetEnd();
1638 if( pTest
->GetStart() >= nNewEnd
)
1640 // das Test-Attribut und alle folgenden beginnen, nachdem das
1641 // gesplittete Attribut endet
1644 else if( nTestEnd
> nNewEnd
)
1646 // das Test-Attribut beginnt, bevor das gesplittete Attribut
1647 // endet und endet danach, muss also auch gesplittet werden
1649 // das neue Ende setzen
1650 pTest
->SetEnd( nNewEnd
);
1652 // das Attribut aus der End-Liste entfernen
1653 USHORT nEPos
= _FindEndPos( pTest
);
1654 if( nEPos
!= USHRT_MAX
)
1655 aEndLst
.Remove( nEPos
, 1 );
1657 // es endet jetzt als erstes Attribut an der entsprechenden
1658 // Position. Diese Position in der Ende-Liste kennen wir schon.
1659 aEndLst
.Insert(pTest
, nEndPos
);
1661 // den "Rest" des Attributs neu einfuegen
1662 InsertItem( *pTest
->GetItem(), nNewEnd
, nTestEnd
);
1668 void HTMLEndPosLst::InsertItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1672 for( i
= 0; i
< aEndLst
.Count(); i
++ )
1674 HTMLSttEndPos
*pTest
= aEndLst
[i
];
1675 xub_StrLen nTestEnd
= pTest
->GetEnd();
1676 if( nTestEnd
<= nStart
)
1678 // das Test-Attribut endet, bevor das neue beginnt
1681 else if( nTestEnd
< nEnd
)
1683 // das Test-Attribut endet, bevor das neue endet. Das
1684 // neue Attribut muss deshalb aufgesplittet werden
1685 _InsertItem( new HTMLSttEndPos( rItem
, nStart
, nTestEnd
), i
);
1690 // das Test-Attribut (und alle folgenden) endet, bevor das neue
1696 // ein Attribut muss noch eingefuegt werden
1697 _InsertItem( new HTMLSttEndPos( rItem
, nStart
, nEnd
), i
);
1702 void HTMLEndPosLst::SplitItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1705 USHORT nWhich
= rItem
.Which();
1707 // erstmal muessen wir die alten Items anhand der Startliste suchen
1708 // und die neuen Item-Bereiche festlegen
1710 for( USHORT i
=0; i
<aStartLst
.Count(); i
++ )
1712 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1713 xub_StrLen nTestStart
= pTest
->GetStart();
1714 xub_StrLen nTestEnd
= pTest
->GetEnd();
1716 if( nTestStart
>= nEnd
)
1718 // dieses und alle nachfolgenden Attribute beginnen spaeter
1721 else if( nTestEnd
> nStart
)
1723 // das Test Attribut endet im zu loeschenenden Bereich
1724 const SfxPoolItem
*pItem
= pTest
->GetItem();
1726 // nur entsprechende On-Tag Attribute muessen beruecksichtigt
1728 if( pItem
->Which() == nWhich
&&
1729 HTML_ON_VALUE
== GetHTMLItemState( *pItem
) )
1731 BOOL bDelete
= TRUE
;
1733 if( nTestStart
< nStart
)
1735 // der Start des neuen Attribut entspricht
1736 // dem neuen Ende des Attribts
1737 FixSplittedItem( pTest
, nStart
, i
);
1742 // das Test-Item beginnt erst hinter dem neuen
1743 // Ende des Attribts und kann deshalb komplett
1745 aStartLst
.Remove( i
, 1 );
1748 USHORT nEndPos
= _FindEndPos( pTest
);
1749 if( nEndPos
!= USHRT_MAX
)
1750 aEndLst
.Remove( nEndPos
, 1 );
1753 // ggf den zweiten Teil des gesplitteten Attribts einfuegen
1754 if( nTestEnd
> nEnd
)
1756 InsertItem( *pTest
->GetItem(), nEnd
, nTestEnd
);
1766 const SwHTMLFmtInfo
*HTMLEndPosLst::GetFmtInfo( const SwFmt
& rFmt
,
1767 SwHTMLFmtInfos
& rFmtInfos
)
1769 const SwHTMLFmtInfo
*pFmtInfo
;
1770 SwHTMLFmtInfo
aFmtInfo( &rFmt
);
1772 if( rFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
1774 pFmtInfo
= rFmtInfos
[nPos
];
1778 pFmtInfo
= new SwHTMLFmtInfo( &rFmt
, pDoc
, pTemplate
,
1780 rFmtInfos
.C40_PTR_INSERT( SwHTMLFmtInfo
, pFmtInfo
);
1781 String
aName( rFmt
.GetName() );
1782 if( rScriptTxtStyles
.Seek_Entry( &aName
) )
1783 ((SwHTMLFmtInfo
*)pFmtInfo
)->bScriptDependent
= sal_True
;
1789 HTMLEndPosLst::HTMLEndPosLst( SwDoc
*pD
, SwDoc
* pTempl
,
1790 const Color
* pDfltCol
, BOOL bStyles
,
1791 ULONG nMode
, const String
& rText
,
1792 SvStringsSortDtor
& rStyles
):
1794 pTemplate( pTempl
),
1795 pDfltColor( pDfltCol
),
1796 rScriptTxtStyles( rStyles
),
1798 bOutStyles( bStyles
)
1800 xub_StrLen nEndPos
= rText
.Len();
1801 xub_StrLen nPos
= 0;
1802 while( nPos
< nEndPos
)
1804 sal_uInt16 nScript
= pBreakIt
->GetBreakIter()->getScriptType( rText
, nPos
);
1805 nPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->endOfScript( rText
, nPos
, nScript
);
1806 aScriptChgLst
.Insert( nPos
, aScriptChgLst
.Count() );
1807 aScriptLst
.Insert( nScript
, aScriptLst
.Count() );
1811 HTMLEndPosLst::~HTMLEndPosLst()
1813 ASSERT( !aStartLst
.Count(), "Start-Liste im Destruktor nicht leer" );
1814 ASSERT( !aEndLst
.Count(), "End-Liste im Destruktor nicht leer" );
1819 void HTMLEndPosLst::InsertNoScript( const SfxPoolItem
& rItem
,
1820 xub_StrLen nStart
, xub_StrLen nEnd
,
1821 SwHTMLFmtInfos
& rFmtInfos
, BOOL bParaAttrs
)
1823 // kein Bereich ?? dann nicht aufnehmen, wird nie wirksam !!
1824 if( nStart
!= nEnd
)
1826 BOOL bSet
= FALSE
, bSplit
= FALSE
;
1827 switch( GetHTMLItemState(rItem
) )
1830 // das Attribut wird ausgegeben, wenn es nicht sowieso
1832 if( !ExistsOnTagItem( rItem
.Which(), nStart
) )
1836 case HTML_OFF_VALUE
:
1837 // wenn das entsprechne Attribut an ist, wird es gesplittet,
1838 // Zusaetlich wird es aber als Style ausgegeben, wenn es nicht
1839 // am ganzen Absatz gesetzt ist, weil es dann ja schon mit dem
1840 // ABsatz-Tag ausgegeben wurde.
1841 if( ExistsOnTagItem( rItem
.Which(), nStart
) )
1843 bSet
= bOutStyles
&& !bParaAttrs
&&
1844 !ExistsOffTagItem( rItem
.Which(), nStart
, nEnd
);
1847 case HTML_REAL_VALUE
:
1848 // das Attribut kann immer ausgegeben werden
1852 case HTML_STYLE_VALUE
:
1853 // Das Attribut kann nur als CSS1 ausgegeben werden. Wenn
1854 // es am Absatz gesetzt ist, wurde es schon mit dem
1855 // Absatz-Tag ausgegeben. Einzige Ausnahme ist das
1856 // Zeichen-Hintergrund-Attribut. Es muss immer wie ein
1857 // Hint behandelt werden.
1858 bSet
= bOutStyles
&&
1860 || rItem
.Which()==RES_CHRATR_BACKGROUND
1861 || rItem
.Which()==RES_CHRATR_OVERLINE
);
1864 case HTML_CHRFMT_VALUE
:
1866 ASSERT( RES_TXTATR_CHARFMT
== rItem
.Which(),
1867 "Doch keine Zeichen-Vorlage" );
1868 const SwFmtCharFmt
& rChrFmt
= (const SwFmtCharFmt
&)rItem
;
1869 const SwCharFmt
* pFmt
= rChrFmt
.GetCharFmt();
1871 const SwHTMLFmtInfo
*pFmtInfo
= GetFmtInfo( *pFmt
, rFmtInfos
);
1872 if( pFmtInfo
->aToken
.Len() )
1874 // das Zeichenvorlagen-Tag muss vor den harten
1875 // Attributen ausgegeben werden
1876 InsertItem( rItem
, nStart
, nEnd
);
1878 if( pFmtInfo
->pItemSet
)
1880 Insert( *pFmtInfo
->pItemSet
, nStart
, nEnd
,
1881 rFmtInfos
, TRUE
, bParaAttrs
);
1886 case HTML_AUTOFMT_VALUE
:
1888 const SwFmtAutoFmt
& rAutoFmt
= (const SwFmtAutoFmt
&)rItem
;
1889 const boost::shared_ptr
<SfxItemSet
> pSet
= rAutoFmt
.GetStyleHandle();
1891 Insert( *pSet
.get(), nStart
, nEnd
, rFmtInfos
, TRUE
, bParaAttrs
);
1895 case HTML_COLOR_VALUE
:
1896 // Eine Vordergrund-Farbe als Absatz-Attribut wird nur
1897 // exportiert, wenn sie nicht der Default-Farbe entspricht.
1899 ASSERT( RES_CHRATR_COLOR
== rItem
.Which(),
1900 "Doch keine Vordergrund-Farbe" );
1901 Color
aColor( ((const SvxColorItem
&)rItem
).GetValue() );
1902 if( COL_AUTO
== aColor
.GetColor() )
1903 aColor
.SetColor( COL_BLACK
);
1904 bSet
= !bParaAttrs
|| !pDfltColor
||
1905 !pDfltColor
->IsRGBEqual( aColor
);
1909 case HTML_DROPCAP_VALUE
:
1911 ASSERT( RES_PARATR_DROP
== rItem
.Which(),
1912 "Doch kein Drop-Cap" );
1913 const SwFmtDrop
& rDrop
= (const SwFmtDrop
&)rItem
;
1914 nEnd
= nStart
+ rDrop
.GetChars();
1917 // Zumindest die Attribute der Zeichenvorlage uebernehmen
1918 const SwCharFmt
*pCharFmt
= rDrop
.GetCharFmt();
1921 Insert( pCharFmt
->GetAttrSet(), nStart
, nEnd
,
1922 rFmtInfos
, TRUE
, bParaAttrs
);
1936 InsertItem( rItem
, nStart
, nEnd
);
1938 SplitItem( rItem
, nStart
, nEnd
);
1942 void HTMLEndPosLst::Insert( const SfxPoolItem
& rItem
,
1943 xub_StrLen nStart
, xub_StrLen nEnd
,
1944 SwHTMLFmtInfos
& rFmtInfos
, BOOL bParaAttrs
)
1946 sal_Bool bDependsOnScript
= sal_False
, bDependsOnAnyScript
= sal_False
;
1947 sal_uInt16 nScript
= i18n::ScriptType::LATIN
;
1948 switch( rItem
.Which() )
1950 case RES_CHRATR_FONT
:
1951 case RES_CHRATR_FONTSIZE
:
1952 case RES_CHRATR_LANGUAGE
:
1953 case RES_CHRATR_POSTURE
:
1954 case RES_CHRATR_WEIGHT
:
1955 bDependsOnScript
= sal_True
;
1956 nScript
= i18n::ScriptType::LATIN
;
1959 case RES_CHRATR_CJK_FONT
:
1960 case RES_CHRATR_CJK_FONTSIZE
:
1961 case RES_CHRATR_CJK_LANGUAGE
:
1962 case RES_CHRATR_CJK_POSTURE
:
1963 case RES_CHRATR_CJK_WEIGHT
:
1964 bDependsOnScript
= sal_True
;
1965 nScript
= i18n::ScriptType::ASIAN
;
1968 case RES_CHRATR_CTL_FONT
:
1969 case RES_CHRATR_CTL_FONTSIZE
:
1970 case RES_CHRATR_CTL_LANGUAGE
:
1971 case RES_CHRATR_CTL_POSTURE
:
1972 case RES_CHRATR_CTL_WEIGHT
:
1973 bDependsOnScript
= sal_True
;
1974 nScript
= i18n::ScriptType::COMPLEX
;
1976 case RES_TXTATR_CHARFMT
:
1978 const SwFmtCharFmt
& rChrFmt
= (const SwFmtCharFmt
&)rItem
;
1979 const SwCharFmt
* pFmt
= rChrFmt
.GetCharFmt();
1980 const SwHTMLFmtInfo
*pFmtInfo
= GetFmtInfo( *pFmt
, rFmtInfos
);
1981 if( pFmtInfo
->bScriptDependent
)
1983 bDependsOnScript
= sal_True
;
1984 bDependsOnAnyScript
= sal_True
;
1988 case RES_TXTATR_INETFMT
:
1990 if( GetFmtInfo( *pDoc
->GetCharFmtFromPool(
1991 RES_POOLCHR_INET_NORMAL
), rFmtInfos
)->bScriptDependent
||
1992 GetFmtInfo( *pDoc
->GetCharFmtFromPool(
1993 RES_POOLCHR_INET_VISIT
), rFmtInfos
)->bScriptDependent
)
1995 bDependsOnScript
= sal_True
;
1996 bDependsOnAnyScript
= sal_True
;
2002 if( bDependsOnScript
)
2004 sal_uInt16 nScriptChgs
= aScriptChgLst
.Count();
2005 xub_StrLen nPos
= nStart
;
2006 for( sal_uInt16 i
=0; i
< nScriptChgs
; i
++ )
2008 xub_StrLen nChgPos
= aScriptChgLst
[i
];
2009 if( nPos
>= nChgPos
)
2011 // the hint starts behind or at the next script change,
2012 // so we may continue with this position.
2015 if( nEnd
<= nChgPos
)
2017 // the (rest of) the hint ends before or at the next script
2018 // change, so we can insert it, but only if it belongs
2019 // to the current script.
2020 if( bDependsOnAnyScript
|| nScript
== aScriptLst
[i
] )
2021 InsertNoScript( rItem
, nPos
, nEnd
, rFmtInfos
,
2026 // the hint starts before the next script change and ends behind
2027 // it, so we can insert a hint upto the next script change and
2028 // continue with the rest of the hint.
2029 if( bDependsOnAnyScript
|| nScript
== aScriptLst
[i
] )
2030 InsertNoScript( rItem
, nPos
, nChgPos
, rFmtInfos
, bParaAttrs
);
2036 InsertNoScript( rItem
, nStart
, nEnd
, rFmtInfos
, bParaAttrs
);
2040 void HTMLEndPosLst::Insert( const SfxItemSet
& rItemSet
,
2041 xub_StrLen nStart
, xub_StrLen nEnd
,
2042 SwHTMLFmtInfos
& rFmtInfos
,
2043 BOOL bDeep
, BOOL bParaAttrs
)
2045 SfxWhichIter
aIter( rItemSet
);
2047 USHORT nWhich
= aIter
.FirstWhich();
2050 const SfxPoolItem
*pItem
;
2051 if( SFX_ITEM_SET
== rItemSet
.GetItemState( nWhich
, bDeep
, &pItem
) )
2053 Insert( *pItem
, nStart
, nEnd
, rFmtInfos
, bParaAttrs
);
2056 nWhich
= aIter
.NextWhich();
2060 void HTMLEndPosLst::Insert( const SwDrawFrmFmt
& rFmt
, xub_StrLen nPos
,
2061 SwHTMLFmtInfos
& rFmtInfos
)
2063 // der Type-Cast ist nur noetig, um nicht seinetwegen
2064 // svdrwobt.hxx zu includem
2065 const SdrObject
* pTextObj
=
2066 (const SdrObject
*)SwHTMLWriter::GetMarqueeTextObj( rFmt
);
2070 // die Edit-Engine-Attribute des Objekts als SW-Attribute holen
2071 // und als Hints einsortieren. Wegen der Menge der Hints werden
2072 // Styles hierbei nicht beruecksichtigt!
2073 const SfxItemSet
& rFmtItemSet
= rFmt
.GetAttrSet();
2074 SfxItemSet
aItemSet( *rFmtItemSet
.GetPool(), RES_CHRATR_BEGIN
,
2076 SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet
, pTextObj
, TRUE
);
2077 BOOL bOutStylesOld
= bOutStyles
;
2079 Insert( aItemSet
, nPos
, nPos
+1, rFmtInfos
, FALSE
, FALSE
);
2080 bOutStyles
= bOutStylesOld
;
2084 sal_uInt16
HTMLEndPosLst::GetScriptAtPos( xub_StrLen nPos
,
2087 sal_uInt16 nRet
= CSS1_OUTMODE_ANY_SCRIPT
;
2089 sal_uInt16 nScriptChgs
= aScriptChgLst
.Count();
2091 while( i
< nScriptChgs
&& nPos
>= aScriptChgLst
[i
] )
2093 ASSERT( i
< nScriptChgs
, "script list is to short" );
2094 if( i
< nScriptChgs
)
2096 if( i18n::ScriptType::WEAK
== aScriptLst
[i
] )
2099 nRet
= SwHTMLWriter::GetCSS1ScriptForScriptType( aScriptLst
[i
] );
2105 void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
2106 HTMLOutContext
*pContext
)
2108 rHWrt
.bTagOn
= TRUE
;
2110 // die Attribute in der Start-Liste sind aufsteigend sortiert
2111 for( USHORT i
=0; i
< aStartLst
.Count(); i
++ )
2113 HTMLSttEndPos
*pPos
= aStartLst
[i
];
2114 xub_StrLen nStart
= pPos
->GetStart();
2117 // dieses und alle folgenden Attribute werden erst noch geoeffnet
2120 else if( nStart
== nPos
)
2122 // das Attribut ausgeben
2123 sal_uInt16 nCSS1Script
= rHWrt
.nCSS1Script
;
2124 sal_uInt16 nWhich
= pPos
->GetItem()->Which();
2125 if( RES_TXTATR_CHARFMT
== nWhich
||
2126 RES_TXTATR_INETFMT
== nWhich
||
2127 RES_PARATR_DROP
== nWhich
)
2129 rHWrt
.nCSS1Script
= GetScriptAtPos( nPos
, nCSS1Script
);
2133 HTMLOutFuncs::FlushToAscii( rHWrt
.Strm(), *pContext
);
2134 pContext
= 0; // one time ony
2136 Out( aHTMLAttrFnTab
, *pPos
->GetItem(), rHWrt
);
2137 rHWrt
.nCSS1Script
= nCSS1Script
;
2142 void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
2143 HTMLOutContext
*pContext
)
2145 rHWrt
.bTagOn
= FALSE
;
2147 // die Attribute in der End-Liste sind aufsteigend sortiert
2149 while( i
< aEndLst
.Count() )
2151 HTMLSttEndPos
*pPos
= aEndLst
[i
];
2152 xub_StrLen nEnd
= pPos
->GetEnd();
2154 if( STRING_MAXLEN
==nPos
|| nEnd
== nPos
)
2158 HTMLOutFuncs::FlushToAscii( rHWrt
.Strm(), *pContext
);
2159 pContext
= 0; // one time ony
2161 Out( aHTMLAttrFnTab
, *pPos
->GetItem(), rHWrt
);
2164 else if( nEnd
> nPos
)
2166 // dieses und alle folgenden Attribute werden erst spaeter beendet
2171 // Das Attribut wird vor der aktuellen Position beendet. Das
2172 // darf nicht sein, aber wie koennen trotzdem damit umgehen
2173 ASSERT( nEnd
>= nPos
,
2174 "Das Attribut sollte schon laengst beendet sein" );
2181 /* Ausgabe der Nodes */
2182 Writer
& OutHTML_SwTxtNode( Writer
& rWrt
, const SwCntntNode
& rNode
)
2184 SwTxtNode
* pNd
= &((SwTxtNode
&)rNode
);
2185 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2187 const String
& rStr
= pNd
->GetTxt();
2188 xub_StrLen nEnde
= rStr
.Len();
2190 // Besonderheit: leere Node und HR-Vorlage (horizontaler Strich)
2191 // nur ein <HR> ausgeben
2192 USHORT nPoolId
= pNd
->GetAnyFmtColl().GetPoolFmtId();
2194 if( !nEnde
&& (RES_POOLCOLL_HTML_HR
==nPoolId
||
2195 pNd
->GetAnyFmtColl().GetName().EqualsAscii( OOO_STRING_SVTOOLS_HTML_horzrule
) ) )
2197 // dann die absatz-gebundenen Grafiken/OLE-Objekte im Absatz
2198 // MIB 8.7.97: Ein <PRE> spannen wir um die Linie auf. Dann stimmen
2199 // zwar die Abstaende nicht, aber sonst bekommen wir einen leeren
2200 // Absatz hinter dem <HR> und das ist noch unschoener.
2201 rHTMLWrt
.ChangeParaToken( 0 );
2203 // Alle an dem Node verankerten Rahmen ausgeben
2204 rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(), 0, HTML_POS_ANY
);
2206 if( rHTMLWrt
.bLFPossible
)
2207 rHTMLWrt
.OutNewLine(); // Absatz-Tag in eine neue Zeile
2209 rHTMLWrt
.bLFPossible
= TRUE
;
2211 ByteString
sOut( '<' );
2212 sOut
+= OOO_STRING_SVTOOLS_HTML_horzrule
;
2214 const SfxItemSet
* pItemSet
= pNd
->GetpSwAttrSet();
2217 rWrt
.Strm() << sOut
.GetBuffer() << '>';
2220 const SfxPoolItem
* pItem
;
2221 if( SFX_ITEM_SET
== pItemSet
->GetItemState( RES_LR_SPACE
, FALSE
, &pItem
))
2223 sal_Int32 nLeft
= ((SvxLRSpaceItem
*)pItem
)->GetLeft();
2224 sal_Int32 nRight
= ((SvxLRSpaceItem
*)pItem
)->GetRight();
2225 if( nLeft
|| nRight
)
2227 const SwFrmFmt
& rPgFmt
=
2228 rHTMLWrt
.pDoc
->GetPageDescFromPool
2229 ( RES_POOLPAGE_HTML
, false )->GetMaster();
2230 const SwFmtFrmSize
& rSz
= rPgFmt
.GetFrmSize();
2231 const SvxLRSpaceItem
& rLR
= rPgFmt
.GetLRSpace();
2232 const SwFmtCol
& rCol
= rPgFmt
.GetCol();
2234 long nPageWidth
= rSz
.GetWidth() - rLR
.GetLeft() - rLR
.GetRight();
2236 if( 1 < rCol
.GetNumCols() )
2237 nPageWidth
/= rCol
.GetNumCols();
2239 const SwTableNode
* pTblNd
= pNd
->FindTableNode();
2242 const SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox(
2243 pNd
->StartOfSectionIndex() );
2245 nPageWidth
= pBox
->GetFrmFmt()->GetFrmSize().GetWidth();
2248 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_width
) += '=';
2249 rWrt
.Strm() << sOut
.GetBuffer();
2250 rWrt
.OutULong( rHTMLWrt
.ToPixel(nPageWidth
-nLeft
-nRight
) );
2252 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_align
) += '=';
2254 sOut
+= OOO_STRING_SVTOOLS_HTML_AL_left
;
2256 sOut
+= OOO_STRING_SVTOOLS_HTML_AL_right
;
2258 sOut
+= OOO_STRING_SVTOOLS_HTML_AL_center
;
2261 rWrt
.Strm() << sOut
.GetBuffer();
2262 if( SFX_ITEM_SET
== pItemSet
->GetItemState( RES_BOX
, FALSE
, &pItem
))
2264 const SvxBoxItem
* pBoxItem
= (const SvxBoxItem
*)pItem
;
2265 const SvxBorderLine
* pBorderLine
= pBoxItem
->GetBottom();
2268 USHORT nWidth
= pBorderLine
->GetOutWidth() +
2269 pBorderLine
->GetInWidth() +
2270 pBorderLine
->GetDistance();
2271 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_size
) += '=';
2272 rWrt
.Strm() << sOut
.GetBuffer();
2273 rWrt
.OutULong( rHTMLWrt
.ToPixel(nWidth
) );
2275 const Color
& rBorderColor
= pBorderLine
->GetColor();
2276 if( !rBorderColor
.IsRGBEqual( Color(COL_GRAY
) ) )
2278 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_color
) += '=';
2279 rWrt
.Strm() << sOut
.GetBuffer();
2280 HTMLOutFuncs::Out_Color( rWrt
.Strm(), rBorderColor
,
2281 rHTMLWrt
.eDestEnc
);
2284 if( !pBorderLine
->GetInWidth() )
2286 (sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_noshade
;
2287 rWrt
.Strm() << sOut
.GetBuffer();
2295 // Die leeren Nodes mit 2pt Font-Hoehe und der Stand-Vorlage, die
2296 // vor Tabellen und Bereichen eingefuegt werden, nicht exportieren,
2297 // Bookmarks oder absatzgebundene Grafiken aber schon.
2298 // MIB 21.7.97: Ausserdem auch keine leeren Tabellen-Zellen exportieren.
2299 if( !nEnde
&& (nPoolId
== RES_POOLCOLL_STANDARD
||
2300 nPoolId
== RES_POOLCOLL_TABLE
||
2301 nPoolId
== RES_POOLCOLL_TABLE_HDLN
) )
2303 // Der aktuelle Node ist leer und enthaelt Standard-Vorlage ...
2304 const SfxPoolItem
* pItem
;
2305 const SfxItemSet
*pItemSet
= pNd
->GetpSwAttrSet();
2306 if( pItemSet
&& pItemSet
->Count() &&
2307 SFX_ITEM_SET
== pItemSet
->GetItemState( RES_CHRATR_FONTSIZE
, FALSE
, &pItem
) &&
2308 40 == ((const SvxFontHeightItem
*)pItem
)->GetHeight() )
2310 // ... ausserdem ist die 2pt Schrift eingestellt ...
2311 ULONG nNdPos
= rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex();
2312 const SwNode
*pNextNd
= rWrt
.pDoc
->GetNodes()[nNdPos
+1];
2313 const SwNode
*pPrevNd
= rWrt
.pDoc
->GetNodes()[nNdPos
-1];
2314 BOOL bStdColl
= nPoolId
== RES_POOLCOLL_STANDARD
;
2315 if( ( bStdColl
&& (pNextNd
->IsTableNode() ||
2316 pNextNd
->IsSectionNode()) ) ||
2317 ( !bStdColl
&& pNextNd
->IsEndNode() &&
2318 pPrevNd
->IsStartNode() &&
2319 SwTableBoxStartNode
==
2320 pPrevNd
->GetStartNode()->GetStartNodeType() ) )
2322 // ... und er steht vor einer Tabelle ohne einem Bereich
2323 rHTMLWrt
.OutBookmarks();
2324 rHTMLWrt
.bLFPossible
= !rHTMLWrt
.nLastParaToken
;
2326 // Alle an dem Node verankerten Rahmen ausgeben
2327 rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(), 0, HTML_POS_ANY
);
2328 rHTMLWrt
.bLFPossible
= FALSE
;
2335 // PagePreaks uns PagDescs abfangen
2336 BOOL bPageBreakBehind
= FALSE
;
2337 if( rHTMLWrt
.bCfgFormFeed
&&
2338 !(rHTMLWrt
.bOutTable
|| rHTMLWrt
.bOutFlyFrame
) &&
2339 rHTMLWrt
.pStartNdIdx
->GetIndex() !=
2340 rHTMLWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() )
2342 BOOL bPageBreakBefore
= FALSE
;
2343 const SfxPoolItem
* pItem
;
2344 const SfxItemSet
* pItemSet
= pNd
->GetpSwAttrSet();
2349 pItemSet
->GetItemState( RES_PAGEDESC
, TRUE
, &pItem
) &&
2350 ((SwFmtPageDesc
*)pItem
)->GetPageDesc() )
2351 bPageBreakBefore
= TRUE
;
2352 else if( SFX_ITEM_SET
==
2353 pItemSet
->GetItemState( RES_BREAK
, TRUE
, &pItem
) )
2355 switch( ((SvxFmtBreakItem
*)pItem
)->GetBreak() )
2357 case SVX_BREAK_PAGE_BEFORE
:
2358 bPageBreakBefore
= TRUE
;
2360 case SVX_BREAK_PAGE_AFTER
:
2361 bPageBreakBehind
= TRUE
;
2363 case SVX_BREAK_PAGE_BOTH
:
2364 bPageBreakBefore
= TRUE
;
2365 bPageBreakBehind
= TRUE
;
2373 if( bPageBreakBefore
)
2374 rWrt
.Strm() << '\f';
2377 // eventuell eine Form oeffnen
2380 // An dem Node "verankerte" Seitenegebunde Rahmen ausgeben
2381 BOOL bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2382 0, HTML_POS_PREFIX
);
2383 // An dem Node verankerte Rahmen ausgeben, die vor dem
2384 // Absatz-Tag geschrieben werden sollen.
2386 bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2387 0, HTML_POS_BEFORE
);
2389 if( rHTMLWrt
.pCurPam
->GetPoint()->nNode
== rHTMLWrt
.pCurPam
->GetMark()->nNode
)
2390 nEnde
= rHTMLWrt
.pCurPam
->GetMark()->nContent
.GetIndex();
2392 // gibt es harte Attribute, die als Optionen geschrieben werden muessen?
2393 rHTMLWrt
.bTagOn
= TRUE
;
2395 // jetzt das Tag des Absatzes ausgeben
2396 const SwFmt
& rFmt
= pNd
->GetAnyFmtColl();
2397 SwHTMLTxtCollOutputInfo aFmtInfo
;
2398 BOOL bOldLFPossible
= rHTMLWrt
.bLFPossible
;
2399 OutHTML_SwFmt( rWrt
, rFmt
, pNd
->GetpSwAttrSet(), aFmtInfo
);
2401 // Wenn vor dem Absatz-Tag keine neue Zeile aufgemacht wurde, dann
2402 // tun wir das jetzt
2403 rHTMLWrt
.bLFPossible
= !rHTMLWrt
.nLastParaToken
;
2404 if( !bOldLFPossible
&& rHTMLWrt
.bLFPossible
)
2405 rHTMLWrt
.OutNewLine();
2408 // dann die Bookmarks (inkl. End-Tag)
2409 rHTMLWrt
.bOutOpts
= FALSE
;
2410 rHTMLWrt
.OutBookmarks();
2412 // jetzt ist noch mal eine gute Gelegenheit fuer ein LF, sofern es noch
2414 if( rHTMLWrt
.bLFPossible
&&
2415 rHTMLWrt
.GetLineLen() >= rHTMLWrt
.nWhishLineLen
)
2417 rHTMLWrt
.OutNewLine();
2419 rHTMLWrt
.bLFPossible
= FALSE
;
2421 // Text, der aus einer Outline-Numerierung kommt ermitteln
2422 xub_StrLen nOffset
= 0;
2425 // --> OD 2006-06-12 #b6435904#
2426 // export numbering string as plain text only for the outline numbering,
2427 // because the outline numbering isn't exported as a numbering - see <SwHTMLNumRuleInfo::Set(..)>
2428 if ( pNd
->IsOutline() &&
2429 pNd
->GetNumRule() == pNd
->GetDoc()->GetOutlineNumRule() )
2432 aOutlineTxt
= pNd
->GetNumString();
2433 nOffset
= nOffset
+ aOutlineTxt
.Len();
2434 aFullText
= aOutlineTxt
;
2436 String aFootEndNoteSym
;
2437 if( rHTMLWrt
.pFmtFtn
)
2439 aFootEndNoteSym
= rHTMLWrt
.GetFootEndNoteSym( *rHTMLWrt
.pFmtFtn
);
2440 nOffset
= nOffset
+ aFootEndNoteSym
.Len();
2441 aFullText
+= aFootEndNoteSym
;
2444 // gibt es harte Attribute, die als Tags geschrieben werden muessen?
2446 HTMLEndPosLst
aEndPosLst( rWrt
.pDoc
, rHTMLWrt
.pTemplate
,
2447 rHTMLWrt
.pDfltColor
, rHTMLWrt
.bCfgOutStyles
,
2448 rHTMLWrt
.GetHTMLMode(), aFullText
,
2449 rHTMLWrt
.aScriptTextStyles
);
2450 if( aFmtInfo
.pItemSet
)
2452 aEndPosLst
.Insert( *aFmtInfo
.pItemSet
, 0, nEnde
+ nOffset
,
2453 rHTMLWrt
.aChrFmtInfos
, FALSE
, TRUE
);
2457 if( aOutlineTxt
.Len() || rHTMLWrt
.pFmtFtn
)
2459 // Absatz-Attribute ausgeben, damit der Text die Attribute des
2460 // Absatzes bekommt.
2461 aEndPosLst
.OutStartAttrs( rHTMLWrt
, 0 );
2463 // Theoretisch muesste man hier die Zeichen-Vorlage der Numerierung
2464 // beachten. Da man die ueber die UI nicht setzen kann, ignorieren
2467 if( aOutlineTxt
.Len() )
2468 HTMLOutFuncs::Out_String( rWrt
.Strm(), aOutlineTxt
,
2469 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
2471 if( rHTMLWrt
.pFmtFtn
)
2473 rHTMLWrt
.OutFootEndNoteSym( *rHTMLWrt
.pFmtFtn
, aFootEndNoteSym
,
2474 aEndPosLst
.GetScriptAtPos( aOutlineTxt
.Len(), rHTMLWrt
.nCSS1Script
) );
2475 rHTMLWrt
.pFmtFtn
= 0;
2479 // erstmal den Start berichtigen. D.h. wird nur ein Teil vom Satz
2480 // ausgegeben, so muessen auch da die Attribute stimmen!!
2481 rHTMLWrt
.bTxtAttr
= TRUE
;
2484 USHORT nAttrPos
= 0;
2485 xub_StrLen nStrPos
= rHTMLWrt
.pCurPam
->GetPoint()->nContent
.GetIndex();
2486 const SwTxtAttr
* pHt
= 0;
2487 USHORT nCntAttr
= pNd
->HasHints() ? pNd
->GetSwpHints().Count() : 0;
2488 if( nCntAttr
&& nStrPos
> *( pHt
= pNd
->GetSwpHints()[ 0 ] )->GetStart() )
2490 // Ok, es gibt vorher Attribute, die ausgegeben werden muessen
2492 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
);
2495 if( RES_TXTATR_FIELD
== pHt
->Which() ) // Felder nicht
2496 continue; // ausgeben
2500 xub_StrLen nHtEnd
= *pHt
->GetEnd(),
2501 nHtStt
= *pHt
->GetStart();
2502 if( !rHTMLWrt
.bWriteAll
&& nHtEnd
<= nStrPos
)
2505 // leere Hints am Anfang nicht beachten, oder ??
2506 if( nHtEnd
== nHtStt
)
2509 // Attribut in die Liste aufnehemen
2510 if( rHTMLWrt
.bWriteAll
)
2511 aEndPosLst
.Insert( pHt
->GetAttr(), nHtStt
+ nOffset
,
2513 rHTMLWrt
.aChrFmtInfos
);
2516 xub_StrLen nTmpStt
= nHtStt
< nStrPos
? nStrPos
: nHtStt
;
2517 xub_StrLen nTmpEnd
= nHtEnd
< nEnde
? nHtEnd
: nEnde
;
2518 aEndPosLst
.Insert( pHt
->GetAttr(), nTmpStt
+ nOffset
,
2520 rHTMLWrt
.aChrFmtInfos
);
2523 // aber nicht ausgeben, das erfolgt spaeter !!
2526 } while( nAttrPos
< nCntAttr
&& nStrPos
>
2527 *( pHt
= pNd
->GetSwpHints()[ nAttrPos
] )->GetStart() );
2529 // dann gebe mal alle gesammelten Attribute von der String-Pos aus
2530 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
);
2531 aEndPosLst
.OutStartAttrs( rHTMLWrt
, nStrPos
+ nOffset
);
2534 BOOL bWriteBreak
= (HTML_PREFORMTXT_ON
!= rHTMLWrt
.nLastParaToken
);
2535 if( bWriteBreak
&& pNd
->GetNumRule() )
2536 bWriteBreak
= FALSE
;
2539 HTMLOutContext
aContext( rHTMLWrt
.eDestEnc
);
2541 xub_StrLen nPreSplitPos
= 0;
2542 for( ; nStrPos
< nEnde
; nStrPos
++ )
2544 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
, &aContext
);
2546 // Die an der aktuellen Position verankerten Rahmen ausgeben
2548 bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2549 nStrPos
, HTML_POS_INSIDE
,
2552 BOOL bOutChar
= TRUE
;
2553 const SwTxtAttr
* pTxtHt
= 0;
2554 if( nAttrPos
< nCntAttr
&& *pHt
->GetStart() == nStrPos
2555 && nStrPos
!= nEnde
)
2560 if( RES_CHRATR_KERNING
== pHt
->Which() &&
2561 rHTMLWrt
.IsHTMLMode(HTMLMODE_FIRSTLINE
) &&
2562 *pHt
->GetEnd() - nStrPos
== 1 &&
2563 ' ' == rStr
.GetChar(nStrPos
) &&
2564 ((const SvxKerningItem
&)pHt
->GetAttr()).GetValue() > 0 )
2566 // Wenn erlaubt, wird das Ding als Spacer exportiert
2568 bOutChar
= FALSE
; // Space nicht ausgeben
2569 bWriteBreak
= FALSE
; // der Absatz ist aber auch nicht leer
2570 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2571 OutHTML_HoriSpacer( rWrt
,
2572 ((const SvxKerningItem
&)pHt
->GetAttr()).GetValue() );
2574 // Der Hint braucht nun doch nicht weiter
2575 // beruecksichtigt werden.
2577 else if( *pHt
->GetEnd() != nStrPos
)
2579 // Hints mit Ende einsortieren, wenn sie keinen
2580 // leeren Bereich aufspannen (Hints, die keinen
2581 // Bereich aufspannen werden ignoriert
2582 aEndPosLst
.Insert( pHt
->GetAttr(), nStrPos
+ nOffset
,
2583 *pHt
->GetEnd() + nOffset
,
2584 rHTMLWrt
.aChrFmtInfos
);
2589 // Hints ohne-Ende werden als letztes ausgebeben
2591 "Wieso gibt es da schon ein Attribut ohne Ende?" );
2592 if( rHTMLWrt
.nTxtAttrsToIgnore
>0 )
2594 rHTMLWrt
.nTxtAttrsToIgnore
--;
2600 if( RES_TXTATR_FIELD
!= pHt
->Which() ||
2601 ( RES_POSTITFLD
!= (nFldWhich
= ((const SwFmtFld
&)pHt
->GetAttr()).GetFld()->Which()) &&
2602 RES_SCRIPTFLD
!= nFldWhich
) )
2603 bWriteBreak
= FALSE
;
2605 bOutChar
= FALSE
; // keine 255 ausgeben
2607 } while( ++nAttrPos
< nCntAttr
&& nStrPos
==
2608 *( pHt
= pNd
->GetSwpHints()[ nAttrPos
] )->GetStart() );
2611 // Manche Draw-Formate koennen auch noch Attribute mitbringen
2612 if( pTxtHt
&& RES_TXTATR_FLYCNT
== pTxtHt
->Which() )
2614 const SwFrmFmt
* pFrmFmt
=
2615 ((const SwFmtFlyCnt
&)pTxtHt
->GetAttr()).GetFrmFmt();
2617 if( RES_DRAWFRMFMT
== pFrmFmt
->Which() )
2618 aEndPosLst
.Insert( *((const SwDrawFrmFmt
*)pFrmFmt
),
2620 rHTMLWrt
.aChrFmtInfos
);
2623 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
, &aContext
);
2624 aEndPosLst
.OutStartAttrs( rHTMLWrt
, nStrPos
+ nOffset
, &aContext
);
2628 rHTMLWrt
.bLFPossible
= !rHTMLWrt
.nLastParaToken
&& nStrPos
> 0 &&
2629 rStr
.GetChar(nStrPos
-1) == ' ';
2630 sal_uInt16 nCSS1Script
= rHTMLWrt
.nCSS1Script
;
2631 rHTMLWrt
.nCSS1Script
= aEndPosLst
.GetScriptAtPos(
2632 nStrPos
+ nOffset
, nCSS1Script
);
2633 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2634 Out( aHTMLAttrFnTab
, pTxtHt
->GetAttr(), rHTMLWrt
);
2635 rHTMLWrt
.nCSS1Script
= nCSS1Script
;
2636 rHTMLWrt
.bLFPossible
= FALSE
;
2641 sal_Unicode c
= rStr
.GetChar( nStrPos
);
2642 // versuche nach ungefaehr 255 Zeichen eine neue Zeile zu
2643 // beginnen, aber nicht in PRE und nur bei Spaces
2644 if( ' '==c
&& !rHTMLWrt
.nLastParaToken
)
2646 xub_StrLen nLineLen
;
2647 if( rHTMLWrt
.nLastParaToken
)
2648 nLineLen
= nStrPos
- nPreSplitPos
;
2650 nLineLen
= rHTMLWrt
.GetLineLen();
2652 xub_StrLen nWordLen
= rStr
.Search( ' ', nStrPos
+1 );
2653 if( nWordLen
== STRING_NOTFOUND
)
2655 nWordLen
= nWordLen
- nStrPos
;
2657 if( nLineLen
>= rHTMLWrt
.nWhishLineLen
||
2658 (nLineLen
+nWordLen
) >= rHTMLWrt
.nWhishLineLen
)
2660 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2661 rHTMLWrt
.OutNewLine();
2663 if( rHTMLWrt
.nLastParaToken
)
2664 nPreSplitPos
= nStrPos
+1;
2672 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2673 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak
);
2676 HTMLOutFuncs::Out_Char( rWrt
.Strm(), c
, aContext
, &rHTMLWrt
.aNonConvertableCharacters
);
2678 // Wenn das letzte Zeichen eines Absatzed ein harter
2679 // Zeilen-Umbruch ist brauchen wir noch ein <BR> mehr, weil
2680 // Netscape & Co in diesem Fall fuer den naechsten Absatz
2681 // nicht in die naechste Zeile gehen.
2682 bWriteBreak
= (0x0a == c
) &&
2683 (HTML_PREFORMTXT_ON
!= rHTMLWrt
.nLastParaToken
);
2687 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2690 aEndPosLst
.OutEndAttrs( rHTMLWrt
, STRING_MAXLEN
);
2692 // Die an der letzten Position verankerten Rahmen ausgeben
2694 bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2695 nEnde
, HTML_POS_INSIDE
);
2696 ASSERT( !bFlysLeft
, "Es wurden nicht alle Rahmen gespeichert!" );
2698 rHTMLWrt
.bTxtAttr
= FALSE
;
2702 BOOL bEndOfCell
= rHTMLWrt
.bOutTable
&&
2703 rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() ==
2704 rWrt
.pCurPam
->GetMark()->nNode
.GetIndex();
2706 if( bEndOfCell
&& !nEnde
&&
2707 rHTMLWrt
.IsHTMLMode(HTMLMODE_NBSP_IN_TABLES
) )
2709 // Wenn der letzte Absatz einer Tabellezelle leer ist und
2710 // wir fuer den MS-IE exportieren, schreiben wir statt eines
2712 rWrt
.Strm() << '&' << OOO_STRING_SVTOOLS_HTML_S_nbsp
<< ';';
2716 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak
);
2717 const SvxULSpaceItem
& rULSpace
=
2718 (const SvxULSpaceItem
&)pNd
->GetSwAttrSet().Get(RES_UL_SPACE
);
2719 if( rULSpace
.GetLower() > 0 && !bEndOfCell
&&
2720 !rHTMLWrt
.IsHTMLMode(HTMLMODE_NO_BR_AT_PAREND
) )
2721 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak
);
2722 rHTMLWrt
.bLFPossible
= TRUE
;
2726 if( rHTMLWrt
.bClearLeft
|| rHTMLWrt
.bClearRight
)
2728 const sal_Char
*pStr
;
2729 if( rHTMLWrt
.bClearLeft
)
2731 if( rHTMLWrt
.bClearRight
)
2732 pStr
= OOO_STRING_SVTOOLS_HTML_AL_all
;
2734 pStr
= OOO_STRING_SVTOOLS_HTML_AL_left
;
2737 pStr
= OOO_STRING_SVTOOLS_HTML_AL_right
;
2739 ByteString
sOut( OOO_STRING_SVTOOLS_HTML_linebreak
);
2740 (((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_clear
) += '=') += pStr
;
2742 HTMLOutFuncs::Out_AsciiTag( rHTMLWrt
.Strm(), sOut
.GetBuffer() );
2743 rHTMLWrt
.bClearLeft
= FALSE
;
2744 rHTMLWrt
.bClearRight
= FALSE
;
2746 rHTMLWrt
.bLFPossible
= TRUE
;
2749 // wenn ein LF nicht schon erlaubt ist wird es erlaubt, wenn der
2750 // Absatz mit einem ' ' endet
2751 if( !rHTMLWrt
.bLFPossible
&& !rHTMLWrt
.nLastParaToken
&&
2752 nEnde
> 0 && ' ' == rStr
.GetChar(nEnde
-1) )
2753 rHTMLWrt
.bLFPossible
= TRUE
;
2755 rHTMLWrt
.bTagOn
= FALSE
;
2756 OutHTML_SwFmtOff( rWrt
, aFmtInfo
);
2758 // eventuell eine Form schliessen
2759 rHTMLWrt
.OutForm( FALSE
);
2761 if( bPageBreakBehind
)
2762 rWrt
.Strm() << '\f';
2768 sal_uInt32
SwHTMLWriter::ToPixel( sal_uInt32 nVal
) const
2770 if( Application::GetDefaultDevice() && nVal
)
2772 nVal
= Application::GetDefaultDevice()->LogicToPixel(
2773 Size( nVal
, nVal
), MapMode( MAP_TWIP
) ).Width();
2774 if( !nVal
) // wo ein Twip ist sollte auch ein Pixel sein
2781 static Writer
& OutHTML_CSS1Attr( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2783 // wenn gerade Hints geschrieben werden versuchen wir den Hint als
2784 // CSS1-Attribut zu schreiben
2786 if( ((SwHTMLWriter
&)rWrt
).bCfgOutStyles
&& ((SwHTMLWriter
&)rWrt
).bTxtAttr
)
2787 OutCSS1_HintSpanTag( rWrt
, rHt
);
2793 /* File CHRATR.HXX: */
2795 static Writer
& OutHTML_SvxColor( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2797 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2798 if( rHTMLWrt
.bOutOpts
)
2801 // die Default-Farbe nur Schreiben, wenn sie als Hint vorkommt
2802 //if( rHTMLWrt.bTagOn && !rHTMLWrt.bTxtAttr && rHTMLWrt.pDfltColor
2803 // && rColor == *rHTMLWrt.pDfltColor )
2806 if( !rHTMLWrt
.bTxtAttr
&& rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bCfgPreferStyles
)
2808 // Font-Farbe nicht als Tag schreiben, wenn Styles normalen Tags
2809 // vorgezogen werden
2813 if( rHTMLWrt
.bTagOn
)
2815 Color
aColor( ((const SvxColorItem
&)rHt
).GetValue() );
2816 if( COL_AUTO
== aColor
.GetColor() )
2817 aColor
.SetColor( COL_BLACK
);
2819 ByteString
sOut( '<' );
2820 (((sOut
+= OOO_STRING_SVTOOLS_HTML_font
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_color
) += '=';
2821 rWrt
.Strm() << sOut
.GetBuffer();
2822 HTMLOutFuncs::Out_Color( rWrt
.Strm(), aColor
, rHTMLWrt
.eDestEnc
) << '>';
2825 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_font
, FALSE
);
2831 static Writer
& OutHTML_SwPosture( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2833 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2834 if( rHTMLWrt
.bOutOpts
)
2837 const FontItalic nPosture
= ((const SvxPostureItem
&)rHt
).GetPosture();
2838 if( ITALIC_NORMAL
== nPosture
)
2840 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_italic
, rHTMLWrt
.bTagOn
);
2842 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2844 // vielleicht als CSS1-Attribut ?
2845 OutCSS1_HintSpanTag( rWrt
, rHt
);
2851 static Writer
& OutHTML_SvxFont( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2853 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2854 if( rHTMLWrt
.bOutOpts
)
2857 if( rHTMLWrt
.bTagOn
)
2860 SwHTMLWriter::PrepareFontList( ((const SvxFontItem
&)rHt
), aNames
, 0,
2861 rHTMLWrt
.IsHTMLMode(HTMLMODE_FONT_GENERIC
) );
2862 ByteString
sOut( '<' );
2863 (((sOut
+= OOO_STRING_SVTOOLS_HTML_font
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_face
) += "=\"";
2864 rWrt
.Strm() << sOut
.GetBuffer();
2865 HTMLOutFuncs::Out_String( rWrt
.Strm(), aNames
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
)
2869 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_font
, FALSE
);
2874 static Writer
& OutHTML_SvxFontHeight( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2876 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2877 if( rHTMLWrt
.bOutOpts
)
2880 if( rHTMLWrt
.bTagOn
)
2882 ByteString
sOut( '<' );
2883 sOut
+= OOO_STRING_SVTOOLS_HTML_font
;
2885 UINT32 nHeight
= ((const SvxFontHeightItem
&)rHt
).GetHeight();
2886 USHORT nSize
= rHTMLWrt
.GetHTMLFontSize( nHeight
);
2887 (((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_size
) += '=')
2888 += ByteString::CreateFromInt32( nSize
);
2889 rWrt
.Strm() << sOut
.GetBuffer();
2891 if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
&&
2892 rHTMLWrt
.aFontHeights
[nSize
-1] != nHeight
)
2894 // wenn die Groesse keiner HTML-Groesse entspricht,
2895 // wird sie noch zusatzlich als Style-Option exportiert
2896 OutCSS1_HintStyleOpt( rWrt
, rHt
);
2902 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_font
, FALSE
);
2908 static Writer
& OutHTML_SvxLanguage( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2910 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2911 if( rHTMLWrt
.bOutOpts
)
2914 LanguageType eLang
= ((const SvxLanguageItem
&)rHt
).GetLanguage();
2915 if( LANGUAGE_DONTKNOW
== eLang
)
2918 if( rHTMLWrt
.bTagOn
)
2920 ByteString
sOut( '<' );
2921 sOut
+= OOO_STRING_SVTOOLS_HTML_span
;
2922 rWrt
.Strm() << sOut
.GetBuffer();
2923 rHTMLWrt
.OutLanguage( ((const SvxLanguageItem
&)rHt
).GetLanguage() );
2928 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_span
, FALSE
);
2933 static Writer
& OutHTML_SwWeight( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2935 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2936 if( rHTMLWrt
.bOutOpts
)
2939 const FontWeight nBold
= ((const SvxWeightItem
&)rHt
).GetWeight();
2940 if( WEIGHT_BOLD
== nBold
)
2942 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_bold
, rHTMLWrt
.bTagOn
);
2944 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2946 // vielleicht als CSS1-Attribut ?
2947 OutCSS1_HintSpanTag( rWrt
, rHt
);
2954 static Writer
& OutHTML_SwCrossedOut( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2956 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2957 if( rHTMLWrt
.bOutOpts
)
2960 // Wegen Netscape schrieben wir hier STRIKE und nicht S raus!
2961 const FontStrikeout nStrike
= ((const SvxCrossedOutItem
&)rHt
).GetStrikeout();
2962 if( STRIKEOUT_NONE
!= nStrike
)
2964 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_strike
, rHTMLWrt
.bTagOn
);
2966 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2968 // vielleicht als CSS1-Attribut ?
2969 OutCSS1_HintSpanTag( rWrt
, rHt
);
2976 static Writer
& OutHTML_SvxEscapement( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2978 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2979 if( rHTMLWrt
.bOutOpts
)
2982 const SvxEscapement eEscape
=
2983 (const SvxEscapement
)((const SvxEscapementItem
&)rHt
).GetEnumValue();
2984 const sal_Char
*pStr
= 0;
2987 case SVX_ESCAPEMENT_SUPERSCRIPT
: pStr
= OOO_STRING_SVTOOLS_HTML_superscript
; break;
2988 case SVX_ESCAPEMENT_SUBSCRIPT
: pStr
= OOO_STRING_SVTOOLS_HTML_subscript
; break;
2995 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), pStr
, rHTMLWrt
.bTagOn
);
2997 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2999 // vielleicht als CSS1-Attribut ?
3000 OutCSS1_HintSpanTag( rWrt
, rHt
);
3008 static Writer
& OutHTML_SwUnderline( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3010 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3011 if( rHTMLWrt
.bOutOpts
)
3014 const FontUnderline eUnder
= ((const SvxUnderlineItem
&)rHt
).GetLineStyle();
3015 if( UNDERLINE_NONE
!= eUnder
)
3017 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_underline
, rHTMLWrt
.bTagOn
);
3019 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
3021 // vielleicht als CSS1-Attribut ?
3022 OutCSS1_HintSpanTag( rWrt
, rHt
);
3029 static Writer
& OutHTML_SwFlyCnt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3031 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3032 SwFmtFlyCnt
& rFlyCnt
= (SwFmtFlyCnt
&)rHt
;
3034 const SwFrmFmt
& rFmt
= *rFlyCnt
.GetFrmFmt();
3035 const SdrObject
*pSdrObj
= 0;
3037 SwHTMLFrmType eType
=
3038 (SwHTMLFrmType
)rHTMLWrt
.GuessFrmType( rFmt
, pSdrObj
);
3039 BYTE nMode
= aHTMLOutFrmAsCharTable
[eType
][rHTMLWrt
.nExportMode
];
3040 rHTMLWrt
.OutFrmFmt( nMode
, rFmt
, pSdrObj
);
3044 static Writer
& OutHTML_SwHardBlank( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3046 HTMLOutContext
aContext ( ((SwHTMLWriter
&)rWrt
).eDestEnc
);
3047 HTMLOutFuncs::Out_Char( rWrt
.Strm(), ((SwFmtHardBlank
&)rHt
).GetChar(),
3049 &((SwHTMLWriter
&)rWrt
).aNonConvertableCharacters
);
3050 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
3054 // Das ist jetzt unser Blink-Item. Blinkend wird eingeschaltet, indem man
3055 // das Item auf TRUE setzt!
3056 static Writer
& OutHTML_SwBlink( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3058 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3059 if( rHTMLWrt
.bOutOpts
|| !rHTMLWrt
.IsHTMLMode(HTMLMODE_BLINK
) )
3062 if( ((const SvxBlinkItem
&)rHt
).GetValue() )
3064 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_blink
, rHTMLWrt
.bTagOn
);
3066 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
3068 // vielleicht als CSS1-Attribut ?
3069 OutCSS1_HintSpanTag( rWrt
, rHt
);
3075 Writer
& OutHTML_INetFmt( Writer
& rWrt
, const SwFmtINetFmt
& rINetFmt
, BOOL bOn
)
3077 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3079 String
aURL( rINetFmt
.GetValue() );
3080 const SvxMacroTableDtor
*pMacTable
= rINetFmt
.GetMacroTbl();
3081 BOOL bEvents
= pMacTable
!= 0 && pMacTable
->Count() > 0;
3083 // Gibt es ueberhaupt etwas auszugeben?
3084 if( !aURL
.Len() && !bEvents
&& !rINetFmt
.GetName().Len() )
3087 // Tag aus? Dann nur ein </A> ausgeben.
3090 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_anchor
, FALSE
);
3094 ByteString
sOut( '<' );
3095 sOut
+= OOO_STRING_SVTOOLS_HTML_anchor
;
3097 sal_Bool bScriptDependent
= sal_False
;
3099 const SwCharFmt
* pFmt
= rWrt
.pDoc
->GetCharFmtFromPool(
3100 RES_POOLCHR_INET_NORMAL
);
3101 SwHTMLFmtInfo
aFmtInfo( pFmt
);
3103 if( rHTMLWrt
.aChrFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
3105 bScriptDependent
= rHTMLWrt
.aChrFmtInfos
[nPos
]->bScriptDependent
;
3108 if( !bScriptDependent
)
3110 const SwCharFmt
* pFmt
= rWrt
.pDoc
->GetCharFmtFromPool(
3111 RES_POOLCHR_INET_VISIT
);
3112 SwHTMLFmtInfo
aFmtInfo( pFmt
);
3114 if( rHTMLWrt
.aChrFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
3116 bScriptDependent
= rHTMLWrt
.aChrFmtInfos
[nPos
]->bScriptDependent
;
3120 if( bScriptDependent
)
3122 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
3123 switch( rHTMLWrt
.nCSS1Script
)
3125 case CSS1_OUTMODE_WESTERN
:
3128 case CSS1_OUTMODE_CJK
:
3131 case CSS1_OUTMODE_CTL
:
3138 rWrt
.Strm() << sOut
.GetBuffer();
3145 if( aURL
.Len() || bEvents
)
3148 String
sTmp( aURL
);
3149 sTmp
.ToUpperAscii();
3150 xub_StrLen nPos
= sTmp
.SearchAscii( "\" REL=" );
3151 if( nPos
!=STRING_NOTFOUND
)
3153 sRel
= aURL
.Copy( nPos
+1 );
3157 aURL
.EraseLeadingChars().EraseTrailingChars();
3159 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_href
) += "=\"";
3160 rWrt
.Strm() << sOut
.GetBuffer();
3161 rHTMLWrt
.OutHyperlinkHRefValue( aURL
);
3167 if( rINetFmt
.GetName().Len() )
3169 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"";
3170 rWrt
.Strm() << sOut
.GetBuffer();
3171 HTMLOutFuncs::Out_String( rWrt
.Strm(), rINetFmt
.GetName(),
3172 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
3176 const String
& rTarget
= rINetFmt
.GetTargetFrame();
3179 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_target
) += "=\"";
3180 rWrt
.Strm() << sOut
.GetBuffer();
3181 HTMLOutFuncs::Out_String( rWrt
.Strm(), rTarget
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
3187 sOut
+= ByteString( sRel
, RTL_TEXTENCODING_ASCII_US
);
3190 rWrt
.Strm() << sOut
.GetBuffer();
3193 HTMLOutFuncs::Out_Events( rWrt
.Strm(), *pMacTable
, aAnchorEventTable
,
3194 rHTMLWrt
.bCfgStarBasic
, rHTMLWrt
.eDestEnc
,
3195 &rHTMLWrt
.aNonConvertableCharacters
);
3201 static Writer
& OutHTML_SwFmtINetFmt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3203 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3205 if( rHTMLWrt
.bOutOpts
)
3208 const SwFmtINetFmt
& rINetFmt
= (const SwFmtINetFmt
&)rHt
;
3210 if( rHTMLWrt
.bTagOn
)
3212 // ggf. ein noch offenes Attribut voruebergehend beenden
3213 if( rHTMLWrt
.aINetFmts
.Count() )
3215 SwFmtINetFmt
*pINetFmt
=
3216 rHTMLWrt
.aINetFmts
[ rHTMLWrt
.aINetFmts
.Count()-1 ];
3217 OutHTML_INetFmt( rWrt
, *pINetFmt
, FALSE
);
3220 // jetzt das neue aufmachen
3221 OutHTML_INetFmt( rWrt
, rINetFmt
, TRUE
);
3224 const SwFmtINetFmt
*pINetFmt
= new SwFmtINetFmt( rINetFmt
);
3225 rHTMLWrt
.aINetFmts
.C40_INSERT( SwFmtINetFmt
, pINetFmt
,
3226 rHTMLWrt
.aINetFmts
.Count() );
3231 OutHTML_INetFmt( rWrt
, rINetFmt
, FALSE
);
3233 ASSERT( rHTMLWrt
.aINetFmts
.Count(), "da fehlt doch ein URL-Attribut" );
3234 if( rHTMLWrt
.aINetFmts
.Count() )
3236 // das eigene Attribut vom Stack holen
3237 SwFmtINetFmt
*pINetFmt
=
3238 rHTMLWrt
.aINetFmts
[ rHTMLWrt
.aINetFmts
.Count()-1 ];
3240 rHTMLWrt
.aINetFmts
.Remove( rHTMLWrt
.aINetFmts
.Count()-1, 1 );
3244 if( rHTMLWrt
.aINetFmts
.Count() )
3246 // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
3248 SwFmtINetFmt
*pINetFmt
=
3249 rHTMLWrt
.aINetFmts
[ rHTMLWrt
.aINetFmts
.Count()-1 ];
3250 OutHTML_INetFmt( rWrt
, *pINetFmt
, TRUE
);
3257 static Writer
& OutHTML_SwTxtCharFmt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3259 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3260 if( rHTMLWrt
.bOutOpts
)
3263 const SwFmtCharFmt
& rChrFmt
= (const SwFmtCharFmt
&)rHt
;
3264 const SwCharFmt
* pFmt
= rChrFmt
.GetCharFmt();
3271 SwHTMLFmtInfo
aFmtInfo( pFmt
);
3273 if( !rHTMLWrt
.aChrFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
3276 const SwHTMLFmtInfo
*pFmtInfo
= rHTMLWrt
.aChrFmtInfos
[nPos
];
3277 ASSERT( pFmtInfo
, "Wieso gint es keine Infos ueber die Zeichenvorlage?" );
3279 if( rHTMLWrt
.bTagOn
)
3281 ByteString
sOut( '<' );
3282 if( pFmtInfo
->aToken
.Len() > 0 )
3283 sOut
+= pFmtInfo
->aToken
;
3285 sOut
+= OOO_STRING_SVTOOLS_HTML_span
;
3286 if( rHTMLWrt
.bCfgOutStyles
&&
3287 (pFmtInfo
->aClass
.Len() || pFmtInfo
->bScriptDependent
) )
3289 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
3290 rWrt
.Strm() << sOut
.GetBuffer();
3291 String
aClass( pFmtInfo
->aClass
);
3292 if( pFmtInfo
->bScriptDependent
)
3296 switch( rHTMLWrt
.nCSS1Script
)
3298 case CSS1_OUTMODE_WESTERN
:
3299 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
3301 case CSS1_OUTMODE_CJK
:
3302 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
3304 case CSS1_OUTMODE_CTL
:
3305 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
3309 HTMLOutFuncs::Out_String( rWrt
.Strm(), aClass
,
3310 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
3314 rWrt
.Strm() << sOut
.GetBuffer();
3318 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(),
3319 pFmtInfo
->aToken
.Len() ? pFmtInfo
->aToken
.GetBuffer()
3320 : OOO_STRING_SVTOOLS_HTML_span
,
3327 static Writer
& OutHTML_SvxAdjust( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3329 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3330 if( !rHTMLWrt
.bOutOpts
|| !rHTMLWrt
.bTagOn
)
3333 SvxAdjustItem
& rAdjust
= (SvxAdjustItem
&)rHt
;
3334 const sal_Char
* pStr
= 0;
3335 switch( rAdjust
.GetAdjust() )
3337 case SVX_ADJUST_CENTER
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_center
; break;
3338 case SVX_ADJUST_LEFT
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_left
; break;
3339 case SVX_ADJUST_RIGHT
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_right
; break;
3340 case SVX_ADJUST_BLOCK
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_justify
; break;
3346 ByteString
sOut( ' ' );
3347 ((sOut
+= OOO_STRING_SVTOOLS_HTML_O_align
) += '=') += pStr
;
3348 rWrt
.Strm() << sOut
.GetBuffer();
3355 * lege hier die Tabellen fuer die HTML-Funktions-Pointer auf
3356 * die Ausgabe-Funktionen an.
3357 * Es sind lokale Strukturen, die nur innerhalb der HTML-DLL
3358 * bekannt sein muessen.
3362 SwAttrFnTab aHTMLAttrFnTab
= {
3363 /* RES_CHRATR_CASEMAP */ OutHTML_CSS1Attr
,
3364 /* RES_CHRATR_CHARSETCOLOR */ 0,
3365 /* RES_CHRATR_COLOR */ OutHTML_SvxColor
,
3366 /* RES_CHRATR_CONTOUR */ 0,
3367 /* RES_CHRATR_CROSSEDOUT */ OutHTML_SwCrossedOut
,
3368 /* RES_CHRATR_ESCAPEMENT */ OutHTML_SvxEscapement
,
3369 /* RES_CHRATR_FONT */ OutHTML_SvxFont
,
3370 /* RES_CHRATR_FONTSIZE */ OutHTML_SvxFontHeight
,
3371 /* RES_CHRATR_KERNING */ OutHTML_CSS1Attr
,
3372 /* RES_CHRATR_LANGUAGE */ OutHTML_SvxLanguage
,
3373 /* RES_CHRATR_POSTURE */ OutHTML_SwPosture
,
3374 /* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
3375 /* RES_CHRATR_SHADOWED */ 0,
3376 /* RES_CHRATR_UNDERLINE */ OutHTML_SwUnderline
,
3377 /* RES_CHRATR_WEIGHT */ OutHTML_SwWeight
,
3378 /* RES_CHRATR_WORDLINEMODE */ 0,
3379 /* RES_CHRATR_AUTOKERN */ 0,
3380 /* RES_CHRATR_BLINK */ OutHTML_SwBlink
,
3381 /* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen
3382 /* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen
3383 /* RES_CHRATR_BACKGROUND */ OutHTML_CSS1Attr
, // Neu: Zeichenhintergrund
3384 /* RES_CHRATR_CJK_FONT */ OutHTML_SvxFont
,
3385 /* RES_CHRATR_CJK_FONTSIZE */ OutHTML_SvxFontHeight
,
3386 /* RES_CHRATR_CJK_LANGUAGE */ OutHTML_SvxLanguage
,
3387 /* RES_CHRATR_CJK_POSTURE */ OutHTML_SwPosture
,
3388 /* RES_CHRATR_CJK_WEIGHT */ OutHTML_SwWeight
,
3389 /* RES_CHRATR_CTL_FONT */ OutHTML_SvxFont
,
3390 /* RES_CHRATR_CTL_FONTSIZE */ OutHTML_SvxFontHeight
,
3391 /* RES_CHRATR_CTL_LANGUAGE */ OutHTML_SvxLanguage
,
3392 /* RES_CHRATR_CTL_POSTURE */ OutHTML_SwPosture
,
3393 /* RES_CHRATR_CTL_WEIGHT */ OutHTML_SwWeight
,
3394 /* RES_CHRATR_ROTATE */ 0,
3395 /* RES_CHRATR_EMPHASIS_MARK */ 0,
3396 /* RES_CHRATR_TWO_LINES */ 0,
3397 /* RES_CHRATR_SCALEW */ 0,
3398 /* RES_CHRATR_RELIEF */ 0,
3399 /* RES_CHRATR_HIDDEN */ 0,
3400 /* RES_CHRATR_OVERLINE */ OutHTML_CSS1Attr
,
3401 /* RES_CHRATR_DUMMY1 */ 0,
3402 /* RES_CHRATR_DUMMY2 */ 0,
3404 /* RES_TXTATR_DUMMY4 */ 0,
3405 /* RES_TXTATR_INETFMT */ OutHTML_SwFmtINetFmt
,
3406 /* RES_TXTATR_REFMARK*/ 0,
3407 /* RES_TXTATR_TOXMARK */ 0,
3408 /* RES_TXTATR_CHARFMT */ OutHTML_SwTxtCharFmt
,
3409 /* RES_TXTATR_TWO_LINES */ 0,
3410 /* RES_TXTATR_CJK_RUBY */ 0,
3411 /* RES_TXTATR_UNKNOWN_CONTAINER */ 0,
3412 /* RES_TXTATR_DUMMY5 */ 0,
3413 /* RES_TXTATR_DUMMY6 */ 0,
3415 /* RES_TXTATR_FIELD */ OutHTML_SwFmtFld
,
3416 /* RES_TXTATR_FLYCNT */ OutHTML_SwFlyCnt
,
3417 /* RES_TXTATR_FTN */ OutHTML_SwFmtFtn
,
3418 /* RES_TXTATR_SOFTHYPH */ 0,
3419 /* RES_TXTATR_HARDBLANK*/ OutHTML_SwHardBlank
,
3420 /* RES_TXTATR_DUMMY1 */ 0, // Dummy:
3421 /* RES_TXTATR_DUMMY2 */ 0, // Dummy:
3423 /* RES_PARATR_LINESPACING */ 0,
3424 /* RES_PARATR_ADJUST */ OutHTML_SvxAdjust
,
3425 /* RES_PARATR_SPLIT */ 0,
3426 /* RES_PARATR_WIDOWS */ 0,
3427 /* RES_PARATR_ORPHANS */ 0,
3428 /* RES_PARATR_TABSTOP */ 0,
3429 /* RES_PARATR_HYPHENZONE*/ 0,
3430 /* RES_PARATR_DROP */ OutHTML_CSS1Attr
,
3431 /* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit
3432 /* RES_PARATR_NUMRULE */ 0, // Dummy:
3433 /* RES_PARATR_SCRIPTSPACE */ 0, // Dummy:
3434 /* RES_PARATR_HANGINGPUNCTUATION */ 0, // Dummy:
3435 /* RES_PARATR_FORBIDDEN_RULES */ 0, // new
3436 /* RES_PARATR_VERTALIGN */ 0, // new
3437 /* RES_PARATR_SNAPTOGRID*/ 0, // new
3438 /* RES_PARATR_CONNECT_TO_BORDER */ 0, // new
3440 /* RES_PARATR_LIST_ID */ 0, // new
3441 /* RES_PARATR_LIST_LEVEL */ 0, // new
3442 /* RES_PARATR_LIST_ISRESTART */ 0, // new
3443 /* RES_PARATR_LIST_RESTARTVALUE */ 0, // new
3444 /* RES_PARATR_LIST_ISCOUNTED */ 0, // new
3446 /* RES_FILL_ORDER */ 0,
3447 /* RES_FRM_SIZE */ 0,
3448 /* RES_PAPER_BIN */ 0,
3449 /* RES_LR_SPACE */ 0,
3450 /* RES_UL_SPACE */ 0,
3451 /* RES_PAGEDESC */ 0,
3458 /* RES_PROTECT */ 0,
3459 /* RES_SURROUND */ 0,
3460 /* RES_VERT_ORIENT */ 0,
3461 /* RES_HORI_ORIENT */ 0,
3463 /* RES_BACKGROUND */ 0,
3466 /* RES_FRMMACRO */ 0,
3470 /* RES_EDIT_IN_READONLY */ 0,
3471 /* RES_LAYOUT_SPLIT */ 0,
3472 /* RES_FRMATR_DUMMY1 */ 0, // Dummy:
3473 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
3474 /* RES_AUTO_STYLE */ 0, // Dummy:
3475 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
3476 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
3477 /* RES_FRMATR_DUMMY6 */ 0, // Dummy:
3478 /* RES_FRMATR_DUMMY7 */ 0, // Dummy:
3479 /* RES_FRMATR_DUMMY8 */ 0, // Dummy:
3480 /* RES_FRMATR_DUMMY9 */ 0, // Dummy:
3481 /* RES_FOLLOW_TEXT_FLOW */ 0,
3482 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ 0,
3483 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
3484 /* RES_AUTO_STYLE */ 0, // Dummy:
3485 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
3486 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
3488 /* RES_GRFATR_MIRRORGRF */ 0,
3489 /* RES_GRFATR_CROPGRF */ 0,
3490 /* RES_GRFATR_ROTATION */ 0,
3491 /* RES_GRFATR_LUMINANCE */ 0,
3492 /* RES_GRFATR_CONTRAST */ 0,
3493 /* RES_GRFATR_CHANNELR */ 0,
3494 /* RES_GRFATR_CHANNELG */ 0,
3495 /* RES_GRFATR_CHANNELB */ 0,
3496 /* RES_GRFATR_GAMMA */ 0,
3497 /* RES_GRFATR_INVERT */ 0,
3498 /* RES_GRFATR_TRANSPARENCY */ 0,
3499 /* RES_GRFATR_DRWAMODE */ 0,
3500 /* RES_GRFATR_DUMMY1 */ 0,
3501 /* RES_GRFATR_DUMMY2 */ 0,
3502 /* RES_GRFATR_DUMMY3 */ 0,
3503 /* RES_GRFATR_DUMMY4 */ 0,
3504 /* RES_GRFATR_DUMMY5 */ 0,
3506 /* RES_BOXATR_FORMAT */ 0,
3507 /* RES_BOXATR_FORMULA */ 0,
3508 /* RES_BOXATR_VALUE */ 0