merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / html / htmlatr.cxx
blobab62e9d2ee9b31091b77cac8cb510b56c188f6b0
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>
40 #endif
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>
47 #endif
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>
80 #include <fmtftn.hxx>
81 #include <txatbase.hxx>
82 #include <frmatr.hxx>
83 #include <charfmt.hxx>
84 #include <fmtfld.hxx>
85 #include <doc.hxx>
86 #include <pam.hxx>
87 #include <ndtxt.hxx>
88 #include <paratr.hxx>
89 #include <poolfmt.hxx>
90 #include <pagedesc.hxx>
91 #include <swtable.hxx>
92 #include "fldbas.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 ??
115 #endif
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 ??
122 #endif
123 #endif
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 ??
128 #endif
130 #endif
132 #define HTML_BULLETCHAR_DISC 34
133 #define HTML_BULLETCHAR_CIRCLE 38
134 #define HTML_BULLETCHAR_SQUARE 36
136 #define COLFUZZY 20
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 },
145 { 0, 0, 0 }
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?" )
153 if( nSize <= 0 )
154 return rWrt;
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();
170 return rWrt;
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) );
185 sDTDD += ' ';
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 );
191 sDTDD += ' ';
192 if( COMPARE_EQUAL == sDTDD.CompareTo( rNm, sDTDD.Len() ) )
193 // DefinitionList - definition
194 return (USHORT)rNm.Copy( sDTDD.Len() ).ToInt32() | HTML_DLCOLL_DD;
196 return 0;
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++ )
215 if( bLFPossible )
216 OutNewLine();
217 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist, TRUE );
218 IncIndentLevel();
219 bLFPossible = TRUE;
222 else if( nDefListLvl > nNewLvl )
224 for( USHORT i=nNewLvl ; i < nDefListLvl; i++ )
226 DecIndentLevel();
227 if( bLFPossible )
228 OutNewLine();
229 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist, FALSE );
230 bLFPossible = TRUE;
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 );
243 bLFPossible = TRUE;
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;
256 break;
257 case i18n::ScriptType::ASIAN:
258 nRet = CSS1_OUTMODE_CJK;
259 break;
260 case i18n::ScriptType::COMPLEX:
261 nRet = CSS1_OUTMODE_CTL;
262 break;
265 return nRet;
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
272 * Tag ausgegeben
273 * - fuer alle anderen wird ein Absatz-Tag <P> ausgegeben und bUserFmt
274 * gesetzt
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() :
294 pItemSet( 0 ),
295 bInNumBulList( FALSE ),
296 bParaPossible( FALSE ),
297 bOutPara( FALSE ),
298 bOutDiv( 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()
309 delete pItemSet;
312 struct SwHTMLFmtInfo
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;
326 USHORT nTopMargin;
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 );
342 ~SwHTMLFmtInfo();
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,
361 BOOL bOutStyles,
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,
369 nRefPoolId );
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;
380 if( nDeep != 0 )
382 // Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
383 // solchen abgeleitet
384 if( !bOutStyles )
386 // wenn keine Styles exportiert werden, muss evtl. zusaetlich
387 // harte Attributierung geschrieben werden
388 switch( nDeep )
390 case CSS1_FMT_ISTAG:
391 case CSS1_FMT_CMPREF:
392 // fuer HTML-Tag-Vorlagen die Unterscheide zum Original
393 // (sofern verfuegbar)
394 pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId,
395 pTemplate );
396 break;
398 default:
399 // sonst die zur HTML-Tag-Vorlage des Originals oder des
400 // aktuellen Doks, wenn die nicht verfuegbar ist
401 if( pTemplate )
402 pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId,
403 pTemplate );
404 else
405 pReferenceFmt = SwHTMLWriter::GetParentFmt( *pFmt, nDeep );
406 break;
410 else if( bTxtColl )
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 );
418 else
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 );
432 if( pReferenceFmt )
433 SwHTMLWriter::SubtractItemSet( *pItemSet, pReferenceFmt->GetAttrSet(),
434 bSetDefaults, bClearSame );
436 // einen leeren Item-Set gleich loeschen, das spart speater
437 // Arbeit
438 if( !pItemSet->Count() )
440 delete pItemSet;
441 pItemSet = 0;
445 if( bTxtColl )
447 if( bOutStyles )
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 }
461 sal_uInt16 nRef = 0;
462 sal_uInt16 aSets[2] = {0,0};
463 switch( nCSS1Script )
465 case CSS1_OUTMODE_WESTERN:
466 nRef = 0;
467 aSets[0] = 1;
468 aSets[1] = 2;
469 break;
470 case CSS1_OUTMODE_CJK:
471 nRef = 1;
472 aSets[0] = 0;
473 aSets[1] = 2;
474 break;
475 case CSS1_OUTMODE_CTL:
476 nRef = 2;
477 aSets[0] = 0;
478 aSets[1] = 1;
479 break;
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] );
487 if( rSet != rRef )
489 if( !pItemSet )
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 ) )
505 BOOL bPut = TRUE;
506 if( pTemplate )
508 pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
509 const SfxPoolItem *pRefItem;
510 BOOL bRefItemSet =
511 SFX_ITEM_SET==pReferenceFmt->GetAttrSet().GetItemState(
512 RES_PARATR_DROP, TRUE, &pRefItem );
513 bPut = !bRefItemSet || *pItem!=*pRefItem;
515 if( bPut )
517 if( !pItemSet )
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 )
547 if( !pItemSet )
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 )
564 if( !pItemSet )
565 pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
566 pFmt->GetAttrSet().GetRanges() );
567 pItemSet->Put( rTmpLang );
574 SwHTMLFmtInfo::~SwHTMLFmtInfo()
576 delete pItemSet;
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;
592 BOOL bDT = 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();
612 else
614 aNumInfo.Set( *pTxtNd );
617 if( aNumInfo.GetNumRule() )
619 rInfo.bInNumBulList = TRUE;
620 nNewDefListLvl = 0;
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" );
631 if( bNumbered )
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());
643 // <--
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 );
651 USHORT nArrayPos;
652 const SwHTMLFmtInfo *pFmtInfo;
653 if( rHWrt.aTxtCollInfos.Seek_Entry( &aFmtInfo, &nArrayPos ) )
655 pFmtInfo = rHWrt.aTxtCollInfos[nArrayPos];
657 else
659 pFmtInfo = new SwHTMLFmtInfo( &rFmt, rWrt.pDoc, rHWrt.pTemplate,
660 rHWrt.bCfgOutStyles, rHWrt.eLang,
661 rHWrt.nCSS1Script,
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;
685 break;
687 case 'B': ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_blockquote),
688 "Doch kein BLOCKQUOTE?" );
689 rInfo.bParaPossible = TRUE;
690 rHWrt.bNoAlign = TRUE;
691 break;
693 case 'P': if( rInfo.aToken.Len() == 1 )
695 bPara = TRUE;
697 else
699 ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_preformtxt),
700 "Doch kein PRE?" );
701 if( HTML_PREFORMTXT_ON == rHWrt.nLastParaToken )
703 bOutNewLine = TRUE;
705 else
707 nToken = HTML_PREFORMTXT_ON;
708 rHWrt.bNoAlign = TRUE;
709 bNoEndTag = TRUE;
712 break;
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;
720 bForceDL = TRUE;
721 break;
724 else
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;
730 bPara = TRUE;
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
741 if( pNodeItemSet )
743 if( rInfo.pItemSet )
744 rInfo.pItemSet->Put( *pNodeItemSet );
745 else
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))
752 : rFmt.GetULSpace();
755 if( (rHWrt.bOutHeader &&
756 rWrt.pCurPam->GetPoint()->nNode.GetIndex() ==
757 rWrt.pCurPam->GetMark()->nNode.GetIndex()) ||
758 rHWrt.bOutFooter )
760 if( rHWrt.bCfgOutStyles )
762 SvxULSpaceItem aULSpaceItem( rULSpace );
763 if( rHWrt.bOutHeader )
764 aULSpaceItem.SetLower( rHWrt.nHeaderFooterSpace );
765 else
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;
778 if( bOutNewLine )
780 // nur einen Zeilen-Umbruch (ohne Einrueckung) am Absatz-Anfang
781 // ausgeben
782 rInfo.aToken.Erase(); // kein End-Tag ausgeben
783 rWrt.Strm() << SwHTMLWriter::sNewLine;
785 return;
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,
795 FALSE, &pItem ) )
797 pAdjItem = pItem;
800 // Unteren Absatz-Abstand beachten ? (nie im letzen Absatz von
801 // Tabellen)
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))
809 : rFmt.GetLRSpace();
810 if( (!rHWrt.bCfgOutStyles || bForceDL) && !rInfo.bInNumBulList )
812 sal_Int32 nLeftMargin;
813 if( bForceDL )
814 nLeftMargin = rLRSpace.GetTxtLeft();
815 else
816 nLeftMargin = rLRSpace.GetTxtLeft() > pFmtInfo->nLeftMargin
817 ? rLRSpace.GetTxtLeft() - pFmtInfo->nLeftMargin
818 : 0;
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 )
825 nNewDefListLvl = 1;
827 else
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]
837 ->IsTxtNode();
839 if( bForceDL && bDT )
841 // Statt eines DD muessen wir hier auch ein DT der Ebene
842 // darueber nehmen
843 nNewDefListLvl++;
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
852 nNewDefListLvl = 1;
853 bDT = TRUE;
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 );
868 if( bNumbered )
870 if( rHWrt.aBulletGrfs[nBulletGrfLvl].Len() )
871 bNumbered = FALSE;
872 else
873 nBulletGrfLvl = 255;
877 // Die Defaults aus der Vorlage merken, denn sie muessen nicht
878 // exportiert werden
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;
904 else
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
911 // setzen.
912 if( rHWrt.bCfgNetscape4 && !bUseParSpace )
913 rHWrt.nDfltBottomMargin = rULSpace.GetLower();
914 else
915 rHWrt.nDfltBottomMargin = pFmtInfo->nBottomMargin;
918 if( rHWrt.nDefListLvl )
920 rHWrt.nLeftMargin =
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);
941 sOut += '>';
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 );
950 if( pAdjItem &&
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 );
964 rWrt.Strm() << '>';
965 pAdjItem = 0;
966 rHWrt.bNoAlign = FALSE;
967 rInfo.bOutDiv = TRUE;
968 rHWrt.IncIndentLevel();
969 rHWrt.bLFPossible = TRUE;
970 rHWrt.OutNewLine();
973 // fuer BLOCKQUOTE, ADDRESS und DD wird noch ein Absatz-Token
974 // ausgegeben, wenn,
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;
983 bPara = TRUE;
984 rHWrt.bNoAlign = FALSE;
985 bNoStyle = FALSE;
988 LanguageType eLang = rInfo.pItemSet
989 ? ((const SvxLanguageItem&)rInfo.pItemSet->Get(SwHTMLWriter::GetLangWhichIdFromScript(rHWrt.nCSS1Script))).GetLanguage()
990 : rHWrt.eLang;
992 if( rInfo.pItemSet )
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
1023 if( !bPara ||
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( '<' );
1037 sOut += aToken;
1039 if( eLang != LANGUAGE_DONTKNOW && eLang != rHWrt.eLang )
1041 rWrt.Strm() << sOut.GetBuffer();
1042 rHWrt.OutLanguage( eLang );
1043 sOut.Erase();
1046 if( nDir != rHWrt.nDirection )
1048 if( sOut.Len() )
1050 rWrt.Strm() << sOut.GetBuffer();
1051 sOut.Erase();
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 )
1064 if( aClass.Len() )
1065 aClass += '-';
1066 switch( rHWrt.nCSS1Script )
1068 case CSS1_OUTMODE_WESTERN:
1069 aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
1070 break;
1071 case CSS1_OUTMODE_CJK:
1072 aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
1073 break;
1074 case CSS1_OUTMODE_CTL:
1075 aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
1076 break;
1079 HTMLOutFuncs::Out_String( rWrt.Strm(), aClass,
1080 rHWrt.eDestEnc, &rHWrt.aNonConvertableCharacters );
1081 sOut = '\"';
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 );
1095 rWrt.Strm() << '>';
1097 // Soll ein </P> geschrieben wenrden
1098 rInfo.bOutPara =
1099 bPara &&
1100 ( rHWrt.bCfgOutStyles ||
1101 (!rHWrt.bCfgOutStyles && bHasParSpace) );
1103 // wenn kein End-Tag geschrieben werden soll, es loeschen
1104 if( bNoEndTag )
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 );
1166 return;
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(),
1182 FALSE );
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 );
1187 if( rInfo.bOutDiv )
1189 rHWrt.DecIndentLevel();
1190 if( rHWrt.bLFPossible )
1191 rHWrt.OutNewLine();
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() );
1205 class HTMLSttEndPos
1207 xub_StrLen nStart;
1208 xub_StrLen nEnd;
1209 SfxPoolItem* pItem;
1211 public:
1213 HTMLSttEndPos( const SfxPoolItem& rItem, xub_StrLen nStt, xub_StrLen nE );
1214 ~HTMLSttEndPos();
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,
1226 xub_StrLen nE ) :
1227 nStart( nStt ),
1228 nEnd( nE ),
1229 pItem( rItem.Clone() )
1232 HTMLSttEndPos::~HTMLSttEndPos()
1234 delete pItem;
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
1251 class HTMLEndPosLst
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; //
1266 ULONG nHTMLMode;
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,
1297 xub_StrLen nEnd );
1299 // Ein bereits vorhandenes Attribut aufteilen
1300 void SplitItem( const SfxPoolItem& rItem, xub_StrLen nStart,
1301 xub_StrLen nEnd );
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 );
1311 public:
1313 HTMLEndPosLst( SwDoc *pDoc, SwDoc* pTemplate, const Color* pDfltColor,
1314 BOOL bOutStyles, ULONG nHTMLMode,
1315 const String& rText, SvStringsSortDtor& rStyles );
1316 ~HTMLEndPosLst();
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
1343 USHORT i;
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
1354 USHORT i;
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();
1370 USHORT i;
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 );
1392 delete pPos;
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() )
1405 case ITALIC_NORMAL:
1406 eState = HTML_ON_VALUE;
1407 break;
1408 case ITALIC_NONE:
1409 eState = HTML_OFF_VALUE;
1410 break;
1411 default:
1412 if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
1413 eState = HTML_STYLE_VALUE;
1414 break;
1416 break;
1418 case RES_CHRATR_CROSSEDOUT:
1419 switch( ((const SvxCrossedOutItem&)rItem).GetStrikeout() )
1421 case STRIKEOUT_SINGLE:
1422 case STRIKEOUT_DOUBLE:
1423 eState = HTML_ON_VALUE;
1424 break;
1425 case STRIKEOUT_NONE:
1426 eState = HTML_OFF_VALUE;
1427 break;
1428 default:
1431 break;
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;
1440 break;
1441 case SVX_ESCAPEMENT_OFF:
1442 eState = HTML_OFF_VALUE;
1443 break;
1444 default:
1447 break;
1449 case RES_CHRATR_UNDERLINE:
1450 switch( ((const SvxUnderlineItem&)rItem).GetLineStyle() )
1452 case UNDERLINE_SINGLE:
1453 eState = HTML_ON_VALUE;
1454 break;
1455 case UNDERLINE_NONE:
1456 eState = HTML_OFF_VALUE;
1457 break;
1458 default:
1459 if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
1460 eState = HTML_STYLE_VALUE;
1461 break;
1463 break;
1465 case RES_CHRATR_OVERLINE:
1466 if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
1467 eState = HTML_STYLE_VALUE;
1468 break;
1470 case RES_CHRATR_WEIGHT:
1471 case RES_CHRATR_CJK_WEIGHT:
1472 case RES_CHRATR_CTL_WEIGHT:
1473 switch( ((const SvxWeightItem&)rItem).GetWeight() )
1475 case WEIGHT_BOLD:
1476 eState = HTML_ON_VALUE;
1477 break;
1478 case WEIGHT_NORMAL:
1479 eState = HTML_OFF_VALUE;
1480 break;
1481 default:
1482 if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
1483 eState = HTML_STYLE_VALUE;
1484 break;
1486 break;
1488 case RES_CHRATR_BLINK:
1489 if( IsHTMLMode(HTMLMODE_BLINK) )
1490 eState = ((const SvxBlinkItem&)rItem).GetValue() ? HTML_ON_VALUE
1491 : HTML_OFF_VALUE;
1492 break;
1494 case RES_CHRATR_COLOR:
1495 eState = HTML_COLOR_VALUE;
1496 break;
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;
1509 break;
1511 case RES_TXTATR_CHARFMT:
1512 eState = HTML_CHRFMT_VALUE;
1513 break;
1515 case RES_TXTATR_AUTOFMT:
1516 eState = HTML_AUTOFMT_VALUE;
1517 break;
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;
1526 break;
1528 case RES_CHRATR_BACKGROUND:
1529 if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
1530 eState = HTML_STYLE_VALUE;
1531 break;
1533 case RES_PARATR_DROP:
1534 eState = HTML_DROPCAP_VALUE;
1535 break;
1537 // default:
1538 // eState = HTML_NOT_SUPPORTED;
1539 // break;
1542 return eState;
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
1554 break;
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
1565 return TRUE;
1570 return FALSE;
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 )
1580 return FALSE;
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
1590 break;
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
1606 return TRUE;
1611 return FALSE;
1614 void HTMLEndPosLst::FixSplittedItem( HTMLSttEndPos *pPos, xub_StrLen nNewEnd,
1615 USHORT nStartPos )
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
1626 // beendet
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
1641 break;
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,
1668 xub_StrLen nEnd )
1670 USHORT i;
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
1678 continue;
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 );
1685 nStart = nTestEnd;
1687 else
1689 // das Test-Attribut (und alle folgenden) endet, bevor das neue
1690 // endet
1691 break;
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,
1702 xub_StrLen nEnd )
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
1718 break;
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
1726 // werden
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 );
1737 bDelete = FALSE;
1739 else
1741 // das Test-Item beginnt erst hinter dem neuen
1742 // Ende des Attribts und kann deshalb komplett
1743 // geloescht werden
1744 aStartLst.Remove( i, 1 );
1745 i--;
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 );
1758 if( bDelete )
1759 delete pTest;
1765 const SwHTMLFmtInfo *HTMLEndPosLst::GetFmtInfo( const SwFmt& rFmt,
1766 SwHTMLFmtInfos& rFmtInfos )
1768 const SwHTMLFmtInfo *pFmtInfo;
1769 SwHTMLFmtInfo aFmtInfo( &rFmt );
1770 USHORT nPos;
1771 if( rFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
1773 pFmtInfo = rFmtInfos[nPos];
1775 else
1777 pFmtInfo = new SwHTMLFmtInfo( &rFmt, pDoc, pTemplate,
1778 bOutStyles );
1779 rFmtInfos.C40_PTR_INSERT( SwHTMLFmtInfo, pFmtInfo );
1780 String aName( rFmt.GetName() );
1781 if( rScriptTxtStyles.Seek_Entry( &aName ) )
1782 ((SwHTMLFmtInfo *)pFmtInfo)->bScriptDependent = sal_True;
1785 return pFmtInfo;
1788 HTMLEndPosLst::HTMLEndPosLst( SwDoc *pD, SwDoc* pTempl,
1789 const Color* pDfltCol, BOOL bStyles,
1790 ULONG nMode, const String& rText,
1791 SvStringsSortDtor& rStyles ):
1792 pDoc( pD ),
1793 pTemplate( pTempl ),
1794 pDfltColor( pDfltCol ),
1795 rScriptTxtStyles( rStyles ),
1796 nHTMLMode( nMode ),
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) )
1828 case HTML_ON_VALUE:
1829 // das Attribut wird ausgegeben, wenn es nicht sowieso
1830 // schon an ist
1831 if( !ExistsOnTagItem( rItem.Which(), nStart ) )
1832 bSet = TRUE;
1833 break;
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 ) )
1841 bSplit = TRUE;
1842 bSet = bOutStyles && !bParaAttrs &&
1843 !ExistsOffTagItem( rItem.Which(), nStart, nEnd );
1844 break;
1846 case HTML_REAL_VALUE:
1847 // das Attribut kann immer ausgegeben werden
1848 bSet = TRUE;
1849 break;
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 &&
1858 (!bParaAttrs
1859 || rItem.Which()==RES_CHRATR_BACKGROUND
1860 || rItem.Which()==RES_CHRATR_OVERLINE);
1861 break;
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 );
1883 break;
1885 case HTML_AUTOFMT_VALUE:
1887 const SwFmtAutoFmt& rAutoFmt = (const SwFmtAutoFmt&)rItem;
1888 const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
1889 if( pSet.get() )
1890 Insert( *pSet.get(), nStart, nEnd, rFmtInfos, TRUE, bParaAttrs );
1892 break;
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 );
1906 break;
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();
1914 if( !bOutStyles )
1916 // Zumindest die Attribute der Zeichenvorlage uebernehmen
1917 const SwCharFmt *pCharFmt = rDrop.GetCharFmt();
1918 if( pCharFmt )
1920 Insert( pCharFmt->GetAttrSet(), nStart, nEnd,
1921 rFmtInfos, TRUE, bParaAttrs );
1924 else
1926 bSet = TRUE;
1929 break;
1930 default:
1934 if( bSet )
1935 InsertItem( rItem, nStart, nEnd );
1936 if( bSplit )
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;
1956 break;
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;
1965 break;
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;
1974 break;
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;
1986 break;
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;
1998 break;
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.
2012 continue;
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,
2021 bParaAttrs );
2022 break;
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 );
2030 nPos = nChgPos;
2033 else
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();
2047 while( nWhich )
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 );
2067 if( pTextObj )
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,
2074 RES_CHRATR_END );
2075 SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, pTextObj, TRUE );
2076 BOOL bOutStylesOld = bOutStyles;
2077 bOutStyles = FALSE;
2078 Insert( aItemSet, nPos, nPos+1, rFmtInfos, FALSE, FALSE );
2079 bOutStyles = bOutStylesOld;
2083 sal_uInt16 HTMLEndPosLst::GetScriptAtPos( xub_StrLen nPos ,
2084 sal_uInt16 nWeak )
2086 sal_uInt16 nRet = CSS1_OUTMODE_ANY_SCRIPT;
2088 sal_uInt16 nScriptChgs = aScriptChgLst.Count();
2089 sal_uInt16 i=0;
2090 while( i < nScriptChgs && nPos >= aScriptChgLst[i] )
2091 i++;
2092 ASSERT( i < nScriptChgs, "script list is to short" );
2093 if( i < nScriptChgs )
2095 if( i18n::ScriptType::WEAK == aScriptLst[i] )
2096 nRet = nWeak;
2097 else
2098 nRet = SwHTMLWriter::GetCSS1ScriptForScriptType( aScriptLst[i] );
2101 return nRet;
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();
2114 if( nStart > nPos )
2116 // dieses und alle folgenden Attribute werden erst noch geoeffnet
2117 break;
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 );
2130 if( pContext )
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
2147 USHORT i=0;
2148 while( i < aEndLst.Count() )
2150 HTMLSttEndPos *pPos = aEndLst[i];
2151 xub_StrLen nEnd = pPos->GetEnd();
2153 if( STRING_MAXLEN==nPos || nEnd == nPos )
2155 if( pContext )
2157 HTMLOutFuncs::FlushToAscii( rHWrt.Strm(), *pContext );
2158 pContext = 0; // one time ony
2160 Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
2161 _RemoveItem( i );
2163 else if( nEnd > nPos )
2165 // dieses und alle folgenden Attribute werden erst spaeter beendet
2166 break;
2168 else
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" );
2174 i++;
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();
2214 if( !pItemSet )
2216 rWrt.Strm() << sOut.GetBuffer() << '>';
2217 return rHTMLWrt;
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();
2239 if( pTblNd )
2241 const SwTableBox* pBox = pTblNd->GetTable().GetTblBox(
2242 pNd->StartOfSectionIndex() );
2243 if( pBox )
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) += '=';
2252 if( !nLeft )
2253 sOut += OOO_STRING_SVTOOLS_HTML_AL_left;
2254 else if( !nRight )
2255 sOut += OOO_STRING_SVTOOLS_HTML_AL_right;
2256 else
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();
2265 if( pBorderLine )
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();
2290 rWrt.Strm() << '>';
2291 return rHTMLWrt;
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;
2329 return rWrt;
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();
2345 if( pItemSet )
2347 if( SFX_ITEM_SET ==
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;
2358 break;
2359 case SVX_BREAK_PAGE_AFTER:
2360 bPageBreakBehind = TRUE;
2361 break;
2362 case SVX_BREAK_PAGE_BOTH:
2363 bPageBreakBefore = TRUE;
2364 bPageBreakBehind = TRUE;
2365 break;
2366 default:
2372 if( bPageBreakBefore )
2373 rWrt.Strm() << '\f';
2376 // eventuell eine Form oeffnen
2377 rHTMLWrt.OutForm();
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.
2384 if( bFlysLeft )
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
2412 // erlaubt ist
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;
2422 String aOutlineTxt;
2423 String aFullText;
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() )
2429 // <--
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?
2444 aFullText += rStr;
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
2464 // wir sie erstmal.
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
2490 do {
2491 aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset );
2493 nAttrPos++;
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 )
2502 continue;
2504 // leere Hints am Anfang nicht beachten, oder ??
2505 if( nHtEnd == nHtStt )
2506 continue;
2508 // Attribut in die Liste aufnehemen
2509 if( rHTMLWrt.bWriteAll )
2510 aEndPosLst.Insert( pHt->GetAttr(), nHtStt + nOffset,
2511 nHtEnd + nOffset,
2512 rHTMLWrt.aChrFmtInfos );
2513 else
2515 xub_StrLen nTmpStt = nHtStt < nStrPos ? nStrPos : nHtStt;
2516 xub_StrLen nTmpEnd = nHtEnd < nEnde ? nHtEnd : nEnde;
2517 aEndPosLst.Insert( pHt->GetAttr(), nTmpStt + nOffset,
2518 nTmpEnd + nOffset,
2519 rHTMLWrt.aChrFmtInfos );
2521 continue;
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
2546 if( bFlysLeft )
2547 bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
2548 nStrPos, HTML_POS_INSIDE,
2549 &aContext );
2551 BOOL bOutChar = TRUE;
2552 const SwTxtAttr * pTxtHt = 0;
2553 if( nAttrPos < nCntAttr && *pHt->GetStart() == nStrPos
2554 && nStrPos != nEnde )
2556 do {
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 );
2586 else
2588 // Hints ohne-Ende werden als letztes ausgebeben
2589 ASSERT( !pTxtHt,
2590 "Wieso gibt es da schon ein Attribut ohne Ende?" );
2591 if( rHTMLWrt.nTxtAttrsToIgnore>0 )
2593 rHTMLWrt.nTxtAttrsToIgnore--;
2595 else
2597 pTxtHt = pHt;
2598 USHORT nFldWhich;
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),
2618 nStrPos + nOffset,
2619 rHTMLWrt.aChrFmtInfos );
2622 aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
2623 aEndPosLst.OutStartAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
2625 if( pTxtHt )
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;
2638 if( bOutChar )
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;
2648 else
2649 nLineLen = rHTMLWrt.GetLineLen();
2651 xub_StrLen nWordLen = rStr.Search( ' ', nStrPos+1 );
2652 if( nWordLen == STRING_NOTFOUND )
2653 nWordLen = nEnde;
2654 nWordLen = nWordLen - nStrPos;
2656 if( nLineLen >= rHTMLWrt.nWhishLineLen ||
2657 (nLineLen+nWordLen) >= rHTMLWrt.nWhishLineLen )
2659 HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
2660 rHTMLWrt.OutNewLine();
2661 bOutChar = FALSE;
2662 if( rHTMLWrt.nLastParaToken )
2663 nPreSplitPos = nStrPos+1;
2667 if( bOutChar )
2669 if( 0x0a == c )
2671 HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
2672 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak );
2674 else
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
2692 if( bFlysLeft )
2693 bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
2694 nEnde, HTML_POS_INSIDE );
2695 ASSERT( !bFlysLeft, "Es wurden nicht alle Rahmen gespeichert!" );
2697 rHTMLWrt.bTxtAttr = FALSE;
2699 if( bWriteBreak )
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
2710 // <BR> ein &nbsp;
2711 rWrt.Strm() << '&' << OOO_STRING_SVTOOLS_HTML_S_nbsp << ';';
2713 else
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;
2732 else
2733 pStr = OOO_STRING_SVTOOLS_HTML_AL_left;
2735 else
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';
2763 return rHTMLWrt;
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
2774 nVal = 1;
2776 return nVal;
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 );
2788 return rWrt;
2792 /* File CHRATR.HXX: */
2794 static Writer& OutHTML_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
2796 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2797 if( rHTMLWrt.bOutOpts )
2798 return rWrt;
2800 // die Default-Farbe nur Schreiben, wenn sie als Hint vorkommt
2801 //if( rHTMLWrt.bTagOn && !rHTMLWrt.bTxtAttr && rHTMLWrt.pDfltColor
2802 // && rColor == *rHTMLWrt.pDfltColor )
2803 // return rWrt;
2805 if( !rHTMLWrt.bTxtAttr && rHTMLWrt.bCfgOutStyles && rHTMLWrt.bCfgPreferStyles )
2807 // Font-Farbe nicht als Tag schreiben, wenn Styles normalen Tags
2808 // vorgezogen werden
2809 return rWrt;
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 ) << '>';
2823 else
2824 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font, FALSE );
2826 return rWrt;
2830 static Writer& OutHTML_SwPosture( Writer& rWrt, const SfxPoolItem& rHt )
2832 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2833 if( rHTMLWrt.bOutOpts )
2834 return rWrt;
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 );
2847 return rWrt;
2850 static Writer& OutHTML_SvxFont( Writer& rWrt, const SfxPoolItem& rHt )
2852 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2853 if( rHTMLWrt.bOutOpts )
2854 return rWrt;
2856 if( rHTMLWrt.bTagOn )
2858 String aNames;
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 )
2865 << "\">";
2867 else
2868 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font , FALSE );
2870 return rWrt;
2873 static Writer& OutHTML_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt )
2875 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2876 if( rHTMLWrt.bOutOpts )
2877 return rWrt;
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 );
2897 rWrt.Strm() << '>';
2899 else
2901 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font, FALSE );
2904 return rWrt;
2907 static Writer& OutHTML_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt )
2909 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2910 if( rHTMLWrt.bOutOpts )
2911 return rWrt;
2913 LanguageType eLang = ((const SvxLanguageItem &)rHt).GetLanguage();
2914 if( LANGUAGE_DONTKNOW == eLang )
2915 return rWrt;
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() );
2923 rWrt.Strm() << '>';
2925 else
2927 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, FALSE );
2930 return rWrt;
2932 static Writer& OutHTML_SwWeight( Writer& rWrt, const SfxPoolItem& rHt )
2934 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2935 if( rHTMLWrt.bOutOpts )
2936 return rWrt;
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 );
2949 return rWrt;
2953 static Writer& OutHTML_SwCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
2955 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2956 if( rHTMLWrt.bOutOpts )
2957 return rWrt;
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 );
2971 return rWrt;
2975 static Writer& OutHTML_SvxEscapement( Writer& rWrt, const SfxPoolItem& rHt )
2977 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2978 if( rHTMLWrt.bOutOpts )
2979 return rWrt;
2981 const SvxEscapement eEscape =
2982 (const SvxEscapement)((const SvxEscapementItem&)rHt).GetEnumValue();
2983 const sal_Char *pStr = 0;
2984 switch( eEscape )
2986 case SVX_ESCAPEMENT_SUPERSCRIPT: pStr = OOO_STRING_SVTOOLS_HTML_superscript; break;
2987 case SVX_ESCAPEMENT_SUBSCRIPT: pStr = OOO_STRING_SVTOOLS_HTML_subscript; break;
2988 default:
2992 if( pStr )
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 );
3002 return rWrt;
3007 static Writer& OutHTML_SwUnderline( Writer& rWrt, const SfxPoolItem& rHt )
3009 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3010 if( rHTMLWrt.bOutOpts )
3011 return rWrt;
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 );
3024 return rWrt;
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 );
3040 return rWrt;
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) )
3050 return rWrt;
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 );
3062 return rWrt;
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() )
3075 return rWrt;
3077 // Tag aus? Dann nur ein </A> ausgeben.
3078 if( !bOn )
3080 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_anchor, FALSE );
3081 return rWrt;
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 );
3092 USHORT nPos;
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 );
3103 USHORT nPos;
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:
3116 sOut += "western";
3117 break;
3118 case CSS1_OUTMODE_CJK:
3119 sOut += "cjk";
3120 break;
3121 case CSS1_OUTMODE_CTL:
3122 sOut += "ctl";
3123 break;
3125 sOut += '\"';
3128 rWrt.Strm() << sOut.GetBuffer();
3130 #define REL_HACK
3131 #ifdef REL_HACK
3132 String sRel;
3133 #endif
3135 if( aURL.Len() || bEvents )
3137 #ifdef REL_HACK
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 );
3144 aURL.Erase( nPos );
3146 #endif
3147 aURL.EraseLeadingChars().EraseTrailingChars();
3149 ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
3150 rWrt.Strm() << sOut.GetBuffer();
3151 rHTMLWrt.OutHyperlinkHRefValue( aURL );
3152 sOut = '\"';
3154 else
3155 sOut.Erase();
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 );
3163 sOut = '\"';
3166 const String& rTarget = rINetFmt.GetTargetFrame();
3167 if( rTarget.Len() )
3169 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
3170 rWrt.Strm() << sOut.GetBuffer();
3171 HTMLOutFuncs::Out_String( rWrt.Strm(), rTarget, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
3172 sOut = '\"';
3175 #ifdef REL_HACK
3176 if( sRel.Len() )
3177 sOut += ByteString( sRel, RTL_TEXTENCODING_ASCII_US );
3178 #endif
3179 if( sOut.Len() )
3180 rWrt.Strm() << sOut.GetBuffer();
3182 if( bEvents )
3183 HTMLOutFuncs::Out_Events( rWrt.Strm(), *pMacTable, aAnchorEventTable,
3184 rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc,
3185 &rHTMLWrt.aNonConvertableCharacters );
3186 rWrt.Strm() << ">";
3188 return rWrt;
3191 static Writer& OutHTML_SwFmtINetFmt( Writer& rWrt, const SfxPoolItem& rHt )
3193 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3195 if( rHTMLWrt.bOutOpts )
3196 return rWrt;
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 );
3213 // und merken
3214 const SwFmtINetFmt *pINetFmt = new SwFmtINetFmt( rINetFmt );
3215 rHTMLWrt.aINetFmts.C40_INSERT( SwFmtINetFmt, pINetFmt,
3216 rHTMLWrt.aINetFmts.Count() );
3218 else
3220 // das
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 );
3231 delete pINetFmt;
3234 if( rHTMLWrt.aINetFmts.Count() )
3236 // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
3237 // werden muss
3238 SwFmtINetFmt *pINetFmt =
3239 rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
3240 OutHTML_INetFmt( rWrt, *pINetFmt, TRUE );
3244 return rWrt;
3247 static Writer& OutHTML_SwTxtCharFmt( Writer& rWrt, const SfxPoolItem& rHt )
3249 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3250 if( rHTMLWrt.bOutOpts )
3251 return rWrt;
3253 const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rHt;
3254 const SwCharFmt* pFmt = rChrFmt.GetCharFmt();
3256 if( !pFmt )
3258 return rWrt;
3261 SwHTMLFmtInfo aFmtInfo( pFmt );
3262 USHORT nPos;
3263 if( !rHTMLWrt.aChrFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
3264 return rWrt;
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;
3274 else
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 )
3284 if( aClass.Len() )
3285 aClass += '-';
3286 switch( rHTMLWrt.nCSS1Script )
3288 case CSS1_OUTMODE_WESTERN:
3289 aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
3290 break;
3291 case CSS1_OUTMODE_CJK:
3292 aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
3293 break;
3294 case CSS1_OUTMODE_CTL:
3295 aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
3296 break;
3299 HTMLOutFuncs::Out_String( rWrt.Strm(), aClass,
3300 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
3301 sOut = '\"';
3303 sOut += '>';
3304 rWrt.Strm() << sOut.GetBuffer();
3306 else
3308 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
3309 pFmtInfo->aToken.Len() ? pFmtInfo->aToken.GetBuffer()
3310 : OOO_STRING_SVTOOLS_HTML_span,
3311 FALSE );
3314 return rWrt;
3317 static Writer& OutHTML_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt )
3319 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
3320 if( !rHTMLWrt.bOutOpts || !rHTMLWrt.bTagOn )
3321 return rWrt;
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;
3331 default:
3334 if( pStr )
3336 ByteString sOut( ' ' );
3337 ((sOut += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
3338 rWrt.Strm() << sOut.GetBuffer();
3341 return rWrt;
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,
3442 /* RES_BREAK */ 0,
3443 /* RES_CNTNT */ 0,
3444 /* RES_HEADER */ 0,
3445 /* RES_FOOTER */ 0,
3446 /* RES_PRINT */ 0,
3447 /* RES_OPAQUE */ 0,
3448 /* RES_PROTECT */ 0,
3449 /* RES_SURROUND */ 0,
3450 /* RES_VERT_ORIENT */ 0,
3451 /* RES_HORI_ORIENT */ 0,
3452 /* RES_ANCHOR */ 0,
3453 /* RES_BACKGROUND */ 0,
3454 /* RES_BOX */ 0,
3455 /* RES_SHADOW */ 0,
3456 /* RES_FRMMACRO */ 0,
3457 /* RES_COL */ 0,
3458 /* RES_KEEP */ 0,
3459 /* RES_URL */ 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