/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "hintids.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // OTES #include #include #include #include // 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 #include #include using namespace ::com::sun::star; using ::editeng::SvxBorderLine; /* * 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(__MINGW32__) #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 CSS1_CONSTASCII_DEF( sCSS1_rule_end, " }" ); sal_Char CSS1_CONSTASCII_DEF( sCSS1_span_tag_end, "\">" ); const sal_Char cCSS1_style_opt_end = '\"'; sal_Char 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_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 rtl::OString ConvToHex(sal_uInt16 nHex) { 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; } return rtl::OString(aNToABuf, 2); } static rtl::OString GetCSS1Color(const Color& rColor) { rtl::OStringBuffer aStr; aStr.append('#'); aStr.append(ConvToHex(rColor.GetRed())); aStr.append(ConvToHex(rColor.GetGreen())); aStr.append(ConvToHex(rColor.GetBlue())); return aStr.makeStringAndClear(); } 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 ) { rtl::OStringBuffer sOut; if( bFirstCSS1Rule && (nCSS1OutMode & CSS1_OUTMODE_RULE_ON)!=0 ) { bFirstCSS1Rule = sal_False; OutNewLine(); sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_style).append(' ') .append(OOO_STRING_SVTOOLS_HTML_O_type).append("=\"text/css\">"); Strm() << sOut.makeStringAndClear().getStr(); 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.append('<').append(OOO_STRING_SVTOOLS_HTML_span) .append(' ').append(OOO_STRING_SVTOOLS_HTML_O_style) .append("=\""); } else { HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False ); return; } break; case CSS1_OUTMODE_RULE_ON: { OutNewLine(); sOut.append(rtl::OUStringToOString(aCSS1Selector, eDestEnc)).append(" { "); } break; case CSS1_OUTMODE_STYLE_OPT_ON: sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_style) .append("=\""); break; } bFirstCSS1Property = sal_False; } else { sOut.append("; "); } sOut.append(pProp).append(": "); if( nCSS1OutMode & CSS1_OUTMODE_ENCODE ) { // In STYLE-Optionen den String codieren Strm() << sOut.makeStringAndClear().getStr(); if( pVal ) HTMLOutFuncs::Out_String( Strm(), rtl::OUString::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.append(pVal); else if( pSVal ) sOut.append(rtl::OUStringToOString(*pSVal, eDestEnc)); } if (sOut.getLength()) Strm() << sOut.makeStringAndClear().getStr(); } static void AddUnitPropertyValue(rtl::OStringBuffer &rOut, long nVal, FieldUnit eUnit) { if( nVal < 0 ) { // Vorzeichen extra behandeln nVal = -nVal; rOut.append('-'); } // 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: OSL_ENSURE( 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: OSL_ENSURE( FUNIT_CM == eUnit, "Masseinheit wird nicht unterstuetzt" ); case FUNIT_CM: // 0.01cm = 5.7twip (ist zwar ungenau, aber die UI ist auch ungenau) nMul = 2540; // 2.54 * 1000 nDiv = 1440; // 72 * 20; nFac = 100; pUnit = sCSS1_UNIT_cm; break; case FUNIT_TWIP: OSL_ENSURE( FUNIT_POINT == eUnit, "Masseinheit wird nicht unterstuetzt" ); case FUNIT_POINT: // 0.1pt = 2.0twip (ist zwar ungenau, aber die UI ist auch ungenau) nMul = 100; nDiv = 20; nFac = 10; pUnit = sCSS1_UNIT_pt; break; case FUNIT_PICA: // 0.01pc = 2.40twip (ist zwar ungenau, aber die UI ist auch ungenau) nMul = 1000; nDiv = 240; // 12 * 20; nFac = 100; pUnit = sCSS1_UNIT_pc; break; case FUNIT_NONE: case FUNIT_FOOT: case FUNIT_MILE: case FUNIT_CUSTOM: case FUNIT_PERCENT: case FUNIT_INCH: default: OSL_ENSURE( FUNIT_INCH == eUnit, "Masseinheit wird nicht unterstuetzt" ); // 0.01in = 14.4twip (ist zwar ungenau, aber die UI ist auch ungenau) nMul = 1000; nDiv = 1440; // 72 * 20; nFac = 100; 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.append('.'); while( nFac > 1 && !(nBigVal % nBigFac).IsZero() ) { nFac /= 10; nBigFac = nFac; rOut.append(static_cast((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.append(nBigVal / (sal_Int64)nFac); if( (nBigVal % (sal_Int64)nFac) != 0 ) { rOut.append('.'); while( nFac > 1 && (nBigVal % (sal_Int64)nFac) != 0 ) { nFac /= 10; rOut.append((nBigVal / (sal_Int64)nFac) % (sal_Int64)10); } } bOutLongVal = sal_False; } #endif } else { nLongVal = nVal * nMul; nLongVal /= nDiv; nLongVal += 5; nLongVal /= 10; } if( bOutLongVal ) { rOut.append(static_cast(nLongVal/nFac)); if( (nLongVal % nFac) != 0 ) { rOut.append('.'); while( nFac > 1 && (nLongVal % nFac) != 0 ) { nFac /= 10; rOut.append(static_cast((nLongVal / nFac) % 10)); } } } rOut.append(pUnit); } void SwHTMLWriter::OutCSS1_UnitProperty( const sal_Char *pProp, long nVal ) { rtl::OStringBuffer sOut; AddUnitPropertyValue(sOut, nVal, eCSS1Unit); OutCSS1_PropertyAscii(pProp, sOut.makeStringAndClear()); } 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; } rtl::OStringBuffer sOut; sOut.append(static_cast(nVal)); sOut.append(sCSS1_UNIT_px); OutCSS1_PropertyAscii(pProp, sOut.makeStringAndClear()); } 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 rtl::OStringBuffer sOut; switch( nCSS1OutMode & CSS1_OUTMODE_ANY_OFF ) { case CSS1_OUTMODE_SPAN_TAG_OFF: sOut.append(sCSS1_span_tag_end); break; case CSS1_OUTMODE_STYLE_OPT_OFF: sOut.append(cCSS1_style_opt_end); break; case CSS1_OUTMODE_RULE_OFF: sOut.append(sCSS1_rule_end); break; } if (sOut.getLength()) Strm() << sOut.makeStringAndClear().getStr(); } } 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

, 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()->size(); 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()->size(); for( i=1; iGetCharFmts())[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.size(); 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, rtl::OString& rToken, String& rClass, sal_uInt16& rRefPoolId, String *pPseudo ) { sal_uInt16 nDeep = 0; rToken = rtl::OString(); 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 = rtl::OString(OOO_STRING_SVTOOLS_HTML_blockquote); } break; case 'C': if( bChrFmt ) { if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_citiation) ) { rRefPoolId = RES_POOLCHR_HTML_CITIATION; rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_citiation); } else if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_code) ) { rRefPoolId = RES_POOLCHR_HTML_CODE; rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_code); } } break; case 'D': if( bChrFmt && rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_definstance) ) { rRefPoolId = RES_POOLCHR_HTML_DEFINSTANCE; rToken = rtl::OString(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 = rtl::OString(OOO_STRING_SVTOOLS_HTML_dd); } else { rRefPoolId = RES_POOLCOLL_HTML_DT; rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_dt); } } } break; case 'E': if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_emphasis ) ) { rRefPoolId = RES_POOLCHR_HTML_EMPHASIS; rToken = rtl::OString(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 = rtl::OString(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 = rtl::OString(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 = rtl::OString(OOO_STRING_SVTOOLS_HTML_preformtxt); } break; case 'S': if( bChrFmt ) { if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_sample ) ) { rRefPoolId = RES_POOLCHR_HTML_SAMPLE; rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_sample); } else if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_strong ) ) { rRefPoolId = RES_POOLCHR_HTML_STRONG; rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_strong); } } break; case 'T': if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_teletype ) ) { rRefPoolId = RES_POOLCHR_HTML_TELETYPE; rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_teletype); } break; case 'V': if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_variable ) ) { rRefPoolId = RES_POOLCHR_HTML_VARIABLE; rToken = rtl::OString(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 = rtl::OString(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 OSL_ENSURE( (rRefPoolId != 0) == (!rToken.isEmpty()), "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 = rtl::OString(OOO_STRING_SVTOOLS_HTML_parabreak); break; case RES_POOLCOLL_HEADLINE1: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_head1); break; case RES_POOLCOLL_HEADLINE2: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_head2); break; case RES_POOLCOLL_HEADLINE3: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_head3); break; case RES_POOLCOLL_HEADLINE4: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_head4); break; case RES_POOLCOLL_HEADLINE5: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_head5); break; case RES_POOLCOLL_HEADLINE6: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_head6); break; case RES_POOLCOLL_SENDADRESS: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_address); break; case RES_POOLCOLL_HTML_BLOCKQUOTE: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_blockquote); break; case RES_POOLCOLL_HTML_PRE: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_preformtxt); break; case RES_POOLCOLL_HTML_DD: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_dd); break; case RES_POOLCOLL_HTML_DT: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_dt); break; case RES_POOLCOLL_TABLE: if( pPseudo ) { rToken = rtl::OStringBuffer( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_tabledata)) .append(' ') .append(RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_parabreak)) .makeStringAndClear(); } else rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_parabreak); break; case RES_POOLCOLL_TABLE_HDLN: if( pPseudo ) { rToken = rtl::OStringBuffer( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_tableheader)) .append(' ') .append(RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_parabreak)) .makeStringAndClear(); } else rToken = rtl::OString(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 = rtl::OString(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 = rtl::OString(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 = rtl::OString(OOO_STRING_SVTOOLS_HTML_emphasis); break; case RES_POOLCHR_HTML_CITIATION: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_citiation); break; case RES_POOLCHR_HTML_STRONG: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_strong); break; case RES_POOLCHR_HTML_CODE: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_code); break; case RES_POOLCHR_HTML_SAMPLE: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_sample); break; case RES_POOLCHR_HTML_KEYBOARD: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_keyboard); break; case RES_POOLCHR_HTML_VARIABLE: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_variable); break; case RES_POOLCHR_HTML_DEFINSTANCE: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_definstance); break; case RES_POOLCHR_HTML_TELETYPE: rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_teletype); break; case RES_POOLCHR_INET_NORMAL: if( pPseudo ) { rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_anchor); pPseudo->AssignAscii( sCSS1_link ); } break; case RES_POOLCHR_INET_VISIT: if( pPseudo ) { rToken = rtl::OString(OOO_STRING_SVTOOLS_HTML_anchor); pPseudo->AssignAscii( sCSS1_visited ); } break; } // Wenn ein Token gesetzt ist, enthaelt nPoolId die dazugehoerige // Vorlage if( !rToken.isEmpty() && !rRefPoolId ) rRefPoolId = nPoolId; } if( !rToken.isEmpty() || bStop ) { // Anhalten wenn eine HTML-Tag-Vorlage gefunden wurde break; } else { // sonst weitersuchen nDeep++; pPFmt = pPFmt->DerivedFrom(); } } if( !rToken.isEmpty() ) { // 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 . exportiert, sonst als .. // 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 ); } rClass = GetAppCharClass().lowercase( 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 ) { rtl::OString aToken; String aClass; String aPseudo; sal_uInt16 nDeep = SwHTMLWriter::GetCSS1Selector( pFmt, aToken, aClass, rRefPoolId, &aPseudo ); if( nDeep ) { if( !aToken.isEmpty() ) rSelector = rtl::OStringToOUString(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 ) { OSL_ENSURE( !(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 ) { OSL_ENSURE( 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 ) { OSL_ENSURE( 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 = comphelper::string::strip(aName, ' '); 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, 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( rFmt.GetName() ); else { if( nPoolFmtId==RES_POOLCOLL_TEXT ) rHTMLWrt.aScriptParaStyles.insert( pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false )->GetName() ); rHTMLWrt.aScriptParaStyles.insert( rFmt.GetName() ); } bHasScriptDependencies = sal_True; } if( nPoolFmtId==RES_POOLCOLL_TEXT && !rHTMLWrt.bFirstCSS1Property ) rHTMLWrt.bPoolCollTextModified = sal_True; // Drop-Caps ausgeben const SfxPoolItem *pItem; if( 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 = rtl::OUString('@'); 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 { rtl::OStringBuffer sVal; AddUnitPropertyValue(sVal, rSz.Width(), rHTMLWrt.GetCSS1Unit()); sVal.append(' '); AddUnitPropertyValue(sVal, rSz.Height(), rHTMLWrt.GetCSS1Unit()); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_size, sVal.makeStringAndClear()); } // 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(); rtl::OString sTmp(rtl::OUStringToOString(aSelector, rHTMLWrt.eDestEnc)); rWrt.Strm() << sTmp.getStr() << " {"; 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( 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() ) { OSL_ENSURE( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" ); if( !pSdrObj ) pSdrObj = rFrmFmt.FindSdrObject(); OSL_ENSURE( 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() ) { OSL_ENSURE( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" ); if( !pSdrObj ) pSdrObj = rFrmFmt.FindSdrObject(); OSL_ENSURE( 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 { OSL_ENSURE( HTML_FRMOPT_ABSSIZE & nFrmOpts, "Absolute Groesse wird exportiert" ); OSL_ENSURE( 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_TableCellBorderHack(SwFrmFmt const& rFrmFmt) { SwCSS1OutMode const aMode(*this, CSS1_OUTMODE_STYLE_OPT_ON|CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_TABLEBOX, true, 0); OutCSS1_SvxBox(*this, rFrmFmt.GetBox()); if (!bFirstCSS1Property) { this->Strm() << cCSS1_style_opt_end; } } 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; /// 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. OSL_ENSURE( 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(); } OutCSS1_PropertyAscii(sCSS1_P_background, GetCSS1Color(aColor)); } } //----------------------------------------------------------------------- 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 OSL_ENSURE( !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 OSL_ENSURE( !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 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), "CrossedOut als Hint schreiben?" ); pCOStr = sCSS1_PV_line_through; } break; } } const sal_Char *pBStr = 0; if( pBItem ) { 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 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), "Blink als Hint schreiben?" ); pBStr = sCSS1_PV_blink; } } rtl::OStringBuffer sOut; if( pUStr ) sOut.append(pUStr); if( pOStr ) { if (sOut.getLength()) sOut.append(' '); sOut.append(pOStr); } if( pCOStr ) { if (sOut.getLength()) sOut.append(' '); sOut.append(pCOStr); } if( pBStr ) { if (sOut.getLength()) sOut.append(' '); sOut.append(pBStr); } if (sOut.getLength()) rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sOut.makeStringAndClear() ); 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; switch( ((const SvxCaseMapItem&)rHt).GetCaseMap() ) { case SVX_CASEMAP_NOT_MAPPED: rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, sCSS1_PV_normal ); break; case SVX_CASEMAP_KAPITAELCHEN: rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, sCSS1_PV_small_caps ); break; case SVX_CASEMAP_VERSALIEN: rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_uppercase ); break; case SVX_CASEMAP_GEMEINE: rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_lowercase ); break; case SVX_CASEMAP_TITEL: rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_capitalize ); break; default: ; } 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; OSL_ENSURE( !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 ); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_color, GetCSS1Color(aColor)); 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; OSL_ENSURE( !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; } rtl::OStringBuffer sHeight; sHeight.append(static_cast(nHeight/20)); sHeight.append(sCSS1_UNIT_pt); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_font_size, sHeight.makeStringAndClear()); 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 OSL_ENSURE( !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 ) { rtl::OStringBuffer sOut; if( nValue < 0 ) { sOut.append('-'); nValue = -nValue; } // Breite als n.n pt nValue = (nValue + 1) / 2; // 1/10pt sOut.append(static_cast(nValue / 10)); sOut.append('.'); sOut.append(static_cast(nValue % 10)); sOut.append(sCSS1_UNIT_pt); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_letter_spacing, sOut.makeStringAndClear()); } 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; OSL_ENSURE( !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 OSL_ENSURE( !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; // 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 ) { rtl::OStringBuffer sHeight; sHeight.append(static_cast(nPrcHeight)); sHeight.append('%'); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_line_height, sHeight.makeStringAndClear()); } 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; rtl::OString aStr(rtl::OString::valueOf(static_cast( ((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; rtl::OString aStr(rtl::OString::valueOf(static_cast( ((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! rtl::OStringBuffer sOut; sOut.append(static_cast(rDrop.GetLines()*100)); sOut.append('%'); rHWrt.OutCSS1_PropertyAscii(sCSS1_P_font_size, sOut.makeStringAndClear()); // 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; const SwFmtFrmSize& rFSItem = (const SwFmtFrmSize&)rHt; if( nMode & CSS1_FRMSIZE_WIDTH ) { sal_uInt8 nPrcWidth = rFSItem.GetWidthPercent(); if( nPrcWidth ) { rtl::OStringBuffer sOut; sOut.append(static_cast(nPrcWidth)); sOut.append('%'); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_width, sOut.makeStringAndClear()); } 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: OSL_ENSURE( bOutHeight, "Hoehe wird nicht exportiert" ); break; } if( bOutHeight ) { sal_uInt8 nPrcHeight = rFSItem.GetHeightPercent(); if( nPrcHeight ) { rtl::OStringBuffer sOut; sOut.append(static_cast(nPrcHeight)); sOut.append('%'); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_height, sOut.makeStringAndClear()); } 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. OSL_ENSURE( 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; /// set 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, rtl::OUString("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 ) { rtl::OString sTmp(GetCSS1Color(aColor)); sOut += String(rtl::OStringToOUString(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 || pLine->isEmpty() ) { rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sCSS1_PV_none ); return; } sal_Int32 nWidth = pLine->GetWidth(); rtl::OStringBuffer 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.append(RTL_CONSTASCII_STRINGPARAM("1px")); } else { nWidth *= 5; // 1/100pt // Breite als n.nn pt sOut.append(static_cast(nWidth / 100)); sOut.append('.').append(static_cast((nWidth/10) % 10)). append(static_cast(nWidth % 10)).append(sCSS1_UNIT_pt); } // Linien-Stil: solid oder double sOut.append(' '); switch (pLine->GetBorderLineStyle()) { case table::BorderLineStyle::SOLID: sOut.append(sCSS1_PV_solid); break; case table::BorderLineStyle::DOTTED: sOut.append(sCSS1_PV_dotted); break; case table::BorderLineStyle::DASHED: sOut.append(sCSS1_PV_dashed); break; case table::BorderLineStyle::DOUBLE: case table::BorderLineStyle::THINTHICK_SMALLGAP: case table::BorderLineStyle::THINTHICK_MEDIUMGAP: case table::BorderLineStyle::THINTHICK_LARGEGAP: case table::BorderLineStyle::THICKTHIN_SMALLGAP: case table::BorderLineStyle::THICKTHIN_MEDIUMGAP: case table::BorderLineStyle::THICKTHIN_LARGEGAP: sOut.append(sCSS1_PV_double); break; case table::BorderLineStyle::EMBOSSED: sOut.append(sCSS1_PV_ridge); break; case table::BorderLineStyle::ENGRAVED: sOut.append(sCSS1_PV_groove); break; case table::BorderLineStyle::INSET: sOut.append(sCSS1_PV_inset); break; case table::BorderLineStyle::OUTSET: sOut.append(sCSS1_PV_outset); break; default: sOut.append(sCSS1_PV_none); } sOut.append(' '); // und noch die Farbe sOut.append(GetCSS1Color(pLine->GetColor())); rHTMLWrt.OutCSS1_PropertyAscii(pProperty, sOut.makeStringAndClear()); } Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt ) { SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)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 ) { rtl::OStringBuffer sVal; AddUnitPropertyValue(sVal, nTopDist, rHTMLWrt.GetCSS1Unit()); if( nTopDist != nLeftDist ) { sVal.append(' '); AddUnitPropertyValue(sVal, nLeftDist, rHTMLWrt.GetCSS1Unit()); } rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_padding, sVal.makeStringAndClear()); } 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_RSID */ 0, /* RES_CHRATR_DUMMY1 */ 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_RSID */ 0, // new /* 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 }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */