/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"



#include "hintids.hxx"
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <svl/whiter.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/crsditem.hxx>
#include <editeng/blnkitem.hxx>
#include <editeng/cmapitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/postitem.hxx>
#include <editeng/kernitem.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/lspcitem.hxx>
#include <editeng/adjitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/brshitem.hxx>
#include <editeng/brkitem.hxx>
#include <editeng/keepitem.hxx>
#include <editeng/widwitem.hxx>
#include <editeng/spltitem.hxx>
#include <editeng/orphitem.hxx>
#include <svx/xoutbmp.hxx>
#include <svx/svdobj.hxx>
#include <editeng/langitem.hxx>
#include <editeng/frmdiritem.hxx>
#include <svtools/htmlout.hxx>
#include <svtools/htmlkywd.hxx>
#include <svx/htmlmode.hxx>
#include <svl/urihelper.hxx>
#include <tools/urlobj.hxx>
#include <tools/bigint.hxx>
#include <unotools/charclass.hxx>
#include <i18npool/mslangid.hxx>
#include <charfmt.hxx>
#include <fmtcol.hxx>
#include <fmtfsize.hxx>
#include <fmtornt.hxx>
#include <fmtpdsc.hxx>
#include <fmtlsplt.hxx>
#include <pagedesc.hxx>
#include <fmtanchr.hxx>
#include <docary.hxx>
#include <pam.hxx>
#include <viewsh.hxx>
#include <viewopt.hxx>
#include <swtable.hxx>
// OTES
#include <ftninfo.hxx>
#include <ftnidx.hxx>
#include <txtftn.hxx>
#include <fmtftn.hxx>
// FOOTNOTES
#include "doc.hxx"
#include "swerror.h"
#include "charatr.hxx"
#include "paratr.hxx"
#include "frmatr.hxx"
#include "poolfmt.hxx"
#include "fltini.hxx"
#include "css1kywd.hxx"
#include "wrthtml.hxx"
#include "htmlnum.hxx"

#include <IDocumentStylePoolAccess.hxx>
#include <numrule.hxx>

/*
 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
 * definiert und mit der akt. verglichen. Bei unterschieden wird der
 * Compiler schon meckern.
 *
 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
 */
#if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)

#define ATTRFNTAB_SIZE 130
#if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
#error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
#endif

#endif

#define HTML_HEADSPACE (12*20)

#define CSS1_BACKGROUND_ATTR	1
#define CSS1_BACKGROUND_PAGE	2
#define CSS1_BACKGROUND_TABLE	3
#define CSS1_BACKGROUND_FLY		4
#define CSS1_BACKGROUND_SECTION	5

#define CSS1_FRMSIZE_WIDTH 		0x01
#define CSS1_FRMSIZE_VARHEIGHT 	0x02
#define CSS1_FRMSIZE_MINHEIGHT	0x04
#define CSS1_FRMSIZE_FIXHEIGHT	0x08
#define CSS1_FRMSIZE_ANYHEIGHT	0x0e
#define CSS1_FRMSIZE_PIXEL		0x10

using namespace ::com::sun::star;

//-----------------------------------------------------------------------

sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_rule_end, " }" );
sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_span_tag_end, "\">" );
const sal_Char cCSS1_style_opt_end = '\"';

sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sHTML_FTN_fontheight, "57%" );

extern SwAttrFnTab aCSS1AttrFnTab;

static Writer& OutCSS1_SwFmt( Writer& rWrt, const SwFmt& rFmt,
							  IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate );
static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rFmt,
								   IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate,
								   sal_uInt16 nRefPoolId, sal_Bool bExtRef,
								   sal_Bool bPseudo=sal_True );
static Writer& OutCSS1_SwFtnInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
								  SwDoc *pDoc, sal_uInt16 nNotes, sal_Bool bEndNote );
static void OutCSS1_SwFmtDropAttrs( SwHTMLWriter& rHWrt,
									const SwFmtDrop& rDrop,
								 	const SfxItemSet *pCharFmtItemSet=0 );
static Writer& OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( Writer& rWrt,
					const SvxUnderlineItem *pUItem,
					const SvxOverlineItem *pOItem,
					const SvxCrossedOutItem *pCOItem,
					const SvxBlinkItem *pBItem );
static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt );
static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt );
static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt );
static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt );
static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
										const SvxULSpaceItem *pULSpace,
										const SvxLRSpaceItem *pLRSpace );
static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
										const SfxItemSet& rItemSet,
										sal_Bool bDeep );
static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
								 sal_uInt16 nMode, const String *pGrfName );
static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt );
static Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt );
static Writer& OutCSS1_SwFmtFrmSize( Writer& rWrt, const SfxPoolItem& rHt,
									 sal_uInt16 nMode );
static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
										const SfxItemSet& rItemSet,
										sal_Bool bDeep );
static Writer& OutCSS1_SwFmtLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt );

static void ConvToHex( sal_uInt16 nHex, ByteString& rStr )
{
	sal_Char aNToABuf[] = "00";

	// Pointer an das Bufferende setzen
	sal_Char *pStr = aNToABuf + (sizeof(aNToABuf)-1);
	for( sal_uInt8 n = 0; n < 2; ++n )
	{
		*(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
		if( *pStr > '9' )
			*pStr += 39;
		nHex >>= 4;
	}

	rStr.Append( aNToABuf );
}

static void GetCSS1Color( const Color& rColor, ByteString& rStr )
{
	rStr += '#';

	ConvToHex( rColor.GetRed(), rStr );
	ConvToHex( rColor.GetGreen(), rStr );
	ConvToHex( rColor.GetBlue(), rStr );
}

class SwCSS1OutMode
{
	SwHTMLWriter& rWrt;
	sal_uInt16 nOldMode;

public:

	SwCSS1OutMode( SwHTMLWriter& rHWrt, sal_uInt16 nMode, sal_Bool bStartFirst=sal_True,
				   const String *pSelector=0 ) :
		rWrt( rHWrt ),
		nOldMode( rHWrt.nCSS1OutMode )
	{
		rWrt.nCSS1OutMode = nMode;
		if( bStartFirst )
			rWrt.bFirstCSS1Property = sal_True;
		if( pSelector )
			rWrt.aCSS1Selector = *pSelector;
	}

	~SwCSS1OutMode()
	{
		rWrt.nCSS1OutMode = nOldMode;
	}
};



void SwHTMLWriter::OutCSS1_Property( const sal_Char *pProp,
									 const sal_Char *pVal,
									 const String *pSVal )
{
	ByteString sOut;

	if( bFirstCSS1Rule && (nCSS1OutMode & CSS1_OUTMODE_RULE_ON)!=0 )
	{
		bFirstCSS1Rule = sal_False;
		OutNewLine();
        ((((sOut += '<') += OOO_STRING_SVTOOLS_HTML_style) += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += "=\"text/css\">";
        Strm() << sOut.GetBuffer();
        sOut.Erase();
		OutNewLine();
		Strm() << '<' << OOO_STRING_SVTOOLS_HTML_comment;

		IncIndentLevel();
	}

	if( bFirstCSS1Property )
	{
		switch( nCSS1OutMode & CSS1_OUTMODE_ANY_ON )
		{
		case CSS1_OUTMODE_SPAN_TAG_ON:
		case CSS1_OUTMODE_SPAN_TAG1_ON:
			if( bTagOn )
			{
				((((sOut += '<') += OOO_STRING_SVTOOLS_HTML_span) += ' ') += OOO_STRING_SVTOOLS_HTML_O_style) += "=\"";
			}
			else
			{
				HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False );
				return;
			}
			break;

		case CSS1_OUTMODE_RULE_ON:
			{
				ByteString sTmp( aCSS1Selector, eDestEnc );
				OutNewLine();
				(sOut = sTmp) += " { ";
			}
			break;

		case CSS1_OUTMODE_STYLE_OPT_ON:
			((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_style) += "=\"";
			break;
		}
		bFirstCSS1Property = sal_False;
	}
	else
	{
		sOut += "; ";
	}


	(sOut += pProp) += ": ";
	if( nCSS1OutMode & CSS1_OUTMODE_ENCODE )
	{
		// In STYLE-Optionen den String codieren
		Strm() << sOut.GetBuffer();
		sOut.Erase();
		if( pVal )
			HTMLOutFuncs::Out_String( Strm(), String::CreateFromAscii(pVal),
									  eDestEnc, &aNonConvertableCharacters );
		else if( pSVal )
			HTMLOutFuncs::Out_String( Strm(), *pSVal, eDestEnc, &aNonConvertableCharacters );
	}
	else
	{
		// Im STYLE-Tag des String direct ausgeben
		if( pVal )
			sOut += pVal;
		else if( pSVal )
		{
			ByteString sTmp( *pSVal, eDestEnc );
			sOut += sTmp;
		}
	}

	if( sOut.Len() )
		Strm() << sOut.GetBuffer();
}

static void AddUnitPropertyValue( long nVal, FieldUnit eUnit, ByteString& rOut )
{
	if( nVal < 0 )
	{
		// Vorzeichen extra behandeln
		nVal = -nVal;
		rOut += '-';
	}

	// Die umgerechnete Einheit ergibt sich aus (x * nMul)/(nDiv*nFac*10)
	long nMul = 1000;
	long nDiv = 1;
	long nFac = 100;
	const sal_Char *pUnit;
	switch( eUnit )
	{
	case FUNIT_100TH_MM:
		ASSERT( FUNIT_MM == eUnit, "Masseinheit wird nicht unterstuetzt" );
	case FUNIT_MM:
		// 0.01mm = 0.57twip
		nMul = 25400;	// 25.4 * 1000
		nDiv = 1440;	// 72 * 20;
		nFac = 100;
		pUnit = sCSS1_UNIT_mm;
		break;

	case FUNIT_M:
	case FUNIT_KM:
		ASSERT( FUNIT_CM == eUnit, "Masseinheit wird nicht unterstuetzt" );
	case FUNIT_CM:
#ifdef EXACT_VALUES
		// 0.001cm = 0.57twip
		nMul = 25400;	// 2.54 * 10000
		nDiv = 1440;	// 72 * 20;
		nFac = 1000;
#else
		// 0.01cm = 5.7twip (ist zwar ungenau, aber die UI ist auch ungenau)
		nMul = 2540;	// 2.54 * 1000
		nDiv = 1440;	// 72 * 20;
		nFac = 100;
#endif
		pUnit = sCSS1_UNIT_cm;
		break;

	case FUNIT_TWIP:
		ASSERT( FUNIT_POINT == eUnit, "Masseinheit wird nicht unterstuetzt" );
	case FUNIT_POINT:
#ifdef EXACT_VALUES
		// 0.01pt = 0.2twip
		nMul = 1000;
		nDiv = 20;
		nFac = 100;
#else
		// 0.1pt = 2.0twip (ist zwar ungenau, aber die UI ist auch ungenau)
		nMul = 100;
		nDiv = 20;
		nFac = 10;
#endif
		pUnit = sCSS1_UNIT_pt;
		break;

	case FUNIT_PICA:
#ifdef EXACT_VALUES
		// 0.001pc = 0.24twip
		nMul = 10000;
		nDiv = 12 * 20;
		nFac = 1000;
#else
		// 0.01pc = 2.40twip (ist zwar ungenau, aber die UI ist auch ungenau)
		nMul = 1000;
		nDiv = 240;		// 12 * 20;
		nFac = 100;
#endif
		pUnit = sCSS1_UNIT_pc;
		break;

	case FUNIT_NONE:
	case FUNIT_FOOT:
	case FUNIT_MILE:
	case FUNIT_CUSTOM:
	case FUNIT_PERCENT:
	case FUNIT_INCH:
	default:
		ASSERT( FUNIT_INCH == eUnit, "Masseinheit wird nicht unterstuetzt" );
#ifdef EXACT_VALUES
		// 0.0001in = 0.144twip
		nMul = 100000;
		nDiv = 1440;	// 72 * 20;
		nFac = 10000;
#else
		// 0.01in = 14.4twip (ist zwar ungenau, aber die UI ist auch ungenau)
		nMul = 1000;
		nDiv = 1440;	// 72 * 20;
		nFac = 100;
#endif
		pUnit = sCSS1_UNIT_inch;
		break;
	}

    long nLongVal = 0;
	sal_Bool bOutLongVal = sal_True;
	if( nVal > LONG_MAX / nMul )
	{
		// Zum Unrechnen der Einheit wird ein BigInt benoetigt
#ifdef SAL_INT64_IS_STRUCT
		BigInt nBigVal( nVal );
		nBigVal *= nMul;
		nBigVal /= nDiv;
		nBigVal += 5;
		nBigVal /= 10;

		if( nBigVal.IsLong() )
		{
			// Zum Ausgeben des Wertes reicht ein long.
			nLongVal = (long)nBigVal;
		}
		else
		{
			BigInt nBigFac( nFac );
			BigInt nBig10( 10 );
			rOut += (long)(nBigVal / nBigFac);
			if( !(nBigVal % nBigFac).IsZero() )
			{
				rOut += '.';
				while( nFac > 1 && !(nBigVal % nBigFac).IsZero() )
				{
					nFac /= 10;
					nBigFac = nFac;
					rOut += (int)((nBigVal / nBigFac) % nBig10 );
				}
			}
			bOutLongVal = sal_False;
		}
#else
		sal_Int64 nBigVal( nVal );
		nBigVal *= nMul;
		nBigVal /= nDiv;
		nBigVal += 5;
		nBigVal /= 10;

		if( nBigVal <= LONG_MAX )
		{
			// Zum Ausgeben des Wertes reicht ein long.
			nLongVal = (long)nBigVal;
		}
		else
		{
			rOut += ByteString::CreateFromInt64( nBigVal / (sal_Int64)nFac );
			if( (nBigVal % (sal_Int64)nFac) != 0 )
			{
				rOut += '.';
				while( nFac > 1 && (nBigVal % (sal_Int64)nFac) != 0 )
				{
					nFac /= 10;
					rOut += ByteString::CreateFromInt64(
								(nBigVal / (sal_Int64)nFac) % (sal_Int64)10 );
				}
			}
			bOutLongVal = sal_False;
		}
#endif
	}
	else
	{
		nLongVal = nVal * nMul;
		nLongVal /= nDiv;
		nLongVal += 5;
		nLongVal /= 10;
	}

	if( bOutLongVal )
	{
		rOut += ByteString::CreateFromInt32( nLongVal/nFac );
		if( (nLongVal % nFac) != 0 )
		{
			rOut += '.';
			while( nFac > 1 && (nLongVal % nFac) != 0 )
			{
				nFac /= 10;
				rOut += ByteString::CreateFromInt32( (nLongVal / nFac) % 10 );
			}
		}
	}

	rOut.Append( pUnit );
}

void SwHTMLWriter::OutCSS1_UnitProperty( const sal_Char *pProp, long nVal )
{
	ByteString sOut;
	AddUnitPropertyValue( nVal, eCSS1Unit, sOut );
	OutCSS1_PropertyAscii( pProp, sOut );
}

void SwHTMLWriter::OutCSS1_PixelProperty( const sal_Char *pProp, long nVal,
										  sal_Bool bVert )
{
	if( nVal && Application::GetDefaultDevice() )
	{
		Size aSz( bVert ? 0 : nVal, bVert ? nVal : 0 );
		aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode( MAP_TWIP) );
		nVal = bVert ? aSz.Height() : aSz.Width();
		if( !nVal )
			nVal = 1;
	}

	ByteString sOut( ByteString::CreateFromInt32( nVal ) );
	sOut.Append( sCSS1_UNIT_px );
	OutCSS1_PropertyAscii( pProp, sOut );
}

void SwHTMLWriter::OutCSS1_SfxItemSet( const SfxItemSet& rItemSet,
									   sal_Bool bDeep )
{
	// den ItemSet ausgeben, und zwar inklusive aller Attribute
	Out_SfxItemSet( aCSS1AttrFnTab, *this, rItemSet, bDeep );

	// ein par Attribute benoetigen eine Spezial-Behandlung
	const SfxPoolItem *pItem = 0;

	// Underline, Overline, CrossedOut und Blink bilden zusammen eine CSS1-Property
	// (geht natuerlich nicht bei Hints)
	if( !IsCSS1Source(CSS1_OUTMODE_HINT) )
	{
		const SvxUnderlineItem *pUnderlineItem = 0;
		if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_UNDERLINE, bDeep, &pItem ))
			pUnderlineItem = (const SvxUnderlineItem *)pItem;

		const SvxOverlineItem *pOverlineItem = 0;
		if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_OVERLINE, bDeep, &pItem ))
			pOverlineItem = (const SvxOverlineItem *)pItem;

		const SvxCrossedOutItem *pCrossedOutItem = 0;
		if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_CROSSEDOUT, bDeep, &pItem ))
			pCrossedOutItem = (const SvxCrossedOutItem *)pItem;

		const SvxBlinkItem *pBlinkItem = 0;
		if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_BLINK, bDeep, &pItem ))
			pBlinkItem = (const SvxBlinkItem *)pItem;

		if( pUnderlineItem || pOverlineItem || pCrossedOutItem || pBlinkItem )
			OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( *this, pUnderlineItem,
												 pOverlineItem,
												 pCrossedOutItem,
												 pBlinkItem );

		OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( *this, rItemSet, bDeep );
	}

	if( !bFirstCSS1Property )
	{
		// wenn eine Property als Bestandteil einer Style-Option
		// ausgegeben wurde, muss die Optiomn noch beendet werden
		ByteString sOut;
		switch( nCSS1OutMode & CSS1_OUTMODE_ANY_OFF )
		{
		case CSS1_OUTMODE_SPAN_TAG_OFF:
			sOut = sCSS1_span_tag_end;
			break;

		case CSS1_OUTMODE_STYLE_OPT_OFF:
			sOut = cCSS1_style_opt_end;
			break;

		case CSS1_OUTMODE_RULE_OFF:
			sOut = sCSS1_rule_end;
			break;
		}
		if( sOut.Len() )
			Strm() << sOut.GetBuffer();
	}
}

void SwHTMLWriter::OutStyleSheet( const SwPageDesc& rPageDesc, sal_Bool bUsed )
{
	bFirstCSS1Rule = sal_True;

// Feature: PrintExt
	if( IsHTMLMode(HTMLMODE_PRINT_EXT) )
	{
		const SwPageDesc *pFirstPageDesc = 0;
		sal_uInt16 nFirstRefPoolId = RES_POOLPAGE_HTML;
		bCSS1IgnoreFirstPageDesc = sal_True;

		// Erstmal versuchen wir zu erraten, wie das Dokument so augebaut ist.
		// Erlaubt sind nur die Vorlagen HTML, erste Seite, linke Seite und
		// rechte Seite.
		// Eine erste Seite wird nur exportiert, wenn die erste Seite auch
		// wirklich die Vorlage "erste Seite" ist.
		// Linke und rechte Seiten werden nur exportiert, wenn diese beiden
		// Vorlagen untereinander verkettet werden.
		// Wenn andere Vorlagen verwendet werden, wird nur in sehr einfachen
		// Faellen etwas exportiert.
		const SwPageDesc *pPageDesc = &rPageDesc;
		const SwPageDesc *pFollow = rPageDesc.GetFollow();
		if( RES_POOLPAGE_FIRST == pPageDesc->GetPoolFmtId() &&
			pFollow != pPageDesc &&
			!IsPoolUserFmt( pFollow->GetPoolFmtId() ) )
		{
			// Das Dokument hat eine erste Seite
			pFirstPageDesc = pPageDesc;
			pPageDesc = pFollow;
			pFollow = pPageDesc->GetFollow();
		}

		IDocumentStylePoolAccess* pStylePoolAccess = getIDocumentStylePoolAccess();
		if( pPageDesc == pFollow )
		{
			// Das Dokument ist einseitig. Egal welche Seite verwendet wird,
			// es wird kein zweiseitiges Dokument daraus gemacht.
			// Die Attributierung wird relativ zur HTML-Seitenvorlage
			// aus der HTML-Vorlage exportiert.
          OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, pTemplate,
								RES_POOLPAGE_HTML, sal_True, sal_False );
			nFirstRefPoolId = pFollow->GetPoolFmtId();
		}
		else if( (RES_POOLPAGE_LEFT == pPageDesc->GetPoolFmtId() &&
				  RES_POOLPAGE_RIGHT == pFollow->GetPoolFmtId()) ||
				 (RES_POOLPAGE_RIGHT == pPageDesc->GetPoolFmtId() &&
				  RES_POOLPAGE_LEFT == pFollow->GetPoolFmtId()) )
		{
			// Das Dokument ist zweiseitig
          OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, pTemplate,
								RES_POOLPAGE_HTML, sal_True );
          OutCSS1_SwPageDesc( *this, *pFollow, pStylePoolAccess, pTemplate,
								RES_POOLPAGE_HTML, sal_True );
			nFirstRefPoolId = RES_POOLPAGE_RIGHT;
			bCSS1IgnoreFirstPageDesc = sal_False;
		}
		// Alles andere bekommen wir nicht hin.

		if( pFirstPageDesc )
          OutCSS1_SwPageDesc( *this, *pFirstPageDesc, pStylePoolAccess, pTemplate,
								nFirstRefPoolId, sal_False );
	}
// /Feature: PrintExt


	// The text body style has to be exported always (if it is changed compared
	// to the template), because it is used as reference for any style
	// that maps to <P>, and that's especially the standard style
    getIDocumentStylePoolAccess()->GetTxtCollFromPool( RES_POOLCOLL_TEXT, false );

	// das Default-TextStyle wir nicht mit ausgegeben !!
	// das 0-Style ist das Default, wird nie ausgegeben !!
	sal_uInt16 nArrLen = pDoc->GetTxtFmtColls()->Count();
	sal_uInt16 i;

	for( i = 1; i < nArrLen; i++ )
	{
		const SwTxtFmtColl* pColl = (*pDoc->GetTxtFmtColls())[i];
		sal_uInt16 nPoolId = pColl->GetPoolFmtId();
		if( !bUsed || nPoolId == RES_POOLCOLL_TEXT ||
			pDoc->IsUsed( *pColl ) )
			OutCSS1_SwFmt( *this, *pColl, pDoc, pTemplate );
	}

	// das Default-TextStyle wir nicht mit ausgegeben !!
	nArrLen = pDoc->GetCharFmts()->Count();
	for( i=1; i<nArrLen; i++ )
	{
		const SwCharFmt *pCFmt = (*pDoc->GetCharFmts())[i];
		sal_uInt16 nPoolId = pCFmt->GetPoolFmtId();
		if( !bUsed || nPoolId == RES_POOLCHR_INET_NORMAL ||
			nPoolId == RES_POOLCHR_INET_VISIT ||
			pDoc->IsUsed( *pCFmt ) )
			OutCSS1_SwFmt( *this, *pCFmt, pDoc, pTemplate );
	}

	const SwFtnIdxs& rIdxs = pDoc->GetFtnIdxs();
	nArrLen = rIdxs.Count();
	sal_uInt16 nEnd = 0, nFtn = 0;
	for( i=0; i < nArrLen; i++ )
	{
		if( rIdxs[i]->GetFtn().IsEndNote() )
			nEnd++;
		else
			nFtn++;
	}
	OutCSS1_SwFtnInfo( *this, pDoc->GetFtnInfo(), pDoc, nFtn, sal_False );
	OutCSS1_SwFtnInfo( *this, pDoc->GetEndNoteInfo(), pDoc, nEnd, sal_True );

	if( !bFirstCSS1Rule )
	{
		DecIndentLevel();
		OutNewLine();
		Strm() << "-->";

		OutNewLine();
		HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_style, sal_False );
	}
	else
	{
		bFirstCSS1Rule = sal_False;
	}

	nDfltTopMargin = 0;
	nDfltBottomMargin = 0;
}

//-----------------------------------------------------------------------

// wenn pPseudo gesetzt ist werden Styles-Sheets ausgegeben,
// sonst wird nur nach Token und Class fuer ein Format gesucht
sal_uInt16 SwHTMLWriter::GetCSS1Selector( const SwFmt *pFmt, ByteString& rToken,
									  String& rClass, sal_uInt16& rRefPoolId,
									  String *pPseudo )
{
	sal_uInt16 nDeep = 0;
	rToken.Erase(); rClass.Erase();
	rRefPoolId = 0;
	if( pPseudo )
		pPseudo->Erase();

	sal_Bool bChrFmt = RES_CHRFMT==pFmt->Which();

	// Nach oben die Formate abklappern, bis man auf eine Standard-
	// oder eine HTML-Tag-Vorlage trifft
	const SwFmt *pPFmt = pFmt;
	while( pPFmt && !pPFmt->IsDefault() )
	{
		sal_Bool bStop = sal_False;
		sal_uInt16 nPoolId = pPFmt->GetPoolFmtId();
		if( USER_FMT & nPoolId )
		{
			// Benutzer-Vorlagen
			const String& rNm = pPFmt->GetName();
			switch( rNm.GetChar(0) )
			{
						// nicht mehr unterstuetzt:
						// OOO_STRING_SVTOOLS_HTML_author
						// OOO_STRING_SVTOOLS_HTML_acronym
						// OOO_STRING_SVTOOLS_HTML_abbreviation
						// OOO_STRING_SVTOOLS_HTML_deletedtext
						// OOO_STRING_SVTOOLS_HTML_insertedtext
						// OOO_STRING_SVTOOLS_HTML_language
						// OOO_STRING_SVTOOLS_HTML_person
			case 'B':	if( !bChrFmt && rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_blockquote) )
						{
							rRefPoolId = RES_POOLCOLL_HTML_BLOCKQUOTE;
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_blockquote );
						}
						break;
			case 'C':	if( bChrFmt )
						{
							if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_citiation) )
							{
								rRefPoolId = RES_POOLCHR_HTML_CITIATION;
								rToken.Assign( OOO_STRING_SVTOOLS_HTML_citiation );
							}
							else if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_code) )
							{
								rRefPoolId = RES_POOLCHR_HTML_CODE;
								rToken.Assign( OOO_STRING_SVTOOLS_HTML_code );
							}
						}
						break;
			case 'D':	if( bChrFmt && rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_definstance) )
						{
							rRefPoolId = RES_POOLCHR_HTML_DEFINSTANCE;
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_definstance);
						}
						else if( !bChrFmt )
						{
							sal_uInt16 nDefListLvl = GetDefListLvl( rNm, nPoolId );
							// Die Vorlagen DD 1/DT 1 werden ausgegeben,
							// aber keine von ihnen abgeleiteten Vorlagen,
							// auch nicht DD 2/DT 2 etc.
							if( nDefListLvl )
							{
								if( pPseudo &&
									(nDeep || (nDefListLvl & 0x0fff) > 1) )
								{
									bStop = sal_True;
								}
								else if( nDefListLvl & HTML_DLCOLL_DD )
								{
									rRefPoolId = RES_POOLCOLL_HTML_DD;
									rToken.Assign( OOO_STRING_SVTOOLS_HTML_dd );
								}
								else
								{
									rRefPoolId = RES_POOLCOLL_HTML_DT;
									rToken.Assign( OOO_STRING_SVTOOLS_HTML_dt );
								}
							}
						}
						break;
			case 'E':	if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_emphasis ) )
						{
							rRefPoolId = RES_POOLCHR_HTML_EMPHASIS;
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_emphasis );
						}
						break;
			case 'H':	if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_horzrule ) )
							// HR nicht ausgeben!
							bStop = (nDeep==0);
						break;
			case 'K':	if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_keyboard ) )
						{
							rRefPoolId = RES_POOLCHR_HTML_KEYBOARD;
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_keyboard );
						}
						break;
			case 'L':	if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_listing ) )
						{
							// Listing als PRE exportieren bzw. von
							// PRE abgeleitete Vorlage exportieren
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
							rRefPoolId = RES_POOLCOLL_HTML_PRE;
							nDeep = CSS1_FMT_CMPREF;
						}
						break;
			case 'P':	if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_preformtxt ) )
						{
							rRefPoolId = RES_POOLCOLL_HTML_PRE;
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
						}
						break;
			case 'S':	if( bChrFmt )
						{
							if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_sample ) )
							{
								rRefPoolId = RES_POOLCHR_HTML_SAMPLE;
								rToken.Assign( OOO_STRING_SVTOOLS_HTML_sample );
							}
							else if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_strong ) )
							{
								rRefPoolId = RES_POOLCHR_HTML_STRONG;
								rToken.Assign( OOO_STRING_SVTOOLS_HTML_strong );
							}
						}
						break;
			case 'T':	if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_teletype ) )
						{
							rRefPoolId = RES_POOLCHR_HTML_TELETYPE;
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_teletype );
						}
						break;
			case 'V':	if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_variable ) )
						{
							rRefPoolId = RES_POOLCHR_HTML_VARIABLE;
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_variable );
						}
						break;
			case 'X':	if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_xmp ) )
						{
							// XMP als PRE exportieren (aber nicht die
							// Vorlage als Style)
							rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
							rRefPoolId = RES_POOLCOLL_HTML_PRE;
							nDeep = CSS1_FMT_CMPREF;
						}
						break;
			}

			// Wenn eine PoolId gesetzt ist, entspricht der Name der
			// Vorlage dem szugehoerigen Token
			ASSERT( rRefPoolId != 0 == rToken.Len() > 0,
					"Token missing" );
		}
		else
		{
			// Pool-Vorlagen
			switch( nPoolId )
			{
			// Absatz-Vorlagen
			case RES_POOLCOLL_HEADLINE_BASE:
			case RES_POOLCOLL_STANDARD:
				// diese Vorlagen nicht ausgeben
				bStop = (nDeep==0);
				break;
			case RES_POOLCOLL_TEXT:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
				break;
			case RES_POOLCOLL_HEADLINE1:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_head1 );
				break;
			case RES_POOLCOLL_HEADLINE2:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_head2 );
				break;
			case RES_POOLCOLL_HEADLINE3:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_head3 );
				break;
			case RES_POOLCOLL_HEADLINE4:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_head4 );
				break;
			case RES_POOLCOLL_HEADLINE5:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_head5 );
				break;
			case RES_POOLCOLL_HEADLINE6:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_head6 );
				break;
			case RES_POOLCOLL_SENDADRESS:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_address );
				break;
			case RES_POOLCOLL_HTML_BLOCKQUOTE:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_blockquote );
				break;
			case RES_POOLCOLL_HTML_PRE:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
				break;

			case RES_POOLCOLL_HTML_DD:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_dd );
				break;
			case RES_POOLCOLL_HTML_DT:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_dt );
				break;

			case RES_POOLCOLL_TABLE:
				if( pPseudo )
				{
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_tabledata );
					rToken.Append( ' ' );
					rToken.Append( OOO_STRING_SVTOOLS_HTML_parabreak );
				}
				else
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
				break;
			case RES_POOLCOLL_TABLE_HDLN:
				if( pPseudo )
				{
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_tableheader );
					rToken.Append( ' ' );
					rToken.Append( OOO_STRING_SVTOOLS_HTML_parabreak );
				}
				else
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
				break;
			case RES_POOLCOLL_HTML_HR:
				// HR nicht ausgeben!
				bStop = (nDeep==0);
				break;
			case RES_POOLCOLL_FOOTNOTE:
				if( !nDeep )
				{
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
					rClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote );
					rRefPoolId = RES_POOLCOLL_TEXT;
					nDeep = CSS1_FMT_CMPREF;
				}
				break;
			case RES_POOLCOLL_ENDNOTE:
				if( !nDeep )
				{
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
					rClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote );
					rRefPoolId = RES_POOLCOLL_TEXT;
					nDeep = CSS1_FMT_CMPREF;
				}
				break;

			// Zeichen-Vorlagen
			case RES_POOLCHR_HTML_EMPHASIS:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_emphasis );
				break;
			case RES_POOLCHR_HTML_CITIATION:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_citiation );
				break;
			case RES_POOLCHR_HTML_STRONG:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_strong );
				break;
			case RES_POOLCHR_HTML_CODE:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_code );
				break;
			case RES_POOLCHR_HTML_SAMPLE:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_sample );
				break;
			case RES_POOLCHR_HTML_KEYBOARD:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_keyboard );
				break;
			case RES_POOLCHR_HTML_VARIABLE:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_variable );
				break;
			case RES_POOLCHR_HTML_DEFINSTANCE:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_definstance );
				break;
			case RES_POOLCHR_HTML_TELETYPE:
				rToken.Assign( OOO_STRING_SVTOOLS_HTML_teletype );
				break;

			case RES_POOLCHR_INET_NORMAL:
				if( pPseudo )
				{
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_anchor );
					pPseudo->AssignAscii( sCSS1_link );
				}
				break;
			case RES_POOLCHR_INET_VISIT:
				if( pPseudo )
				{
					rToken.Assign( OOO_STRING_SVTOOLS_HTML_anchor );
					pPseudo->AssignAscii( sCSS1_visited );
				}
				break;
			}

			// Wenn ein Token gesetzt ist, enthaelt nPoolId die dazugehoerige
			// Vorlage
			if( rToken.Len() && !rRefPoolId )
				rRefPoolId = nPoolId;
		}

		if( rToken.Len() || bStop )
		{
			// Anhalten wenn eine HTML-Tag-Vorlage gefunden wurde
			break;
		}
		else
		{
			// sonst weitersuchen
			nDeep++;
			pPFmt = pPFmt->DerivedFrom();
		}
	}

	if( rToken.Len() )
	{
		// Es ist eine HTML-Tag-Vorlage
		if( !nDeep )
			nDeep = CSS1_FMT_ISTAG;
	}
	else
	{
		// Es ist keine HTML-Tag-Vorlage und auch keine davon abgeleitete
		nDeep = 0;
	}
	if( nDeep > 0 && nDeep < CSS1_FMT_SPECIAL )
	{
		// Wenn die Vorlage von einer HTML-Vorlage abgeleitet ist,
		// wird sie als <TOKEN>.<CLASS> exportiert, sonst als .<CLASS>.
		// <CLASS> ergibt sich aus dem Namen der Vorlage durch entfernen
		// aller Zeichen vor und inklusive dem ersten '.'
		rClass = pFmt->GetName();
		xub_StrLen nPos = rClass.Search( '.' );
		if( nPos != STRING_NOTFOUND && rClass.Len() > nPos+1 )
		{
			rClass.Erase( 0, nPos+1 );
		}

		GetAppCharClass().toLower( rClass );
		while( STRING_NOTFOUND != rClass.SearchAndReplace( '.', '-' ) )
			;
		while( STRING_NOTFOUND != rClass.SearchAndReplace( ' ', '-' ) )
			;
		while( STRING_NOTFOUND != rClass.SearchAndReplace( '_', '-' ) )
			;
	}

	return nDeep;
}

static sal_uInt16 GetCSS1Selector( const SwFmt *pFmt, String& rSelector,
							   sal_uInt16& rRefPoolId )
{
	ByteString aToken;
	String aClass;
	String aPseudo;

	sal_uInt16 nDeep = SwHTMLWriter::GetCSS1Selector( pFmt, aToken, aClass,
												  rRefPoolId, &aPseudo );
	if( nDeep )
	{
		if( aToken.Len() )
			rSelector = String( aToken, RTL_TEXTENCODING_ASCII_US );
		else
			rSelector.Erase();

		if( aClass.Len() )
			(rSelector += '.') += aClass;
		if( aPseudo.Len() )
			(rSelector += ':') += aPseudo;
	}

	return nDeep;
}

const SwFmt *SwHTMLWriter::GetTemplateFmt( sal_uInt16 nPoolFmtId,
										   IDocumentStylePoolAccess* pTemplate /*SwDoc *pTemplate*/)
{
	const SwFmt *pRefFmt = 0;

	if( pTemplate )
	{
		ASSERT( !(USER_FMT & nPoolFmtId),
				"In der Dok-Vorlage gibt es keine Benutzer-Vorlagen" );
		if( POOLGRP_NOCOLLID & nPoolFmtId )
			pRefFmt = pTemplate->GetCharFmtFromPool( nPoolFmtId );
		else
            pRefFmt = pTemplate->GetTxtCollFromPool( nPoolFmtId, false );
	}

	return pRefFmt;
}

const SwFmt *SwHTMLWriter::GetParentFmt( const SwFmt& rFmt, sal_uInt16 nDeep )
{
	ASSERT( nDeep != USHRT_MAX, "GetParent fuer HTML-Vorlage aufgerufen!" );
	const SwFmt *pRefFmt = 0;

	if( nDeep > 0 )
	{
		// hier wird die HTML-Tag-Vorlage, von der die Vorlage abgeleitet
		// ist als Referenz geholt
		pRefFmt = &rFmt;
		for( sal_uInt16 i=nDeep; i>0; i-- )
			pRefFmt = pRefFmt->DerivedFrom();

		if( pRefFmt && pRefFmt->IsDefault() )
			pRefFmt = 0;
	}

	return pRefFmt;
}

sal_Bool lcl_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 )
{
	return 	((const SvxFontItem &)r1).GetFamilyName() ==
					((const SvxFontItem &)r2).GetFamilyName() &&
			((const SvxFontItem &)r1).GetFamily() ==
					((const SvxFontItem &)r2).GetFamily();
}

void SwHTMLWriter::SubtractItemSet( SfxItemSet& rItemSet,
									const SfxItemSet& rRefItemSet,
									sal_Bool bSetDefaults,
									sal_Bool bClearSame,
								 	const SfxItemSet *pRefScriptItemSet )
{
	ASSERT( bSetDefaults || bClearSame,
			"SwHTMLWriter::SubtractItemSet: Bei diesen Flags passiert nix" );
	SfxItemSet aRefItemSet( *rRefItemSet.GetPool(),	rRefItemSet.GetRanges() );
	aRefItemSet.Set( rRefItemSet );

	// und mit dem Attr-Set der Vorlage vergleichen
	SfxWhichIter aIter( rItemSet );
	sal_uInt16 nWhich = aIter.FirstWhich();
	while( nWhich )
	{
		const SfxPoolItem *pRefItem, *pItem;
		sal_Bool bItemSet = ( SFX_ITEM_SET ==
				rItemSet.GetItemState( nWhich, sal_False, &pItem) );
		sal_Bool bRefItemSet;

		if( pRefScriptItemSet )
		{
			switch( nWhich )
			{
			case RES_CHRATR_FONT:
			case RES_CHRATR_FONTSIZE:
			case RES_CHRATR_LANGUAGE:
			case RES_CHRATR_POSTURE:
			case RES_CHRATR_WEIGHT:
			case RES_CHRATR_CJK_FONT:
			case RES_CHRATR_CJK_FONTSIZE:
			case RES_CHRATR_CJK_LANGUAGE:
			case RES_CHRATR_CJK_POSTURE:
			case RES_CHRATR_CJK_WEIGHT:
			case RES_CHRATR_CTL_FONT:
			case RES_CHRATR_CTL_FONTSIZE:
			case RES_CHRATR_CTL_LANGUAGE:
			case RES_CHRATR_CTL_POSTURE:
			case RES_CHRATR_CTL_WEIGHT:
				bRefItemSet = ( SFX_ITEM_SET ==
					pRefScriptItemSet->GetItemState( nWhich, sal_True, &pRefItem) );
				break;
			default:
				bRefItemSet = ( SFX_ITEM_SET ==
					aRefItemSet.GetItemState( nWhich, sal_False, &pRefItem) );
				break;
			}
		}
		else
		{
			bRefItemSet = ( SFX_ITEM_SET ==
				aRefItemSet.GetItemState( nWhich, sal_False, &pRefItem) );
		}

		if( bItemSet )
		{
			if( (bClearSame || pRefScriptItemSet) && bRefItemSet &&
				( *pItem == *pRefItem ||
				  ((RES_CHRATR_FONT == nWhich ||
					RES_CHRATR_CJK_FONT == nWhich ||
					RES_CHRATR_CTL_FONT == nWhich)  &&
				   lcl_css1atr_equalFontItems( *pItem, *pRefItem )) ) )
			{
				// das Attribut ist mit dem gleichen Wert in beiden
				// Vorlagen vorhanden und muss nicht ausgegeben werden
				rItemSet.ClearItem( nWhich );
			}
		}
		else
		{
			if( (bSetDefaults || pRefScriptItemSet) && bRefItemSet )
			{
				// das Attribut ist nur in der Referenz vorhanden. Das
				// Default muss ggf. ausgegeben werden
				rItemSet.Put( rItemSet.GetPool()->GetDefaultItem(nWhich) );
			}
		}

		nWhich = aIter.NextWhich();
	}
}

void SwHTMLWriter::PrepareFontList( const SvxFontItem& rFontItem,
									String& rNames,
									sal_Unicode cQuote, sal_Bool bGeneric )
{
	rNames = aEmptyStr;
	const String& rName = rFontItem.GetFamilyName();
	sal_Bool bContainsKeyword = sal_False;
	if( rName.Len() )
	{
		xub_StrLen nStrPos = 0;
		while( nStrPos != STRING_NOTFOUND )
		{
			String aName = rName.GetToken( 0, ';', nStrPos );
			aName.EraseTrailingChars().EraseLeadingChars();
			if( !aName.Len() )
				continue;

			sal_Bool bIsKeyword = sal_False;
			switch( aName.GetChar( 0 ) )
			{
			case 'c':
			case 'C':
				bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_cursive );
				break;

			case 'f':
			case 'F':
				bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_fantasy );
				break;

			case 'm':
			case 'M':
				bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_monospace );
				break;

			case 's':
			case 'S':
				bIsKeyword =
					aName.EqualsIgnoreCaseAscii( sCSS1_PV_serif ) ||
					aName.EqualsIgnoreCaseAscii( sCSS1_PV_sans_serif );
				break;
			}

			bContainsKeyword |= bIsKeyword;

			if( rNames.Len() )
				rNames.AppendAscii( ", " );
			if( cQuote && !bIsKeyword )
				rNames += cQuote;
			rNames += aName;
			if( cQuote && !bIsKeyword )
				rNames += cQuote;
		}
	}

	if( !bContainsKeyword && bGeneric )
	{
		const sal_Char *pStr = 0;
		switch( rFontItem.GetFamily() )
		{
		case FAMILY_ROMAN:		pStr = sCSS1_PV_serif;		break;
		case FAMILY_SWISS:		pStr = sCSS1_PV_sans_serif;	break;
		case FAMILY_SCRIPT:		pStr = sCSS1_PV_cursive;	break;
		case FAMILY_DECORATIVE:	pStr = sCSS1_PV_fantasy;	break;
		case FAMILY_MODERN:		pStr = sCSS1_PV_monospace;	break;
		default:
			;
		}

		if( pStr )
		{
			if( rNames.Len() )
				rNames.AppendAscii( ", " );
			rNames.AppendAscii( pStr );
		}
	}
}

sal_Bool SwHTMLWriter::HasScriptDependentItems( const SfxItemSet& rItemSet,
											 	sal_Bool bCheckDropCap )
{
	static sal_uInt16 aWhichIds[] =
	{
		RES_CHRATR_FONT,		RES_CHRATR_CJK_FONT,		RES_CHRATR_CTL_FONT,
		RES_CHRATR_FONTSIZE,	RES_CHRATR_CJK_FONTSIZE,	RES_CHRATR_CTL_FONTSIZE,
		RES_CHRATR_LANGUAGE,	RES_CHRATR_CJK_LANGUAGE,	RES_CHRATR_CTL_LANGUAGE,
		RES_CHRATR_POSTURE,		RES_CHRATR_CJK_POSTURE,		RES_CHRATR_CTL_POSTURE,
		RES_CHRATR_WEIGHT,		RES_CHRATR_CJK_WEIGHT,		RES_CHRATR_CTL_WEIGHT,
		0,						0,							0
	};

	for( sal_uInt16 i=0; aWhichIds[i]; i += 3 )
	{
		const SfxPoolItem *pItem = 0, *pItemCJK = 0, *pItemCTL = 0, *pTmp;
		sal_uInt16 nItemCount = 0;
		if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], sal_False,
												   &pTmp ) )
		{
			pItem = pTmp;
			nItemCount++;
		}
		if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i+1], sal_False,
												   &pTmp ) )
		{
			pItemCJK = pTmp;
			nItemCount++;
		}
		if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i+2], sal_False,
												   &pTmp ) )
		{
			pItemCTL = pTmp;
			nItemCount++;
		}

		// If some of the items are set, but not all, we need script dependent
		// styles
		if( nItemCount > 0 && nItemCount < 3 )
			return sal_True;

		if( 3 == nItemCount )
		{
			// If all items are set, but some of them have different values,
			// we need script dependent styles, too. For font items, we have
			// to take care about their special HTML/CSS1 representation.
			if( RES_CHRATR_FONT == aWhichIds[i] )
			{
				if( !lcl_css1atr_equalFontItems( *pItem, *pItemCJK ) ||
					!lcl_css1atr_equalFontItems( *pItem, *pItemCTL ) ||
					!lcl_css1atr_equalFontItems( *pItemCJK, *pItemCTL ) )
					return sal_True;
			}
			else
			{
				if( !( *pItem == *pItemCJK ) ||
					!( *pItem == *pItemCTL ) ||
					!( *pItemCJK == *pItemCTL ) )
					return sal_True;
			}
		}
	}

	const SfxPoolItem *pItem;
	if( bCheckDropCap &&
		SFX_ITEM_SET == rItemSet.GetItemState( RES_PARATR_DROP, sal_True,
				&pItem ) )
	{
		const SwFmtDrop *pDrop = (const SwFmtDrop *)pItem;
		const SwCharFmt *pDCCharFmt = pDrop->GetCharFmt();
		if( pDCCharFmt )
		{
			SfxItemSet aTstItemSet( *pDCCharFmt->GetAttrSet().GetPool(),
				RES_CHRATR_FONT, 		RES_CHRATR_FONT,
				RES_CHRATR_POSTURE,		RES_CHRATR_POSTURE,
				RES_CHRATR_WEIGHT,		RES_CHRATR_WEIGHT,
				RES_CHRATR_CJK_FONT,	RES_CHRATR_CJK_FONT,
				RES_CHRATR_CJK_POSTURE,	RES_CHRATR_CJK_WEIGHT,
				RES_CHRATR_CTL_FONT,	RES_CHRATR_CTL_FONT,
				RES_CHRATR_CTL_POSTURE,	RES_CHRATR_CTL_WEIGHT,
				0 );
			aTstItemSet.Set( pDCCharFmt->GetAttrSet(), sal_True );
			return HasScriptDependentItems( aTstItemSet, sal_False );
		}
	}

	return sal_False;
}

static sal_Bool OutCSS1Rule( SwHTMLWriter& rHTMLWrt, const String& rSelector,
					const SfxItemSet& rItemSet, sal_Bool bHasClass,
				 	sal_Bool bCheckForPseudo  )
{
	sal_Bool bScriptDependent = sal_False;
	if( SwHTMLWriter::HasScriptDependentItems( rItemSet,
				rHTMLWrt.IsHTMLMode(HTMLMODE_DROPCAPS) && bHasClass ) )
	{
		bScriptDependent = sal_True;
		String aSelector( rSelector );

		String aPseudo;
		if( bCheckForPseudo )
		{
			xub_StrLen nPos = aSelector.SearchBackward( ':' );
			if( STRING_NOTFOUND != nPos )
			{
				aPseudo = aSelector.Copy( nPos );
				aSelector.Erase( nPos );
			}
		}

		if( !bHasClass )
		{
			// If we are exporting styles for a tag we have to export a tag
			// rule for all properties that aren't style dependent and
			// some class rule for the additional style dependen properties
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
									 sal_True, &rSelector );
				rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
			}

			SfxItemSet aScriptItemSet( *rItemSet.GetPool(),
									   RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
									   RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
									   RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
									   RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
									   0 );
			aScriptItemSet.Put( rItemSet );

			String aNewSelector( aSelector );
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".western") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
									 sal_True, &aNewSelector );
				rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, sal_False );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".cjk") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
									 sal_True, &aNewSelector );
				rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, sal_False );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".ctl") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
									 sal_True, &aNewSelector );
				rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, sal_False );
			}
		}
		else
		{
			// If ther are script dependencies and we are derived from a tag,
			// when we have to export a style dependent class for all
			// scripts
			String aNewSelector( aSelector );
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
									 sal_True, &aNewSelector );
				rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
									 sal_True, &aNewSelector );
				rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
									 sal_True, &aNewSelector );
				rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
			}
		}
	}
	else
	{
		// If there are no script dependencies, when all items are
		// exported in one step. For hyperlinks only, a script information
		// must be there, because these two chr formats don't support
		// script dependencies by now.
		SwCSS1OutMode aMode( rHTMLWrt,
				rHTMLWrt.nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
							 sal_True, &rSelector );
		rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
	}

	return bScriptDependent;
}

static void OutCSS1DropCapRule(
					SwHTMLWriter& rHTMLWrt, const String& rSelector,
					const SwFmtDrop& rDrop, sal_Bool bHasClass,
				 	sal_Bool bHasScriptDependencies  )
{
	const SwCharFmt *pDCCharFmt = rDrop.GetCharFmt();
	if( (bHasScriptDependencies && bHasClass) ||
	 	(pDCCharFmt && SwHTMLWriter::HasScriptDependentItems( pDCCharFmt->GetAttrSet(), sal_False ) ) )
	{
		String aSelector( rSelector );

		String aPseudo;
		xub_StrLen nPos = aSelector.SearchBackward( ':' );
		if( STRING_NOTFOUND != nPos )
		{
			aPseudo = aSelector.Copy( nPos );
			aSelector.Erase( nPos );
		}

		if( !bHasClass )
		{
			// If we are exporting styles for a tag we have to export a tag
			// rule for all properties that aren't style dependent and
			// some class rule for the additional style dependen properties
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
									 sal_True, &rSelector );
				OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
			}

			SfxItemSet aScriptItemSet( rHTMLWrt.pDoc->GetAttrPool(),
									   RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
									   RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
									   RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
									   RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
									   0 );
			if( pDCCharFmt )
				aScriptItemSet.Set( pDCCharFmt->GetAttrSet(), sal_True );

			String aNewSelector( aSelector );
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".western") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
									 sal_True, &aNewSelector );
				OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop, &aScriptItemSet );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".cjk") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
									 sal_True, &aNewSelector );
				OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop, &aScriptItemSet );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".ctl") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
									 sal_True, &aNewSelector );
				OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop, &aScriptItemSet );
			}
		}
		else
		{
			// If ther are script dependencies and we are derived from a tag,
			// when we have to export a style dependent class for all
			// scripts
			String aNewSelector( aSelector );
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
									 sal_True, &aNewSelector );
				OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
									 sal_True, &aNewSelector );
				OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop );
			}

			aNewSelector = aSelector;
			aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
			aNewSelector.Append( aPseudo );
			{
				SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
									 sal_True, &aNewSelector );
				OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop );
			}
		}
	}
	else
	{
		// If there are no script dependencies, when all items are
		// exported in one step. For hyperlinks only, a script information
		// must be there, because these two chr formats don't support
		// script dependencies by now.
		SwCSS1OutMode aMode( rHTMLWrt,
				rHTMLWrt.nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
							 sal_True, &rSelector );
				OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
	}
}

static Writer& OutCSS1_SwFmt( Writer& rWrt, const SwFmt& rFmt,
							  IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	sal_Bool bCharFmt = sal_False;
	switch( rFmt.Which() )
	{
	case RES_CHRFMT:
		bCharFmt = sal_True;
		break;

	case RES_TXTFMTCOLL:
	case RES_CONDTXTFMTCOLL:
		// diese Vorlagen-Typen koennen exportiert werden
		break;

	default:
		// und diese nicht
		return rWrt;
	}

	// den Selector und die auszugebende Attr-Set-Tiefe ermitteln
	String aSelector;
	sal_uInt16 nRefPoolId = 0;
	sal_uInt16 nDeep = GetCSS1Selector( &rFmt, aSelector, nRefPoolId );
	if( !nDeep )
		return rWrt;	// von keiner HTML-Vorlage abgeleitet

	sal_uInt16 nPoolFmtId = rFmt.GetPoolFmtId();

	// Den auszugebenden Attr-Set bestimmen. Hier muessen 3 Faelle
	// unterschieden werden:
	// - HTML-Tag-Vorlagen (nDeep==USHRT_MAX):
	//   Es werden die Attrs ausgegeben
	//     - die in der Vorlage gesetzt sind, aber nicht im Original aus
	//       der HTML-Vorlage
	//     - die Default-Attrs fuer die Attrs, die im Original aus der
	//       HTML-Vorlage gesetzt sind, aber nicht in der vorliegeden Vorlage.
	// - direkt von HTML-Vorlagen abgeleitete Vorlagen (nDeep==1):
	//   Es weren nur die Attribute des Vorlagen-Item-Set ohne seine
	//   Parents ausgegeben.
	// - indirekt von HTML-Tag-Vorlagen abgeleitete Vorlagen (nDeep>1)
	//   Es werden die Attribute des Vorlagen-Item-Sets inkl. seiner Parents,
	//   aber ohne die Attribute, die in der HTML-Tag-Vorlage gesetzt sind,
	//   ausgegeben.

	// einen Item-Set mit allen Attributen aus der Vorlage anlegen
	// (ausser fuer nDeep==1)
	const SfxItemSet& rFmtItemSet = rFmt.GetAttrSet();
	SfxItemSet aItemSet( *rFmtItemSet.GetPool(), rFmtItemSet.GetRanges() );
	aItemSet.Set( rFmtItemSet, sal_True ); // Was nDeep!=1 that is not working
									   // for script dependent items buts should
									   // not make a deifference for any other

	sal_Bool bSetDefaults = sal_True, bClearSame = sal_True;
	const SwFmt *pRefFmt = 0;
	const SwFmt *pRefFmtScript = 0;
	switch( nDeep )
	{
	case CSS1_FMT_ISTAG:
		pRefFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
		break;
	case CSS1_FMT_CMPREF:
		pRefFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pDoc );
		pRefFmtScript = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
		bClearSame = sal_False;
		break;
	default:
		pRefFmt = SwHTMLWriter::GetParentFmt( rFmt, nDeep );
		pRefFmtScript = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
		bSetDefaults = sal_False;
		break;
	}

	if( pRefFmt )
	{
		// Den Item-Set der Referenz-Vorlage (inkl. seiner Parents) vom
		// ItemSet abziehen
		SwHTMLWriter::SubtractItemSet( aItemSet, pRefFmt->GetAttrSet(),
									   bSetDefaults, bClearSame,
									   pRefFmtScript
									   		? &pRefFmtScript->GetAttrSet()
											: 0  );

		if( !bCharFmt )
		{
			const SvxULSpaceItem& rULItem = pRefFmt->GetULSpace();
			rHTMLWrt.nDfltTopMargin = rULItem.GetUpper();
			rHTMLWrt.nDfltBottomMargin = rULItem.GetLower();
		}
	}
	else if( CSS1_FMT_ISTAG==nDeep && !bCharFmt )
	{
		// die Default-Abstaende nach oben und unten setzen (fuer den
		// Fall, dass es keine Vorlage als Referenz gibt)
		rHTMLWrt.nDfltTopMargin = 0;
		rHTMLWrt.nDfltBottomMargin = HTML_PARSPACE;
		if( USER_FMT & nPoolFmtId )
		{
			// Benutzer-Vorlagen
			const String& rNm = rFmt.GetName();
			switch( rNm.GetChar(0) )
			{
			case 'D':	if( rNm.EqualsAscii("DD 1") || rNm.EqualsAscii("DT 1") )
							rHTMLWrt.nDfltBottomMargin = 0;
						break;
			case 'L':	if(rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_listing) )
							rHTMLWrt.nDfltBottomMargin = 0;
						break;
			case 'P':	if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_preformtxt) )
							rHTMLWrt.nDfltBottomMargin = 0;
						break;
			case 'X':	if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_xmp) )
							rHTMLWrt.nDfltBottomMargin = 0;
						break;
			}
		}
		else
		{
			// Pool-Vorlagen
			switch( nPoolFmtId )
			{
			case RES_POOLCOLL_HEADLINE1:
			case RES_POOLCOLL_HEADLINE2:
			case RES_POOLCOLL_HEADLINE3:
			case RES_POOLCOLL_HEADLINE4:
			case RES_POOLCOLL_HEADLINE5:
			case RES_POOLCOLL_HEADLINE6:
				rHTMLWrt.nDfltTopMargin = HTML_HEADSPACE;
				break;
			case RES_POOLCOLL_SENDADRESS:
			case RES_POOLCOLL_HTML_DT:
			case RES_POOLCOLL_HTML_DD:
			case RES_POOLCOLL_HTML_PRE:
				rHTMLWrt.nDfltBottomMargin = 0;
				break;
			}
		}
	}

	// wo nicht auszugeben ist ...
	if( !aItemSet.Count() )
		return rWrt;

	// There is no support for script dependent hyperlinks by now.
	sal_Bool bCheckForPseudo = sal_False;
	if( bCharFmt &&
		(RES_POOLCHR_INET_NORMAL==nRefPoolId ||
		 RES_POOLCHR_INET_VISIT==nRefPoolId) )
		bCheckForPseudo = sal_True;


	// jetzt die Attribute (inkl. Selektor) ausgeben
	sal_Bool bHasScriptDependencies = sal_False;
	if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, CSS1_FMT_ISTAG != nDeep,
		 			 bCheckForPseudo ) )
	{
		if( bCharFmt )
			rHTMLWrt.aScriptTextStyles.Insert( new String( rFmt.GetName() ) );
		else
		{
			if( nPoolFmtId==RES_POOLCOLL_TEXT )
				rHTMLWrt.aScriptParaStyles.Insert
                    (new String( pDoc->GetTxtCollFromPool
                                 ( RES_POOLCOLL_STANDARD, false )->GetName()
                                 ) );
			rHTMLWrt.aScriptParaStyles.Insert( new String( rFmt.GetName() ) );
		}
		bHasScriptDependencies = sal_True;
	}

	if( nPoolFmtId==RES_POOLCOLL_TEXT && !rHTMLWrt.bFirstCSS1Property )
		rHTMLWrt.bPoolCollTextModified = sal_True;

	// Drop-Caps ausgeben
	const SfxPoolItem *pItem;
	if( rHTMLWrt.IsHTMLMode(HTMLMODE_DROPCAPS) &&
		SFX_ITEM_SET==aItemSet.GetItemState( RES_PARATR_DROP, sal_False, &pItem ))
	{
		String sOut( aSelector );
		sOut.Append( ':');
		sOut.AppendAscii( sCSS1_first_letter );
		const SwFmtDrop *pDrop = (const SwFmtDrop *)pItem;
		OutCSS1DropCapRule( rHTMLWrt, sOut, *pDrop, CSS1_FMT_ISTAG != nDeep, bHasScriptDependencies );
	}

	return rWrt;
}

static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rPageDesc,
								   IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate,
								   sal_uInt16 nRefPoolId, sal_Bool bExtRef,
								   sal_Bool bPseudo )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	const SwPageDesc* pRefPageDesc = 0;
	if( !bExtRef )
        pRefPageDesc = pDoc->GetPageDescFromPool( nRefPoolId, false );
	else if( pTemplate )
        pRefPageDesc = pTemplate->GetPageDescFromPool( nRefPoolId, false );

	String aSelector( '@' );
	aSelector.AppendAscii( sCSS1_page );

	if( bPseudo )
	{
		const sal_Char *pPseudo = 0;
		switch( rPageDesc.GetPoolFmtId() )
		{
		case RES_POOLPAGE_FIRST:	pPseudo = sCSS1_first;	break;
		case RES_POOLPAGE_LEFT:		pPseudo = sCSS1_left;	break;
		case RES_POOLPAGE_RIGHT:	pPseudo = sCSS1_right;	break;
		}
		if( pPseudo )
		{
			aSelector.Append( ':' );
			aSelector.AppendAscii( pPseudo );
		}
	}

	SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE_ON|CSS1_OUTMODE_TEMPLATE,
						 sal_True, &aSelector );

	// Die Groesse: Wenn sie sich nur durch das Landscape-Flag unterscheidet,
	// wird nur Portrait oder Landscape exportiert. Sonst wird die Groesse
	// exportiert.
	sal_Bool bRefLandscape = pRefPageDesc ? pRefPageDesc->GetLandscape() : sal_False;
	Size aRefSz;
	const Size& rSz = rPageDesc.GetMaster().GetFrmSize().GetSize();
	if( pRefPageDesc )
	{
		aRefSz = pRefPageDesc->GetMaster().GetFrmSize().GetSize();
		if( bRefLandscape != rPageDesc.GetLandscape() )
		{
			long nTmp = aRefSz.Height();
			aRefSz.Height() = aRefSz.Width();
			aRefSz.Width() = nTmp;
		}
	}

	// Boeser uebler Hack: Auf der Seiten-Tabpage gibt es leichte
	// Rundungsfehler bei der Seitengroesse. Unter anderem wegen bug
	// 25535 wird dummerweise auch noch immer Size-Item vom Dialog geputtet,
	// auch wenn man gar nichts geaendert hat. Folge: Sobald man einmal im
	// Seiten-Dialog war und ihn mit OK verlassen hat, bekommt man eine
	// neue Seitengroesse, die dann hier exportiert wuerde. Um das
	// vermeiden erlauben wir hier kleine Abweichungen.
	if( Abs( rSz.Width() - aRefSz.Width() ) <= 2 &&
		Abs( rSz.Height() - aRefSz.Height() ) <= 2 )
	{
		if( bRefLandscape != rPageDesc.GetLandscape() )
		{
			rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size,
				rPageDesc.GetLandscape() ? sCSS1_PV_landscape
										 : sCSS1_PV_portrait );
		}
	}
	else
	{
		ByteString sVal;
		AddUnitPropertyValue( rSz.Width(), rHTMLWrt.GetCSS1Unit(), sVal );
		sVal += ' ';
		AddUnitPropertyValue( rSz.Height(), rHTMLWrt.GetCSS1Unit(), sVal );
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size, sVal );
	}

	// Die Abstand-Attribute koennen auf gwohnte Weise exportiert werden
	const SwFrmFmt &rMaster = rPageDesc.GetMaster();
	SfxItemSet aItemSet( *rMaster.GetAttrSet().GetPool(),
						 RES_LR_SPACE, RES_UL_SPACE );
	aItemSet.Set( rMaster.GetAttrSet(), sal_True );

	if( pRefPageDesc )
	{
		SwHTMLWriter::SubtractItemSet( aItemSet,
									   pRefPageDesc->GetMaster().GetAttrSet(),
									   sal_True );
	}

	OutCSS1_SvxULSpace_SvxLRSpace( rWrt, aItemSet, sal_False );

	// Wenn fuer einen Pseudo-Selektor keine Property ausgegeben wurde, muessen
	// wir trotzdem etwas ausgeben, damit beim Import die entsprechende
	// Vorlage angelegt wird.
	if( rHTMLWrt.bFirstCSS1Property && bPseudo )
	{
		rHTMLWrt.OutNewLine();
		ByteString sTmp( aSelector, rHTMLWrt.eDestEnc );
		rWrt.Strm() << sTmp.GetBuffer() << " {";
		rHTMLWrt.bFirstCSS1Property = sal_False;
	}

	if( !rHTMLWrt.bFirstCSS1Property )
		rWrt.Strm() << sCSS1_rule_end;

	return rWrt;
}

static Writer& OutCSS1_SwFtnInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
								  SwDoc *pDoc, sal_uInt16 nNotes, sal_Bool bEndNote )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	String aSelector;

	if( nNotes > 0 )
	{
		aSelector.AssignAscii( OOO_STRING_SVTOOLS_HTML_anchor );
		aSelector.Append( '.');
		aSelector.AppendAscii( bEndNote ? OOO_STRING_SVTOOLS_HTML_sdendnote_anc
										: OOO_STRING_SVTOOLS_HTML_sdfootnote_anc );
		SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
							 sal_True, &aSelector );
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size,
										sHTML_FTN_fontheight );
		rHTMLWrt.Strm() << sCSS1_rule_end;
	}

	const SwCharFmt *pSymCharFmt = rInfo.GetCharFmt( *pDoc );
	if( pSymCharFmt )
	{
		const SfxItemSet& rFmtItemSet = pSymCharFmt->GetAttrSet();
		SfxItemSet aItemSet( *rFmtItemSet.GetPool(), rFmtItemSet.GetRanges() );
		aItemSet.Set( rFmtItemSet, sal_True );

		// Wenn es Fuss- bzw. Endnoten gibt, dann muessen alles Attribute
		// ausgegeben werden, damit Netscape das Dokument richtig anzeigt.
		// Anderenfalls genuegt es, die Unterschiede zur Fuss-/Endnoten
		// Vorlage rauszuschreiben.
		if( nNotes == 0 && rHTMLWrt.pTemplate )
		{
			SwFmt *pRefFmt = rHTMLWrt.pTemplate->GetCharFmtFromPool(
                        static_cast< sal_uInt16 >(bEndNote ? RES_POOLCHR_ENDNOTE : RES_POOLCHR_FOOTNOTE) );
			if( pRefFmt )
				SwHTMLWriter::SubtractItemSet( aItemSet, pRefFmt->GetAttrSet(),
											   sal_True );
		}
		if( aItemSet.Count() )
		{
			aSelector.AssignAscii( OOO_STRING_SVTOOLS_HTML_anchor );
			aSelector.Append( '.');
			aSelector.AppendAscii( bEndNote ? OOO_STRING_SVTOOLS_HTML_sdendnote_sym
										: OOO_STRING_SVTOOLS_HTML_sdfootnote_sym );
			if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, sal_True, sal_False ))
				rHTMLWrt.aScriptTextStyles.Insert( new String( pSymCharFmt->GetName() ) );
		}
	}

	return rWrt;
}

Writer& OutCSS1_BodyTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet,
								 String aEmbBGGrfName )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
								   CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_BODY );


	// Es werden nur die Attribute der Seiten-Vorlage ausgegeben.
	// Die Attribute der Standard-Absatz-Vorlage werden schon beim
	// Export der Absatz-Vorlagen beruecksichtigt.

	const SfxPoolItem *pItem;
	if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, sal_False,
											   &pItem ) )
	{
		OutCSS1_SvxBrush( rWrt, *pItem, CSS1_BACKGROUND_PAGE,
						  &aEmbBGGrfName );
	}

	if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, sal_False,
											   &pItem ))
	{
		OutCSS1_SvxBox( rWrt, *pItem );
	}

	if( !rHTMLWrt.bFirstCSS1Property )
	{
		// wenn eine Property als Bestandteil einer Style-Option
		// ausgegeben wurde, muss die Optiomn noch beendet werden
		rWrt.Strm() << '\"';
	}

	return rWrt;
}

Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	SwCSS1OutMode aMode( rHTMLWrt, rHTMLWrt.nCSS1Script|CSS1_OUTMODE_STYLE_OPT |
								   CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA );
	rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );

	return rWrt;
}

Writer& OutCSS1_HintSpanTag( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_SPAN_TAG |
								   CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_HINT );

	Out( aCSS1AttrFnTab, rHt, rWrt );

	if( !rHTMLWrt.bFirstCSS1Property  && rHTMLWrt.bTagOn )
		rWrt.Strm() << sCSS1_span_tag_end;

	return rWrt;
}

Writer& OutCSS1_HintStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
								   CSS1_OUTMODE_ENCODE|
								   CSS1_OUTMODE_HINT );

	Out( aCSS1AttrFnTab, rHt, rWrt );

	if( !rHTMLWrt.bFirstCSS1Property )
		rWrt.Strm() << '\"';

	return rWrt;
}

// Wrapper fuer die Ausgabe von Tabellen-Hintergruenden
Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
								   CSS1_OUTMODE_ENCODE|
								   CSS1_OUTMODE_TABLEBOX );
	OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_TABLE, 0 );

	if( !rHTMLWrt.bFirstCSS1Property )
		rWrt.Strm() << '\"';

	return rWrt;
}


Writer& OutCSS1_NumBulListStyleOpt( Writer& rWrt, const SwNumRule& rNumRule,
									sal_uInt8 nLevel )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT |
								   CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA );

	const SwNumFmt& rNumFmt = rNumRule.Get( nLevel );

	long nLSpace = rNumFmt.GetAbsLSpace();
	long nFirstLineOffset = rNumFmt.GetFirstLineOffset();
	long nDfltFirstLineOffset = HTML_NUMBUL_INDENT;
	if( nLevel > 0 )
	{
		const SwNumFmt& rPrevNumFmt = rNumRule.Get( nLevel-1 );
		nLSpace -= rPrevNumFmt.GetAbsLSpace();
		nDfltFirstLineOffset = rPrevNumFmt.GetFirstLineOffset();
	}

	if( rHTMLWrt.IsHTMLMode(HTMLMODE_LSPACE_IN_NUMBUL) &&
		nLSpace != HTML_NUMBUL_MARGINLEFT )
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLSpace );

	if( rHTMLWrt.IsHTMLMode(HTMLMODE_FRSTLINE_IN_NUMBUL) &&
		nFirstLineOffset != nDfltFirstLineOffset )
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent, nFirstLineOffset );

	if( !rHTMLWrt.bFirstCSS1Property )
		rWrt.Strm() << '\"';

	return rWrt;
}

//-----------------------------------------------------------------------

void SwHTMLWriter::OutCSS1_FrmFmtOptions( const SwFrmFmt& rFrmFmt,
										  sal_uInt32 nFrmOpts,
										  const SdrObject *pSdrObj,
										  const SfxItemSet *pItemSet )
{
	SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
								CSS1_OUTMODE_ENCODE|
								CSS1_OUTMODE_FRAME );

	const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient();
	SvxLRSpaceItem aLRItem( rFrmFmt.GetLRSpace() );
	SvxULSpaceItem aULItem( rFrmFmt.GetULSpace() );
	if( nFrmOpts & HTML_FRMOPT_S_ALIGN )
	{
		const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
		switch( rAnchor.GetAnchorId() )
        {
        case FLY_AT_PARA:
        case FLY_AT_CHAR:
            if( text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
                text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
			{
				if( !(nFrmOpts & HTML_FRMOPT_ALIGN) )
				{
					// float
                    const sal_Char *pStr = text::HoriOrientation::RIGHT==rHoriOri.GetHoriOrient()
							? sCSS1_PV_right
							: sCSS1_PV_left;
					OutCSS1_PropertyAscii( sCSS1_P_float, pStr );
				}
				break;
			}

        case FLY_AT_PAGE:
		case FLY_AT_FLY:
			{
				// position
				OutCSS1_PropertyAscii( sCSS1_P_position, sCSS1_PV_absolute );

				// Fuer top/left muessen die Abstaende des Rahmens von
				// der Position abgezogen werden, da sie in CSS1 noch
				// zur Position addiert werden.
				// Das funktioniert auch fuer automatisch ausgerichtete
				// Rahmen, obwohl der Abstand da ja auch im Writer noch
				// addiert wird. Denn auch in diesem Fall enthalten
				// die Orient-Attribute die korrekte Position

				// top
				long nXPos=0, nYPos=0;
				sal_Bool bOutXPos = sal_False, bOutYPos = sal_False;
				if( RES_DRAWFRMFMT == rFrmFmt.Which() )
				{
					ASSERT( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" );
					if( !pSdrObj )
						pSdrObj = rFrmFmt.FindSdrObject();
					ASSERT( pSdrObj, "Wo ist das SdrObject" );
					if( pSdrObj )
					{
						Point aPos( pSdrObj->GetRelativePos() );
						nXPos = aPos.A();
						nYPos = aPos.B();
					}
					bOutXPos = bOutYPos = sal_True;
				}
				else
				{
                    bOutXPos = text::RelOrientation::CHAR != rHoriOri.GetRelationOrient();
                    nXPos = text::HoriOrientation::NONE == rHoriOri.GetHoriOrient()
								? rHoriOri.GetPos() : 0;

					const SwFmtVertOrient& rVertOri = rFrmFmt.GetVertOrient();
                    bOutYPos = text::RelOrientation::CHAR != rVertOri.GetRelationOrient();
                    nYPos = text::VertOrientation::NONE == rVertOri.GetVertOrient()
								 ? rVertOri.GetPos() : 0;
				}

				if( bOutYPos )
				{
					if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
					{
						nYPos -= aULItem.GetUpper();
						if( nYPos < 0 )
						{
							aULItem.SetUpper( (sal_uInt16)(aULItem.GetUpper() + nYPos) );
							nYPos = 0;
						}
					}

					OutCSS1_UnitProperty( sCSS1_P_top, nYPos );
				}

				if( bOutXPos )
				{
					// left
					if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
					{
						nXPos -= aLRItem.GetLeft();
						if( nXPos < 0 )
						{
							aLRItem.SetLeft( (sal_uInt16)(aLRItem.GetLeft() + nXPos) );
							nXPos = 0;
						}
					}

					OutCSS1_UnitProperty( sCSS1_P_left, nXPos );
				}
			}
			break;

		default:
			;
		}
	}

	// width/height
	if( nFrmOpts & HTML_FRMOPT_S_SIZE )
	{
		if( RES_DRAWFRMFMT == rFrmFmt.Which() )
		{
			ASSERT( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" );
			if( !pSdrObj )
				pSdrObj = rFrmFmt.FindSdrObject();
			ASSERT( pSdrObj, "Wo ist das SdrObject" );
			if( pSdrObj )
			{
				Size aTwipSz( pSdrObj->GetLogicRect().GetSize() );
				if( nFrmOpts & HTML_FRMOPT_S_WIDTH )
				{
					if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
						OutCSS1_PixelProperty( sCSS1_P_width, aTwipSz.Width(),
											   sal_False );
					else
						OutCSS1_UnitProperty( sCSS1_P_width, aTwipSz.Width() );
				}
				if( nFrmOpts & HTML_FRMOPT_S_HEIGHT )
				{
					if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
						OutCSS1_PixelProperty( sCSS1_P_height, aTwipSz.Height(),
											   sal_True );
					else
						OutCSS1_UnitProperty( sCSS1_P_height, aTwipSz.Height() );
				}
			}
		}
		else
		{
			ASSERT( HTML_FRMOPT_ABSSIZE & nFrmOpts,
					"Absolute Groesse wird exportiert" );
			ASSERT( HTML_FRMOPT_ANYSIZE & nFrmOpts,
					"Jede Groesse wird exportiert" );
			sal_uInt16 nMode = 0;
			if( nFrmOpts & HTML_FRMOPT_S_WIDTH )
				nMode |= CSS1_FRMSIZE_WIDTH;
			if( nFrmOpts & HTML_FRMOPT_S_HEIGHT )
				nMode |= (CSS1_FRMSIZE_MINHEIGHT|CSS1_FRMSIZE_FIXHEIGHT);
			if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
				nMode |= CSS1_FRMSIZE_PIXEL;

			OutCSS1_SwFmtFrmSize( *this, rFrmFmt.GetFrmSize(), nMode );
		}
	}

	const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
	// margin-*
	if( (nFrmOpts & HTML_FRMOPT_S_SPACE) &&
		IsHTMLMode( HTMLMODE_FLY_MARGINS) )
	{
		const SvxLRSpaceItem *pLRItem = 0;
		const SvxULSpaceItem *pULItem = 0;
		if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, sal_True ) )
			pLRItem = &aLRItem;
		if( SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, sal_True ) )
			pULItem = &aULItem;
		if( pLRItem || pULItem )
			OutCSS1_SvxULSpace_SvxLRSpace( *this, pULItem, pLRItem );
	}

	// border
	if( nFrmOpts & HTML_FRMOPT_S_BORDER )
	{
		const SfxPoolItem* pItem;
		if( nFrmOpts & HTML_FRMOPT_S_NOBORDER )
			OutCSS1_SvxBox( *this, rFrmFmt.GetBox() );
		else if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOX, sal_True, &pItem ) )
			OutCSS1_SvxBox( *this, *pItem );
	}

	// background (wenn, dann muss auch eine Farbe ausgegeben werden)
	if( nFrmOpts & HTML_FRMOPT_S_BACKGROUND )
		OutCSS1_FrmFmtBackground( rFrmFmt );

	if( pItemSet )
		OutCSS1_SfxItemSet( *pItemSet, sal_False );

	if( !bFirstCSS1Property )
		Strm() << '\"';
}

void SwHTMLWriter::OutCSS1_TableFrmFmtOptions( const SwFrmFmt& rFrmFmt )
{
	SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
								CSS1_OUTMODE_ENCODE|
								CSS1_OUTMODE_TABLE );

	const SfxPoolItem *pItem;
	const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
	if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
		OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_TABLE, 0 );

	if( IsHTMLMode( HTMLMODE_PRINT_EXT ) )
		OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( *this, rItemSet, sal_False );

	if( SFX_ITEM_SET==rItemSet.GetItemState( RES_LAYOUT_SPLIT, sal_False, &pItem ) )
		OutCSS1_SwFmtLayoutSplit( *this, *pItem );

	if( !bFirstCSS1Property )
		Strm() << '\"';
}

void SwHTMLWriter::OutCSS1_SectionFmtOptions( const SwFrmFmt& rFrmFmt )
{
	SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
								CSS1_OUTMODE_ENCODE|
								CSS1_OUTMODE_SECTION );

	const SfxPoolItem *pItem;
	const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
	if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
		OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_SECTION, 0 );

	if( !bFirstCSS1Property )
		Strm() << '\"';
}

static sal_Bool OutCSS1_FrmFmtBrush( SwHTMLWriter& rWrt,
								 const SvxBrushItem& rBrushItem )
{
	sal_Bool bWritten = sal_False;
    /// OD 02.09.2002 #99657#
    /// output brush of frame format, if its background color is not "no fill"/"auto fill"
    /// or it has a background graphic.
    if( rBrushItem.GetColor() != COL_TRANSPARENT ||
		0 != rBrushItem.GetGraphicLink() ||
		0 != rBrushItem.GetGraphicPos() )
	{
		OutCSS1_SvxBrush( rWrt, rBrushItem, CSS1_BACKGROUND_FLY, 0 );
		bWritten = sal_True;
	}
	return bWritten;
}

void SwHTMLWriter::OutCSS1_FrmFmtBackground( const SwFrmFmt& rFrmFmt )
{
	// Wenn der Rahmen selbst einen Hintergrund hat, wird der ausgegeben.
	if( OutCSS1_FrmFmtBrush( *this, rFrmFmt.GetBackground() ) )
		return;

	// Wenn der Rahmen nicht seitengebunden ist, wird sonst muss der
	// Hintergrund vom Anker betrachtet
	const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
	RndStdIds eAnchorId = rAnchor.GetAnchorId();
	const SwPosition *pAnchorPos = rAnchor.GetCntntAnchor();
    if (FLY_AT_PAGE != eAnchorId && pAnchorPos)
    {
		const SwNode& rNode = pAnchorPos->nNode.GetNode();
		if( rNode.IsCntntNode() )
		{
			// Wenn der Rahmen in einem Content-Node verankert ist,
			// wird der Hintergrund von Content-Node ausgegeben, wenn
			// der einen hat.
			if( OutCSS1_FrmFmtBrush( *this,
					rNode.GetCntntNode()->GetSwAttrSet().GetBackground()) )
				return;

			// Sonst koennen wir evtl. auch in einer Tabelle stehen
			const SwTableNode *pTableNd = rNode.FindTableNode();
			if( pTableNd )
			{
				const SwStartNode *pBoxSttNd = rNode.FindTableBoxStartNode();
				const SwTableBox *pBox =
					pTableNd->GetTable().GetTblBox( pBoxSttNd->GetIndex() );

				// Wenn die Box einen Hintergrund hat, nehmen wir den.
				if( OutCSS1_FrmFmtBrush( *this,
						pBox->GetFrmFmt()->GetBackground() ) )
					return;

				// Sonst betrachten wir den der Lines
				const SwTableLine *pLine = pBox->GetUpper();
				while( pLine )
				{
					if( OutCSS1_FrmFmtBrush( *this,
							pLine->GetFrmFmt()->GetBackground() ) )
						return;
					pBox = pLine->GetUpper();
					pLine = pBox ? pBox->GetUpper() : 0;
				}

				// Wenn da auch nichts war den der Tabelle.
				if( OutCSS1_FrmFmtBrush( *this,
						pTableNd->GetTable().GetFrmFmt()->GetBackground() ) )
					return;
			}

		}

		// Wenn der Anker wieder in einem Fly-Frame steht, dann
		// wird der Hintergrund des Fly-Frames ausgegeben.
		const SwFrmFmt *pFrmFmt = rNode.GetFlyFmt();
		if( pFrmFmt )
		{
			OutCSS1_FrmFmtBackground( *pFrmFmt );
			return;
		}
	}

	// Schliesslich bleibt noch der Hintergrund der Seite uebrig und als
	// letzte Rettung das Item der Config.
	ASSERT( pCurrPageDesc, "Keine Seiten-Vorlage gemerkt" );
	if( !OutCSS1_FrmFmtBrush( *this,
							  pCurrPageDesc->GetMaster().GetBackground() ) )
	{
		Color aColor( COL_WHITE );

		// Die Hintergrund-Farbe wird normalerweise nur in Browse-Mode
		// benutzt. Wir benutzen si bei einem HTML-Dokument immer und
		// bei einem Text-Dokument nur, wenn es im Browse-Mode angezeigt
		// wird.
		if( pDoc->get(IDocumentSettingAccess::HTML_MODE) ||
            pDoc->get(IDocumentSettingAccess::BROWSE_MODE))
		{
			ViewShell *pVSh = 0;
			pDoc->GetEditShell( &pVSh );
			if ( pVSh &&
				 COL_TRANSPARENT != pVSh->GetViewOptions()->GetRetoucheColor().GetColor())
				aColor = pVSh->GetViewOptions()->GetRetoucheColor().GetColor();
		}

		ByteString sOut;
		GetCSS1Color( aColor, sOut );
		OutCSS1_PropertyAscii( sCSS1_P_background, sOut );
	}
}

//-----------------------------------------------------------------------

static Writer& OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( Writer& rWrt,
					const SvxUnderlineItem *pUItem,
					const SvxOverlineItem *pOItem,
					const SvxCrossedOutItem *pCOItem,
					const SvxBlinkItem *pBItem )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
    sal_Bool bNone = sal_False;

	const sal_Char *pUStr = 0;
	if( pUItem )
	{
		switch( pUItem->GetLineStyle() )
		{
		case UNDERLINE_NONE:
			bNone = sal_True;
			break;
		case UNDERLINE_DONTKNOW:
			break;
		default:
			if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
			{
				// das geht auch in HTML und muss nicht als STYLE-Option
				// und darf nicht als Hint geschrieben werden
				ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
						"Underline als Hint schreiben?" );
				pUStr = sCSS1_PV_underline;
			}
			break;
		}
	}

	const sal_Char *pOStr = 0;
	if( pOItem )
	{
		switch( pOItem->GetLineStyle() )
		{
		case UNDERLINE_NONE:
			bNone = sal_True;
			break;
		case UNDERLINE_DONTKNOW:
			break;
		default:
			if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
			{
				// das geht auch in HTML und muss nicht als STYLE-Option
				// und darf nicht als Hint geschrieben werden
				ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
						"Overline als Hint schreiben?" );
				pOStr = sCSS1_PV_overline;
			}
			break;
		}
	}

	const sal_Char *pCOStr = 0;
	if( pCOItem )
	{
		switch( pCOItem->GetStrikeout() )
		{
		case STRIKEOUT_NONE:
			bNone = sal_True;
			break;
		case STRIKEOUT_DONTKNOW:
			break;
		default:
			if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
			{
				// das geht auch in HTML und muss nicht als STYLE-Option
				// und darf nicht als Hint geschrieben werden
				ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
						"CrossedOut als Hint schreiben?" );
				pCOStr = sCSS1_PV_line_through;
			}
			break;
		}
	}

	const sal_Char *pBStr = 0;
	if( pBItem && rHTMLWrt.IsHTMLMode(HTMLMODE_BLINK) )
	{
		if( !pBItem->GetValue() )
		{
			bNone = sal_True;
		}
		else if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
		{
			// das geht auch in HTML und muss nicht als STYLE-Option
			// und darf nicht als Hint geschrieben werden
			ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
					"Blink als Hint schreiben?" );
			pBStr = sCSS1_PV_blink;
		}
	}

	ByteString sOut;
	if( pUStr )
		sOut.Append( pUStr );

	if( pOStr )
	{
		if( sOut.Len() )
			sOut += ' ';

		sOut.Append( pOStr );
	}

	if( pCOStr )
	{
		if( sOut.Len() )
			sOut += ' ';

		sOut.Append( pCOStr );
	}

	if( pBStr )
	{
		if( sOut.Len() )
			sOut += ' ';

		sOut.Append( pBStr );
	}

	if( sOut.Len() )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sOut );
    else if( bNone )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sCSS1_PV_none );

	return rWrt;
}


static Writer& OutCSS1_SvxCaseMap( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	if( !rHTMLWrt.IsHTMLMode(HTMLMODE_SMALL_CAPS) )
		return rWrt;

	const sal_Char *pStr = 0;
	switch( ((const SvxCaseMapItem&)rHt).GetCaseMap() )
	{
	case SVX_CASEMAP_NOT_MAPPED:	pStr = sCSS1_PV_normal;		break;
	case SVX_CASEMAP_KAPITAELCHEN:	pStr = sCSS1_PV_small_caps;	break;
	default:
		;
	}

	if( pStr )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, pStr );

	return rWrt;
}


static Writer& OutCSS1_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Farben muessen nicht in der Style-Option ausgegeben werden.
	if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
		!rHTMLWrt.bCfgPreferStyles )
		return rWrt;
	ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
			"Farbe wirklich als Hint ausgeben?" );

	Color aColor( ((const SvxColorItem&)rHt).GetValue() );
	if( COL_AUTO == aColor.GetColor() )
		aColor.SetColor( COL_BLACK );

	ByteString sOut;
	GetCSS1Color( aColor, sOut );

	rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_color, sOut );

	return rWrt;
}


static Writer& OutCSS1_SvxCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
{
	// Mit dieser Methode werden nur Hints ausgegeben!
	// Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.

	if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
		OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
				0, 0, (const SvxCrossedOutItem *)&rHt, 0 );

	return rWrt;
}

static Writer& OutCSS1_SvxFont( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Fonts muessen nicht in der Style-Option ausgegeben werden.
	if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
		return rWrt;

	sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
	switch( rHt.Which() )
	{
	case RES_CHRATR_CJK_FONT:	nScript = CSS1_OUTMODE_CJK;	break;
	case RES_CHRATR_CTL_FONT:	nScript = CSS1_OUTMODE_CTL;	break;
	}
	if( !rHTMLWrt.IsCSS1Script( nScript ) )
		return rWrt;

	ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
			"Font wirklich als Hint ausgeben?" );

	String sOut;
	// MS IE3b1 hat mit einfachen Haekchen Probleme
	sal_uInt16 nMode = rHTMLWrt.nCSS1OutMode & CSS1_OUTMODE_ANY_ON;
	sal_Unicode cQuote = nMode == CSS1_OUTMODE_RULE_ON ? '\"' : '\'';
	SwHTMLWriter::PrepareFontList( ((const SvxFontItem&)rHt), sOut, cQuote,
								   sal_True );

	rHTMLWrt.OutCSS1_Property( sCSS1_P_font_family, sOut );

	return rWrt;
}

static Writer& OutCSS1_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Font-Hoehen muessen nicht in der Style-Option ausgegeben werden.
	// Fuer Drop-Caps wird ein andewres font-size ausgegeben
	if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
		rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_DROPCAP ) )
		return rWrt;

	sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
	switch( rHt.Which() )
	{
	case RES_CHRATR_CJK_FONTSIZE:	nScript = CSS1_OUTMODE_CJK;	break;
	case RES_CHRATR_CTL_FONTSIZE:	nScript = CSS1_OUTMODE_CTL;	break;
	}
	if( !rHTMLWrt.IsCSS1Script( nScript ) )
		return rWrt;

	sal_uInt32 nHeight = ((const SvxFontHeightItem&)rHt).GetHeight();
	if( rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) )
	{
		// einen Hint nur dann ausgeben wenn es auch was bringt
		sal_uInt16 nSize = rHTMLWrt.GetHTMLFontSize( nHeight );
		if( rHTMLWrt.aFontHeights[nSize-1] == nHeight )
			return rWrt;
	}
	ByteString sHeight( ByteString::CreateFromInt32(
											(sal_Int32)(nHeight/20) ) );
	sHeight.Append( sCSS1_UNIT_pt );

	rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size, sHeight );

	return rWrt;
}

static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
	switch( rHt.Which() )
	{
	case RES_CHRATR_CJK_POSTURE:	nScript = CSS1_OUTMODE_CJK;	break;
	case RES_CHRATR_CTL_POSTURE:	nScript = CSS1_OUTMODE_CTL;	break;
	}
	if( !rHTMLWrt.IsCSS1Script( nScript ) )
		return rWrt;

	const sal_Char *pStr = 0;
	switch( ((const SvxPostureItem&)rHt).GetPosture() )
	{
	case ITALIC_NONE:		pStr = sCSS1_PV_normal;		break;
	case ITALIC_OBLIQUE:	pStr = sCSS1_PV_oblique;	break;
	case ITALIC_NORMAL:
		if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
		{
			// das geht auch in HTML und muss nicht als STYLE-Option
			// und darf nicht als Hint geschrieben werden
			ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
					"Italic als Hint schreiben?" );
			pStr = sCSS1_PV_italic;
		}
		break;
	default:
		;
	}

	if( pStr )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_style, pStr );

	return rWrt;
}

static Writer& OutCSS1_SvxKerning( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Kerning-Item nur ausgeben, wenn volle Style-Unterst?tzung da ist
	if( !rHTMLWrt.IsHTMLMode(HTMLMODE_FULL_STYLES) )
		return rWrt;

	sal_Int16 nValue = ((const SvxKerningItem&)rHt).GetValue();
	if( nValue )
	{
		ByteString sOut;
		if( nValue < 0 )
		{
			sOut = '-';
			nValue = -nValue;
		}

		// Breite als n.n pt
		nValue = (nValue + 1) / 2; 	// 1/10pt
		sOut.Append( ByteString::CreateFromInt32( (sal_Int32)(nValue  / 10) ) );
		sOut.Append( '.' );
		sOut.Append( ByteString::CreateFromInt32( (sal_Int32)(nValue % 10) ) );
		sOut.Append( sCSS1_UNIT_pt );

		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing, sOut );
	}
	else
	{
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing,
										sCSS1_PV_normal );
	}

	return rWrt;
}

static Writer& OutCSS1_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Language will be exported rules only
	if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
		return rWrt;

	sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
	switch( rHt.Which() )
	{
	case RES_CHRATR_CJK_LANGUAGE:	nScript = CSS1_OUTMODE_CJK;	break;
	case RES_CHRATR_CTL_LANGUAGE:	nScript = CSS1_OUTMODE_CTL;	break;
	}
	if( !rHTMLWrt.IsCSS1Script( nScript ) )
		return rWrt;

	ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
			"Language wirklich als Hint ausgeben?" );

	LanguageType eLang = ((const SvxLanguageItem &)rHt).GetLanguage();
	if( LANGUAGE_DONTKNOW == eLang )
		return rWrt;

	String sOut = MsLangId::convertLanguageToIsoString( eLang );

	rHTMLWrt.OutCSS1_Property( sCSS1_P_so_language, sOut );

	return rWrt;
}

static Writer& OutCSS1_SvxUnderline( Writer& rWrt, const SfxPoolItem& rHt )
{
	// Mit dieser Methode werden nur Hints ausgegeben!
	// Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.

	if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
		OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
				(const SvxUnderlineItem *)&rHt, 0, 0, 0 );

	return rWrt;
}


static Writer& OutCSS1_SvxOverline( Writer& rWrt, const SfxPoolItem& rHt )
{
	// Mit dieser Methode werden nur Hints ausgegeben!
	// Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.

	if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
		OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
				0, (const SvxOverlineItem *)&rHt, 0, 0 );

	return rWrt;
}


static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
	switch( rHt.Which() )
	{
	case RES_CHRATR_CJK_WEIGHT:	nScript = CSS1_OUTMODE_CJK;	break;
	case RES_CHRATR_CTL_WEIGHT:	nScript = CSS1_OUTMODE_CTL;	break;
	}
	if( !rHTMLWrt.IsCSS1Script( nScript ) )
		return rWrt;

	const sal_Char *pStr = 0;
	switch( ((const SvxWeightItem&)rHt).GetWeight() )
	{
	case WEIGHT_ULTRALIGHT:	pStr = sCSS1_PV_extra_light; 	break;
	case WEIGHT_LIGHT:		pStr = sCSS1_PV_light; 			break;
	case WEIGHT_SEMILIGHT:	pStr = sCSS1_PV_demi_light; 	break;
	case WEIGHT_NORMAL:		pStr = sCSS1_PV_normal;			break;
	case WEIGHT_SEMIBOLD:	pStr = sCSS1_PV_demi_bold; 		break;
	case WEIGHT_BOLD:
		if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
		{
			// das geht auch in HTML und muss nicht als STYLE-Option
			// und darf nicht als Hint geschrieben werden
			ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
					"Fett als Hint schreiben?" );
			pStr = sCSS1_PV_bold;
		}
		break;
	case WEIGHT_ULTRABOLD:	pStr = sCSS1_PV_extra_bold;		break;
	default:
		pStr = sCSS1_PV_normal;;
	}

	if( pStr )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_weight, pStr );

	return rWrt;
}

static Writer& OutCSS1_SvxBlink( Writer& rWrt, const SfxPoolItem& rHt )
{
	// Mit dieser Methode werden nur Hints ausgegeben!
	// Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.

	if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
		OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
				0, 0, 0, (const SvxBlinkItem *)&rHt );

	return rWrt;
}

static Writer& OutCSS1_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// #60393#: Netscape4 hat massive Probleme mit den Zellenhoehen
	// wenn der Zeilenabstand innerhalb einer Tabelle geaendert wird
	// und die Breite der Tabelle nicht automatisch berechnet wird
	// (also wenn eine WIDTH-Option vorhanden ist).
	if( rHTMLWrt.bOutTable && rHTMLWrt.bCfgNetscape4 )
		return rWrt;

	const SvxLineSpacingItem& rLSItem =	(const SvxLineSpacingItem&)rHt;

	sal_uInt16 nHeight = 0;
	sal_uInt16 nPrcHeight = 0;
	SvxLineSpace eLineSpace = rLSItem.GetLineSpaceRule();
	switch( rLSItem.GetInterLineSpaceRule() )
	{
	case SVX_INTER_LINE_SPACE_OFF:
	case SVX_INTER_LINE_SPACE_FIX:
		{
			switch( eLineSpace )
			{
			case SVX_LINE_SPACE_MIN:
			case SVX_LINE_SPACE_FIX:
				nHeight = rLSItem.GetLineHeight();
				break;
			case SVX_LINE_SPACE_AUTO:
				nPrcHeight = 100;
				break;
			default:
				;
			}
		}
		break;
	case SVX_INTER_LINE_SPACE_PROP:
		nPrcHeight = rLSItem.GetPropLineSpace();
		break;

	default:
		;
	}

	if( nHeight )
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_line_height, (long)nHeight );
	else if( nPrcHeight )
	{
		ByteString sHeight(
				ByteString::CreateFromInt32( (sal_Int32)nPrcHeight ) );
		sHeight += '%';
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_line_height, sHeight );
	}

	return rWrt;

}

static Writer& OutCSS1_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Alignment in Style-Option nur ausgeben, wenn das Tag kein
	// ALIGN=xxx zulaesst
	if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
		!rHTMLWrt.bNoAlign)
		return rWrt;

	const sal_Char* pStr = 0;
	switch( ((const SvxAdjustItem&)rHt).GetAdjust() )
	{
	case SVX_ADJUST_LEFT:	pStr = sCSS1_PV_left; 		break;
	case SVX_ADJUST_RIGHT:	pStr = sCSS1_PV_right;		break;
	case SVX_ADJUST_BLOCK:	pStr = sCSS1_PV_justify;	break;
	case SVX_ADJUST_CENTER: pStr = sCSS1_PV_center; 	break;
	default:
		;
	}

	if( pStr )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_align, pStr );

	return rWrt;
}

static Writer& OutCSS1_SvxFmtSplit( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	const sal_Char *pStr = ((const SvxFmtSplitItem&)rHt).GetValue()
							? sCSS1_PV_auto
							: sCSS1_PV_avoid;
	rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );

	return rWrt;
}

static Writer& OutCSS1_SwFmtLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	const sal_Char *pStr = ((const SwFmtLayoutSplit&)rHt).GetValue()
							? sCSS1_PV_auto
							: sCSS1_PV_avoid;
	rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );

	return rWrt;
}

static Writer& OutCSS1_SvxWidows( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	ByteString aStr(
		ByteString::CreateFromInt32( ((const SvxWidowsItem&)rHt).GetValue() ) );
	rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_widows, aStr );

	return rWrt;
}

static Writer& OutCSS1_SvxOrphans( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	ByteString aStr(
	   ByteString::CreateFromInt32( ((const SvxOrphansItem&)rHt).GetValue() ) );
	rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_orphans, aStr );

	return rWrt;
}

static void OutCSS1_SwFmtDropAttrs( SwHTMLWriter& rHWrt,
									const SwFmtDrop& rDrop,
								 	const SfxItemSet *pCharFmtItemSet )
{
	// Text fliesst rechts drumrum
	rHWrt.OutCSS1_PropertyAscii( sCSS1_P_float, sCSS1_PV_left );

	// Anzahl der Zeilen -> %-Angabe fuer Font-Hoehe!
	ByteString sOut( ByteString::CreateFromInt32( rDrop.GetLines()*100 ) );
	sOut += '%';
	rHWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size, sOut );

	// Abstand zum Text = rechter Rand
	sal_uInt16 nDistance = rDrop.GetDistance();
	if( nDistance > 0 )
		rHWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right, nDistance );

	const SwCharFmt *pDCCharFmt = rDrop.GetCharFmt();
	if( pCharFmtItemSet )
		rHWrt.OutCSS1_SfxItemSet( *pCharFmtItemSet );
	else if( pDCCharFmt )
		rHWrt.OutCSS1_SfxItemSet( pDCCharFmt->GetAttrSet() );
	else if( (rHWrt.nCSS1OutMode & CSS1_OUTMODE_ANY_OFF) == CSS1_OUTMODE_RULE_OFF )
		rHWrt.Strm() << sCSS1_rule_end;

}

static Writer& OutCSS1_SwFmtDrop( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	// nie als Option eines Absatzes ausgeben, sondern nur als Hints
	if( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) )
		return rWrt;

	if( rHTMLWrt.bTagOn )
	{
		SwCSS1OutMode aMode( rHTMLWrt,
							 rHTMLWrt.nCSS1Script|CSS1_OUTMODE_SPAN_TAG1_ON|CSS1_OUTMODE_ENCODE|
							 CSS1_OUTMODE_DROPCAP );

		OutCSS1_SwFmtDropAttrs( rHTMLWrt, (const SwFmtDrop&)rHt );
		// Ein "> wird schon vom aufrufenden OutCSS1_HintAsSpanTag geschrieben.
	}
	else
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False );
	}

	return rWrt;
}

static Writer& OutCSS1_SwFmtFrmSize( Writer& rWrt, const SfxPoolItem& rHt,
									 sal_uInt16 nMode )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	ByteString sOut;
	const SwFmtFrmSize& rFSItem = (const SwFmtFrmSize&)rHt;

	if( nMode & CSS1_FRMSIZE_WIDTH )
	{
		sal_uInt8 nPrcWidth = rFSItem.GetWidthPercent();
		if( nPrcWidth )
		{
			(sOut = ByteString::CreateFromInt32( nPrcWidth) ) += '%';
			rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_width, sOut );
		}
		else if( nMode & CSS1_FRMSIZE_PIXEL )
		{
			rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_width,
											rFSItem.GetSize().Width(), sal_False );
		}
		else
		{
			rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_width,
										   rFSItem.GetSize().Width() );
		}
	}

	if( nMode & CSS1_FRMSIZE_ANYHEIGHT )
	{
		sal_Bool bOutHeight = sal_False;
        switch( rFSItem.GetHeightSizeType() )
		{
		case ATT_FIX_SIZE:
			bOutHeight = (nMode & CSS1_FRMSIZE_FIXHEIGHT) != 0;
			break;
		case ATT_MIN_SIZE:
			bOutHeight = (nMode & CSS1_FRMSIZE_MINHEIGHT) != 0;
			break;
		case ATT_VAR_SIZE:
			bOutHeight = (nMode & CSS1_FRMSIZE_VARHEIGHT) != 0;
			break;
		default:
			ASSERT( bOutHeight, "Hoehe wird nicht exportiert" );
			break;
		}

		if( bOutHeight )
		{
			sal_uInt8 nPrcHeight = rFSItem.GetHeightPercent();
			if( nPrcHeight )
			{
				(sOut = ByteString::CreateFromInt32( nPrcHeight ) ) += '%';
				rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_height, sOut );
			}
			else if( nMode & CSS1_FRMSIZE_PIXEL )
			{
				rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_height,
												rFSItem.GetSize().Width(),
												sal_True );
			}
			else
			{
				rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_height,
											   rFSItem.GetSize().Height() );
			}
		}
	}

	return rWrt;
}

static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	const SvxLRSpaceItem& rLRItem = (const SvxLRSpaceItem&)rHt;

	// Der Export der harten Attributierung ist unnoetig, wenn die
	// neuen Werte denen der aktuellen Vorlage entsprechen

	// Einen linken Rand kann es durch eine Liste bereits in der
	// Umgebung geben
	long nLeftMargin = (long)rLRItem.GetTxtLeft() - rHTMLWrt.nLeftMargin;
	if( rHTMLWrt.nDfltLeftMargin != nLeftMargin )
	{
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLeftMargin );
	}

	if( rHTMLWrt.nDfltRightMargin != rLRItem.GetRight() )
	{
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right,
								 (long)rLRItem.GetRight() );
	}

	// Der Erstzeilen-Einzug kann den Platz fuer eine Numerierung
	// enthalten
	long nFirstLineIndent = (long)rLRItem.GetTxtFirstLineOfst() -
		rHTMLWrt.nFirstLineIndent;
	if( rHTMLWrt.nDfltFirstLineIndent != nFirstLineIndent )
	{
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent,
									 nFirstLineIndent );
	}

	return rWrt;
}

static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)rHt;

	if( rHTMLWrt.nDfltTopMargin != rULItem.GetUpper() )
	{
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_top,
									 (long)rULItem.GetUpper() );
	}

	if( rHTMLWrt.nDfltBottomMargin != rULItem.GetLower() )
	{
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_bottom,
									 (long)rULItem.GetLower() );
	}

	return rWrt;
}

static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
										const SvxULSpaceItem *pULItem,
										const SvxLRSpaceItem *pLRItem )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	if( pLRItem && pULItem &&
		pLRItem->GetLeft() == pLRItem->GetRight() &&
		pLRItem->GetLeft() == pULItem->GetUpper() &&
		pLRItem->GetLeft() == pULItem->GetLower() &&
		pLRItem->GetLeft() != rHTMLWrt.nDfltLeftMargin &&
		pLRItem->GetRight() != rHTMLWrt.nDfltRightMargin &&
		pULItem->GetUpper() != rHTMLWrt.nDfltTopMargin &&
		pULItem->GetLower() != rHTMLWrt.nDfltBottomMargin )
	{
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin, (long)pLRItem->GetLeft() );
	}
	else
	{
		if( pLRItem )
			OutCSS1_SvxLRSpace( rWrt, *pLRItem );
		if( pULItem )
			OutCSS1_SvxULSpace( rWrt, *pULItem );
	}

	return rWrt;
}

static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
										const SfxItemSet& rItemSet,
										sal_Bool bDeep )
{
	const SvxULSpaceItem *pULSpace = 0;
	const SvxLRSpaceItem *pLRSpace = 0;
	const SfxPoolItem *pItem;
	if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, bDeep, &pItem ) )
		pLRSpace = (const SvxLRSpaceItem *)pItem;

	if( SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, bDeep, &pItem ) )
		pULSpace = (const SvxULSpaceItem *)pItem;

	if( pLRSpace || pULSpace )
		OutCSS1_SvxULSpace_SvxLRSpace( rWrt, pULSpace, pLRSpace );

	return rWrt;
}

static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
										const SvxFmtBreakItem *pBreakItem,
										const SwFmtPageDesc *pPDescItem,
										const SvxFmtKeepItem *pKeepItem	)
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PRINT_EXT) )
		return rWrt;

	const sal_Char *pBreakBefore = 0;
	const sal_Char *pBreakAfter = 0;

	if( pKeepItem )
	{
		pBreakAfter = pKeepItem->GetValue() ? sCSS1_PV_avoid : sCSS1_PV_auto;
	}
	if( pBreakItem )
	{
		switch( pBreakItem->GetBreak() )
		{
		case SVX_BREAK_NONE:
			pBreakBefore = sCSS1_PV_auto;
			if( !pBreakAfter )
				pBreakAfter = sCSS1_PV_auto;
			break;

		case SVX_BREAK_PAGE_BEFORE:
			pBreakBefore = sCSS1_PV_always;
			break;

		case SVX_BREAK_PAGE_AFTER:
			pBreakAfter= sCSS1_PV_always;
			break;

		default:
			;
		}
	}
	if( pPDescItem )
	{
		const SwPageDesc *pPDesc = pPDescItem->GetPageDesc();
		if( pPDesc )
		{
			switch( pPDesc->GetPoolFmtId() )
			{
			case RES_POOLPAGE_LEFT:		pBreakBefore = sCSS1_PV_left;	break;
			case RES_POOLPAGE_RIGHT:	pBreakBefore = sCSS1_PV_right;	break;
			default:					pBreakBefore = sCSS1_PV_always;	break;
			}
		}
		else if( !pBreakBefore )
		{
			pBreakBefore = sCSS1_PV_auto;
		}
	}

	if( pBreakBefore )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_before,
										pBreakBefore );
	if( pBreakAfter )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_after,
										pBreakAfter );

	return rWrt;
}

static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
										const SfxItemSet& rItemSet,
										sal_Bool bDeep )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	const SfxPoolItem *pItem;
	const SvxFmtBreakItem *pBreakItem = 0;
	if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BREAK, bDeep, &pItem ))
		pBreakItem = (const SvxFmtBreakItem *)pItem;

	const SwFmtPageDesc *pPDescItem = 0;
	if( ( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
		  !rHTMLWrt.bCSS1IgnoreFirstPageDesc ||
		  rHTMLWrt.pStartNdIdx->GetIndex() !=
					  rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex() ) &&
		SFX_ITEM_SET==rItemSet.GetItemState( RES_PAGEDESC, bDeep, &pItem ))
		pPDescItem = (const SwFmtPageDesc*)pItem;

	const SvxFmtKeepItem *pKeepItem = 0;
	if( SFX_ITEM_SET==rItemSet.GetItemState( RES_KEEP, bDeep, &pItem ))
		pKeepItem = (const SvxFmtKeepItem *)pItem;

	if( pBreakItem || pPDescItem || pKeepItem )
		OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( rWrt, pBreakItem,
												   pPDescItem, pKeepItem );

	return rWrt;
}

// Wrapper fuer OutCSS1_SfxItemSet etc.
static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt )
{
	OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_ATTR, 0 );
	return rWrt;
}


static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
								 sal_uInt16 nMode, const String *pGrfName )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Das Zeichen-Attribut wird nicht ausgegeben, wenn gerade
	// Optionen ausgegeben werden
	if( rHt.Which() < RES_CHRATR_END &&
		rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
		return rWrt;

	// Erstmal ein par Werte holen
//	const Brush &rBrush = ((const SvxBrushItem &)rHt).GetBrush();
	const Color & rColor = ((const SvxBrushItem &)rHt).GetColor();
	const String *pLink = pGrfName ? pGrfName
							: ((const SvxBrushItem &)rHt).GetGraphicLink();
	SvxGraphicPosition ePos = ((const SvxBrushItem &)rHt).GetGraphicPos();

	if( CSS1_BACKGROUND_PAGE==nMode )
	{
		// Fuer Seitenvorlagen wurde der Grafik-Name uebergeben. Es wird
		// nur ein Attribut ausgegeben, wenn die Grafik nicht gekachelt ist.
		ASSERT( pLink, "Wo ist der Grafik-Name der Seitenvorlage?" );
		if( !pLink || !pLink->Len() || GPOS_TILED==ePos )
			return rWrt;
	}

	// Erstmal die Farbe holen
	sal_Bool bColor = sal_False;
    /// OD 02.09.2002 #99657#
    /// set <bTransparent> to sal_True, if color is "no fill"/"auto fill"
    sal_Bool bTransparent = (rColor.GetColor() == COL_TRANSPARENT);
	Color aColor;
	if( !bTransparent )
	{
		aColor = rColor;
		bColor = sal_True;
	}

	// und jetzt eine Grafik
	String sGrfNm;

	if( !pLink )
	{
		// embeddete Grafik -> WriteEmbedded schreiben
		const Graphic* pGrf = ((const SvxBrushItem &)rHt).GetGraphic();
		if( pGrf )
		{
			// Grafik als (JPG-)File speichern
			const String* pTempFileName = rHTMLWrt.GetOrigFileName();
			if( pTempFileName )
				sGrfNm = *pTempFileName;
			sal_uInt16 nErr = XOutBitmap::WriteGraphic( *pGrf, sGrfNm,
						String::CreateFromAscii("JPG"),
						XOUTBMP_USE_NATIVE_IF_POSSIBLE );
			if( !nErr )		// fehlerhaft, da ist nichts auszugeben
			{
                sGrfNm = URIHelper::SmartRel2Abs(
                    INetURLObject(rWrt.GetBaseURL()), sGrfNm,
                    URIHelper::GetMaybeFileHdl() );
				pLink = &sGrfNm;
			}
			else
			{
				rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
			}
		}
	}
	else if( !pGrfName && rHTMLWrt.bCfgCpyLinkedGrfs )
	{
		sGrfNm = *pLink;
		rWrt.CopyLocalFileToINet( sGrfNm );
		pLink = &sGrfNm;
	}

	// In Tabellen wird nur dann etwas exportiert, wenn eine Grafik
	// existiert.
	if( CSS1_BACKGROUND_TABLE==nMode && !pLink )
		return rWrt;

	// ggf. noch die Ausrichtung der Grafik
	const sal_Char *pRepeat = 0, *pHori = 0, *pVert = 0;
	if( pLink )
	{
		if( GPOS_TILED==ePos )
		{
			pRepeat = sCSS1_PV_repeat;
		}
		else
		{
			switch( ePos )
			{
			case GPOS_LT:
			case GPOS_MT:
			case GPOS_RT:
				pHori = sCSS1_PV_top;
				break;

			case GPOS_LM:
			case GPOS_MM:
			case GPOS_RM:
				pHori = sCSS1_PV_middle;
				break;

			case GPOS_LB:
			case GPOS_MB:
			case GPOS_RB:
				pHori = sCSS1_PV_bottom;
				break;

			default:
				;
			}

			switch( ePos )
			{
			case GPOS_LT:
			case GPOS_LM:
			case GPOS_LB:
				pVert = sCSS1_PV_left;
				break;

			case GPOS_MT:
			case GPOS_MM:
			case GPOS_MB:
				pVert = sCSS1_PV_center;
				break;

			case GPOS_RT:
			case GPOS_RM:
			case GPOS_RB:
				pVert = sCSS1_PV_right;
				break;

			default:
				;
			}

			if( pHori || pVert )
				pRepeat = sCSS1_PV_no_repeat;
		}
	}

	// jetzt den String zusammen bauen
	String sOut;
	if( !pLink && !bColor )
	{
		// keine Farbe und kein Link, aber ein transparenter Brush
		if( bTransparent && CSS1_BACKGROUND_FLY != nMode )
			sOut.AssignAscii( sCSS1_PV_transparent );
	}
	else
	{
		if( bColor )
		{
			ByteString sTmp;
			GetCSS1Color( aColor, sTmp );
			sOut += String( sTmp, RTL_TEXTENCODING_ASCII_US );
		}

		if( pLink )
		{
			if( bColor )
				sOut += ' ';

			sOut.AppendAscii( sCSS1_url );
			sOut.Append( '(' );
            sOut.Append( String(URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(),
              *pLink)));

			sOut.Append( ')' );

			if( pRepeat )
			{
				sOut.Append( ' ' );
				sOut.AppendAscii( pRepeat );
			}

			if( pHori )
			{
				sOut.Append( ' ' );
				sOut.AppendAscii( pHori );
			}
			if( pVert )
			{
				sOut.Append( ' ' );
				sOut.AppendAscii( pVert );
			}

			sOut.Append( ' ' );
			sOut.AppendAscii( sCSS1_PV_scroll );
		}
	}

	if( sOut.Len() )
		rHTMLWrt.OutCSS1_Property( sCSS1_P_background, sOut );

	return rWrt;
}

static void OutCSS1_SvxBorderLine( SwHTMLWriter& rHTMLWrt,
								   const sal_Char *pProperty,
								   const SvxBorderLine *pLine )
{
	if( !pLine )
	{
		rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sCSS1_PV_none );
		return;
	}

	sal_Bool bDouble = sal_False;
    sal_Int32 nWidth = pLine->GetOutWidth();
	if( pLine->GetInWidth() )
	{
		nWidth += pLine->GetDistance();
		nWidth += pLine->GetInWidth();
		bDouble = sal_True;
	}

	ByteString sOut;
	if( Application::GetDefaultDevice() &&
		nWidth <= Application::GetDefaultDevice()->PixelToLogic(
					Size( 1, 1 ), MapMode( MAP_TWIP) ).Width() )
	{
		// Wenn die Breite kleiner ist als ein Pixel, dann als 1px
		// ausgeben, damit Netscape und IE die Linie auch darstellen.
		sOut += "1px";
	}
	else
	{
		nWidth *= 5; 	// 1/100pt

		// Breite als n.nn pt
		sOut += ByteString::CreateFromInt32( nWidth / 100 );
		(((sOut += '.')
			+= ByteString::CreateFromInt32((nWidth/10) % 10))
			+= ByteString::CreateFromInt32(nWidth % 10)) += sCSS1_UNIT_pt;
	}

	// Linien-Stil: solid oder double
	((sOut += ' ')
		+= (bDouble ? sCSS1_PV_double : sCSS1_PV_solid)) += ' ';

	// und noch die Farbe
	GetCSS1Color( pLine->GetColor(), sOut );

	rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sOut );
}

static Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	// Das Zeichen-Attribut wird nicht ausgegeben, wenn gerade
	// Optionen ausgegeben werden
	if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PARA_BORDER))
		return rWrt;

	const SvxBoxItem& rBoxItem = (const SvxBoxItem&)rHt;
	const SvxBorderLine *pTop = rBoxItem.GetTop();
	const SvxBorderLine *pBottom = rBoxItem.GetBottom();
	const SvxBorderLine *pLeft = rBoxItem.GetLeft();
	const SvxBorderLine *pRight = rBoxItem.GetRight();

	if( (pTop && pBottom && pLeft && pRight &&
		 *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) ||
		 (!pTop && !pBottom && !pLeft && !pRight) )
	{
		// alle Linien gesetzt und gleich oder alle Linien nicht gesetzt
		// => border : ...
		OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border, pTop );
	}
	else
	{
		// sonst alle Linien individuell ausgeben
		OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_top, pTop );
		OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_bottom, pBottom );
		OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_left, pLeft );
		OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_right, pRight );
	}

	long nTopDist = pTop ? rBoxItem.GetDistance( BOX_LINE_TOP ) : 0;
	long nBottomDist = pBottom ? rBoxItem.GetDistance( BOX_LINE_BOTTOM ) : 0;
	long nLeftDist = pLeft ? rBoxItem.GetDistance( BOX_LINE_LEFT ) : 0;
	long nRightDist = pRight ? rBoxItem.GetDistance( BOX_LINE_RIGHT ) : 0;

	if( nTopDist == nBottomDist && nLeftDist == nRightDist )
	{
		ByteString sVal;
		AddUnitPropertyValue( nTopDist, rHTMLWrt.GetCSS1Unit(), sVal );
		if( nTopDist != nLeftDist )
		{
			sVal += ' ';
			AddUnitPropertyValue( nLeftDist, rHTMLWrt.GetCSS1Unit(), sVal );
		}
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_padding, sVal );
	}
	else
	{
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_top, nTopDist );
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_bottom, nBottomDist );
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_left, nLeftDist );
		rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_right, nRightDist );
	}

	return rWrt;
}

static Writer& OutCSS1_SvxFrameDirection( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = static_cast< SwHTMLWriter& >( rWrt  );

	// Language will be exported rules only
	if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_TEMPLATE ) )
		return rWrt;

	sal_uInt16 nDir =
		static_cast< const SvxFrameDirectionItem& >( rHt ).GetValue();
	sal_Char *pStr = 0;
	switch( nDir )
	{
	case FRMDIR_HORI_LEFT_TOP:
	case FRMDIR_VERT_TOP_LEFT:
		pStr = sCSS1_PV_ltr;
		break;
	case FRMDIR_HORI_RIGHT_TOP:
	case FRMDIR_VERT_TOP_RIGHT:
		pStr = sCSS1_PV_rtl;
		break;
	case FRMDIR_ENVIRONMENT:
		pStr = sCSS1_PV_inherit;
		break;
	}

	if( pStr )
		rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_direction, pStr );

	return rWrt;
}

/*
 * lege hier die Tabellen fuer die HTML-Funktions-Pointer auf
 * die Ausgabe-Funktionen an.
 * Es sind lokale Strukturen, die nur innerhalb der HTML-DLL
 * bekannt sein muessen.
 */


SwAttrFnTab aCSS1AttrFnTab = {
/* RES_CHRATR_CASEMAP	*/          OutCSS1_SvxCaseMap,
/* RES_CHRATR_CHARSETCOLOR	*/      0,
/* RES_CHRATR_COLOR	*/              OutCSS1_SvxColor,
/* RES_CHRATR_CONTOUR	*/          0,
/* RES_CHRATR_CROSSEDOUT	*/      OutCSS1_SvxCrossedOut,
/* RES_CHRATR_ESCAPEMENT	*/      0,
/* RES_CHRATR_FONT	*/              OutCSS1_SvxFont,
/* RES_CHRATR_FONTSIZE	*/          OutCSS1_SvxFontHeight,
/* RES_CHRATR_KERNING	*/          OutCSS1_SvxKerning,
/* RES_CHRATR_LANGUAGE	*/          OutCSS1_SvxLanguage,
/* RES_CHRATR_POSTURE	*/          OutCSS1_SvxPosture,
/* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
/* RES_CHRATR_SHADOWED	*/          0,
/* RES_CHRATR_UNDERLINE	*/          OutCSS1_SvxUnderline,
/* RES_CHRATR_WEIGHT	*/          OutCSS1_SvxFontWeight,
/* RES_CHRATR_WORDLINEMODE	*/      0,
/* RES_CHRATR_AUTOKERN	*/          0,
/* RES_CHRATR_BLINK	*/          	OutCSS1_SvxBlink,
/* RES_CHRATR_NOHYPHEN	*/          0, // Neu: nicht trennen
/* RES_CHRATR_NOLINEBREAK */        0, // Neu: nicht umbrechen
/* RES_CHRATR_BACKGROUND */        	OutCSS1_SvxBrush, // Neu: Zeichenhintergrund
/* RES_CHRATR_CJK_FONT */			OutCSS1_SvxFont,
/* RES_CHRATR_CJK_FONTSIZE */		OutCSS1_SvxFontHeight,
/* RES_CHRATR_CJK_LANGUAGE */		OutCSS1_SvxLanguage,
/* RES_CHRATR_CJK_POSTURE */		OutCSS1_SvxPosture,
/* RES_CHRATR_CJK_WEIGHT */			OutCSS1_SvxFontWeight,
/* RES_CHRATR_CTL_FONT */			OutCSS1_SvxFont,
/* RES_CHRATR_CTL_FONTSIZE */		OutCSS1_SvxFontHeight,
/* RES_CHRATR_CTL_LANGUAGE */		OutCSS1_SvxLanguage,
/* RES_CHRATR_CTL_POSTURE */		OutCSS1_SvxPosture,
/* RES_CHRATR_CTL_WEIGHT */			OutCSS1_SvxFontWeight,
/* RES_CHRATR_ROTATE */             0,
/* RES_CHRATR_EMPHASIS_MARK */      0,
/* RES_CHRATR_TWO_LINES */          0,
/* RES_CHRATR_SCALEW */             0,
/* RES_CHRATR_RELIEF */             0,
/* RES_CHRATR_HIDDEN */             0,
/* RES_CHRATR_OVERLINE */           OutCSS1_SvxOverline,
/* RES_CHRATR_DUMMY1 */             0,
/* RES_CHRATR_DUMMY2 */             0,

/* RES_TXTATR_REFMARK */            0,
/* RES_TXTATR_TOXMARK */            0,
/* RES_TXTATR_META */               0,
/* RES_TXTATR_METAFIELD */          0,
/* RES_TXTATR_AUTOFMT */            0,
/* RES_TXTATR_INETFMT */            0,
/* RES_TXTATR_CHARFMT */            0,
/* RES_TXTATR_CJK_RUBY */           0,
/* RES_TXTATR_UNKNOWN_CONTAINER */  0,
/* RES_TXTATR_DUMMY5 */             0,

/* RES_TXTATR_FIELD	*/          	0,
/* RES_TXTATR_FLYCNT */ 			0,
/* RES_TXTATR_FTN */				0,
/* RES_TXTATR_DUMMY4 */             0,
/* RES_TXTATR_DUMMY3 */             0,
/* RES_TXTATR_DUMMY1 */        	    0, // Dummy:
/* RES_TXTATR_DUMMY2 */        	    0, // Dummy:

/* RES_PARATR_LINESPACING	*/      OutCSS1_SvxLineSpacing,
/* RES_PARATR_ADJUST	*/          OutCSS1_SvxAdjust,
/* RES_PARATR_SPLIT	*/				OutCSS1_SvxFmtSplit,
/* RES_PARATR_WIDOWS	*/          OutCSS1_SvxWidows,
/* RES_PARATR_ORPHANS	*/          OutCSS1_SvxOrphans,
/* RES_PARATR_TABSTOP	*/          0,
/* RES_PARATR_HYPHENZONE*/          0,
/* RES_PARATR_DROP */				OutCSS1_SwFmtDrop,
/* RES_PARATR_REGISTER */        	0, // neu:  Registerhaltigkeit
/* RES_PARATR_NUMRULE */       	    0, // Dummy:
/* RES_PARATR_SCRIPTSPACE */   	    0, // Dummy:
/* RES_PARATR_HANGINGPUNCTUATION */	0, // Dummy:
/* RES_PARATR_FORBIDDEN_RULES */    0, // new
/* RES_PARATR_VERTALIGN */          0, // new
/* RES_PARATR_SNAPTOGRID*/          0, // new
/* RES_PARATR_CONNECT_TO_BORDER */  0, // new
/* RES_PARATR_OUTLINELEVEL */       0, // new since cws outlinelevel

/* RES_PARATR_LIST_ID */            0, // new
/* RES_PARATR_LIST_LEVEL */         0, // new
/* RES_PARATR_LIST_ISRESTART */     0, // new
/* RES_PARATR_LIST_RESTARTVALUE */  0, // new
/* RES_PARATR_LIST_ISCOUNTED */     0, // new

/* RES_FILL_ORDER	*/				0,
/* RES_FRM_SIZE	*/					0,
/* RES_PAPER_BIN	*/              0,
/* RES_LR_SPACE	*/                  OutCSS1_SvxLRSpace,
/* RES_UL_SPACE	*/                  OutCSS1_SvxULSpace,
/* RES_PAGEDESC */					0,
/* RES_BREAK */						0,
/* RES_CNTNT */						0,
/* RES_HEADER */		   			0,
/* RES_FOOTER */		   			0,
/* RES_PRINT */						0,
/* RES_OPAQUE */					0,
/* RES_PROTECT */					0,
/* RES_SURROUND */					0,
/* RES_VERT_ORIENT */				0,
/* RES_HORI_ORIENT */				0,
/* RES_ANCHOR */					0,
/* RES_BACKGROUND */				OutCSS1_SvxBrush,
/* RES_BOX	*/                      OutCSS1_SvxBox,
/* RES_SHADOW */					0,
/* RES_FRMMACRO */					0,
/* RES_COL */						0,
/* RES_KEEP */						0,
/* RES_URL */        	    		0,
/* RES_EDIT_IN_READONLY */        	0,
/* RES_LAYOUT_SPLIT */ 	    		0,
/* RES_CHAIN */        	    		0,
/* RES_TEXTGRID */        	    	0,
/* RES_LINENUMBER */        	    0,
/* RES_FTN_AT_TXTEND */        	    0,
/* RES_END_AT_TXTEND */        	    0,
/* RES_COLUMNBALANCE */        	    0,
/* RES_FRAMEDIR */        	    	OutCSS1_SvxFrameDirection,
/* RES_HEADER_FOOTER_EAT_SPACING */ 0,
/* RES_FRMATR_DUMMY9 */        	    0, // Dummy:
/* RES_FOLLOW_TEXT_FLOW */          0,
/* RES_WRAP_INFLUENCE_ON_OBJPOS */  0,
/* RES_FRMATR_DUMMY2 */             0, // Dummy:
/* RES_AUTO_STYLE */                0, // Dummy:
/* RES_FRMATR_DUMMY4 */             0, // Dummy:
/* RES_FRMATR_DUMMY5 */             0, // Dummy:

/* RES_GRFATR_MIRRORGRF */          0,
/* RES_GRFATR_CROPGRF	*/			0,
/* RES_GRFATR_ROTATION */			0,
/* RES_GRFATR_LUMINANCE */			0,
/* RES_GRFATR_CONTRAST */			0,
/* RES_GRFATR_CHANNELR */			0,
/* RES_GRFATR_CHANNELG */			0,
/* RES_GRFATR_CHANNELB */			0,
/* RES_GRFATR_GAMMA */				0,
/* RES_GRFATR_INVERT */				0,
/* RES_GRFATR_TRANSPARENCY */		0,
/* RES_GRFATR_DRWAMODE */			0,
/* RES_GRFATR_DUMMY1 */				0,
/* RES_GRFATR_DUMMY2 */				0,
/* RES_GRFATR_DUMMY3 */				0,
/* RES_GRFATR_DUMMY4 */				0,
/* RES_GRFATR_DUMMY5 */				0,

/* RES_BOXATR_FORMAT */				0,
/* RES_BOXATR_FORMULA */			0,
/* RES_BOXATR_VALUE */				0
};
