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>
89 #include <poolfmt.hxx>
90 #include <pagedesc.hxx>
91 #include <swtable.hxx>
93 #include <breakit.hxx>
94 #include <htmlnum.hxx>
95 #include <wrthtml.hxx>
96 #include <htmlfly.hxx>
97 #include <numrule.hxx>
99 using namespace ::com::sun::star
;
102 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
103 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
104 * definiert und mit der akt. verglichen. Bei unterschieden wird der
105 * Compiler schon meckern.
107 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
108 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
110 #if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
112 #define ATTRFNTAB_SIZE 130
113 #if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
114 #error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
117 #ifdef FORMAT_TABELLE
118 // da sie nicht benutzt wird!
119 #define FORMATTAB_SIZE 7
120 #if FORMATTAB_SIZE != RES_FMT_END - RES_FMT_BEGIN
121 #error Format-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
125 #define NODETAB_SIZE 3
126 #if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
127 #error Node-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
132 #define HTML_BULLETCHAR_DISC 34
133 #define HTML_BULLETCHAR_CIRCLE 38
134 #define HTML_BULLETCHAR_SQUARE 36
138 //-----------------------------------------------------------------------
140 HTMLOutEvent __FAR_DATA aAnchorEventTable
[] =
142 { OOO_STRING_SVTOOLS_HTML_O_SDonclick
, OOO_STRING_SVTOOLS_HTML_O_onclick
, SFX_EVENT_MOUSECLICK_OBJECT
},
143 { OOO_STRING_SVTOOLS_HTML_O_SDonmouseover
, OOO_STRING_SVTOOLS_HTML_O_onmouseover
, SFX_EVENT_MOUSEOVER_OBJECT
},
144 { OOO_STRING_SVTOOLS_HTML_O_SDonmouseout
, OOO_STRING_SVTOOLS_HTML_O_onmouseout
, SFX_EVENT_MOUSEOUT_OBJECT
},
148 static Writer
& OutHTML_SvxAdjust( Writer
& rWrt
, const SfxPoolItem
& rHt
);
150 static Writer
& OutHTML_HoriSpacer( Writer
& rWrt
, INT16 nSize
)
152 ASSERT( nSize
>0, "horizontaler SPACER mit negativem Wert?" )
156 if( Application::GetDefaultDevice() )
158 nSize
= (INT16
)Application::GetDefaultDevice()
159 ->LogicToPixel( Size(nSize
,0), MapMode(MAP_TWIP
) ).Width();
162 ByteString
sOut( '<' );
163 (((((((((sOut
+= OOO_STRING_SVTOOLS_HTML_spacer
)
164 += ' ') += OOO_STRING_SVTOOLS_HTML_O_type
) += '=') += OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal
)
165 += ' ') += OOO_STRING_SVTOOLS_HTML_O_size
) += '=')
166 +=ByteString::CreateFromInt32(nSize
)) += '>';
168 rWrt
.Strm() << sOut
.GetBuffer();
173 USHORT
SwHTMLWriter::GetDefListLvl( const String
& rNm
, USHORT nPoolId
)
175 if( nPoolId
== RES_POOLCOLL_HTML_DD
)
177 return 1 | HTML_DLCOLL_DD
;
179 else if( nPoolId
== RES_POOLCOLL_HTML_DT
)
181 return 1 | HTML_DLCOLL_DT
;
184 String
sDTDD( String::CreateFromAscii(OOO_STRING_SVTOOLS_HTML_dt
) );
186 if( COMPARE_EQUAL
== sDTDD
.CompareTo( rNm
, sDTDD
.Len() ) )
187 // DefinitionList - term
188 return (USHORT
)rNm
.Copy( sDTDD
.Len() ).ToInt32() | HTML_DLCOLL_DT
;
190 sDTDD
.AssignAscii( OOO_STRING_SVTOOLS_HTML_dd
);
192 if( COMPARE_EQUAL
== sDTDD
.CompareTo( rNm
, sDTDD
.Len() ) )
193 // DefinitionList - definition
194 return (USHORT
)rNm
.Copy( sDTDD
.Len() ).ToInt32() | HTML_DLCOLL_DD
;
199 void SwHTMLWriter::OutAndSetDefList( USHORT nNewLvl
)
201 // eventuell muss erst mal eine Liste aufgemacht werden
202 if( nDefListLvl
< nNewLvl
)
204 // output </pre> for the previous(!) pararagraph, if required.
205 // Preferable, the <pre> is exported by OutHTML_SwFmtOff for the
206 // previous paragraph already, but that's not possible, because a very
207 // deep look at the next paragraph (this one) is required to figure
208 // out that a def list starts here.
210 ChangeParaToken( 0 );
212 // entsprechend dem Level-Unterschied schreiben!
213 for( USHORT i
=nDefListLvl
; i
<nNewLvl
; i
++ )
217 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist
, TRUE
);
222 else if( nDefListLvl
> nNewLvl
)
224 for( USHORT i
=nNewLvl
; i
< nDefListLvl
; i
++ )
229 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist
, FALSE
);
234 nDefListLvl
= nNewLvl
;
238 void SwHTMLWriter::ChangeParaToken( USHORT nNew
)
240 if( nNew
!= nLastParaToken
&& HTML_PREFORMTXT_ON
== nLastParaToken
)
242 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_preformtxt
, FALSE
);
245 nLastParaToken
= nNew
;
248 sal_uInt16
SwHTMLWriter::GetCSS1ScriptForScriptType( sal_uInt16 nScriptType
)
250 sal_uInt16 nRet
= CSS1_OUTMODE_ANY_SCRIPT
;
252 switch( nScriptType
)
254 case i18n::ScriptType::LATIN
:
255 nRet
= CSS1_OUTMODE_WESTERN
;
257 case i18n::ScriptType::ASIAN
:
258 nRet
= CSS1_OUTMODE_CJK
;
260 case i18n::ScriptType::COMPLEX
:
261 nRet
= CSS1_OUTMODE_CTL
;
268 // fuer die Formate muesste eine einzige Ausgabe-Funktion genuegen !
270 * Formate wie folgt ausgeben:
271 * - fuer Formate, fuer die es entsprechende HTML-Tags gibt wird das
273 * - fuer alle anderen wird ein Absatz-Tag <P> ausgegeben und bUserFmt
275 * - Wenn eine Absatz-Ausrichtung am uebergebenen Item-Set des Nodes
276 * oder im Item-Set des Format gesetzt ist, wird ein ALIGN=xxx ausgegeben,
277 * sofern HTML es zulaesst
278 * - in jedem Fall wird harte Attributierung als STYLE-Option geschrieben.
279 * Wenn bUserFmt nicht gesetzt ist, wird nur der uebergebene Item-Set
280 * betrachtet. Sonst werden auch Attribute des Formats ausgegeben.
283 struct SwHTMLTxtCollOutputInfo
285 ByteString aToken
; // auszugendens End-Token
286 SfxItemSet
*pItemSet
; // harte Attributierung
288 BOOL bInNumBulList
; // in einer Aufzaehlungs-Liste;
289 BOOL bParaPossible
; // ein </P> darf zusaetzlich ausgegeben werden
290 BOOL bOutPara
; // ein </P> soll ausgegeben werden
291 BOOL bOutDiv
; // write a </DIV>
293 SwHTMLTxtCollOutputInfo() :
295 bInNumBulList( FALSE
),
296 bParaPossible( FALSE
),
301 ~SwHTMLTxtCollOutputInfo();
303 BOOL
HasParaToken() const { return aToken
.Len()==1 && aToken
.GetChar(0)=='P'; }
304 BOOL
ShouldOutputToken() const { return bOutPara
|| !HasParaToken(); }
307 SwHTMLTxtCollOutputInfo::~SwHTMLTxtCollOutputInfo()
314 const SwFmt
*pFmt
; // das Format selbst
315 const SwFmt
*pRefFmt
; // das Vergleichs-Format
317 ByteString aToken
; // das auszugebende Token
318 String aClass
; // die auszugebende Klasse
320 SfxItemSet
*pItemSet
; // der auszugebende Attribut-Set
322 sal_Int32 nLeftMargin
; // ein par default-Werte fuer
323 sal_Int32 nRightMargin
; // Absatz-Vorlagen
324 short nFirstLineIndent
;
327 USHORT nBottomMargin
;
329 sal_Bool bScriptDependent
;
331 // Konstruktor fuer einen Dummy zum Suchen
332 SwHTMLFmtInfo( const SwFmt
*pF
) :
333 pFmt( pF
), pItemSet( 0 )
337 // Konstruktor zum Erstellen der Format-Info
338 SwHTMLFmtInfo( const SwFmt
*pFmt
, SwDoc
*pDoc
, SwDoc
*pTemlate
,
339 BOOL bOutStyles
, LanguageType eDfltLang
=LANGUAGE_DONTKNOW
,
340 sal_uInt16 nScript
=CSS1_OUTMODE_ANY_SCRIPT
,
341 BOOL bHardDrop
=FALSE
);
344 friend BOOL
operator==( const SwHTMLFmtInfo
& rInfo1
,
345 const SwHTMLFmtInfo
& rInfo2
)
347 return (long)rInfo1
.pFmt
== (long)rInfo2
.pFmt
;
350 friend BOOL
operator<( const SwHTMLFmtInfo
& rInfo1
,
351 const SwHTMLFmtInfo
& rInfo2
)
353 return (long)rInfo1
.pFmt
< (long)rInfo2
.pFmt
;
358 SV_IMPL_OP_PTRARR_SORT( SwHTMLFmtInfos
, SwHTMLFmtInfo
* )
360 SwHTMLFmtInfo::SwHTMLFmtInfo( const SwFmt
*pF
, SwDoc
*pDoc
, SwDoc
*pTemplate
,
362 LanguageType eDfltLang
,
363 sal_uInt16 nCSS1Script
, BOOL bHardDrop
) :
364 pFmt( pF
), pItemSet( 0 ), bScriptDependent( sal_False
)
366 USHORT nRefPoolId
= 0;
367 // Den Selektor des Formats holen
368 USHORT nDeep
= SwHTMLWriter::GetCSS1Selector( pFmt
, aToken
, aClass
,
370 ASSERT( nDeep
? aToken
.Len()>0 : aToken
.Len()==0,
371 "Hier stimmt doch was mit dem Token nicht!" );
372 ASSERT( nDeep
? nRefPoolId
: !nRefPoolId
,
373 "Hier stimmt doch was mit der Vergleichs-Vorlage nicht!" );
375 BOOL bTxtColl
= pFmt
->Which() == RES_TXTFMTCOLL
||
376 pFmt
->Which() == RES_CONDTXTFMTCOLL
;
378 const SwFmt
*pReferenceFmt
= 0; // Vergleichs-Format
379 sal_Bool bSetDefaults
= sal_True
, bClearSame
= sal_True
;
382 // Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
383 // solchen abgeleitet
386 // wenn keine Styles exportiert werden, muss evtl. zusaetlich
387 // harte Attributierung geschrieben werden
391 case CSS1_FMT_CMPREF
:
392 // fuer HTML-Tag-Vorlagen die Unterscheide zum Original
393 // (sofern verfuegbar)
394 pReferenceFmt
= SwHTMLWriter::GetTemplateFmt( nRefPoolId
,
399 // sonst die zur HTML-Tag-Vorlage des Originals oder des
400 // aktuellen Doks, wenn die nicht verfuegbar ist
402 pReferenceFmt
= SwHTMLWriter::GetTemplateFmt( nRefPoolId
,
405 pReferenceFmt
= SwHTMLWriter::GetParentFmt( *pFmt
, nDeep
);
412 // Nicht von einer HTML-Tag-Vorlage abgeleitete Absatz-Vorlagen
413 // muessen als harte Attributierung relativ zur Textkoerper-Volage
414 // exportiert werden. Fuer Nicht-Styles-Export sollte die der
415 // HTML-Vorlage als Referenz dienen
416 if( !bOutStyles
&& pTemplate
)
417 pReferenceFmt
= pTemplate
->GetTxtCollFromPool( RES_POOLCOLL_TEXT
, false );
419 pReferenceFmt
= pDoc
->GetTxtCollFromPool( RES_POOLCOLL_TEXT
, false );
422 if( pReferenceFmt
|| nDeep
==0 )
424 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
425 pFmt
->GetAttrSet().GetRanges() );
426 // wenn Unterschiede zu einer anderen Vorlage geschrieben werden
427 // sollen ist harte Attributierung noetig. Fuer Vorlagen, die
428 // nicht von HTML-Tag-Vorlagen abgeleitet sind, gilt das immer
430 pItemSet
->Set( pFmt
->GetAttrSet(), TRUE
);
433 SwHTMLWriter::SubtractItemSet( *pItemSet
, pReferenceFmt
->GetAttrSet(),
434 bSetDefaults
, bClearSame
);
436 // einen leeren Item-Set gleich loeschen, das spart speater
438 if( !pItemSet
->Count() )
449 // We have to add hard attributes for any script dependent
450 // item that is not accessed by the style
451 static sal_uInt16 aWhichIds
[3][4] =
453 { RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
,
454 RES_CHRATR_POSTURE
, RES_CHRATR_WEIGHT
},
455 { RES_CHRATR_CJK_FONT
, RES_CHRATR_CJK_FONTSIZE
,
456 RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CJK_WEIGHT
},
457 { RES_CHRATR_CTL_FONT
, RES_CHRATR_CTL_FONTSIZE
,
458 RES_CHRATR_CTL_POSTURE
, RES_CHRATR_CTL_WEIGHT
}
462 sal_uInt16 aSets
[2] = {0,0};
463 switch( nCSS1Script
)
465 case CSS1_OUTMODE_WESTERN
:
470 case CSS1_OUTMODE_CJK
:
475 case CSS1_OUTMODE_CTL
:
481 for( sal_uInt16 i
=0; i
<4; i
++ )
483 const SfxPoolItem
& rRef
= pFmt
->GetFmtAttr( aWhichIds
[nRef
][i
] );
484 for( sal_uInt16 j
=0; j
<2; j
++ )
486 const SfxPoolItem
& rSet
= pFmt
->GetFmtAttr( aWhichIds
[aSets
[j
]][i
] );
490 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
491 pFmt
->GetAttrSet().GetRanges() );
492 pItemSet
->Put( rSet
);
498 // Ggf. noch ein DropCap-Attribut uebernehmen
499 if( bOutStyles
&& bHardDrop
&& nDeep
!= 0 )
501 const SfxPoolItem
*pItem
;
502 if( SFX_ITEM_SET
==pFmt
->GetAttrSet().GetItemState(
503 RES_PARATR_DROP
, TRUE
, &pItem
) )
508 pReferenceFmt
= SwHTMLWriter::GetTemplateFmt( nRefPoolId
, pTemplate
);
509 const SfxPoolItem
*pRefItem
;
511 SFX_ITEM_SET
==pReferenceFmt
->GetAttrSet().GetItemState(
512 RES_PARATR_DROP
, TRUE
, &pRefItem
);
513 bPut
= !bRefItemSet
|| *pItem
!=*pRefItem
;
518 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
519 pFmt
->GetAttrSet().GetRanges() );
520 pItemSet
->Put( *pItem
);
526 // Die diversen default-Abstaende aus der Vorlage oder der
527 // Vergleischs-Vorlage merken
528 const SvxLRSpaceItem
&rLRSpace
=
529 (pReferenceFmt
? pReferenceFmt
: pFmt
)->GetLRSpace();
530 nLeftMargin
= rLRSpace
.GetTxtLeft();
531 nRightMargin
= rLRSpace
.GetRight();
532 nFirstLineIndent
= rLRSpace
.GetTxtFirstLineOfst();
534 const SvxULSpaceItem
&rULSpace
=
535 (pReferenceFmt
? pReferenceFmt
: pFmt
)->GetULSpace();
536 nTopMargin
= rULSpace
.GetUpper();
537 nBottomMargin
= rULSpace
.GetLower();
539 // export language if it differs from the default language
540 sal_uInt16 nWhichId
=
541 SwHTMLWriter::GetLangWhichIdFromScript( nCSS1Script
);
542 const SvxLanguageItem
& rLang
=
543 (const SvxLanguageItem
&)pFmt
->GetFmtAttr( nWhichId
);
544 LanguageType eLang
= rLang
.GetLanguage();
545 if( eLang
!= eDfltLang
)
548 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
549 pFmt
->GetAttrSet().GetRanges() );
550 pItemSet
->Put( rLang
);
553 static sal_uInt16 aWhichIds
[3] =
554 { RES_CHRATR_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
,
555 RES_CHRATR_CTL_LANGUAGE
};
556 for( sal_uInt16 i
=0; i
<3; i
++ )
558 if( aWhichIds
[i
] != nWhichId
)
560 const SvxLanguageItem
& rTmpLang
=
561 (const SvxLanguageItem
&)pFmt
->GetFmtAttr(aWhichIds
[i
]);
562 if( rTmpLang
.GetLanguage() != eLang
)
565 pItemSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
566 pFmt
->GetAttrSet().GetRanges() );
567 pItemSet
->Put( rTmpLang
);
574 SwHTMLFmtInfo::~SwHTMLFmtInfo()
579 void OutHTML_SwFmt( Writer
& rWrt
, const SwFmt
& rFmt
,
580 const SfxItemSet
*pNodeItemSet
,
581 SwHTMLTxtCollOutputInfo
& rInfo
)
583 ASSERT( RES_CONDTXTFMTCOLL
==rFmt
.Which() || RES_TXTFMTCOLL
==rFmt
.Which(),
584 "keine Absatz-Vorlage" );
586 SwHTMLWriter
& rHWrt
= (SwHTMLWriter
&)rWrt
;
588 // Erstmal ein par Flags ...
589 USHORT nNewDefListLvl
= 0;
590 USHORT nNumStart
= USHRT_MAX
;
591 BOOL bForceDL
= FALSE
;
593 rInfo
.bInNumBulList
= FALSE
; // Wir sind in einer Liste?
594 BOOL bNumbered
= FALSE
; // Der aktuelle Absatz ist numeriert
595 BOOL bPara
= FALSE
; // das aktuelle Token ist <P>
596 rInfo
.bParaPossible
= FALSE
; // ein <P> darf zusaetzlich ausgegeben werden
597 BOOL bNoEndTag
= FALSE
; // kein End-Tag ausgeben
599 rHWrt
.bNoAlign
= FALSE
; // kein ALIGN=... moeglich
600 BOOL bNoStyle
= FALSE
; // kein STYLE=... moeglich
601 BYTE nBulletGrfLvl
= 255; // Die auszugebende Bullet-Grafik
603 // Sind wir in einer Aufzaehlungs- oder Numerierungliste?
604 const SwTxtNode
* pTxtNd
= rWrt
.pCurPam
->GetNode()->GetTxtNode();
606 SwHTMLNumRuleInfo aNumInfo
;
607 if( rHWrt
.GetNextNumInfo() )
609 aNumInfo
= *rHWrt
.GetNextNumInfo();
610 rHWrt
.ClearNextNumInfo();
614 aNumInfo
.Set( *pTxtNd
);
617 if( aNumInfo
.GetNumRule() )
619 rInfo
.bInNumBulList
= TRUE
;
622 // ist der aktuelle Absatz numeriert?
623 bNumbered
= aNumInfo
.IsNumbered();
624 BYTE nLvl
= aNumInfo
.GetLevel();
626 ASSERT( pTxtNd
->GetActualListLevel() == nLvl
,
627 "Gemerkter Num-Level ist falsch" );
628 ASSERT( bNumbered
== static_cast< BOOL
>(pTxtNd
->IsCountedInList()),
629 "Gemerkter Numerierungs-Zustand ist falsch" );
633 nBulletGrfLvl
= nLvl
; // nur veruebergehend!!!
634 // --> OD 2005-11-15 #i57919#
635 // correction of re-factoring done by cws swnumtree:
636 // - <nNumStart> has to contain the restart value, if the
637 // numbering is restarted at this text node. Value <USHRT_MAX>
638 // indicates, that no additional restart value has to be written.
639 if ( pTxtNd
->IsListRestart() )
641 nNumStart
= static_cast< USHORT
>(pTxtNd
->GetActualListStartValue());
644 DBG_ASSERT( rHWrt
.nLastParaToken
== 0,
645 "<PRE> wurde nicht vor <LI> beendet." );
649 // Jetzt holen wir das Token und ggf. die Klasse
650 SwHTMLFmtInfo
aFmtInfo( &rFmt
);
652 const SwHTMLFmtInfo
*pFmtInfo
;
653 if( rHWrt
.aTxtCollInfos
.Seek_Entry( &aFmtInfo
, &nArrayPos
) )
655 pFmtInfo
= rHWrt
.aTxtCollInfos
[nArrayPos
];
659 pFmtInfo
= new SwHTMLFmtInfo( &rFmt
, rWrt
.pDoc
, rHWrt
.pTemplate
,
660 rHWrt
.bCfgOutStyles
, rHWrt
.eLang
,
662 !rHWrt
.IsHTMLMode(HTMLMODE_DROPCAPS
) );
663 rHWrt
.aTxtCollInfos
.C40_PTR_INSERT( SwHTMLFmtInfo
, pFmtInfo
);
664 String
aName( rFmt
.GetName() );
665 if( rHWrt
.aScriptParaStyles
.Seek_Entry( &aName
) )
666 ((SwHTMLFmtInfo
*)pFmtInfo
)->bScriptDependent
= sal_True
;
669 // Jetzt wird festgelegt, was aufgrund des Tokens so moeglich ist
670 USHORT nToken
= 0; // Token fuer Tag-Wechsel
671 BOOL bOutNewLine
= FALSE
; // nur ein LF ausgeben?
672 if( pFmtInfo
->aToken
.Len() )
674 // Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
675 // solchen abgeleitet
676 rInfo
.aToken
= pFmtInfo
->aToken
;
678 // der erste Buchstabe reicht meistens
679 switch( rInfo
.aToken
.GetChar( 0 ) )
681 case 'A': ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_address
),
682 "Doch kein ADDRESS?" );
683 rInfo
.bParaPossible
= TRUE
;
684 rHWrt
.bNoAlign
= TRUE
;
687 case 'B': ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_blockquote
),
688 "Doch kein BLOCKQUOTE?" );
689 rInfo
.bParaPossible
= TRUE
;
690 rHWrt
.bNoAlign
= TRUE
;
693 case 'P': if( rInfo
.aToken
.Len() == 1 )
699 ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_preformtxt
),
701 if( HTML_PREFORMTXT_ON
== rHWrt
.nLastParaToken
)
707 nToken
= HTML_PREFORMTXT_ON
;
708 rHWrt
.bNoAlign
= TRUE
;
714 case 'D': ASSERT( rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_dt
) ||
715 rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_dd
),
716 "Doch kein DD/DT?" );
717 bDT
= rInfo
.aToken
.Equals(OOO_STRING_SVTOOLS_HTML_dt
);
718 rInfo
.bParaPossible
= !bDT
;
719 rHWrt
.bNoAlign
= TRUE
;
726 // alle Vorlagen, die nicht einem HTML-Tag entsprechen oder von
727 // diesem abgeleitet sind, werden als <P> exportiert
729 rInfo
.aToken
= OOO_STRING_SVTOOLS_HTML_parabreak
;
733 // Falls noetig, die harte Attributierung der Vorlage uebernehmen
734 if( pFmtInfo
->pItemSet
)
736 ASSERT( !rInfo
.pItemSet
, "Wo kommt der Item-Set her?" );
737 rInfo
.pItemSet
= new SfxItemSet( *pFmtInfo
->pItemSet
);
740 // und noch die harte Attributierung des Absatzes dazunehmen
744 rInfo
.pItemSet
->Put( *pNodeItemSet
);
746 rInfo
.pItemSet
= new SfxItemSet( *pNodeItemSet
);
749 // den unteren Absatz-Abstand brauchen wir noch
750 const SvxULSpaceItem
& rULSpace
=
751 pNodeItemSet
? ((const SvxULSpaceItem
&)pNodeItemSet
->Get(RES_UL_SPACE
))
755 if( (rHWrt
.bOutHeader
&&
756 rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() ==
757 rWrt
.pCurPam
->GetMark()->nNode
.GetIndex()) ||
760 if( rHWrt
.bCfgOutStyles
)
762 SvxULSpaceItem
aULSpaceItem( rULSpace
);
763 if( rHWrt
.bOutHeader
)
764 aULSpaceItem
.SetLower( rHWrt
.nHeaderFooterSpace
);
766 aULSpaceItem
.SetUpper( rHWrt
.nHeaderFooterSpace
);
768 if( !rInfo
.pItemSet
)
769 rInfo
.pItemSet
= new SfxItemSet(
770 *rFmt
.GetAttrSet().GetPool(),
771 RES_UL_SPACE
, RES_UL_SPACE
);
772 rInfo
.pItemSet
->Put( aULSpaceItem
);
774 rHWrt
.bOutHeader
= FALSE
;
775 rHWrt
.bOutFooter
= FALSE
;
780 // nur einen Zeilen-Umbruch (ohne Einrueckung) am Absatz-Anfang
782 rInfo
.aToken
.Erase(); // kein End-Tag ausgeben
783 rWrt
.Strm() << SwHTMLWriter::sNewLine
;
789 // soll ein ALIGN=... geschrieben werden?
790 const SfxPoolItem
* pAdjItem
= 0;
791 const SfxPoolItem
* pItem
;
793 if( rInfo
.pItemSet
&&
794 SFX_ITEM_SET
== rInfo
.pItemSet
->GetItemState( RES_PARATR_ADJUST
,
800 // Unteren Absatz-Abstand beachten ? (nie im letzen Absatz von
802 BOOL bUseParSpace
= !rHWrt
.bOutTable
||
803 (rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() !=
804 rWrt
.pCurPam
->GetMark()->nNode
.GetIndex());
805 // Wenn Styles exportiert werden, wird aus eingerueckten Absaetzen
806 // eine Definitions-Liste
807 const SvxLRSpaceItem
& rLRSpace
=
808 pNodeItemSet
? ((const SvxLRSpaceItem
&)pNodeItemSet
->Get(RES_LR_SPACE
))
810 if( (!rHWrt
.bCfgOutStyles
|| bForceDL
) && !rInfo
.bInNumBulList
)
812 sal_Int32 nLeftMargin
;
814 nLeftMargin
= rLRSpace
.GetTxtLeft();
816 nLeftMargin
= rLRSpace
.GetTxtLeft() > pFmtInfo
->nLeftMargin
817 ? rLRSpace
.GetTxtLeft() - pFmtInfo
->nLeftMargin
820 if( nLeftMargin
> 0 && rHWrt
.nDefListMargin
> 0 )
822 nNewDefListLvl
= static_cast< USHORT
>((nLeftMargin
+ (rHWrt
.nDefListMargin
/2)) /
823 rHWrt
.nDefListMargin
);
824 if( nNewDefListLvl
== 0 && bForceDL
&& !bDT
)
829 // If the left margin is 0 or negative, emulating indent
830 // with <dd> does not work. We then set a def list only if
831 // the dd style is used.
832 nNewDefListLvl
= (bForceDL
&& !bDT
) ? 1 : 0;
835 BOOL bIsNextTxtNode
=
836 rWrt
.pDoc
->GetNodes()[rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex()+1]
839 if( bForceDL
&& bDT
)
841 // Statt eines DD muessen wir hier auch ein DT der Ebene
845 else if( !nNewDefListLvl
&& !rHWrt
.bCfgOutStyles
&& bPara
&&
846 rULSpace
.GetLower()==0 &&
847 ((bUseParSpace
&& bIsNextTxtNode
) || rHWrt
.nDefListLvl
==1) &&
848 (!pAdjItem
|| SVX_ADJUST_LEFT
==
849 ((const SvxAdjustItem
*)pAdjItem
)->GetAdjust()) )
851 // Absaetze ohne unteren Abstand als DT exportieren
854 rInfo
.bParaPossible
= FALSE
;
855 rHWrt
.bNoAlign
= TRUE
;
859 if( nNewDefListLvl
!= rHWrt
.nDefListLvl
)
860 rHWrt
.OutAndSetDefList( nNewDefListLvl
);
862 // ggf. eine Aufzaehlung- oder Numerierungsliste beginnen
863 if( rInfo
.bInNumBulList
)
865 ASSERT( !rHWrt
.nDefListLvl
, "DL in OL geht nicht!" );
866 OutHTML_NumBulListStart( rHWrt
, aNumInfo
);
870 if( rHWrt
.aBulletGrfs
[nBulletGrfLvl
].Len() )
877 // Die Defaults aus der Vorlage merken, denn sie muessen nicht
879 rHWrt
.nDfltLeftMargin
= pFmtInfo
->nLeftMargin
;
880 rHWrt
.nDfltRightMargin
= pFmtInfo
->nRightMargin
;
881 rHWrt
.nDfltFirstLineIndent
= pFmtInfo
->nFirstLineIndent
;
883 if( rInfo
.bInNumBulList
)
885 if( !rHWrt
.IsHTMLMode( HTMLMODE_LSPACE_IN_NUMBUL
) )
886 rHWrt
.nDfltLeftMargin
= rLRSpace
.GetTxtLeft();
888 // In Numerierungs-Listen keinen Ertzeilen-Einzug ausgeben.
889 rHWrt
.nFirstLineIndent
= rLRSpace
.GetTxtFirstLineOfst();
892 if( rInfo
.bInNumBulList
&& bNumbered
&& bPara
&& !rHWrt
.bCfgOutStyles
)
894 // ein einzelnes LI hat keinen Abstand
895 rHWrt
.nDfltTopMargin
= 0;
896 rHWrt
.nDfltBottomMargin
= 0;
898 else if( rHWrt
.nDefListLvl
&& bPara
)
900 // ein einzelnes DD hat auch keinen Abstand
901 rHWrt
.nDfltTopMargin
= 0;
902 rHWrt
.nDfltBottomMargin
= 0;
906 rHWrt
.nDfltTopMargin
= pFmtInfo
->nTopMargin
;
907 // #60393#: Wenn im letzten Absatz einer Tabelle der
908 // untere Absatz-Abstand veraendert wird, vertut sich
909 // Netscape total. Deshalb exportieren wir hier erstmal
910 // nichts, indem wir den Abstand aus dem Absatz als Default
912 if( rHWrt
.bCfgNetscape4
&& !bUseParSpace
)
913 rHWrt
.nDfltBottomMargin
= rULSpace
.GetLower();
915 rHWrt
.nDfltBottomMargin
= pFmtInfo
->nBottomMargin
;
918 if( rHWrt
.nDefListLvl
)
921 (rHWrt
.nDefListLvl
-1) * rHWrt
.nDefListMargin
;
924 if( rHWrt
.bLFPossible
)
925 rHWrt
.OutNewLine(); // Absatz-Tag in neue Zeile
926 rInfo
.bOutPara
= FALSE
;
928 // das ist jetzt unser neues Token
929 rHWrt
.ChangeParaToken( nToken
);
931 BOOL bHasParSpace
= bUseParSpace
&& rULSpace
.GetLower() > 0;
933 // ggf ein List-Item aufmachen
934 if( rInfo
.bInNumBulList
&& bNumbered
)
936 ByteString
sOut( '<' );
937 sOut
+= OOO_STRING_SVTOOLS_HTML_li
;
938 if( USHRT_MAX
!= nNumStart
)
939 (((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_value
) += '=')
940 += ByteString::CreateFromInt32(nNumStart
);
942 rWrt
.Strm() << sOut
.GetBuffer();
945 if( rHWrt
.nDefListLvl
> 0 && !bForceDL
)
947 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), bDT
? OOO_STRING_SVTOOLS_HTML_dt
: OOO_STRING_SVTOOLS_HTML_dd
);
951 rHWrt
.IsHTMLMode( HTMLMODE_NO_CONTROL_CENTERING
) &&
952 rHWrt
.HasControls() )
954 // #64687#: The align=... attribute does behave strange in netscape
955 // if there are controls in a paragraph, because the control and
956 // all text behind the control does not recognize this attribute.
957 ByteString
sOut( '<' );
958 sOut
+= OOO_STRING_SVTOOLS_HTML_division
;
959 rWrt
.Strm() << sOut
.GetBuffer();
961 rHWrt
.bTxtAttr
= FALSE
;
962 rHWrt
.bOutOpts
= TRUE
;
963 OutHTML_SvxAdjust( rWrt
, *pAdjItem
);
966 rHWrt
.bNoAlign
= FALSE
;
967 rInfo
.bOutDiv
= TRUE
;
968 rHWrt
.IncIndentLevel();
969 rHWrt
.bLFPossible
= TRUE
;
973 // fuer BLOCKQUOTE, ADDRESS und DD wird noch ein Absatz-Token
975 // - keine Styles geschrieben werden, und
976 // - ein untere Abstand oder eine Absatz-Ausrichtung existiert
977 ByteString aToken
= rInfo
.aToken
;
978 if( !rHWrt
.bCfgOutStyles
&& rInfo
.bParaPossible
&& !bPara
&&
979 (bHasParSpace
|| pAdjItem
) )
981 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), rInfo
.aToken
.GetBuffer() );
982 aToken
= OOO_STRING_SVTOOLS_HTML_parabreak
;
984 rHWrt
.bNoAlign
= FALSE
;
988 LanguageType eLang
= rInfo
.pItemSet
989 ? ((const SvxLanguageItem
&)rInfo
.pItemSet
->Get(SwHTMLWriter::GetLangWhichIdFromScript(rHWrt
.nCSS1Script
))).GetLanguage()
994 static sal_uInt16 aWhichIds
[3] = { RES_CHRATR_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
, RES_CHRATR_CTL_LANGUAGE
};
996 for( sal_uInt16 i
=0; i
<3; i
++ )
998 // export language if it differs from the default language only.
999 const SfxPoolItem
*pTmpItem
;
1000 if( SFX_ITEM_SET
== rInfo
.pItemSet
->GetItemState( aWhichIds
[i
],
1001 sal_True
, &pTmpItem
) &&
1002 ((const SvxLanguageItem
*)pTmpItem
)->GetLanguage() == eLang
)
1003 rInfo
.pItemSet
->ClearItem( aWhichIds
[i
] );
1007 // and the text direction
1008 sal_uInt16 nDir
= rHWrt
.GetHTMLDirection(
1009 (pNodeItemSet
? static_cast < const SvxFrameDirectionItem
& >(
1010 pNodeItemSet
->Get( RES_FRAMEDIR
) )
1011 : rFmt
.GetFrmDir() ).GetValue() );
1013 // Ein <P> wird nur geschrieben, wenn
1014 // - wir in keiner OL/UL/DL sind, oder
1015 // - der Absatz einer OL/UL nicht numeriert ist, oder
1016 // - keine Styles exportiert werden und
1017 // - ein unterer Abstand oder
1018 // - eine Absatz-Ausrichtung existiert, ode
1019 // - Styles exportiert werden und,
1020 // - die Textkoerper-Vorlage geaendert wurde, oder
1021 // - ein Benutzer-Format exportiert wird, oder
1022 // - Absatz-Attribute existieren
1024 (!rInfo
.bInNumBulList
&& !rHWrt
.nDefListLvl
) ||
1025 (rInfo
.bInNumBulList
&& !bNumbered
) ||
1026 (!rHWrt
.bCfgOutStyles
&&
1027 (bHasParSpace
|| pAdjItem
||
1028 (eLang
!= LANGUAGE_DONTKNOW
&& eLang
!= rHWrt
.eLang
))) ||
1029 nDir
!= rHWrt
.nDirection
||
1030 rHWrt
.bCfgOutStyles
)
1032 // jetzt werden Optionen ausgegeben
1033 rHWrt
.bTxtAttr
= FALSE
;
1034 rHWrt
.bOutOpts
= TRUE
;
1036 ByteString
sOut( '<' );
1039 if( eLang
!= LANGUAGE_DONTKNOW
&& eLang
!= rHWrt
.eLang
)
1041 rWrt
.Strm() << sOut
.GetBuffer();
1042 rHWrt
.OutLanguage( eLang
);
1046 if( nDir
!= rHWrt
.nDirection
)
1050 rWrt
.Strm() << sOut
.GetBuffer();
1053 rHWrt
.OutDirection( nDir
);
1056 if( rHWrt
.bCfgOutStyles
&&
1057 (pFmtInfo
->aClass
.Len() || pFmtInfo
->bScriptDependent
) )
1059 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
1060 rWrt
.Strm() << sOut
.GetBuffer();
1061 String
aClass( pFmtInfo
->aClass
);
1062 if( pFmtInfo
->bScriptDependent
)
1066 switch( rHWrt
.nCSS1Script
)
1068 case CSS1_OUTMODE_WESTERN
:
1069 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
1071 case CSS1_OUTMODE_CJK
:
1072 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
1074 case CSS1_OUTMODE_CTL
:
1075 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
1079 HTMLOutFuncs::Out_String( rWrt
.Strm(), aClass
,
1080 rHWrt
.eDestEnc
, &rHWrt
.aNonConvertableCharacters
);
1083 rWrt
.Strm() << sOut
.GetBuffer();
1085 // ggf. Ausrichtung ausgeben.
1086 if( !rHWrt
.bNoAlign
&& pAdjItem
)
1087 OutHTML_SvxAdjust( rWrt
, *pAdjItem
);
1089 // und nun ggf. noch die STYLE-Option
1090 if( rHWrt
.bCfgOutStyles
&& rInfo
.pItemSet
&& !bNoStyle
)
1092 OutCSS1_ParaTagStyleOpt( rWrt
, *rInfo
.pItemSet
);
1097 // Soll ein </P> geschrieben wenrden
1100 ( rHWrt
.bCfgOutStyles
||
1101 (!rHWrt
.bCfgOutStyles
&& bHasParSpace
) );
1103 // wenn kein End-Tag geschrieben werden soll, es loeschen
1105 rInfo
.aToken
.Erase();
1108 // ??? Warum nicht ueber den Hint-Mechanismus ???
1109 if( rHWrt
.IsHTMLMode(HTMLMODE_FIRSTLINE
) )
1111 const SvxLRSpaceItem
& rLRSpaceTmp
=
1112 pNodeItemSet
? ((const SvxLRSpaceItem
&)pNodeItemSet
->Get(RES_LR_SPACE
))
1113 : rFmt
.GetLRSpace();
1114 if( rLRSpaceTmp
.GetTxtFirstLineOfst() > 0 )
1116 OutHTML_HoriSpacer( rWrt
, rLRSpaceTmp
.GetTxtFirstLineOfst() );
1120 if( nBulletGrfLvl
!= 255 )
1122 ASSERT( aNumInfo
.GetNumRule(), "Wo ist die Numerierung geblieben???" );
1123 ASSERT( nBulletGrfLvl
< MAXLEVEL
, "So viele Ebenen gibt's nicht" );
1124 const SwNumFmt
& rNumFmt
= aNumInfo
.GetNumRule()->Get(nBulletGrfLvl
);
1126 OutHTML_BulletImage( rWrt
, OOO_STRING_SVTOOLS_HTML_image
, 0,
1127 rHWrt
.aBulletGrfs
[nBulletGrfLvl
],
1128 rNumFmt
.GetGraphicSize(), rNumFmt
.GetGraphicOrientation() );
1131 rHWrt
.GetNumInfo() = aNumInfo
;
1133 // die Defaults zuruecksetzen
1134 rHWrt
.nDfltLeftMargin
= 0;
1135 rHWrt
.nDfltRightMargin
= 0;
1136 rHWrt
.nDfltFirstLineIndent
= 0;
1137 rHWrt
.nDfltTopMargin
= 0;
1138 rHWrt
.nDfltBottomMargin
= 0;
1139 rHWrt
.nLeftMargin
= 0;
1140 rHWrt
.nFirstLineIndent
= 0;
1143 void OutHTML_SwFmtOff( Writer
& rWrt
, const SwHTMLTxtCollOutputInfo
& rInfo
)
1145 SwHTMLWriter
& rHWrt
= (SwHTMLWriter
&)rWrt
;
1147 // wenn es kein Token gibt haben wir auch nichts auszugeben
1148 if( !rInfo
.aToken
.Len() )
1150 rHWrt
.FillNextNumInfo();
1151 const SwHTMLNumRuleInfo
& rNextInfo
= *rHWrt
.GetNextNumInfo();
1152 // Auch in PRE muss eine Bullet-Liste beendet werden
1153 if( rInfo
.bInNumBulList
)
1156 const SwHTMLNumRuleInfo
& rNRInfo
= rHWrt
.GetNumInfo();
1157 if( rNextInfo
.GetNumRule() != rNRInfo
.GetNumRule() ||
1158 rNextInfo
.GetDepth() != rNRInfo
.GetDepth() ||
1159 rNextInfo
.IsNumbered() || rNextInfo
.IsRestart() )
1160 rHWrt
.ChangeParaToken( 0 );
1161 OutHTML_NumBulListEnd( rHWrt
, rNextInfo
);
1163 else if( rNextInfo
.GetNumRule() != 0 )
1164 rHWrt
.ChangeParaToken( 0 );
1169 if( rInfo
.ShouldOutputToken() )
1171 if( rHWrt
.bLFPossible
)
1172 rHWrt
.OutNewLine( TRUE
);
1174 // fuer BLOCKQUOTE, ADDRESS und DD wird ggf noch ein
1175 // Absatz-Token ausgegeben, wenn
1176 // - keine Styles geschrieben werden, und
1177 // - ein untere Abstand existiert
1178 if( rInfo
.bParaPossible
&& rInfo
.bOutPara
)
1179 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_parabreak
, FALSE
);
1181 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), rInfo
.aToken
.GetBuffer(),
1183 rHWrt
.bLFPossible
= !rInfo
.aToken
.Equals( OOO_STRING_SVTOOLS_HTML_dt
) &&
1184 !rInfo
.aToken
.Equals( OOO_STRING_SVTOOLS_HTML_dd
) &&
1185 !rInfo
.aToken
.Equals( OOO_STRING_SVTOOLS_HTML_li
);
1189 rHWrt
.DecIndentLevel();
1190 if( rHWrt
.bLFPossible
)
1192 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_division
, FALSE
);
1193 rHWrt
.bLFPossible
= TRUE
;
1196 // ggf. eine Aufzaehlung- oder Numerierungsliste beenden
1197 if( rInfo
.bInNumBulList
)
1199 rHWrt
.FillNextNumInfo();
1200 OutHTML_NumBulListEnd( rHWrt
, *rHWrt
.GetNextNumInfo() );
1213 HTMLSttEndPos( const SfxPoolItem
& rItem
, xub_StrLen nStt
, xub_StrLen nE
);
1216 const SfxPoolItem
*GetItem() const { return pItem
; }
1218 void SetStart( xub_StrLen nStt
) { nStart
= nStt
; }
1219 xub_StrLen
GetStart() const { return nStart
; }
1221 xub_StrLen
GetEnd() const { return nEnd
; }
1222 void SetEnd( xub_StrLen nE
) { nEnd
= nE
; }
1225 HTMLSttEndPos::HTMLSttEndPos( const SfxPoolItem
& rItem
, xub_StrLen nStt
,
1229 pItem( rItem
.Clone() )
1232 HTMLSttEndPos::~HTMLSttEndPos()
1237 typedef HTMLSttEndPos
*HTMLSttEndPosPtr
;
1238 SV_DECL_PTRARR( _HTMLEndLst
, HTMLSttEndPosPtr
, 5, 5 )
1240 enum HTMLOnOffState
{ HTML_NOT_SUPPORTED
, // nicht unterst. Attribut
1241 HTML_REAL_VALUE
, // Attribut mit Wert
1242 HTML_ON_VALUE
, // Attribut entspricht On-Tag
1243 HTML_OFF_VALUE
, // Attribut entspricht Off-Tag
1244 HTML_CHRFMT_VALUE
, // Attribut fuer Zeichenvorlage
1245 HTML_COLOR_VALUE
, // Attribut fuer Vordergrundfarbe
1246 HTML_STYLE_VALUE
, // Attribut muss als Style exp.
1247 HTML_DROPCAP_VALUE
, // DropCap-Attributs
1248 HTML_AUTOFMT_VALUE
}; // Attribute for automatic character styles
1253 _HTMLEndLst aStartLst
; // nach Anfangs-Psoitionen sortierte Liste
1254 _HTMLEndLst aEndLst
; // nach End-Psotionen sortierte Liste
1255 SvXub_StrLens aScriptChgLst
; // positions where script changes
1256 // 0 is not contained in this list,
1257 // but the text length
1258 SvUShorts aScriptLst
; // the script that is valif up to the position
1259 // contained in aScriptChgList at the same index
1261 SwDoc
*pDoc
; // das aktuelle Dokument
1262 SwDoc
* pTemplate
; // die HTML-Vorlage (oder 0)
1263 const Color
* pDfltColor
;// die Default-Vordergrund-Farbe
1264 SvStringsSortDtor
& rScriptTxtStyles
; //
1267 BOOL bOutStyles
: 1; // werden Styles exportiert
1270 // die Position eines Items in der Start-/Ende-Liste suchen
1271 USHORT
_FindStartPos( const HTMLSttEndPos
*pPos
) const;
1272 USHORT
_FindEndPos( const HTMLSttEndPos
*pPos
) const;
1274 // Eine SttEndPos in die Start- und Ende-Listen eintragen bzw. aus
1275 // ihnen loeschen, wobei die Ende-Position bekannt ist
1276 void _InsertItem( HTMLSttEndPos
*pPos
, USHORT nEndPos
);
1277 void _RemoveItem( USHORT nEndPos
);
1279 // die "Art" es Attributs ermitteln
1280 HTMLOnOffState
GetHTMLItemState( const SfxPoolItem
& rItem
);
1282 // Existiert ein bestimmtes On-Tag-Item
1283 BOOL
ExistsOnTagItem( USHORT nWhich
, xub_StrLen nPos
);
1285 // Existiert ein Item zum ausschalten eines Attributs, das genauso
1286 // exportiert wird wie das uebergebene Item im gleichen Bereich?
1287 BOOL
ExistsOffTagItem( USHORT nWhich
, xub_StrLen nStartPos
,
1288 xub_StrLen nEndPos
);
1291 // das Ende eines gesplitteten Items anpassen
1292 void FixSplittedItem( HTMLSttEndPos
*pPos
, USHORT nStartPos
,
1293 xub_StrLen nNewEnd
);
1295 // Ein Attribut in die Listen eintragen und ggf. aufteilen
1296 void InsertItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1299 // Ein bereits vorhandenes Attribut aufteilen
1300 void SplitItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1303 // Insert without taking care of script
1304 void InsertNoScript( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1305 xub_StrLen nEnd
, SwHTMLFmtInfos
& rFmtInfos
,
1306 BOOL bParaAttrs
=FALSE
);
1308 const SwHTMLFmtInfo
*GetFmtInfo( const SwFmt
& rFmt
,
1309 SwHTMLFmtInfos
& rFmtInfos
);
1313 HTMLEndPosLst( SwDoc
*pDoc
, SwDoc
* pTemplate
, const Color
* pDfltColor
,
1314 BOOL bOutStyles
, ULONG nHTMLMode
,
1315 const String
& rText
, SvStringsSortDtor
& rStyles
);
1318 // Ein Attribut einfuegen
1319 void Insert( const SfxPoolItem
& rItem
, xub_StrLen nStart
, xub_StrLen nEnd
,
1320 SwHTMLFmtInfos
& rFmtInfos
, BOOL bParaAttrs
=FALSE
);
1321 void Insert( const SfxItemSet
& rItemSet
, xub_StrLen nStart
, xub_StrLen nEnd
,
1322 SwHTMLFmtInfos
& rFmtInfos
, BOOL bDeep
,
1323 BOOL bParaAttrs
=FALSE
);
1324 void Insert( const SwDrawFrmFmt
& rFmt
, xub_StrLen nPos
,
1325 SwHTMLFmtInfos
& rFmtInfos
);
1327 sal_uInt16
GetScriptAtPos( xub_StrLen nPos
,
1328 sal_uInt16 nWeak
=CSS1_OUTMODE_ANY_SCRIPT
);
1330 void OutStartAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
1331 HTMLOutContext
*pContext
= 0 );
1332 void OutEndAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
1333 HTMLOutContext
*pContext
= 0 );
1335 USHORT
Count() const { return aEndLst
.Count(); }
1337 BOOL
IsHTMLMode( ULONG nMode
) const { return (nHTMLMode
& nMode
) != 0; }
1341 USHORT
HTMLEndPosLst::_FindStartPos( const HTMLSttEndPos
*pPos
) const
1344 for( i
= 0; i
< aStartLst
.Count() && aStartLst
[i
] != pPos
; i
++ )
1347 ASSERT( i
!= aStartLst
.Count(), "Item nicht in Start-Liste gefunden!" );
1349 return i
==aStartLst
.Count() ? USHRT_MAX
: i
;
1352 USHORT
HTMLEndPosLst::_FindEndPos( const HTMLSttEndPos
*pPos
) const
1356 for( i
= 0; i
< aEndLst
.Count() && aEndLst
[i
] != pPos
; i
++ )
1359 ASSERT( i
!= aEndLst
.Count(), "Item nicht in Ende-Liste gefunden" );
1361 return i
==aEndLst
.Count() ? USHRT_MAX
: i
;
1365 void HTMLEndPosLst::_InsertItem( HTMLSttEndPos
*pPos
, USHORT nEndPos
)
1367 // In der Start-Liste das Attribut hinter allen vorher und an
1368 // der gleichen Position gestarteten Attributen einfuegen
1369 xub_StrLen nStart
= pPos
->GetStart();
1372 for( i
= 0; i
< aStartLst
.Count() &&
1373 aStartLst
[i
]->GetStart() <= nStart
; i
++ )
1375 aStartLst
.Insert( pPos
, i
);
1377 // die Position in der Ende-Liste wurde uebergeben
1378 aEndLst
.Insert( pPos
, nEndPos
);
1381 void HTMLEndPosLst::_RemoveItem( USHORT nEndPos
)
1383 HTMLSttEndPos
*pPos
= aEndLst
[nEndPos
];
1385 // jetzt Suchen wir es in der Start-Liste
1386 USHORT nStartPos
= _FindStartPos( pPos
);
1387 if( nStartPos
!= USHRT_MAX
)
1388 aStartLst
.Remove( nStartPos
, 1 );
1390 aEndLst
.Remove( nEndPos
, 1 );
1395 HTMLOnOffState
HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem
& rItem
)
1397 HTMLOnOffState eState
= HTML_NOT_SUPPORTED
;
1398 switch( rItem
.Which() )
1400 case RES_CHRATR_POSTURE
:
1401 case RES_CHRATR_CJK_POSTURE
:
1402 case RES_CHRATR_CTL_POSTURE
:
1403 switch( ((const SvxPostureItem
&)rItem
).GetPosture() )
1406 eState
= HTML_ON_VALUE
;
1409 eState
= HTML_OFF_VALUE
;
1412 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1413 eState
= HTML_STYLE_VALUE
;
1418 case RES_CHRATR_CROSSEDOUT
:
1419 switch( ((const SvxCrossedOutItem
&)rItem
).GetStrikeout() )
1421 case STRIKEOUT_SINGLE
:
1422 case STRIKEOUT_DOUBLE
:
1423 eState
= HTML_ON_VALUE
;
1425 case STRIKEOUT_NONE
:
1426 eState
= HTML_OFF_VALUE
;
1433 case RES_CHRATR_ESCAPEMENT
:
1434 switch( (const SvxEscapement
)
1435 ((const SvxEscapementItem
&)rItem
).GetEnumValue() )
1437 case SVX_ESCAPEMENT_SUPERSCRIPT
:
1438 case SVX_ESCAPEMENT_SUBSCRIPT
:
1439 eState
= HTML_ON_VALUE
;
1441 case SVX_ESCAPEMENT_OFF
:
1442 eState
= HTML_OFF_VALUE
;
1449 case RES_CHRATR_UNDERLINE
:
1450 switch( ((const SvxUnderlineItem
&)rItem
).GetLineStyle() )
1452 case UNDERLINE_SINGLE
:
1453 eState
= HTML_ON_VALUE
;
1455 case UNDERLINE_NONE
:
1456 eState
= HTML_OFF_VALUE
;
1459 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1460 eState
= HTML_STYLE_VALUE
;
1465 case RES_CHRATR_OVERLINE
:
1466 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1467 eState
= HTML_STYLE_VALUE
;
1470 case RES_CHRATR_WEIGHT
:
1471 case RES_CHRATR_CJK_WEIGHT
:
1472 case RES_CHRATR_CTL_WEIGHT
:
1473 switch( ((const SvxWeightItem
&)rItem
).GetWeight() )
1476 eState
= HTML_ON_VALUE
;
1479 eState
= HTML_OFF_VALUE
;
1482 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1483 eState
= HTML_STYLE_VALUE
;
1488 case RES_CHRATR_BLINK
:
1489 if( IsHTMLMode(HTMLMODE_BLINK
) )
1490 eState
= ((const SvxBlinkItem
&)rItem
).GetValue() ? HTML_ON_VALUE
1494 case RES_CHRATR_COLOR
:
1495 eState
= HTML_COLOR_VALUE
;
1498 case RES_CHRATR_FONT
:
1499 case RES_CHRATR_FONTSIZE
:
1500 case RES_CHRATR_LANGUAGE
:
1501 case RES_CHRATR_CJK_FONT
:
1502 case RES_CHRATR_CJK_FONTSIZE
:
1503 case RES_CHRATR_CJK_LANGUAGE
:
1504 case RES_CHRATR_CTL_FONT
:
1505 case RES_CHRATR_CTL_FONTSIZE
:
1506 case RES_CHRATR_CTL_LANGUAGE
:
1507 case RES_TXTATR_INETFMT
:
1508 eState
= HTML_REAL_VALUE
;
1511 case RES_TXTATR_CHARFMT
:
1512 eState
= HTML_CHRFMT_VALUE
;
1515 case RES_TXTATR_AUTOFMT
:
1516 eState
= HTML_AUTOFMT_VALUE
;
1519 case RES_CHRATR_CASEMAP
:
1520 if( IsHTMLMode(HTMLMODE_SMALL_CAPS
) )
1521 eState
= HTML_STYLE_VALUE
;
1523 case RES_CHRATR_KERNING
:
1524 if( IsHTMLMode(HTMLMODE_FULL_STYLES
) )
1525 eState
= HTML_STYLE_VALUE
;
1528 case RES_CHRATR_BACKGROUND
:
1529 if( IsHTMLMode(HTMLMODE_SOME_STYLES
) )
1530 eState
= HTML_STYLE_VALUE
;
1533 case RES_PARATR_DROP
:
1534 eState
= HTML_DROPCAP_VALUE
;
1538 // eState = HTML_NOT_SUPPORTED;
1545 BOOL
HTMLEndPosLst::ExistsOnTagItem( USHORT nWhich
, xub_StrLen nPos
)
1547 for( USHORT i
=0; i
<aStartLst
.Count(); i
++ )
1549 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1551 if( pTest
->GetStart() > nPos
)
1553 // dieses uns alle folgenden Attribute beginnen spaeter
1556 else if( pTest
->GetEnd() > nPos
)
1558 // das Attribut beginnt vor oder an der aktuellen Position
1559 // und endet hinter ihr
1560 const SfxPoolItem
*pItem
= pTest
->GetItem();
1561 if( pItem
->Which() == nWhich
&&
1562 HTML_ON_VALUE
== GetHTMLItemState(*pItem
) )
1564 // ein On-Tag-Attibut wurde gefunden
1573 BOOL
HTMLEndPosLst::ExistsOffTagItem( USHORT nWhich
, xub_StrLen nStartPos
,
1574 xub_StrLen nEndPos
)
1576 if( nWhich
!= RES_CHRATR_CROSSEDOUT
&&
1577 nWhich
!= RES_CHRATR_UNDERLINE
&&
1578 nWhich
!= RES_CHRATR_BLINK
)
1583 for( USHORT i
=0; i
<aStartLst
.Count(); i
++ )
1585 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1587 if( pTest
->GetStart() > nStartPos
)
1589 // dieses uns alle folgenden Attribute beginnen spaeter
1592 else if( pTest
->GetStart()==nStartPos
&&
1593 pTest
->GetEnd()==nEndPos
)
1595 // das Attribut beginnt vor oder an der aktuellen Position
1596 // und endet hinter ihr
1597 const SfxPoolItem
*pItem
= pTest
->GetItem();
1598 USHORT nTstWhich
= pItem
->Which() ;
1599 if( (nTstWhich
== RES_CHRATR_CROSSEDOUT
||
1600 nTstWhich
== RES_CHRATR_UNDERLINE
||
1601 nTstWhich
== RES_CHRATR_BLINK
) &&
1602 HTML_OFF_VALUE
== GetHTMLItemState(*pItem
) )
1604 // Ein Off-Tag-Attibut wurde gefunden, das genauso
1605 // exportiert wird, wie das aktuelle Item
1614 void HTMLEndPosLst::FixSplittedItem( HTMLSttEndPos
*pPos
, xub_StrLen nNewEnd
,
1617 // die End-Position entsprechend fixen
1618 pPos
->SetEnd( nNewEnd
);
1620 // das Item aus der End-Liste entfernen
1621 USHORT nEndPos
= _FindEndPos( pPos
);
1622 if( nEndPos
!= USHRT_MAX
)
1623 aEndLst
.Remove( nEndPos
, 1 );
1625 // es wird von nun an als letztes an der entsprechenden Position
1627 for( nEndPos
=0; nEndPos
< aEndLst
.Count() &&
1628 aEndLst
[nEndPos
]->GetEnd() <= nNewEnd
; nEndPos
++ )
1630 aEndLst
.Insert( pPos
, nEndPos
);
1632 // jetzt noch die spaeter gestarteten Attribute anpassen
1633 for( USHORT i
=nStartPos
+1; i
<aStartLst
.Count(); i
++ )
1635 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1636 xub_StrLen nTestEnd
= pTest
->GetEnd();
1637 if( pTest
->GetStart() >= nNewEnd
)
1639 // das Test-Attribut und alle folgenden beginnen, nachdem das
1640 // gesplittete Attribut endet
1643 else if( nTestEnd
> nNewEnd
)
1645 // das Test-Attribut beginnt, bevor das gesplittete Attribut
1646 // endet und endet danach, muss also auch gesplittet werden
1648 // das neue Ende setzen
1649 pTest
->SetEnd( nNewEnd
);
1651 // das Attribut aus der End-Liste entfernen
1652 USHORT nEPos
= _FindEndPos( pTest
);
1653 if( nEPos
!= USHRT_MAX
)
1654 aEndLst
.Remove( nEPos
, 1 );
1656 // es endet jetzt als erstes Attribut an der entsprechenden
1657 // Position. Diese Position in der Ende-Liste kennen wir schon.
1658 aEndLst
.Insert(pTest
, nEndPos
);
1660 // den "Rest" des Attributs neu einfuegen
1661 InsertItem( *pTest
->GetItem(), nNewEnd
, nTestEnd
);
1667 void HTMLEndPosLst::InsertItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1671 for( i
= 0; i
< aEndLst
.Count(); i
++ )
1673 HTMLSttEndPos
*pTest
= aEndLst
[i
];
1674 xub_StrLen nTestEnd
= pTest
->GetEnd();
1675 if( nTestEnd
<= nStart
)
1677 // das Test-Attribut endet, bevor das neue beginnt
1680 else if( nTestEnd
< nEnd
)
1682 // das Test-Attribut endet, bevor das neue endet. Das
1683 // neue Attribut muss deshalb aufgesplittet werden
1684 _InsertItem( new HTMLSttEndPos( rItem
, nStart
, nTestEnd
), i
);
1689 // das Test-Attribut (und alle folgenden) endet, bevor das neue
1695 // ein Attribut muss noch eingefuegt werden
1696 _InsertItem( new HTMLSttEndPos( rItem
, nStart
, nEnd
), i
);
1701 void HTMLEndPosLst::SplitItem( const SfxPoolItem
& rItem
, xub_StrLen nStart
,
1704 USHORT nWhich
= rItem
.Which();
1706 // erstmal muessen wir die alten Items anhand der Startliste suchen
1707 // und die neuen Item-Bereiche festlegen
1709 for( USHORT i
=0; i
<aStartLst
.Count(); i
++ )
1711 HTMLSttEndPos
*pTest
= aStartLst
[i
];
1712 xub_StrLen nTestStart
= pTest
->GetStart();
1713 xub_StrLen nTestEnd
= pTest
->GetEnd();
1715 if( nTestStart
>= nEnd
)
1717 // dieses und alle nachfolgenden Attribute beginnen spaeter
1720 else if( nTestEnd
> nStart
)
1722 // das Test Attribut endet im zu loeschenenden Bereich
1723 const SfxPoolItem
*pItem
= pTest
->GetItem();
1725 // nur entsprechende On-Tag Attribute muessen beruecksichtigt
1727 if( pItem
->Which() == nWhich
&&
1728 HTML_ON_VALUE
== GetHTMLItemState( *pItem
) )
1730 BOOL bDelete
= TRUE
;
1732 if( nTestStart
< nStart
)
1734 // der Start des neuen Attribut entspricht
1735 // dem neuen Ende des Attribts
1736 FixSplittedItem( pTest
, nStart
, i
);
1741 // das Test-Item beginnt erst hinter dem neuen
1742 // Ende des Attribts und kann deshalb komplett
1744 aStartLst
.Remove( i
, 1 );
1747 USHORT nEndPos
= _FindEndPos( pTest
);
1748 if( nEndPos
!= USHRT_MAX
)
1749 aEndLst
.Remove( nEndPos
, 1 );
1752 // ggf den zweiten Teil des gesplitteten Attribts einfuegen
1753 if( nTestEnd
> nEnd
)
1755 InsertItem( *pTest
->GetItem(), nEnd
, nTestEnd
);
1765 const SwHTMLFmtInfo
*HTMLEndPosLst::GetFmtInfo( const SwFmt
& rFmt
,
1766 SwHTMLFmtInfos
& rFmtInfos
)
1768 const SwHTMLFmtInfo
*pFmtInfo
;
1769 SwHTMLFmtInfo
aFmtInfo( &rFmt
);
1771 if( rFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
1773 pFmtInfo
= rFmtInfos
[nPos
];
1777 pFmtInfo
= new SwHTMLFmtInfo( &rFmt
, pDoc
, pTemplate
,
1779 rFmtInfos
.C40_PTR_INSERT( SwHTMLFmtInfo
, pFmtInfo
);
1780 String
aName( rFmt
.GetName() );
1781 if( rScriptTxtStyles
.Seek_Entry( &aName
) )
1782 ((SwHTMLFmtInfo
*)pFmtInfo
)->bScriptDependent
= sal_True
;
1788 HTMLEndPosLst::HTMLEndPosLst( SwDoc
*pD
, SwDoc
* pTempl
,
1789 const Color
* pDfltCol
, BOOL bStyles
,
1790 ULONG nMode
, const String
& rText
,
1791 SvStringsSortDtor
& rStyles
):
1793 pTemplate( pTempl
),
1794 pDfltColor( pDfltCol
),
1795 rScriptTxtStyles( rStyles
),
1797 bOutStyles( bStyles
)
1799 xub_StrLen nEndPos
= rText
.Len();
1800 xub_StrLen nPos
= 0;
1801 while( nPos
< nEndPos
)
1803 sal_uInt16 nScript
= pBreakIt
->GetBreakIter()->getScriptType( rText
, nPos
);
1804 nPos
= (xub_StrLen
)pBreakIt
->GetBreakIter()->endOfScript( rText
, nPos
, nScript
);
1805 aScriptChgLst
.Insert( nPos
, aScriptChgLst
.Count() );
1806 aScriptLst
.Insert( nScript
, aScriptLst
.Count() );
1810 HTMLEndPosLst::~HTMLEndPosLst()
1812 ASSERT( !aStartLst
.Count(), "Start-Liste im Destruktor nicht leer" );
1813 ASSERT( !aEndLst
.Count(), "End-Liste im Destruktor nicht leer" );
1818 void HTMLEndPosLst::InsertNoScript( const SfxPoolItem
& rItem
,
1819 xub_StrLen nStart
, xub_StrLen nEnd
,
1820 SwHTMLFmtInfos
& rFmtInfos
, BOOL bParaAttrs
)
1822 // kein Bereich ?? dann nicht aufnehmen, wird nie wirksam !!
1823 if( nStart
!= nEnd
)
1825 BOOL bSet
= FALSE
, bSplit
= FALSE
;
1826 switch( GetHTMLItemState(rItem
) )
1829 // das Attribut wird ausgegeben, wenn es nicht sowieso
1831 if( !ExistsOnTagItem( rItem
.Which(), nStart
) )
1835 case HTML_OFF_VALUE
:
1836 // wenn das entsprechne Attribut an ist, wird es gesplittet,
1837 // Zusaetlich wird es aber als Style ausgegeben, wenn es nicht
1838 // am ganzen Absatz gesetzt ist, weil es dann ja schon mit dem
1839 // ABsatz-Tag ausgegeben wurde.
1840 if( ExistsOnTagItem( rItem
.Which(), nStart
) )
1842 bSet
= bOutStyles
&& !bParaAttrs
&&
1843 !ExistsOffTagItem( rItem
.Which(), nStart
, nEnd
);
1846 case HTML_REAL_VALUE
:
1847 // das Attribut kann immer ausgegeben werden
1851 case HTML_STYLE_VALUE
:
1852 // Das Attribut kann nur als CSS1 ausgegeben werden. Wenn
1853 // es am Absatz gesetzt ist, wurde es schon mit dem
1854 // Absatz-Tag ausgegeben. Einzige Ausnahme ist das
1855 // Zeichen-Hintergrund-Attribut. Es muss immer wie ein
1856 // Hint behandelt werden.
1857 bSet
= bOutStyles
&&
1859 || rItem
.Which()==RES_CHRATR_BACKGROUND
1860 || rItem
.Which()==RES_CHRATR_OVERLINE
);
1863 case HTML_CHRFMT_VALUE
:
1865 ASSERT( RES_TXTATR_CHARFMT
== rItem
.Which(),
1866 "Doch keine Zeichen-Vorlage" );
1867 const SwFmtCharFmt
& rChrFmt
= (const SwFmtCharFmt
&)rItem
;
1868 const SwCharFmt
* pFmt
= rChrFmt
.GetCharFmt();
1870 const SwHTMLFmtInfo
*pFmtInfo
= GetFmtInfo( *pFmt
, rFmtInfos
);
1871 if( pFmtInfo
->aToken
.Len() )
1873 // das Zeichenvorlagen-Tag muss vor den harten
1874 // Attributen ausgegeben werden
1875 InsertItem( rItem
, nStart
, nEnd
);
1877 if( pFmtInfo
->pItemSet
)
1879 Insert( *pFmtInfo
->pItemSet
, nStart
, nEnd
,
1880 rFmtInfos
, TRUE
, bParaAttrs
);
1885 case HTML_AUTOFMT_VALUE
:
1887 const SwFmtAutoFmt
& rAutoFmt
= (const SwFmtAutoFmt
&)rItem
;
1888 const boost::shared_ptr
<SfxItemSet
> pSet
= rAutoFmt
.GetStyleHandle();
1890 Insert( *pSet
.get(), nStart
, nEnd
, rFmtInfos
, TRUE
, bParaAttrs
);
1894 case HTML_COLOR_VALUE
:
1895 // Eine Vordergrund-Farbe als Absatz-Attribut wird nur
1896 // exportiert, wenn sie nicht der Default-Farbe entspricht.
1898 ASSERT( RES_CHRATR_COLOR
== rItem
.Which(),
1899 "Doch keine Vordergrund-Farbe" );
1900 Color
aColor( ((const SvxColorItem
&)rItem
).GetValue() );
1901 if( COL_AUTO
== aColor
.GetColor() )
1902 aColor
.SetColor( COL_BLACK
);
1903 bSet
= !bParaAttrs
|| !pDfltColor
||
1904 !pDfltColor
->IsRGBEqual( aColor
);
1908 case HTML_DROPCAP_VALUE
:
1910 ASSERT( RES_PARATR_DROP
== rItem
.Which(),
1911 "Doch kein Drop-Cap" );
1912 const SwFmtDrop
& rDrop
= (const SwFmtDrop
&)rItem
;
1913 nEnd
= nStart
+ rDrop
.GetChars();
1916 // Zumindest die Attribute der Zeichenvorlage uebernehmen
1917 const SwCharFmt
*pCharFmt
= rDrop
.GetCharFmt();
1920 Insert( pCharFmt
->GetAttrSet(), nStart
, nEnd
,
1921 rFmtInfos
, TRUE
, bParaAttrs
);
1935 InsertItem( rItem
, nStart
, nEnd
);
1937 SplitItem( rItem
, nStart
, nEnd
);
1941 void HTMLEndPosLst::Insert( const SfxPoolItem
& rItem
,
1942 xub_StrLen nStart
, xub_StrLen nEnd
,
1943 SwHTMLFmtInfos
& rFmtInfos
, BOOL bParaAttrs
)
1945 sal_Bool bDependsOnScript
= sal_False
, bDependsOnAnyScript
= sal_False
;
1946 sal_uInt16 nScript
= i18n::ScriptType::LATIN
;
1947 switch( rItem
.Which() )
1949 case RES_CHRATR_FONT
:
1950 case RES_CHRATR_FONTSIZE
:
1951 case RES_CHRATR_LANGUAGE
:
1952 case RES_CHRATR_POSTURE
:
1953 case RES_CHRATR_WEIGHT
:
1954 bDependsOnScript
= sal_True
;
1955 nScript
= i18n::ScriptType::LATIN
;
1958 case RES_CHRATR_CJK_FONT
:
1959 case RES_CHRATR_CJK_FONTSIZE
:
1960 case RES_CHRATR_CJK_LANGUAGE
:
1961 case RES_CHRATR_CJK_POSTURE
:
1962 case RES_CHRATR_CJK_WEIGHT
:
1963 bDependsOnScript
= sal_True
;
1964 nScript
= i18n::ScriptType::ASIAN
;
1967 case RES_CHRATR_CTL_FONT
:
1968 case RES_CHRATR_CTL_FONTSIZE
:
1969 case RES_CHRATR_CTL_LANGUAGE
:
1970 case RES_CHRATR_CTL_POSTURE
:
1971 case RES_CHRATR_CTL_WEIGHT
:
1972 bDependsOnScript
= sal_True
;
1973 nScript
= i18n::ScriptType::COMPLEX
;
1975 case RES_TXTATR_CHARFMT
:
1977 const SwFmtCharFmt
& rChrFmt
= (const SwFmtCharFmt
&)rItem
;
1978 const SwCharFmt
* pFmt
= rChrFmt
.GetCharFmt();
1979 const SwHTMLFmtInfo
*pFmtInfo
= GetFmtInfo( *pFmt
, rFmtInfos
);
1980 if( pFmtInfo
->bScriptDependent
)
1982 bDependsOnScript
= sal_True
;
1983 bDependsOnAnyScript
= sal_True
;
1987 case RES_TXTATR_INETFMT
:
1989 if( GetFmtInfo( *pDoc
->GetCharFmtFromPool(
1990 RES_POOLCHR_INET_NORMAL
), rFmtInfos
)->bScriptDependent
||
1991 GetFmtInfo( *pDoc
->GetCharFmtFromPool(
1992 RES_POOLCHR_INET_VISIT
), rFmtInfos
)->bScriptDependent
)
1994 bDependsOnScript
= sal_True
;
1995 bDependsOnAnyScript
= sal_True
;
2001 if( bDependsOnScript
)
2003 sal_uInt16 nScriptChgs
= aScriptChgLst
.Count();
2004 xub_StrLen nPos
= nStart
;
2005 for( sal_uInt16 i
=0; i
< nScriptChgs
; i
++ )
2007 xub_StrLen nChgPos
= aScriptChgLst
[i
];
2008 if( nPos
>= nChgPos
)
2010 // the hint starts behind or at the next script change,
2011 // so we may continue with this position.
2014 if( nEnd
<= nChgPos
)
2016 // the (rest of) the hint ends before or at the next script
2017 // change, so we can insert it, but only if it belongs
2018 // to the current script.
2019 if( bDependsOnAnyScript
|| nScript
== aScriptLst
[i
] )
2020 InsertNoScript( rItem
, nPos
, nEnd
, rFmtInfos
,
2025 // the hint starts before the next script change and ends behind
2026 // it, so we can insert a hint upto the next script change and
2027 // continue with the rest of the hint.
2028 if( bDependsOnAnyScript
|| nScript
== aScriptLst
[i
] )
2029 InsertNoScript( rItem
, nPos
, nChgPos
, rFmtInfos
, bParaAttrs
);
2035 InsertNoScript( rItem
, nStart
, nEnd
, rFmtInfos
, bParaAttrs
);
2039 void HTMLEndPosLst::Insert( const SfxItemSet
& rItemSet
,
2040 xub_StrLen nStart
, xub_StrLen nEnd
,
2041 SwHTMLFmtInfos
& rFmtInfos
,
2042 BOOL bDeep
, BOOL bParaAttrs
)
2044 SfxWhichIter
aIter( rItemSet
);
2046 USHORT nWhich
= aIter
.FirstWhich();
2049 const SfxPoolItem
*pItem
;
2050 if( SFX_ITEM_SET
== rItemSet
.GetItemState( nWhich
, bDeep
, &pItem
) )
2052 Insert( *pItem
, nStart
, nEnd
, rFmtInfos
, bParaAttrs
);
2055 nWhich
= aIter
.NextWhich();
2059 void HTMLEndPosLst::Insert( const SwDrawFrmFmt
& rFmt
, xub_StrLen nPos
,
2060 SwHTMLFmtInfos
& rFmtInfos
)
2062 // der Type-Cast ist nur noetig, um nicht seinetwegen
2063 // svdrwobt.hxx zu includem
2064 const SdrObject
* pTextObj
=
2065 (const SdrObject
*)SwHTMLWriter::GetMarqueeTextObj( rFmt
);
2069 // die Edit-Engine-Attribute des Objekts als SW-Attribute holen
2070 // und als Hints einsortieren. Wegen der Menge der Hints werden
2071 // Styles hierbei nicht beruecksichtigt!
2072 const SfxItemSet
& rFmtItemSet
= rFmt
.GetAttrSet();
2073 SfxItemSet
aItemSet( *rFmtItemSet
.GetPool(), RES_CHRATR_BEGIN
,
2075 SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet
, pTextObj
, TRUE
);
2076 BOOL bOutStylesOld
= bOutStyles
;
2078 Insert( aItemSet
, nPos
, nPos
+1, rFmtInfos
, FALSE
, FALSE
);
2079 bOutStyles
= bOutStylesOld
;
2083 sal_uInt16
HTMLEndPosLst::GetScriptAtPos( xub_StrLen nPos
,
2086 sal_uInt16 nRet
= CSS1_OUTMODE_ANY_SCRIPT
;
2088 sal_uInt16 nScriptChgs
= aScriptChgLst
.Count();
2090 while( i
< nScriptChgs
&& nPos
>= aScriptChgLst
[i
] )
2092 ASSERT( i
< nScriptChgs
, "script list is to short" );
2093 if( i
< nScriptChgs
)
2095 if( i18n::ScriptType::WEAK
== aScriptLst
[i
] )
2098 nRet
= SwHTMLWriter::GetCSS1ScriptForScriptType( aScriptLst
[i
] );
2104 void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
2105 HTMLOutContext
*pContext
)
2107 rHWrt
.bTagOn
= TRUE
;
2109 // die Attribute in der Start-Liste sind aufsteigend sortiert
2110 for( USHORT i
=0; i
< aStartLst
.Count(); i
++ )
2112 HTMLSttEndPos
*pPos
= aStartLst
[i
];
2113 xub_StrLen nStart
= pPos
->GetStart();
2116 // dieses und alle folgenden Attribute werden erst noch geoeffnet
2119 else if( nStart
== nPos
)
2121 // das Attribut ausgeben
2122 sal_uInt16 nCSS1Script
= rHWrt
.nCSS1Script
;
2123 sal_uInt16 nWhich
= pPos
->GetItem()->Which();
2124 if( RES_TXTATR_CHARFMT
== nWhich
||
2125 RES_TXTATR_INETFMT
== nWhich
||
2126 RES_PARATR_DROP
== nWhich
)
2128 rHWrt
.nCSS1Script
= GetScriptAtPos( nPos
, nCSS1Script
);
2132 HTMLOutFuncs::FlushToAscii( rHWrt
.Strm(), *pContext
);
2133 pContext
= 0; // one time ony
2135 Out( aHTMLAttrFnTab
, *pPos
->GetItem(), rHWrt
);
2136 rHWrt
.nCSS1Script
= nCSS1Script
;
2141 void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter
& rHWrt
, xub_StrLen nPos
,
2142 HTMLOutContext
*pContext
)
2144 rHWrt
.bTagOn
= FALSE
;
2146 // die Attribute in der End-Liste sind aufsteigend sortiert
2148 while( i
< aEndLst
.Count() )
2150 HTMLSttEndPos
*pPos
= aEndLst
[i
];
2151 xub_StrLen nEnd
= pPos
->GetEnd();
2153 if( STRING_MAXLEN
==nPos
|| nEnd
== nPos
)
2157 HTMLOutFuncs::FlushToAscii( rHWrt
.Strm(), *pContext
);
2158 pContext
= 0; // one time ony
2160 Out( aHTMLAttrFnTab
, *pPos
->GetItem(), rHWrt
);
2163 else if( nEnd
> nPos
)
2165 // dieses und alle folgenden Attribute werden erst spaeter beendet
2170 // Das Attribut wird vor der aktuellen Position beendet. Das
2171 // darf nicht sein, aber wie koennen trotzdem damit umgehen
2172 ASSERT( nEnd
>= nPos
,
2173 "Das Attribut sollte schon laengst beendet sein" );
2180 /* Ausgabe der Nodes */
2181 Writer
& OutHTML_SwTxtNode( Writer
& rWrt
, const SwCntntNode
& rNode
)
2183 SwTxtNode
* pNd
= &((SwTxtNode
&)rNode
);
2184 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2186 const String
& rStr
= pNd
->GetTxt();
2187 xub_StrLen nEnde
= rStr
.Len();
2189 // Besonderheit: leere Node und HR-Vorlage (horizontaler Strich)
2190 // nur ein <HR> ausgeben
2191 USHORT nPoolId
= pNd
->GetAnyFmtColl().GetPoolFmtId();
2193 if( !nEnde
&& (RES_POOLCOLL_HTML_HR
==nPoolId
||
2194 pNd
->GetAnyFmtColl().GetName().EqualsAscii( OOO_STRING_SVTOOLS_HTML_horzrule
) ) )
2196 // dann die absatz-gebundenen Grafiken/OLE-Objekte im Absatz
2197 // MIB 8.7.97: Ein <PRE> spannen wir um die Linie auf. Dann stimmen
2198 // zwar die Abstaende nicht, aber sonst bekommen wir einen leeren
2199 // Absatz hinter dem <HR> und das ist noch unschoener.
2200 rHTMLWrt
.ChangeParaToken( 0 );
2202 // Alle an dem Node verankerten Rahmen ausgeben
2203 rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(), 0, HTML_POS_ANY
);
2205 if( rHTMLWrt
.bLFPossible
)
2206 rHTMLWrt
.OutNewLine(); // Absatz-Tag in eine neue Zeile
2208 rHTMLWrt
.bLFPossible
= TRUE
;
2210 ByteString
sOut( '<' );
2211 sOut
+= OOO_STRING_SVTOOLS_HTML_horzrule
;
2213 const SfxItemSet
* pItemSet
= pNd
->GetpSwAttrSet();
2216 rWrt
.Strm() << sOut
.GetBuffer() << '>';
2219 const SfxPoolItem
* pItem
;
2220 if( SFX_ITEM_SET
== pItemSet
->GetItemState( RES_LR_SPACE
, FALSE
, &pItem
))
2222 sal_Int32 nLeft
= ((SvxLRSpaceItem
*)pItem
)->GetLeft();
2223 sal_Int32 nRight
= ((SvxLRSpaceItem
*)pItem
)->GetRight();
2224 if( nLeft
|| nRight
)
2226 const SwFrmFmt
& rPgFmt
=
2227 rHTMLWrt
.pDoc
->GetPageDescFromPool
2228 ( RES_POOLPAGE_HTML
, false )->GetMaster();
2229 const SwFmtFrmSize
& rSz
= rPgFmt
.GetFrmSize();
2230 const SvxLRSpaceItem
& rLR
= rPgFmt
.GetLRSpace();
2231 const SwFmtCol
& rCol
= rPgFmt
.GetCol();
2233 long nPageWidth
= rSz
.GetWidth() - rLR
.GetLeft() - rLR
.GetRight();
2235 if( 1 < rCol
.GetNumCols() )
2236 nPageWidth
/= rCol
.GetNumCols();
2238 const SwTableNode
* pTblNd
= pNd
->FindTableNode();
2241 const SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox(
2242 pNd
->StartOfSectionIndex() );
2244 nPageWidth
= pBox
->GetFrmFmt()->GetFrmSize().GetWidth();
2247 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_width
) += '=';
2248 rWrt
.Strm() << sOut
.GetBuffer();
2249 rWrt
.OutULong( rHTMLWrt
.ToPixel(nPageWidth
-nLeft
-nRight
) );
2251 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_align
) += '=';
2253 sOut
+= OOO_STRING_SVTOOLS_HTML_AL_left
;
2255 sOut
+= OOO_STRING_SVTOOLS_HTML_AL_right
;
2257 sOut
+= OOO_STRING_SVTOOLS_HTML_AL_center
;
2260 rWrt
.Strm() << sOut
.GetBuffer();
2261 if( SFX_ITEM_SET
== pItemSet
->GetItemState( RES_BOX
, FALSE
, &pItem
))
2263 const SvxBoxItem
* pBoxItem
= (const SvxBoxItem
*)pItem
;
2264 const SvxBorderLine
* pBorderLine
= pBoxItem
->GetBottom();
2267 USHORT nWidth
= pBorderLine
->GetOutWidth() +
2268 pBorderLine
->GetInWidth() +
2269 pBorderLine
->GetDistance();
2270 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_size
) += '=';
2271 rWrt
.Strm() << sOut
.GetBuffer();
2272 rWrt
.OutULong( rHTMLWrt
.ToPixel(nWidth
) );
2274 const Color
& rBorderColor
= pBorderLine
->GetColor();
2275 if( !rBorderColor
.IsRGBEqual( Color(COL_GRAY
) ) )
2277 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_color
) += '=';
2278 rWrt
.Strm() << sOut
.GetBuffer();
2279 HTMLOutFuncs::Out_Color( rWrt
.Strm(), rBorderColor
,
2280 rHTMLWrt
.eDestEnc
);
2283 if( !pBorderLine
->GetInWidth() )
2285 (sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_noshade
;
2286 rWrt
.Strm() << sOut
.GetBuffer();
2294 // Die leeren Nodes mit 2pt Font-Hoehe und der Stand-Vorlage, die
2295 // vor Tabellen und Bereichen eingefuegt werden, nicht exportieren,
2296 // Bookmarks oder absatzgebundene Grafiken aber schon.
2297 // MIB 21.7.97: Ausserdem auch keine leeren Tabellen-Zellen exportieren.
2298 if( !nEnde
&& (nPoolId
== RES_POOLCOLL_STANDARD
||
2299 nPoolId
== RES_POOLCOLL_TABLE
||
2300 nPoolId
== RES_POOLCOLL_TABLE_HDLN
) )
2302 // Der aktuelle Node ist leer und enthaelt Standard-Vorlage ...
2303 const SfxPoolItem
* pItem
;
2304 const SfxItemSet
*pItemSet
= pNd
->GetpSwAttrSet();
2305 if( pItemSet
&& pItemSet
->Count() &&
2306 SFX_ITEM_SET
== pItemSet
->GetItemState( RES_CHRATR_FONTSIZE
, FALSE
, &pItem
) &&
2307 40 == ((const SvxFontHeightItem
*)pItem
)->GetHeight() )
2309 // ... ausserdem ist die 2pt Schrift eingestellt ...
2310 ULONG nNdPos
= rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex();
2311 const SwNode
*pNextNd
= rWrt
.pDoc
->GetNodes()[nNdPos
+1];
2312 const SwNode
*pPrevNd
= rWrt
.pDoc
->GetNodes()[nNdPos
-1];
2313 BOOL bStdColl
= nPoolId
== RES_POOLCOLL_STANDARD
;
2314 if( ( bStdColl
&& (pNextNd
->IsTableNode() ||
2315 pNextNd
->IsSectionNode()) ) ||
2316 ( !bStdColl
&& pNextNd
->IsEndNode() &&
2317 pPrevNd
->IsStartNode() &&
2318 SwTableBoxStartNode
==
2319 pPrevNd
->GetStartNode()->GetStartNodeType() ) )
2321 // ... und er steht vor einer Tabelle ohne einem Bereich
2322 rHTMLWrt
.OutBookmarks();
2323 rHTMLWrt
.bLFPossible
= !rHTMLWrt
.nLastParaToken
;
2325 // Alle an dem Node verankerten Rahmen ausgeben
2326 rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(), 0, HTML_POS_ANY
);
2327 rHTMLWrt
.bLFPossible
= FALSE
;
2334 // PagePreaks uns PagDescs abfangen
2335 BOOL bPageBreakBehind
= FALSE
;
2336 if( rHTMLWrt
.bCfgFormFeed
&&
2337 !(rHTMLWrt
.bOutTable
|| rHTMLWrt
.bOutFlyFrame
) &&
2338 rHTMLWrt
.pStartNdIdx
->GetIndex() !=
2339 rHTMLWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() )
2341 BOOL bPageBreakBefore
= FALSE
;
2342 const SfxPoolItem
* pItem
;
2343 const SfxItemSet
* pItemSet
= pNd
->GetpSwAttrSet();
2348 pItemSet
->GetItemState( RES_PAGEDESC
, TRUE
, &pItem
) &&
2349 ((SwFmtPageDesc
*)pItem
)->GetPageDesc() )
2350 bPageBreakBefore
= TRUE
;
2351 else if( SFX_ITEM_SET
==
2352 pItemSet
->GetItemState( RES_BREAK
, TRUE
, &pItem
) )
2354 switch( ((SvxFmtBreakItem
*)pItem
)->GetBreak() )
2356 case SVX_BREAK_PAGE_BEFORE
:
2357 bPageBreakBefore
= TRUE
;
2359 case SVX_BREAK_PAGE_AFTER
:
2360 bPageBreakBehind
= TRUE
;
2362 case SVX_BREAK_PAGE_BOTH
:
2363 bPageBreakBefore
= TRUE
;
2364 bPageBreakBehind
= TRUE
;
2372 if( bPageBreakBefore
)
2373 rWrt
.Strm() << '\f';
2376 // eventuell eine Form oeffnen
2379 // An dem Node "verankerte" Seitenegebunde Rahmen ausgeben
2380 BOOL bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2381 0, HTML_POS_PREFIX
);
2382 // An dem Node verankerte Rahmen ausgeben, die vor dem
2383 // Absatz-Tag geschrieben werden sollen.
2385 bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2386 0, HTML_POS_BEFORE
);
2388 if( rHTMLWrt
.pCurPam
->GetPoint()->nNode
== rHTMLWrt
.pCurPam
->GetMark()->nNode
)
2389 nEnde
= rHTMLWrt
.pCurPam
->GetMark()->nContent
.GetIndex();
2391 // gibt es harte Attribute, die als Optionen geschrieben werden muessen?
2392 rHTMLWrt
.bTagOn
= TRUE
;
2394 // jetzt das Tag des Absatzes ausgeben
2395 const SwFmt
& rFmt
= pNd
->GetAnyFmtColl();
2396 SwHTMLTxtCollOutputInfo aFmtInfo
;
2397 BOOL bOldLFPossible
= rHTMLWrt
.bLFPossible
;
2398 OutHTML_SwFmt( rWrt
, rFmt
, pNd
->GetpSwAttrSet(), aFmtInfo
);
2400 // Wenn vor dem Absatz-Tag keine neue Zeile aufgemacht wurde, dann
2401 // tun wir das jetzt
2402 rHTMLWrt
.bLFPossible
= !rHTMLWrt
.nLastParaToken
;
2403 if( !bOldLFPossible
&& rHTMLWrt
.bLFPossible
)
2404 rHTMLWrt
.OutNewLine();
2407 // dann die Bookmarks (inkl. End-Tag)
2408 rHTMLWrt
.bOutOpts
= FALSE
;
2409 rHTMLWrt
.OutBookmarks();
2411 // jetzt ist noch mal eine gute Gelegenheit fuer ein LF, sofern es noch
2413 if( rHTMLWrt
.bLFPossible
&&
2414 rHTMLWrt
.GetLineLen() >= rHTMLWrt
.nWhishLineLen
)
2416 rHTMLWrt
.OutNewLine();
2418 rHTMLWrt
.bLFPossible
= FALSE
;
2420 // Text, der aus einer Outline-Numerierung kommt ermitteln
2421 xub_StrLen nOffset
= 0;
2424 // --> OD 2006-06-12 #b6435904#
2425 // export numbering string as plain text only for the outline numbering,
2426 // because the outline numbering isn't exported as a numbering - see <SwHTMLNumRuleInfo::Set(..)>
2427 if ( pNd
->IsOutline() &&
2428 pNd
->GetNumRule() == pNd
->GetDoc()->GetOutlineNumRule() )
2431 aOutlineTxt
= pNd
->GetNumString();
2432 nOffset
= nOffset
+ aOutlineTxt
.Len();
2433 aFullText
= aOutlineTxt
;
2435 String aFootEndNoteSym
;
2436 if( rHTMLWrt
.pFmtFtn
)
2438 aFootEndNoteSym
= rHTMLWrt
.GetFootEndNoteSym( *rHTMLWrt
.pFmtFtn
);
2439 nOffset
= nOffset
+ aFootEndNoteSym
.Len();
2440 aFullText
+= aFootEndNoteSym
;
2443 // gibt es harte Attribute, die als Tags geschrieben werden muessen?
2445 HTMLEndPosLst
aEndPosLst( rWrt
.pDoc
, rHTMLWrt
.pTemplate
,
2446 rHTMLWrt
.pDfltColor
, rHTMLWrt
.bCfgOutStyles
,
2447 rHTMLWrt
.GetHTMLMode(), aFullText
,
2448 rHTMLWrt
.aScriptTextStyles
);
2449 if( aFmtInfo
.pItemSet
)
2451 aEndPosLst
.Insert( *aFmtInfo
.pItemSet
, 0, nEnde
+ nOffset
,
2452 rHTMLWrt
.aChrFmtInfos
, FALSE
, TRUE
);
2456 if( aOutlineTxt
.Len() || rHTMLWrt
.pFmtFtn
)
2458 // Absatz-Attribute ausgeben, damit der Text die Attribute des
2459 // Absatzes bekommt.
2460 aEndPosLst
.OutStartAttrs( rHTMLWrt
, 0 );
2462 // Theoretisch muesste man hier die Zeichen-Vorlage der Numerierung
2463 // beachten. Da man die ueber die UI nicht setzen kann, ignorieren
2466 if( aOutlineTxt
.Len() )
2467 HTMLOutFuncs::Out_String( rWrt
.Strm(), aOutlineTxt
,
2468 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
2470 if( rHTMLWrt
.pFmtFtn
)
2472 rHTMLWrt
.OutFootEndNoteSym( *rHTMLWrt
.pFmtFtn
, aFootEndNoteSym
,
2473 aEndPosLst
.GetScriptAtPos( aOutlineTxt
.Len(), rHTMLWrt
.nCSS1Script
) );
2474 rHTMLWrt
.pFmtFtn
= 0;
2478 // erstmal den Start berichtigen. D.h. wird nur ein Teil vom Satz
2479 // ausgegeben, so muessen auch da die Attribute stimmen!!
2480 rHTMLWrt
.bTxtAttr
= TRUE
;
2483 USHORT nAttrPos
= 0;
2484 xub_StrLen nStrPos
= rHTMLWrt
.pCurPam
->GetPoint()->nContent
.GetIndex();
2485 const SwTxtAttr
* pHt
= 0;
2486 USHORT nCntAttr
= pNd
->HasHints() ? pNd
->GetSwpHints().Count() : 0;
2487 if( nCntAttr
&& nStrPos
> *( pHt
= pNd
->GetSwpHints()[ 0 ] )->GetStart() )
2489 // Ok, es gibt vorher Attribute, die ausgegeben werden muessen
2491 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
);
2494 if( RES_TXTATR_FIELD
== pHt
->Which() ) // Felder nicht
2495 continue; // ausgeben
2497 if ( pHt
->GetEnd() && !pHt
->HasDummyChar() )
2499 xub_StrLen nHtEnd
= *pHt
->GetEnd(),
2500 nHtStt
= *pHt
->GetStart();
2501 if( !rHTMLWrt
.bWriteAll
&& nHtEnd
<= nStrPos
)
2504 // leere Hints am Anfang nicht beachten, oder ??
2505 if( nHtEnd
== nHtStt
)
2508 // Attribut in die Liste aufnehemen
2509 if( rHTMLWrt
.bWriteAll
)
2510 aEndPosLst
.Insert( pHt
->GetAttr(), nHtStt
+ nOffset
,
2512 rHTMLWrt
.aChrFmtInfos
);
2515 xub_StrLen nTmpStt
= nHtStt
< nStrPos
? nStrPos
: nHtStt
;
2516 xub_StrLen nTmpEnd
= nHtEnd
< nEnde
? nHtEnd
: nEnde
;
2517 aEndPosLst
.Insert( pHt
->GetAttr(), nTmpStt
+ nOffset
,
2519 rHTMLWrt
.aChrFmtInfos
);
2522 // aber nicht ausgeben, das erfolgt spaeter !!
2525 } while( nAttrPos
< nCntAttr
&& nStrPos
>
2526 *( pHt
= pNd
->GetSwpHints()[ nAttrPos
] )->GetStart() );
2528 // dann gebe mal alle gesammelten Attribute von der String-Pos aus
2529 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
);
2530 aEndPosLst
.OutStartAttrs( rHTMLWrt
, nStrPos
+ nOffset
);
2533 BOOL bWriteBreak
= (HTML_PREFORMTXT_ON
!= rHTMLWrt
.nLastParaToken
);
2534 if( bWriteBreak
&& pNd
->GetNumRule() )
2535 bWriteBreak
= FALSE
;
2538 HTMLOutContext
aContext( rHTMLWrt
.eDestEnc
);
2540 xub_StrLen nPreSplitPos
= 0;
2541 for( ; nStrPos
< nEnde
; nStrPos
++ )
2543 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
, &aContext
);
2545 // Die an der aktuellen Position verankerten Rahmen ausgeben
2547 bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2548 nStrPos
, HTML_POS_INSIDE
,
2551 BOOL bOutChar
= TRUE
;
2552 const SwTxtAttr
* pTxtHt
= 0;
2553 if( nAttrPos
< nCntAttr
&& *pHt
->GetStart() == nStrPos
2554 && nStrPos
!= nEnde
)
2557 if ( pHt
->GetEnd() && !pHt
->HasDummyChar() )
2559 if( RES_CHRATR_KERNING
== pHt
->Which() &&
2560 rHTMLWrt
.IsHTMLMode(HTMLMODE_FIRSTLINE
) &&
2561 *pHt
->GetEnd() - nStrPos
== 1 &&
2562 ' ' == rStr
.GetChar(nStrPos
) &&
2563 ((const SvxKerningItem
&)pHt
->GetAttr()).GetValue() > 0 )
2565 // Wenn erlaubt, wird das Ding als Spacer exportiert
2567 bOutChar
= FALSE
; // Space nicht ausgeben
2568 bWriteBreak
= FALSE
; // der Absatz ist aber auch nicht leer
2569 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2570 OutHTML_HoriSpacer( rWrt
,
2571 ((const SvxKerningItem
&)pHt
->GetAttr()).GetValue() );
2573 // Der Hint braucht nun doch nicht weiter
2574 // beruecksichtigt werden.
2576 else if( *pHt
->GetEnd() != nStrPos
)
2578 // Hints mit Ende einsortieren, wenn sie keinen
2579 // leeren Bereich aufspannen (Hints, die keinen
2580 // Bereich aufspannen werden ignoriert
2581 aEndPosLst
.Insert( pHt
->GetAttr(), nStrPos
+ nOffset
,
2582 *pHt
->GetEnd() + nOffset
,
2583 rHTMLWrt
.aChrFmtInfos
);
2588 // Hints ohne-Ende werden als letztes ausgebeben
2590 "Wieso gibt es da schon ein Attribut ohne Ende?" );
2591 if( rHTMLWrt
.nTxtAttrsToIgnore
>0 )
2593 rHTMLWrt
.nTxtAttrsToIgnore
--;
2599 if( RES_TXTATR_FIELD
!= pHt
->Which() ||
2600 ( RES_POSTITFLD
!= (nFldWhich
= ((const SwFmtFld
&)pHt
->GetAttr()).GetFld()->Which()) &&
2601 RES_SCRIPTFLD
!= nFldWhich
) )
2602 bWriteBreak
= FALSE
;
2604 bOutChar
= FALSE
; // keine 255 ausgeben
2606 } while( ++nAttrPos
< nCntAttr
&& nStrPos
==
2607 *( pHt
= pNd
->GetSwpHints()[ nAttrPos
] )->GetStart() );
2610 // Manche Draw-Formate koennen auch noch Attribute mitbringen
2611 if( pTxtHt
&& RES_TXTATR_FLYCNT
== pTxtHt
->Which() )
2613 const SwFrmFmt
* pFrmFmt
=
2614 ((const SwFmtFlyCnt
&)pTxtHt
->GetAttr()).GetFrmFmt();
2616 if( RES_DRAWFRMFMT
== pFrmFmt
->Which() )
2617 aEndPosLst
.Insert( *((const SwDrawFrmFmt
*)pFrmFmt
),
2619 rHTMLWrt
.aChrFmtInfos
);
2622 aEndPosLst
.OutEndAttrs( rHTMLWrt
, nStrPos
+ nOffset
, &aContext
);
2623 aEndPosLst
.OutStartAttrs( rHTMLWrt
, nStrPos
+ nOffset
, &aContext
);
2627 rHTMLWrt
.bLFPossible
= !rHTMLWrt
.nLastParaToken
&& nStrPos
> 0 &&
2628 rStr
.GetChar(nStrPos
-1) == ' ';
2629 sal_uInt16 nCSS1Script
= rHTMLWrt
.nCSS1Script
;
2630 rHTMLWrt
.nCSS1Script
= aEndPosLst
.GetScriptAtPos(
2631 nStrPos
+ nOffset
, nCSS1Script
);
2632 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2633 Out( aHTMLAttrFnTab
, pTxtHt
->GetAttr(), rHTMLWrt
);
2634 rHTMLWrt
.nCSS1Script
= nCSS1Script
;
2635 rHTMLWrt
.bLFPossible
= FALSE
;
2640 sal_Unicode c
= rStr
.GetChar( nStrPos
);
2641 // versuche nach ungefaehr 255 Zeichen eine neue Zeile zu
2642 // beginnen, aber nicht in PRE und nur bei Spaces
2643 if( ' '==c
&& !rHTMLWrt
.nLastParaToken
)
2645 xub_StrLen nLineLen
;
2646 if( rHTMLWrt
.nLastParaToken
)
2647 nLineLen
= nStrPos
- nPreSplitPos
;
2649 nLineLen
= rHTMLWrt
.GetLineLen();
2651 xub_StrLen nWordLen
= rStr
.Search( ' ', nStrPos
+1 );
2652 if( nWordLen
== STRING_NOTFOUND
)
2654 nWordLen
= nWordLen
- nStrPos
;
2656 if( nLineLen
>= rHTMLWrt
.nWhishLineLen
||
2657 (nLineLen
+nWordLen
) >= rHTMLWrt
.nWhishLineLen
)
2659 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2660 rHTMLWrt
.OutNewLine();
2662 if( rHTMLWrt
.nLastParaToken
)
2663 nPreSplitPos
= nStrPos
+1;
2671 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2672 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak
);
2675 HTMLOutFuncs::Out_Char( rWrt
.Strm(), c
, aContext
, &rHTMLWrt
.aNonConvertableCharacters
);
2677 // Wenn das letzte Zeichen eines Absatzed ein harter
2678 // Zeilen-Umbruch ist brauchen wir noch ein <BR> mehr, weil
2679 // Netscape & Co in diesem Fall fuer den naechsten Absatz
2680 // nicht in die naechste Zeile gehen.
2681 bWriteBreak
= (0x0a == c
) &&
2682 (HTML_PREFORMTXT_ON
!= rHTMLWrt
.nLastParaToken
);
2686 HTMLOutFuncs::FlushToAscii( rWrt
.Strm(), aContext
);
2689 aEndPosLst
.OutEndAttrs( rHTMLWrt
, STRING_MAXLEN
);
2691 // Die an der letzten Position verankerten Rahmen ausgeben
2693 bFlysLeft
= rHTMLWrt
.OutFlyFrm( rNode
.GetIndex(),
2694 nEnde
, HTML_POS_INSIDE
);
2695 ASSERT( !bFlysLeft
, "Es wurden nicht alle Rahmen gespeichert!" );
2697 rHTMLWrt
.bTxtAttr
= FALSE
;
2701 BOOL bEndOfCell
= rHTMLWrt
.bOutTable
&&
2702 rWrt
.pCurPam
->GetPoint()->nNode
.GetIndex() ==
2703 rWrt
.pCurPam
->GetMark()->nNode
.GetIndex();
2705 if( bEndOfCell
&& !nEnde
&&
2706 rHTMLWrt
.IsHTMLMode(HTMLMODE_NBSP_IN_TABLES
) )
2708 // Wenn der letzte Absatz einer Tabellezelle leer ist und
2709 // wir fuer den MS-IE exportieren, schreiben wir statt eines
2711 rWrt
.Strm() << '&' << OOO_STRING_SVTOOLS_HTML_S_nbsp
<< ';';
2715 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak
);
2716 const SvxULSpaceItem
& rULSpace
=
2717 (const SvxULSpaceItem
&)pNd
->GetSwAttrSet().Get(RES_UL_SPACE
);
2718 if( rULSpace
.GetLower() > 0 && !bEndOfCell
&&
2719 !rHTMLWrt
.IsHTMLMode(HTMLMODE_NO_BR_AT_PAREND
) )
2720 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak
);
2721 rHTMLWrt
.bLFPossible
= TRUE
;
2725 if( rHTMLWrt
.bClearLeft
|| rHTMLWrt
.bClearRight
)
2727 const sal_Char
*pStr
;
2728 if( rHTMLWrt
.bClearLeft
)
2730 if( rHTMLWrt
.bClearRight
)
2731 pStr
= OOO_STRING_SVTOOLS_HTML_AL_all
;
2733 pStr
= OOO_STRING_SVTOOLS_HTML_AL_left
;
2736 pStr
= OOO_STRING_SVTOOLS_HTML_AL_right
;
2738 ByteString
sOut( OOO_STRING_SVTOOLS_HTML_linebreak
);
2739 (((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_clear
) += '=') += pStr
;
2741 HTMLOutFuncs::Out_AsciiTag( rHTMLWrt
.Strm(), sOut
.GetBuffer() );
2742 rHTMLWrt
.bClearLeft
= FALSE
;
2743 rHTMLWrt
.bClearRight
= FALSE
;
2745 rHTMLWrt
.bLFPossible
= TRUE
;
2748 // wenn ein LF nicht schon erlaubt ist wird es erlaubt, wenn der
2749 // Absatz mit einem ' ' endet
2750 if( !rHTMLWrt
.bLFPossible
&& !rHTMLWrt
.nLastParaToken
&&
2751 nEnde
> 0 && ' ' == rStr
.GetChar(nEnde
-1) )
2752 rHTMLWrt
.bLFPossible
= TRUE
;
2754 rHTMLWrt
.bTagOn
= FALSE
;
2755 OutHTML_SwFmtOff( rWrt
, aFmtInfo
);
2757 // eventuell eine Form schliessen
2758 rHTMLWrt
.OutForm( FALSE
);
2760 if( bPageBreakBehind
)
2761 rWrt
.Strm() << '\f';
2767 sal_uInt32
SwHTMLWriter::ToPixel( sal_uInt32 nVal
) const
2769 if( Application::GetDefaultDevice() && nVal
)
2771 nVal
= Application::GetDefaultDevice()->LogicToPixel(
2772 Size( nVal
, nVal
), MapMode( MAP_TWIP
) ).Width();
2773 if( !nVal
) // wo ein Twip ist sollte auch ein Pixel sein
2780 static Writer
& OutHTML_CSS1Attr( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2782 // wenn gerade Hints geschrieben werden versuchen wir den Hint als
2783 // CSS1-Attribut zu schreiben
2785 if( ((SwHTMLWriter
&)rWrt
).bCfgOutStyles
&& ((SwHTMLWriter
&)rWrt
).bTxtAttr
)
2786 OutCSS1_HintSpanTag( rWrt
, rHt
);
2792 /* File CHRATR.HXX: */
2794 static Writer
& OutHTML_SvxColor( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2796 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2797 if( rHTMLWrt
.bOutOpts
)
2800 // die Default-Farbe nur Schreiben, wenn sie als Hint vorkommt
2801 //if( rHTMLWrt.bTagOn && !rHTMLWrt.bTxtAttr && rHTMLWrt.pDfltColor
2802 // && rColor == *rHTMLWrt.pDfltColor )
2805 if( !rHTMLWrt
.bTxtAttr
&& rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bCfgPreferStyles
)
2807 // Font-Farbe nicht als Tag schreiben, wenn Styles normalen Tags
2808 // vorgezogen werden
2812 if( rHTMLWrt
.bTagOn
)
2814 Color
aColor( ((const SvxColorItem
&)rHt
).GetValue() );
2815 if( COL_AUTO
== aColor
.GetColor() )
2816 aColor
.SetColor( COL_BLACK
);
2818 ByteString
sOut( '<' );
2819 (((sOut
+= OOO_STRING_SVTOOLS_HTML_font
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_color
) += '=';
2820 rWrt
.Strm() << sOut
.GetBuffer();
2821 HTMLOutFuncs::Out_Color( rWrt
.Strm(), aColor
, rHTMLWrt
.eDestEnc
) << '>';
2824 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_font
, FALSE
);
2830 static Writer
& OutHTML_SwPosture( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2832 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2833 if( rHTMLWrt
.bOutOpts
)
2836 const FontItalic nPosture
= ((const SvxPostureItem
&)rHt
).GetPosture();
2837 if( ITALIC_NORMAL
== nPosture
)
2839 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_italic
, rHTMLWrt
.bTagOn
);
2841 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2843 // vielleicht als CSS1-Attribut ?
2844 OutCSS1_HintSpanTag( rWrt
, rHt
);
2850 static Writer
& OutHTML_SvxFont( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2852 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2853 if( rHTMLWrt
.bOutOpts
)
2856 if( rHTMLWrt
.bTagOn
)
2859 SwHTMLWriter::PrepareFontList( ((const SvxFontItem
&)rHt
), aNames
, 0,
2860 rHTMLWrt
.IsHTMLMode(HTMLMODE_FONT_GENERIC
) );
2861 ByteString
sOut( '<' );
2862 (((sOut
+= OOO_STRING_SVTOOLS_HTML_font
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_face
) += "=\"";
2863 rWrt
.Strm() << sOut
.GetBuffer();
2864 HTMLOutFuncs::Out_String( rWrt
.Strm(), aNames
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
)
2868 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_font
, FALSE
);
2873 static Writer
& OutHTML_SvxFontHeight( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2875 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2876 if( rHTMLWrt
.bOutOpts
)
2879 if( rHTMLWrt
.bTagOn
)
2881 ByteString
sOut( '<' );
2882 sOut
+= OOO_STRING_SVTOOLS_HTML_font
;
2884 UINT32 nHeight
= ((const SvxFontHeightItem
&)rHt
).GetHeight();
2885 USHORT nSize
= rHTMLWrt
.GetHTMLFontSize( nHeight
);
2886 (((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_size
) += '=')
2887 += ByteString::CreateFromInt32( nSize
);
2888 rWrt
.Strm() << sOut
.GetBuffer();
2890 if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
&&
2891 rHTMLWrt
.aFontHeights
[nSize
-1] != nHeight
)
2893 // wenn die Groesse keiner HTML-Groesse entspricht,
2894 // wird sie noch zusatzlich als Style-Option exportiert
2895 OutCSS1_HintStyleOpt( rWrt
, rHt
);
2901 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_font
, FALSE
);
2907 static Writer
& OutHTML_SvxLanguage( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2909 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2910 if( rHTMLWrt
.bOutOpts
)
2913 LanguageType eLang
= ((const SvxLanguageItem
&)rHt
).GetLanguage();
2914 if( LANGUAGE_DONTKNOW
== eLang
)
2917 if( rHTMLWrt
.bTagOn
)
2919 ByteString
sOut( '<' );
2920 sOut
+= OOO_STRING_SVTOOLS_HTML_span
;
2921 rWrt
.Strm() << sOut
.GetBuffer();
2922 rHTMLWrt
.OutLanguage( ((const SvxLanguageItem
&)rHt
).GetLanguage() );
2927 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_span
, FALSE
);
2932 static Writer
& OutHTML_SwWeight( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2934 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2935 if( rHTMLWrt
.bOutOpts
)
2938 const FontWeight nBold
= ((const SvxWeightItem
&)rHt
).GetWeight();
2939 if( WEIGHT_BOLD
== nBold
)
2941 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_bold
, rHTMLWrt
.bTagOn
);
2943 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2945 // vielleicht als CSS1-Attribut ?
2946 OutCSS1_HintSpanTag( rWrt
, rHt
);
2953 static Writer
& OutHTML_SwCrossedOut( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2955 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2956 if( rHTMLWrt
.bOutOpts
)
2959 // Wegen Netscape schrieben wir hier STRIKE und nicht S raus!
2960 const FontStrikeout nStrike
= ((const SvxCrossedOutItem
&)rHt
).GetStrikeout();
2961 if( STRIKEOUT_NONE
!= nStrike
)
2963 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_strike
, rHTMLWrt
.bTagOn
);
2965 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2967 // vielleicht als CSS1-Attribut ?
2968 OutCSS1_HintSpanTag( rWrt
, rHt
);
2975 static Writer
& OutHTML_SvxEscapement( Writer
& rWrt
, const SfxPoolItem
& rHt
)
2977 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
2978 if( rHTMLWrt
.bOutOpts
)
2981 const SvxEscapement eEscape
=
2982 (const SvxEscapement
)((const SvxEscapementItem
&)rHt
).GetEnumValue();
2983 const sal_Char
*pStr
= 0;
2986 case SVX_ESCAPEMENT_SUPERSCRIPT
: pStr
= OOO_STRING_SVTOOLS_HTML_superscript
; break;
2987 case SVX_ESCAPEMENT_SUBSCRIPT
: pStr
= OOO_STRING_SVTOOLS_HTML_subscript
; break;
2994 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), pStr
, rHTMLWrt
.bTagOn
);
2996 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
2998 // vielleicht als CSS1-Attribut ?
2999 OutCSS1_HintSpanTag( rWrt
, rHt
);
3007 static Writer
& OutHTML_SwUnderline( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3009 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3010 if( rHTMLWrt
.bOutOpts
)
3013 const FontUnderline eUnder
= ((const SvxUnderlineItem
&)rHt
).GetLineStyle();
3014 if( UNDERLINE_NONE
!= eUnder
)
3016 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_underline
, rHTMLWrt
.bTagOn
);
3018 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
3020 // vielleicht als CSS1-Attribut ?
3021 OutCSS1_HintSpanTag( rWrt
, rHt
);
3028 static Writer
& OutHTML_SwFlyCnt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3030 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3031 SwFmtFlyCnt
& rFlyCnt
= (SwFmtFlyCnt
&)rHt
;
3033 const SwFrmFmt
& rFmt
= *rFlyCnt
.GetFrmFmt();
3034 const SdrObject
*pSdrObj
= 0;
3036 SwHTMLFrmType eType
=
3037 (SwHTMLFrmType
)rHTMLWrt
.GuessFrmType( rFmt
, pSdrObj
);
3038 BYTE nMode
= aHTMLOutFrmAsCharTable
[eType
][rHTMLWrt
.nExportMode
];
3039 rHTMLWrt
.OutFrmFmt( nMode
, rFmt
, pSdrObj
);
3044 // Das ist jetzt unser Blink-Item. Blinkend wird eingeschaltet, indem man
3045 // das Item auf TRUE setzt!
3046 static Writer
& OutHTML_SwBlink( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3048 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3049 if( rHTMLWrt
.bOutOpts
|| !rHTMLWrt
.IsHTMLMode(HTMLMODE_BLINK
) )
3052 if( ((const SvxBlinkItem
&)rHt
).GetValue() )
3054 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_blink
, rHTMLWrt
.bTagOn
);
3056 else if( rHTMLWrt
.bCfgOutStyles
&& rHTMLWrt
.bTxtAttr
)
3058 // vielleicht als CSS1-Attribut ?
3059 OutCSS1_HintSpanTag( rWrt
, rHt
);
3065 Writer
& OutHTML_INetFmt( Writer
& rWrt
, const SwFmtINetFmt
& rINetFmt
, BOOL bOn
)
3067 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3069 String
aURL( rINetFmt
.GetValue() );
3070 const SvxMacroTableDtor
*pMacTable
= rINetFmt
.GetMacroTbl();
3071 BOOL bEvents
= pMacTable
!= 0 && pMacTable
->Count() > 0;
3073 // Gibt es ueberhaupt etwas auszugeben?
3074 if( !aURL
.Len() && !bEvents
&& !rINetFmt
.GetName().Len() )
3077 // Tag aus? Dann nur ein </A> ausgeben.
3080 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_anchor
, FALSE
);
3084 ByteString
sOut( '<' );
3085 sOut
+= OOO_STRING_SVTOOLS_HTML_anchor
;
3087 sal_Bool bScriptDependent
= sal_False
;
3089 const SwCharFmt
* pFmt
= rWrt
.pDoc
->GetCharFmtFromPool(
3090 RES_POOLCHR_INET_NORMAL
);
3091 SwHTMLFmtInfo
aFmtInfo( pFmt
);
3093 if( rHTMLWrt
.aChrFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
3095 bScriptDependent
= rHTMLWrt
.aChrFmtInfos
[nPos
]->bScriptDependent
;
3098 if( !bScriptDependent
)
3100 const SwCharFmt
* pFmt
= rWrt
.pDoc
->GetCharFmtFromPool(
3101 RES_POOLCHR_INET_VISIT
);
3102 SwHTMLFmtInfo
aFmtInfo( pFmt
);
3104 if( rHTMLWrt
.aChrFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
3106 bScriptDependent
= rHTMLWrt
.aChrFmtInfos
[nPos
]->bScriptDependent
;
3110 if( bScriptDependent
)
3112 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
3113 switch( rHTMLWrt
.nCSS1Script
)
3115 case CSS1_OUTMODE_WESTERN
:
3118 case CSS1_OUTMODE_CJK
:
3121 case CSS1_OUTMODE_CTL
:
3128 rWrt
.Strm() << sOut
.GetBuffer();
3135 if( aURL
.Len() || bEvents
)
3138 String
sTmp( aURL
);
3139 sTmp
.ToUpperAscii();
3140 xub_StrLen nPos
= sTmp
.SearchAscii( "\" REL=" );
3141 if( nPos
!=STRING_NOTFOUND
)
3143 sRel
= aURL
.Copy( nPos
+1 );
3147 aURL
.EraseLeadingChars().EraseTrailingChars();
3149 ((sOut
= ' ') += OOO_STRING_SVTOOLS_HTML_O_href
) += "=\"";
3150 rWrt
.Strm() << sOut
.GetBuffer();
3151 rHTMLWrt
.OutHyperlinkHRefValue( aURL
);
3157 if( rINetFmt
.GetName().Len() )
3159 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"";
3160 rWrt
.Strm() << sOut
.GetBuffer();
3161 HTMLOutFuncs::Out_String( rWrt
.Strm(), rINetFmt
.GetName(),
3162 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
3166 const String
& rTarget
= rINetFmt
.GetTargetFrame();
3169 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_target
) += "=\"";
3170 rWrt
.Strm() << sOut
.GetBuffer();
3171 HTMLOutFuncs::Out_String( rWrt
.Strm(), rTarget
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
3177 sOut
+= ByteString( sRel
, RTL_TEXTENCODING_ASCII_US
);
3180 rWrt
.Strm() << sOut
.GetBuffer();
3183 HTMLOutFuncs::Out_Events( rWrt
.Strm(), *pMacTable
, aAnchorEventTable
,
3184 rHTMLWrt
.bCfgStarBasic
, rHTMLWrt
.eDestEnc
,
3185 &rHTMLWrt
.aNonConvertableCharacters
);
3191 static Writer
& OutHTML_SwFmtINetFmt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3193 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3195 if( rHTMLWrt
.bOutOpts
)
3198 const SwFmtINetFmt
& rINetFmt
= (const SwFmtINetFmt
&)rHt
;
3200 if( rHTMLWrt
.bTagOn
)
3202 // ggf. ein noch offenes Attribut voruebergehend beenden
3203 if( rHTMLWrt
.aINetFmts
.Count() )
3205 SwFmtINetFmt
*pINetFmt
=
3206 rHTMLWrt
.aINetFmts
[ rHTMLWrt
.aINetFmts
.Count()-1 ];
3207 OutHTML_INetFmt( rWrt
, *pINetFmt
, FALSE
);
3210 // jetzt das neue aufmachen
3211 OutHTML_INetFmt( rWrt
, rINetFmt
, TRUE
);
3214 const SwFmtINetFmt
*pINetFmt
= new SwFmtINetFmt( rINetFmt
);
3215 rHTMLWrt
.aINetFmts
.C40_INSERT( SwFmtINetFmt
, pINetFmt
,
3216 rHTMLWrt
.aINetFmts
.Count() );
3221 OutHTML_INetFmt( rWrt
, rINetFmt
, FALSE
);
3223 ASSERT( rHTMLWrt
.aINetFmts
.Count(), "da fehlt doch ein URL-Attribut" );
3224 if( rHTMLWrt
.aINetFmts
.Count() )
3226 // das eigene Attribut vom Stack holen
3227 SwFmtINetFmt
*pINetFmt
=
3228 rHTMLWrt
.aINetFmts
[ rHTMLWrt
.aINetFmts
.Count()-1 ];
3230 rHTMLWrt
.aINetFmts
.Remove( rHTMLWrt
.aINetFmts
.Count()-1, 1 );
3234 if( rHTMLWrt
.aINetFmts
.Count() )
3236 // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
3238 SwFmtINetFmt
*pINetFmt
=
3239 rHTMLWrt
.aINetFmts
[ rHTMLWrt
.aINetFmts
.Count()-1 ];
3240 OutHTML_INetFmt( rWrt
, *pINetFmt
, TRUE
);
3247 static Writer
& OutHTML_SwTxtCharFmt( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3249 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3250 if( rHTMLWrt
.bOutOpts
)
3253 const SwFmtCharFmt
& rChrFmt
= (const SwFmtCharFmt
&)rHt
;
3254 const SwCharFmt
* pFmt
= rChrFmt
.GetCharFmt();
3261 SwHTMLFmtInfo
aFmtInfo( pFmt
);
3263 if( !rHTMLWrt
.aChrFmtInfos
.Seek_Entry( &aFmtInfo
, &nPos
) )
3266 const SwHTMLFmtInfo
*pFmtInfo
= rHTMLWrt
.aChrFmtInfos
[nPos
];
3267 ASSERT( pFmtInfo
, "Wieso gint es keine Infos ueber die Zeichenvorlage?" );
3269 if( rHTMLWrt
.bTagOn
)
3271 ByteString
sOut( '<' );
3272 if( pFmtInfo
->aToken
.Len() > 0 )
3273 sOut
+= pFmtInfo
->aToken
;
3275 sOut
+= OOO_STRING_SVTOOLS_HTML_span
;
3276 if( rHTMLWrt
.bCfgOutStyles
&&
3277 (pFmtInfo
->aClass
.Len() || pFmtInfo
->bScriptDependent
) )
3279 ((sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
3280 rWrt
.Strm() << sOut
.GetBuffer();
3281 String
aClass( pFmtInfo
->aClass
);
3282 if( pFmtInfo
->bScriptDependent
)
3286 switch( rHTMLWrt
.nCSS1Script
)
3288 case CSS1_OUTMODE_WESTERN
:
3289 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
3291 case CSS1_OUTMODE_CJK
:
3292 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
3294 case CSS1_OUTMODE_CTL
:
3295 aClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
3299 HTMLOutFuncs::Out_String( rWrt
.Strm(), aClass
,
3300 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
3304 rWrt
.Strm() << sOut
.GetBuffer();
3308 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(),
3309 pFmtInfo
->aToken
.Len() ? pFmtInfo
->aToken
.GetBuffer()
3310 : OOO_STRING_SVTOOLS_HTML_span
,
3317 static Writer
& OutHTML_SvxAdjust( Writer
& rWrt
, const SfxPoolItem
& rHt
)
3319 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
3320 if( !rHTMLWrt
.bOutOpts
|| !rHTMLWrt
.bTagOn
)
3323 SvxAdjustItem
& rAdjust
= (SvxAdjustItem
&)rHt
;
3324 const sal_Char
* pStr
= 0;
3325 switch( rAdjust
.GetAdjust() )
3327 case SVX_ADJUST_CENTER
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_center
; break;
3328 case SVX_ADJUST_LEFT
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_left
; break;
3329 case SVX_ADJUST_RIGHT
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_right
; break;
3330 case SVX_ADJUST_BLOCK
: pStr
= OOO_STRING_SVTOOLS_HTML_AL_justify
; break;
3336 ByteString
sOut( ' ' );
3337 ((sOut
+= OOO_STRING_SVTOOLS_HTML_O_align
) += '=') += pStr
;
3338 rWrt
.Strm() << sOut
.GetBuffer();
3345 * lege hier die Tabellen fuer die HTML-Funktions-Pointer auf
3346 * die Ausgabe-Funktionen an.
3347 * Es sind lokale Strukturen, die nur innerhalb der HTML-DLL
3348 * bekannt sein muessen.
3352 SwAttrFnTab aHTMLAttrFnTab
= {
3353 /* RES_CHRATR_CASEMAP */ OutHTML_CSS1Attr
,
3354 /* RES_CHRATR_CHARSETCOLOR */ 0,
3355 /* RES_CHRATR_COLOR */ OutHTML_SvxColor
,
3356 /* RES_CHRATR_CONTOUR */ 0,
3357 /* RES_CHRATR_CROSSEDOUT */ OutHTML_SwCrossedOut
,
3358 /* RES_CHRATR_ESCAPEMENT */ OutHTML_SvxEscapement
,
3359 /* RES_CHRATR_FONT */ OutHTML_SvxFont
,
3360 /* RES_CHRATR_FONTSIZE */ OutHTML_SvxFontHeight
,
3361 /* RES_CHRATR_KERNING */ OutHTML_CSS1Attr
,
3362 /* RES_CHRATR_LANGUAGE */ OutHTML_SvxLanguage
,
3363 /* RES_CHRATR_POSTURE */ OutHTML_SwPosture
,
3364 /* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
3365 /* RES_CHRATR_SHADOWED */ 0,
3366 /* RES_CHRATR_UNDERLINE */ OutHTML_SwUnderline
,
3367 /* RES_CHRATR_WEIGHT */ OutHTML_SwWeight
,
3368 /* RES_CHRATR_WORDLINEMODE */ 0,
3369 /* RES_CHRATR_AUTOKERN */ 0,
3370 /* RES_CHRATR_BLINK */ OutHTML_SwBlink
,
3371 /* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen
3372 /* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen
3373 /* RES_CHRATR_BACKGROUND */ OutHTML_CSS1Attr
, // Neu: Zeichenhintergrund
3374 /* RES_CHRATR_CJK_FONT */ OutHTML_SvxFont
,
3375 /* RES_CHRATR_CJK_FONTSIZE */ OutHTML_SvxFontHeight
,
3376 /* RES_CHRATR_CJK_LANGUAGE */ OutHTML_SvxLanguage
,
3377 /* RES_CHRATR_CJK_POSTURE */ OutHTML_SwPosture
,
3378 /* RES_CHRATR_CJK_WEIGHT */ OutHTML_SwWeight
,
3379 /* RES_CHRATR_CTL_FONT */ OutHTML_SvxFont
,
3380 /* RES_CHRATR_CTL_FONTSIZE */ OutHTML_SvxFontHeight
,
3381 /* RES_CHRATR_CTL_LANGUAGE */ OutHTML_SvxLanguage
,
3382 /* RES_CHRATR_CTL_POSTURE */ OutHTML_SwPosture
,
3383 /* RES_CHRATR_CTL_WEIGHT */ OutHTML_SwWeight
,
3384 /* RES_CHRATR_ROTATE */ 0,
3385 /* RES_CHRATR_EMPHASIS_MARK */ 0,
3386 /* RES_CHRATR_TWO_LINES */ 0,
3387 /* RES_CHRATR_SCALEW */ 0,
3388 /* RES_CHRATR_RELIEF */ 0,
3389 /* RES_CHRATR_HIDDEN */ 0,
3390 /* RES_CHRATR_OVERLINE */ OutHTML_CSS1Attr
,
3391 /* RES_CHRATR_DUMMY1 */ 0,
3392 /* RES_CHRATR_DUMMY2 */ 0,
3394 /* RES_TXTATR_DUMMY4 */ 0,
3395 /* RES_TXTATR_INETFMT */ OutHTML_SwFmtINetFmt
,
3396 /* RES_TXTATR_REFMARK*/ 0,
3397 /* RES_TXTATR_TOXMARK */ 0,
3398 /* RES_TXTATR_CHARFMT */ OutHTML_SwTxtCharFmt
,
3399 /* RES_TXTATR_TWO_LINES */ 0,
3400 /* RES_TXTATR_CJK_RUBY */ 0,
3401 /* RES_TXTATR_UNKNOWN_CONTAINER */ 0,
3402 /* RES_TXTATR_DUMMY5 */ 0,
3403 /* RES_TXTATR_DUMMY6 */ 0,
3405 /* RES_TXTATR_FIELD */ OutHTML_SwFmtFld
,
3406 /* RES_TXTATR_FLYCNT */ OutHTML_SwFlyCnt
,
3407 /* RES_TXTATR_FTN */ OutHTML_SwFmtFtn
,
3408 /* RES_TXTATR_SOFTHYPH */ 0,
3409 /* RES_TXTATR_HARDBLANK*/ 0,
3410 /* RES_TXTATR_DUMMY1 */ 0, // Dummy:
3411 /* RES_TXTATR_DUMMY2 */ 0, // Dummy:
3413 /* RES_PARATR_LINESPACING */ 0,
3414 /* RES_PARATR_ADJUST */ OutHTML_SvxAdjust
,
3415 /* RES_PARATR_SPLIT */ 0,
3416 /* RES_PARATR_WIDOWS */ 0,
3417 /* RES_PARATR_ORPHANS */ 0,
3418 /* RES_PARATR_TABSTOP */ 0,
3419 /* RES_PARATR_HYPHENZONE*/ 0,
3420 /* RES_PARATR_DROP */ OutHTML_CSS1Attr
,
3421 /* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit
3422 /* RES_PARATR_NUMRULE */ 0, // Dummy:
3423 /* RES_PARATR_SCRIPTSPACE */ 0, // Dummy:
3424 /* RES_PARATR_HANGINGPUNCTUATION */ 0, // Dummy:
3425 /* RES_PARATR_FORBIDDEN_RULES */ 0, // new
3426 /* RES_PARATR_VERTALIGN */ 0, // new
3427 /* RES_PARATR_SNAPTOGRID*/ 0, // new
3428 /* RES_PARATR_CONNECT_TO_BORDER */ 0, // new
3430 /* RES_PARATR_LIST_ID */ 0, // new
3431 /* RES_PARATR_LIST_LEVEL */ 0, // new
3432 /* RES_PARATR_LIST_ISRESTART */ 0, // new
3433 /* RES_PARATR_LIST_RESTARTVALUE */ 0, // new
3434 /* RES_PARATR_LIST_ISCOUNTED */ 0, // new
3436 /* RES_FILL_ORDER */ 0,
3437 /* RES_FRM_SIZE */ 0,
3438 /* RES_PAPER_BIN */ 0,
3439 /* RES_LR_SPACE */ 0,
3440 /* RES_UL_SPACE */ 0,
3441 /* RES_PAGEDESC */ 0,
3448 /* RES_PROTECT */ 0,
3449 /* RES_SURROUND */ 0,
3450 /* RES_VERT_ORIENT */ 0,
3451 /* RES_HORI_ORIENT */ 0,
3453 /* RES_BACKGROUND */ 0,
3456 /* RES_FRMMACRO */ 0,
3460 /* RES_EDIT_IN_READONLY */ 0,
3461 /* RES_LAYOUT_SPLIT */ 0,
3462 /* RES_FRMATR_DUMMY1 */ 0, // Dummy:
3463 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
3464 /* RES_AUTO_STYLE */ 0, // Dummy:
3465 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
3466 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
3467 /* RES_FRMATR_DUMMY6 */ 0, // Dummy:
3468 /* RES_FRMATR_DUMMY7 */ 0, // Dummy:
3469 /* RES_FRMATR_DUMMY8 */ 0, // Dummy:
3470 /* RES_FRMATR_DUMMY9 */ 0, // Dummy:
3471 /* RES_FOLLOW_TEXT_FLOW */ 0,
3472 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ 0,
3473 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
3474 /* RES_AUTO_STYLE */ 0, // Dummy:
3475 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
3476 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
3478 /* RES_GRFATR_MIRRORGRF */ 0,
3479 /* RES_GRFATR_CROPGRF */ 0,
3480 /* RES_GRFATR_ROTATION */ 0,
3481 /* RES_GRFATR_LUMINANCE */ 0,
3482 /* RES_GRFATR_CONTRAST */ 0,
3483 /* RES_GRFATR_CHANNELR */ 0,
3484 /* RES_GRFATR_CHANNELG */ 0,
3485 /* RES_GRFATR_CHANNELB */ 0,
3486 /* RES_GRFATR_GAMMA */ 0,
3487 /* RES_GRFATR_INVERT */ 0,
3488 /* RES_GRFATR_TRANSPARENCY */ 0,
3489 /* RES_GRFATR_DRWAMODE */ 0,
3490 /* RES_GRFATR_DUMMY1 */ 0,
3491 /* RES_GRFATR_DUMMY2 */ 0,
3492 /* RES_GRFATR_DUMMY3 */ 0,
3493 /* RES_GRFATR_DUMMY4 */ 0,
3494 /* RES_GRFATR_DUMMY5 */ 0,
3496 /* RES_BOXATR_FORMAT */ 0,
3497 /* RES_BOXATR_FORMULA */ 0,
3498 /* RES_BOXATR_VALUE */ 0