summaryrefslogtreecommitdiff
path: root/sw/source/filter/html/htmlfly.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/html/htmlfly.cxx')
-rw-r--r--sw/source/filter/html/htmlfly.cxx1929
1 files changed, 1929 insertions, 0 deletions
diff --git a/sw/source/filter/html/htmlfly.cxx b/sw/source/filter/html/htmlfly.cxx
new file mode 100644
index 000000000000..24875b456565
--- /dev/null
+++ b/sw/source/filter/html/htmlfly.cxx
@@ -0,0 +1,1929 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <svx/svxids.hrc>
+#include "hintids.hxx"
+#include <tools/string.hxx>
+#include <svl/urihelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/imap.hxx>
+#include <svtools/imapobj.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <svx/xoutbmp.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+
+
+#include <fmtanchr.hxx>
+#include <fmtornt.hxx>
+#include <fmturl.hxx>
+#include <fmtfsize.hxx>
+#include <fmtclds.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtinfmt.hxx>
+#include <txtinet.hxx>
+#include "frmatr.hxx"
+#include <grfatr.hxx>
+#include <flypos.hxx>
+#include <docary.hxx>
+#include <ndgrf.hxx>
+
+#include "doc.hxx"
+#include "ndtxt.hxx"
+#include "pam.hxx"
+#include "swerror.h"
+#include "frmfmt.hxx"
+#include "wrthtml.hxx"
+#include "css1kywd.hxx"
+#include "htmlfly.hxx"
+
+using namespace ::com::sun::star;
+
+////////////////////////////////////////////////////////////
+
+const ULONG HTML_FRMOPTS_IMG_ALL =
+ HTML_FRMOPT_ALT |
+ HTML_FRMOPT_SIZE |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_BORDER |
+ HTML_FRMOPT_NAME;
+const ULONG HTML_FRMOPTS_IMG_CNTNR =
+ HTML_FRMOPTS_IMG_ALL |
+ HTML_FRMOPT_ABSSIZE;
+const ULONG HTML_FRMOPTS_IMG =
+ HTML_FRMOPTS_IMG_ALL |
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SPACE |
+ HTML_FRMOPT_BRCLEAR;
+const ULONG HTML_FRMOPTS_IMG_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SPACE;
+
+const ULONG HTML_FRMOPTS_DIV =
+ HTML_FRMOPT_ID |
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SIZE |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_ABSSIZE |
+ HTML_FRMOPT_S_SPACE |
+ HTML_FRMOPT_S_BORDER |
+ HTML_FRMOPT_S_BACKGROUND |
+ HTML_FRMOPT_BRCLEAR |
+ HTML_FRMOPT_DIR;
+
+const ULONG HTML_FRMOPTS_MULTICOL =
+ HTML_FRMOPT_ID |
+ HTML_FRMOPT_WIDTH |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_ABSSIZE |
+ HTML_FRMOPT_DIR;
+const ULONG HTML_FRMOPTS_MULTICOL_CNTNR =
+ HTML_FRMOPTS_MULTICOL;
+const ULONG HTML_FRMOPTS_MULTICOL_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SIZE |
+ HTML_FRMOPT_S_SPACE |
+ HTML_FRMOPT_S_BORDER|
+ HTML_FRMOPT_S_BACKGROUND;
+
+const ULONG HTML_FRMOPTS_SPACER =
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SIZE |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_BRCLEAR |
+ HTML_FRMOPT_MARGINSIZE |
+ HTML_FRMOPT_ABSSIZE;
+
+const ULONG HTML_FRMOPTS_CNTNR =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SPACE |
+ HTML_FRMOPT_S_WIDTH |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_ABSSIZE |
+ HTML_FRMOPT_S_PIXSIZE;
+
+
+static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt );
+static Writer& OutHTML_FrmFmtAsMulticol( Writer& rWrt, const SwFrmFmt& rFmt,
+ BOOL bInCntnr );
+static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFmt );
+static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
+ const SwFrmFmt& rFrmFmt, BOOL bSpan );
+static Writer& OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFmt,
+ BOOL bInCntnr );
+
+static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFmt,
+ BOOL bInCntnr );
+
+static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ const SdrObject& rSdrObj );
+//-----------------------------------------------------------------------
+
+extern HTMLOutEvent __FAR_DATA aAnchorEventTable[];
+
+static HTMLOutEvent __FAR_DATA aImageEventTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_O_SDonload, OOO_STRING_SVTOOLS_HTML_O_onload, SVX_EVENT_IMAGE_LOAD },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonabort, OOO_STRING_SVTOOLS_HTML_O_onabort, SVX_EVENT_IMAGE_ABORT },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonerror, OOO_STRING_SVTOOLS_HTML_O_onerror, SVX_EVENT_IMAGE_ERROR },
+ { 0, 0, 0 }
+};
+
+static HTMLOutEvent __FAR_DATA aIMapEventTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_O_SDonmouseover, OOO_STRING_SVTOOLS_HTML_O_onmouseover, SFX_EVENT_MOUSEOVER_OBJECT },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonmouseout, OOO_STRING_SVTOOLS_HTML_O_onmouseout, SFX_EVENT_MOUSEOUT_OBJECT },
+ { 0, 0, 0 }
+};
+
+
+
+SV_IMPL_OP_PTRARR_SORT( SwHTMLPosFlyFrms, SwHTMLPosFlyFrmPtr )
+
+USHORT SwHTMLWriter::GuessFrmType( const SwFrmFmt& rFrmFmt,
+ const SdrObject*& rpSdrObj )
+{
+ SwHTMLFrmType eType;
+
+ if( RES_DRAWFRMFMT == rFrmFmt.Which() )
+ {
+ // Als Default irgendein Zeichen-Objekt
+ eType = HTML_FRMTYPE_DRAW;
+
+ const SdrObject *pObj =
+ SwHTMLWriter::GetMarqueeTextObj( (const SwDrawFrmFmt &)rFrmFmt );
+ if( pObj )
+ {
+ // Laufschrift
+ rpSdrObj = pObj;
+ eType = HTML_FRMTYPE_MARQUEE;
+ }
+ else
+ {
+ pObj = GetHTMLControl( (const SwDrawFrmFmt &)rFrmFmt );
+
+ if( pObj )
+ {
+ // Form-Control
+ rpSdrObj = pObj;
+ eType = HTML_FRMTYPE_CONTROL;
+ }
+ }
+ }
+ else
+ {
+ // Als Default ein Textrahmen
+ eType = HTML_FRMTYPE_TEXT;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ const SwNode* pNd = pDoc->GetNodes()[ nStt ];
+
+ if( pNd->IsGrfNode() )
+ {
+ // Grafik - Node
+ eType = HTML_FRMTYPE_GRF;
+ }
+ else if( pNd->IsOLENode() )
+ {
+ // Applet, Plugin, Floating-Frame
+ eType = (SwHTMLFrmType)GuessOLENodeFrmType( *pNd );
+ }
+ else
+ {
+ ULONG nEnd = pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
+
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_COL,
+ TRUE, &pItem ) &&
+ ((const SwFmtCol *)pItem)->GetNumCols() > 1 )
+ {
+ // spaltiger Rahmen
+ eType = HTML_FRMTYPE_MULTICOL;
+ }
+ else if( pNd->IsTableNode() )
+ {
+ const SwTableNode *pTblNd = pNd->GetTableNode();
+ ULONG nTblEnd = pTblNd->EndOfSectionIndex();
+
+ if( nTblEnd+1 == nEnd )
+ {
+ // Tabelle
+ eType = HTML_FRMTYPE_TABLE;
+ }
+ else if( nTblEnd+2 == nEnd )
+ {
+ // Tabelle mit Unterschrft
+ eType = HTML_FRMTYPE_TABLE_CAP;
+ }
+ }
+ else if( pNd->IsTxtNode() )
+ {
+ const SwTxtNode *pTxtNd = pNd->GetTxtNode();
+
+ BOOL bEmpty = FALSE;
+ if( nStt==nEnd-1 && !pTxtNd->Len() )
+ {
+ // leerer Rahmen? Nur wenn kein Rahmen am
+ // Text- oder Start-Node verankert ist.
+ bEmpty = TRUE;
+ if( pHTMLPosFlyFrms )
+ {
+ for( USHORT i=0; i<pHTMLPosFlyFrms->Count(); i++ )
+ {
+ ULONG nIdx = (*pHTMLPosFlyFrms)[i]
+ ->GetNdIndex().GetIndex();
+ bEmpty = (nIdx != nStt) && (nIdx != nStt-1);
+ if( !bEmpty || nIdx > nStt )
+ break;
+ }
+ }
+ }
+ if( bEmpty )
+ {
+ const SvxBrushItem& rBrush = rFrmFmt.GetBackground();
+ /// OD 02.09.2002 #99657#
+ /// background is not empty, if it has a background graphic
+ /// or its background color is not "no fill"/"auto fill".
+ if( GPOS_NONE != rBrush.GetGraphicPos() ||
+ rBrush.GetColor() != COL_TRANSPARENT )
+ bEmpty = FALSE;
+ }
+ if( bEmpty )
+ {
+ // leerer Rahmen
+ eType = HTML_FRMTYPE_EMPTY;
+ }
+ else if( pDoc->GetNodes()[nStt+1]->IsTableNode() )
+ {
+ const SwTableNode *pTblNd =
+ pDoc->GetNodes()[nStt+1]->GetTableNode();
+ if( pTblNd->EndOfSectionIndex()+1 == nEnd )
+ {
+ // Tabelle mit Ueberschrift
+ eType = HTML_FRMTYPE_TABLE_CAP;
+ }
+ }
+ }
+ }
+ }
+
+ return static_cast< USHORT >(eType);
+}
+
+void SwHTMLWriter::CollectFlyFrms()
+{
+ ASSERT( HTML_CFG_MAX+1 == MAX_BROWSERS,
+ "number of browser configurations has changed" );
+
+ BYTE nSz = (BYTE)Min( pDoc->GetSpzFrmFmts()->Count(), USHORT(255) );
+ SwPosFlyFrms aFlyPos( nSz, nSz );
+ pDoc->GetAllFlyFmts( aFlyPos, bWriteAll ? 0 : pCurPam, TRUE );
+
+ for( USHORT i=0; i< aFlyPos.Count(); i++ )
+ {
+ const SwFrmFmt& rFrmFmt = aFlyPos[i]->GetFmt();
+ const SdrObject *pSdrObj = 0;
+ const SwPosition *pAPos;
+ const SwCntntNode *pACNd;
+ SwHTMLFrmType eType = (SwHTMLFrmType)GuessFrmType( rFrmFmt, pSdrObj );
+
+ BYTE nMode;
+ const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
+ sal_Int16 eHoriRel = rFrmFmt.GetHoriOrient().GetRelationOrient();
+ switch( rAnchor.GetAnchorId() )
+ {
+ case FLY_AT_PAGE:
+ case FLY_AT_FLY:
+ nMode = aHTMLOutFrmPageFlyTable[eType][nExportMode];
+ break;
+
+ case FLY_AT_PARA:
+ // Absatz-gebundene Rahmen werden nur dann vor den
+ // Absatz geschrieben, wenn der Absatz einen Abstand
+ // hat.
+ if( text::RelOrientation::FRAME == eHoriRel &&
+ (pAPos = rAnchor.GetCntntAnchor()) != 0 &&
+ (pACNd = pAPos->nNode.GetNode().GetCntntNode()) != 0 )
+ {
+ const SvxLRSpaceItem& rLRItem =
+ (const SvxLRSpaceItem&)pACNd->GetAttr(RES_LR_SPACE);
+ if( rLRItem.GetTxtLeft() || rLRItem.GetRight() )
+ {
+ nMode = aHTMLOutFrmParaFrameTable[eType][nExportMode];
+ break;
+ }
+ }
+ nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
+ break;
+
+ case FLY_AT_CHAR:
+ if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
+ nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
+ else
+ nMode = aHTMLOutFrmParaOtherTable[eType][nExportMode];
+ break;
+
+ default:
+ nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
+ break;
+ }
+
+ if( !pHTMLPosFlyFrms )
+ pHTMLPosFlyFrms = new SwHTMLPosFlyFrms;
+
+ SwHTMLPosFlyFrm *pNew =
+ new SwHTMLPosFlyFrm( *aFlyPos[i], pSdrObj, nMode );
+ pHTMLPosFlyFrms->Insert( pNew );
+ }
+}
+
+BOOL SwHTMLWriter::OutFlyFrm( ULONG nNdIdx, xub_StrLen nCntntIdx, BYTE nPos,
+ HTMLOutContext *pContext )
+{
+ BOOL bFlysLeft = FALSE; // Noch Flys an aktueller Node-Position da?
+
+ // OutFlyFrm kan rekursiv aufgerufen werden. Deshalb muss man
+ // manchmal wieder von vorne anfangen, nachdem ein Fly ausgegeben
+ // wurde.
+ BOOL bRestart = TRUE;
+ while( pHTMLPosFlyFrms && bRestart )
+ {
+ bFlysLeft = bRestart = FALSE;
+
+ // suche nach dem Anfang der FlyFrames
+ USHORT i;
+
+ for( i = 0; i < pHTMLPosFlyFrms->Count() &&
+ (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() < nNdIdx; i++ )
+ ;
+ for( ; !bRestart && i < pHTMLPosFlyFrms->Count() &&
+ (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() == nNdIdx; i++ )
+ {
+ SwHTMLPosFlyFrm *pPosFly = (*pHTMLPosFlyFrms)[i];
+ if( ( HTML_POS_ANY == nPos ||
+ pPosFly->GetOutPos() == nPos ) &&
+ pPosFly->GetCntntIndex() == nCntntIdx )
+ {
+ // Erst entfernen ist wichtig, weil in tieferen
+ // Rekursionen evtl. weitere Eintraege oder das
+ // ganze Array geloscht werden koennte.
+ pHTMLPosFlyFrms->Remove( i, 1 );
+ i--;
+ if( !pHTMLPosFlyFrms->Count() )
+ {
+ delete pHTMLPosFlyFrms;
+ pHTMLPosFlyFrms = 0;
+ bRestart = TRUE; // nicht wirklich, nur raus
+ // aus der Schleife
+ }
+
+ if( pContext )
+ {
+ HTMLOutFuncs::FlushToAscii(Strm(), *pContext );
+ pContext = 0; // one time only
+ }
+
+ OutFrmFmt( pPosFly->GetOutMode(), pPosFly->GetFmt(),
+ pPosFly->GetSdrObject() );
+ switch( pPosFly->GetOutFn() )
+ {
+ case HTML_OUT_DIV:
+ case HTML_OUT_SPAN:
+ case HTML_OUT_MULTICOL:
+ case HTML_OUT_TBLNODE:
+ bRestart = TRUE; // Hier wird's evtl rekursiv
+ break;
+ }
+ delete pPosFly;
+ }
+ else
+ {
+ bFlysLeft = TRUE;
+ }
+ }
+ }
+
+ return bFlysLeft;
+}
+
+void SwHTMLWriter::OutFrmFmt( BYTE nMode, const SwFrmFmt& rFrmFmt,
+ const SdrObject *pSdrObject )
+{
+ BYTE nCntnrMode = SwHTMLPosFlyFrm::GetOutCntnr( nMode );
+ BYTE nOutMode = SwHTMLPosFlyFrm::GetOutFn(nMode);
+ const sal_Char *pCntnrStr = 0;
+ if( HTML_CNTNR_NONE != nCntnrMode )
+ {
+
+ if( bLFPossible && HTML_CNTNR_DIV == nCntnrMode )
+ OutNewLine();
+
+ ByteString sOut( '<' );
+ pCntnrStr = (HTML_CNTNR_DIV == nCntnrMode)
+ ? OOO_STRING_SVTOOLS_HTML_division
+ : OOO_STRING_SVTOOLS_HTML_span;
+ sOut += pCntnrStr;
+ ((((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"")
+ += sCSS1_class_abs_pos) += '\"';
+ Strm() << sOut.GetBuffer();
+
+ // Fuer Nicht-Zeichenobekte eine Breite ausgeben
+ ULONG nFrmFlags = HTML_FRMOPTS_CNTNR;
+
+ // Fuer spaltige Rahmen koennen wir auch noch den Hintergrund ausgeben.
+ if( HTML_OUT_MULTICOL == nOutMode )
+ nFrmFlags |= HTML_FRMOPT_S_BACKGROUND|HTML_FRMOPT_S_BORDER;
+
+ if( IsHTMLMode( HTMLMODE_BORDER_NONE ) )
+ nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
+ OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags, pSdrObject );
+ Strm() << '>';
+
+ if( HTML_CNTNR_DIV == nCntnrMode )
+ {
+ IncIndentLevel();
+ bLFPossible = TRUE;
+ }
+ }
+
+ switch( nOutMode )
+ {
+ case HTML_OUT_TBLNODE: // OK
+ ASSERT( !pCntnrStr, "Table: Container ist hier nicht vorgesehen" );
+ OutHTML_FrmFmtTableNode( *this, rFrmFmt );
+ break;
+ case HTML_OUT_GRFNODE: // OK
+ OutHTML_FrmFmtGrfNode( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_OLENODE: // OK
+ OutHTML_FrmFmtOLENode( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_OLEGRF: // OK
+ OutHTML_FrmFmtOLENodeGrf( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_DIV:
+ case HTML_OUT_SPAN:
+ ASSERT( !pCntnrStr, "Div: Container ist hier nicht vorgesehen" );
+ OutHTML_FrmFmtAsDivOrSpan( *this, rFrmFmt, HTML_OUT_SPAN==nOutMode );
+ break;
+ case HTML_OUT_MULTICOL: // OK
+ OutHTML_FrmFmtAsMulticol( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_SPACER: // OK
+ ASSERT( !pCntnrStr, "Spacer: Container ist hier nicht vorgesehen" );
+ OutHTML_FrmFmtAsSpacer( *this, rFrmFmt );
+ break;
+ case HTML_OUT_CONTROL: // OK
+ OutHTML_DrawFrmFmtAsControl( *this,
+ (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject,
+ pCntnrStr != 0 );
+ break;
+ case HTML_OUT_AMARQUEE:
+ OutHTML_FrmFmtAsMarquee( *this, rFrmFmt, *pSdrObject );
+ break;
+ case HTML_OUT_MARQUEE:
+ ASSERT( !pCntnrStr, "Marquee: Container ist hier nicht vorgesehen" );
+ OutHTML_DrawFrmFmtAsMarquee( *this,
+ (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject );
+ break;
+ case HTML_OUT_GRFFRM:
+ OutHTML_FrmFmtAsImage( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ }
+
+ if( HTML_CNTNR_DIV == nCntnrMode )
+ {
+ DecIndentLevel();
+ if( bLFPossible )
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
+ bLFPossible = TRUE;
+ }
+ else if( HTML_CNTNR_SPAN == nCntnrMode )
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, FALSE );
+}
+
+
+void SwHTMLWriter::OutFrmFmtOptions( const SwFrmFmt &rFrmFmt,
+ const String& rAlternateTxt,
+ ByteString &rEndTags,
+ sal_uInt32 nFrmOpts )
+{
+ ByteString sOut;
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+
+ // Name
+ if( (nFrmOpts & (HTML_FRMOPT_ID|HTML_FRMOPT_NAME)) &&
+ rFrmFmt.GetName().Len() )
+ {
+ const sal_Char *pStr =
+ (nFrmOpts & HTML_FRMOPT_ID) ? OOO_STRING_SVTOOLS_HTML_O_id : OOO_STRING_SVTOOLS_HTML_O_name;
+ ((sOut += ' ') += pStr) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), rFrmFmt.GetName(), eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ // Name
+ if( nFrmOpts & HTML_FRMOPT_DIR )
+ {
+ sal_uInt16 nDir = GetHTMLDirection( rItemSet );
+ Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ OutDirection( nDir );
+ }
+
+
+ // ALT
+ if( (nFrmOpts & HTML_FRMOPT_ALT) && rAlternateTxt.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_alt) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), rAlternateTxt, eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ // ALIGN
+ const sal_Char *pStr = 0;
+ RndStdIds eAnchorId = rFrmFmt.GetAnchor().GetAnchorId();
+ if( (nFrmOpts & HTML_FRMOPT_ALIGN) &&
+ ((FLY_AT_PARA == eAnchorId) || (FLY_AT_CHAR == eAnchorId)) )
+ {
+ // MIB 12.3.98: Ist es nicht schlauer, absatzgebundene
+ // Rahmen notfalls links auszurichten als sie
+ // zeichengebunden einzufuegen???
+ const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient();
+ if( !(nFrmOpts & HTML_FRMOPT_S_ALIGN) ||
+ text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
+ text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
+ {
+ pStr = text::HoriOrientation::RIGHT == rHoriOri.GetHoriOrient()
+ ? OOO_STRING_SVTOOLS_HTML_AL_right
+ : OOO_STRING_SVTOOLS_HTML_AL_left;
+ }
+ }
+ if( (nFrmOpts & HTML_FRMOPT_ALIGN) && !pStr &&
+ ( (nFrmOpts & HTML_FRMOPT_S_ALIGN) == 0 ||
+ (FLY_AS_CHAR == eAnchorId) ) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_VERT_ORIENT, TRUE, &pItem ))
+ {
+ switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
+ {
+ case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
+ case text::VertOrientation::CHAR_TOP:
+ case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // geht nicht
+ case text::VertOrientation::LINE_CENTER:
+ case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // geht nicht
+ case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
+ case text::VertOrientation::LINE_BOTTOM:
+ case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // geht nicht
+ case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
+ case text::VertOrientation::NONE: break;
+ }
+ }
+ if( pStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
+
+
+ // HSPACE und VSPACE
+ Size aTwipSpc( 0, 0 );
+ if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, TRUE, &pItem ))
+ {
+ aTwipSpc.Width() =
+ ( ((SvxLRSpaceItem*)pItem)->GetLeft() +
+ ((SvxLRSpaceItem*)pItem)->GetRight() ) / 2;
+ nDfltLeftMargin = nDfltRightMargin = aTwipSpc.Width();
+ }
+ if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, TRUE, &pItem ))
+ {
+ aTwipSpc.Height() =
+ ( ((SvxULSpaceItem*)pItem)->GetUpper() +
+ ((SvxULSpaceItem*)pItem)->GetLower() ) / 2;
+ nDfltTopMargin = nDfltBottomMargin = (USHORT)aTwipSpc.Height();
+ }
+
+ if( (nFrmOpts & HTML_FRMOPT_SPACE) &&
+ (aTwipSpc.Width() || aTwipSpc.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ Size aPixelSpc =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipSpc,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSpc.Width() && aTwipSpc.Width() )
+ aPixelSpc.Width() = 1;
+ if( !aPixelSpc.Height() && aTwipSpc.Height() )
+ aPixelSpc.Height() = 1;
+
+ if( aPixelSpc.Width() )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_hspace) += '=')
+ += ByteString::CreateFromInt32( aPixelSpc.Width() );
+ }
+
+ if( aPixelSpc.Height() )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_vspace) += '=')
+ += ByteString::CreateFromInt32( aPixelSpc.Height() );
+ }
+ }
+
+ // Der Abstand muss bei der Groesse beruecksichtigt, wenn das entsprechende
+ // Flag gesetzt ist.
+ if( (nFrmOpts & HTML_FRMOPT_MARGINSIZE) )
+ {
+ aTwipSpc.Width() *= -2;
+ aTwipSpc.Height() *= -2;
+ }
+ else
+ {
+ aTwipSpc.Width() = 0;
+ aTwipSpc.Height() = 0;
+ }
+
+ if( !(nFrmOpts & HTML_FRMOPT_ABSSIZE) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, TRUE, &pItem ))
+ {
+ const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
+
+ aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_LEFT );
+ aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_RIGHT );
+ aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_TOP );
+ aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_BOTTOM );
+ }
+
+ // WIDTH und/oder HEIGHT
+ // ATT_VAR_SIZE/ATT_MIN_SIZE nur ausgeben, wenn ANYSIZE gesezut ist
+ if( (nFrmOpts & HTML_FRMOPT_SIZE) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_FRM_SIZE, TRUE, &pItem ) &&
+ ( (nFrmOpts & HTML_FRMOPT_ANYSIZE) ||
+ ATT_FIX_SIZE == ((const SwFmtFrmSize *)pItem)->GetHeightSizeType()) )
+ {
+ const SwFmtFrmSize *pFSItem = (const SwFmtFrmSize *)pItem;
+ BYTE nPrcWidth = pFSItem->GetWidthPercent();
+ BYTE nPrcHeight = pFSItem->GetHeightPercent();
+
+ // Groesse des Objekts Twips ohne Raender
+ Size aTwipSz( (nPrcWidth ? 0
+ : pFSItem->GetWidth()-aTwipSpc.Width()),
+ (nPrcHeight ? 0
+ : pFSItem->GetHeight()-aTwipSpc.Height()) );
+
+ ASSERT( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0,
+ "Rahmengroesse minus Abstand < 0!!!???" );
+ if( aTwipSz.Width() < 0 )
+ aTwipSz.Width() = 0;
+ if( aTwipSz.Height() < 0 )
+ aTwipSz.Height() = 0;
+
+ Size aPixelSz( 0, 0 );
+ if( (aTwipSz.Width() || aTwipSz.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ aPixelSz =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSz.Width() && aTwipSz.Width() )
+ aPixelSz.Width() = 1;
+ if( !aPixelSz.Height() && aTwipSz.Height() )
+ aPixelSz.Height() = 1;
+ }
+
+ if( (nFrmOpts & HTML_FRMOPT_WIDTH) &&
+ ((nPrcWidth && nPrcWidth!=255) || aPixelSz.Width()) )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=';
+ if( nPrcWidth )
+ (sOut += ByteString::CreateFromInt32( nPrcWidth )) += '%';
+ else
+ sOut += ByteString::CreateFromInt32( aPixelSz.Width() );
+ }
+
+ if( (nFrmOpts & HTML_FRMOPT_HEIGHT) &&
+ ((nPrcHeight && nPrcHeight!=255) || aPixelSz.Height()) )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=';
+ if( nPrcHeight )
+ (sOut += ByteString::CreateFromInt32( nPrcHeight )) += '%';
+ else
+ sOut += ByteString::CreateFromInt32( aPixelSz.Height() );
+ }
+ }
+
+ if( sOut.Len() )
+ Strm() << sOut.GetBuffer();
+
+ // Umlauf fuer absatzgeb. Grafiken als <BR CLEAR=...> in den String
+ // schreiben
+ if( (nFrmOpts & HTML_FRMOPT_BRCLEAR) &&
+ ((FLY_AT_PARA == rFrmFmt.GetAnchor().GetAnchorId()) ||
+ (FLY_AT_CHAR == rFrmFmt.GetAnchor().GetAnchorId())) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_SURROUND, TRUE, &pItem ))
+ {
+ const SwFmtSurround* pSurround = (const SwFmtSurround*)pItem;
+ sal_Int16 eHoriOri = rFrmFmt.GetHoriOrient().GetHoriOrient();
+ pStr = 0;
+ SwSurround eSurround = pSurround->GetSurround();
+ BOOL bAnchorOnly = pSurround->IsAnchorOnly();
+ switch( eHoriOri )
+ {
+ case text::HoriOrientation::RIGHT:
+ {
+ switch( eSurround )
+ {
+ case SURROUND_NONE:
+ case SURROUND_RIGHT:
+ pStr = OOO_STRING_SVTOOLS_HTML_AL_right;
+ break;
+ case SURROUND_LEFT:
+ case SURROUND_PARALLEL:
+ if( bAnchorOnly )
+ bClearRight = TRUE;
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+
+ default:
+ // #67508#: If a frame is centered, it gets left aligned. This
+ // should be taken into account here, too.
+ {
+ switch( eSurround )
+ {
+ case SURROUND_NONE:
+ case SURROUND_LEFT:
+ pStr = OOO_STRING_SVTOOLS_HTML_AL_left;
+ break;
+ case SURROUND_RIGHT:
+ case SURROUND_PARALLEL:
+ if( bAnchorOnly )
+ bClearLeft = TRUE;
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+
+ }
+
+ if( pStr )
+ {
+ (((((((sOut = '<') += OOO_STRING_SVTOOLS_HTML_linebreak) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += pStr) += '>') += rEndTags;
+ rEndTags = sOut;
+ }
+ }
+}
+
+
+Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt,
+ const String &rGrfName, const String& rAlternateTxt,
+ const Size &rRealSize, sal_uInt32 nFrmOpts,
+ const sal_Char *pMarkType,
+ const ImageMap *pAltImgMap )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // ggf. ein noch offenes Attribut voruebergehend beenden
+ if( rHTMLWrt.aINetFmts.Count() )
+ {
+ SwFmtINetFmt *pINetFmt =
+ rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
+ OutHTML_INetFmt( rWrt, *pINetFmt, FALSE );
+ }
+
+ String aGrfNm( rGrfName );
+ if( !HTMLOutFuncs::PrivateURLToInternalImg(aGrfNm) )
+ aGrfNm = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), aGrfNm);
+
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+
+ const SwFmtURL *pURLItem = 0;
+
+ // das URL-Attribut nur beruecksichtigen, wenn keine Image-Map
+ // uebergeben wurde
+ if( !pAltImgMap &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_URL, TRUE, &pItem ))
+ {
+ pURLItem = (const SwFmtURL *)pItem;
+ }
+
+ // Image-Map rausschreiben
+ const ImageMap *pIMap = pAltImgMap;
+ if( !pIMap && pURLItem )
+ {
+ pIMap = pURLItem->GetMap();
+ }
+
+ String aIMapName;
+ if( pIMap )
+ {
+ // den Namen eindeutig machen
+ aIMapName = pIMap->GetName();
+ String aNameBase;
+ if( aIMapName.Len() )
+ aNameBase = aIMapName;
+ else
+ aNameBase.AssignAscii( OOO_STRING_SVTOOLS_HTML_map );
+ if( !aIMapName.Len() )
+ (aIMapName = aNameBase)
+ += String::CreateFromInt32( rHTMLWrt.nImgMapCnt );
+
+ BOOL bFound;
+ do
+ {
+ bFound = FALSE;
+ for( USHORT i=0; i<rHTMLWrt.aImgMapNames.Count(); i++ )
+ {
+ // TODO: Unicode: Comparison is case insensitive for ASCII
+ // characters only now!
+ if( aIMapName.EqualsIgnoreCaseAscii(*rHTMLWrt.aImgMapNames[i]) )
+ {
+ bFound = TRUE;
+ break;
+ }
+ }
+ if( bFound )
+ {
+ rHTMLWrt.nImgMapCnt++;
+ (aIMapName = aNameBase)
+ += String::CreateFromInt32( rHTMLWrt.nImgMapCnt );
+ }
+
+ } while( bFound );
+
+ BOOL bScale = FALSE;
+ //Size aGrfSize( rNode.GetTwipSize() );
+ Fraction aScaleX( 1, 1 );
+ Fraction aScaleY( 1, 1 );
+
+ const SwFmtFrmSize& rFrmSize = rFrmFmt.GetFrmSize();
+ const SvxBoxItem& rBox = rFrmFmt.GetBox();
+
+ if( !rFrmSize.GetWidthPercent() && rRealSize.Width() )
+ {
+ SwTwips nWidth = rFrmSize.GetWidth();
+ nWidth -= ( rBox.CalcLineSpace(BOX_LINE_LEFT) +
+ rBox.CalcLineSpace(BOX_LINE_RIGHT) );
+
+ ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
+ if( nWidth<=0 ) // sollte nicht passieren
+ nWidth = 1;
+
+ if( rRealSize.Width() != nWidth )
+ {
+ aScaleX = Fraction( nWidth, rRealSize.Width() );
+ bScale = TRUE;
+ }
+ }
+ if( !rFrmSize.GetHeightPercent() && rRealSize.Height() )
+ {
+ SwTwips nHeight = rFrmSize.GetHeight();
+ nHeight -= ( rBox.CalcLineSpace(BOX_LINE_TOP) +
+ rBox.CalcLineSpace(BOX_LINE_BOTTOM) );
+
+ ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
+ if( nHeight<=0 )
+ nHeight = 1;
+
+ if( rRealSize.Height() != nHeight )
+ {
+ aScaleY = Fraction( nHeight, rRealSize.Height() );
+ bScale = TRUE;
+ }
+ }
+
+ rHTMLWrt.aImgMapNames.Insert( new String(aIMapName),
+ rHTMLWrt.aImgMapNames.Count() );
+
+ ByteString aIndMap, aIndArea;
+ const sal_Char *pLF = 0, *pIndArea = 0, *pIndMap = 0;
+#if defined(UNX)
+ sal_Char aLF[2] = "\x00";
+#endif
+
+ if( rHTMLWrt.bLFPossible )
+ {
+ rHTMLWrt.OutNewLine( TRUE );
+ rHTMLWrt.GetIndentString( aIndMap );
+ rHTMLWrt.GetIndentString( aIndArea, 1 );
+#if defined(UNX)
+ aLF[0] = SwHTMLWriter::sNewLine;
+ pLF = aLF;
+#else
+ pLF = SwHTMLWriter::sNewLine;
+#endif
+ pIndArea = aIndArea.GetBuffer();
+ pIndMap = aIndMap.GetBuffer();
+ }
+
+ if( bScale )
+ {
+ ImageMap aScaledIMap( *pIMap );
+ aScaledIMap.Scale( aScaleX, aScaleY );
+ HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), aScaledIMap, aIMapName,
+ aIMapEventTable,
+ rHTMLWrt.bCfgStarBasic,
+ pLF, pIndArea, pIndMap,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+ else
+ {
+ HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), *pIMap, aIMapName,
+ aIMapEventTable,
+ rHTMLWrt.bCfgStarBasic,
+ pLF, pIndArea, pIndMap,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+ }
+
+ // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( TRUE );
+
+ // Attribute die ausserhelb der Grafik geschreiben werden muessen sammeln
+ ByteString sOut;
+ ByteString aEndTags;
+
+ // implizite Sprungmarke -> <A NAME=...></A>...<IMG ...>
+ if( pMarkType && rFrmFmt.GetName().Len() )
+ rHTMLWrt.OutImplicitMark( rFrmFmt.GetName(), pMarkType );
+
+ // URL -> <A>...<IMG ... >...</A>
+ const SvxMacroItem *pMacItem = 0;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, TRUE, &pItem ))
+ pMacItem = (const SvxMacroItem *)pItem;
+
+ if( pURLItem || pMacItem )
+ {
+ String aMapURL;
+ String aName;
+ String aTarget;
+ if( pURLItem )
+ {
+ aMapURL = pURLItem->GetURL();
+ aName = pURLItem->GetName();
+ aTarget = pURLItem->GetTargetFrameName();
+ }
+ BOOL bEvents = pMacItem && pMacItem->GetMacroTable().Count();
+
+ if( aMapURL.Len() || aName.Len() || aTarget.Len() || bEvents )
+ {
+ (sOut = '<') += OOO_STRING_SVTOOLS_HTML_anchor;
+
+ // Ein HREF nur Ausgaben, wenn es einen Link oder Makros gibt
+ if( aMapURL.Len() || bEvents )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ rHTMLWrt.OutHyperlinkHRefValue( aMapURL );
+ sOut = '\"';
+ }
+
+ if( aName.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aName,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ if( aTarget.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aTarget,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ if( sOut.Len() )
+ {
+ rWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ }
+
+ if( pMacItem )
+ {
+ const SvxMacroTableDtor& rMacTable = pMacItem->GetMacroTable();
+ if( rMacTable.Count() )
+ HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable,
+ aAnchorEventTable,
+ rHTMLWrt.bCfgStarBasic,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+
+ rWrt.Strm() << ">";
+ (((sOut = "</") += OOO_STRING_SVTOOLS_HTML_anchor) += ">") += aEndTags;
+ aEndTags = sOut;
+ }
+ }
+
+ // Umrandung -> <FONT COLOR = ...>...<IMG ... >...</FONT>
+ USHORT nBorderWidth = 0;
+ if( (nFrmOpts & HTML_FRMOPT_BORDER) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, TRUE, &pItem ))
+ {
+ Size aTwipBorder( 0, 0 );
+ const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
+
+ const SvxBorderLine *pColBorderLine = 0;
+ const SvxBorderLine *pBorderLine = pBoxItem->GetLeft();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Width() += pBorderLine->GetOutWidth();
+ }
+
+ pBorderLine = pBoxItem->GetRight();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Width() += pBorderLine->GetOutWidth();
+ }
+
+ pBorderLine = pBoxItem->GetTop();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Height() += pBorderLine->GetOutWidth();
+ }
+
+ pBorderLine = pBoxItem->GetBottom();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Height() += pBorderLine->GetOutWidth();
+ }
+
+ aTwipBorder.Width() /= 2;
+ aTwipBorder.Height() /= 2;
+
+ if( (aTwipBorder.Width() || aTwipBorder.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ Size aPixelBorder =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipBorder,
+ MapMode(MAP_TWIP) );
+ if( !aPixelBorder.Width() && aTwipBorder.Width() )
+ aPixelBorder.Width() = 1;
+ if( !aPixelBorder.Height() && aTwipBorder.Height() )
+ aPixelBorder.Height() = 1;
+
+ if( aPixelBorder.Width() )
+ aPixelBorder.Height() = 0;
+
+ nBorderWidth =
+ (USHORT)(aPixelBorder.Width() + aPixelBorder.Height());
+ }
+
+ if( pColBorderLine )
+ {
+ sOut = '<';
+ (((sOut += OOO_STRING_SVTOOLS_HTML_font) += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_Color( rWrt.Strm(),
+ pColBorderLine->GetColor(), rHTMLWrt.eDestEnc ) << '>';
+
+ (((sOut = "</" ) += OOO_STRING_SVTOOLS_HTML_font) += '>') += aEndTags;
+ aEndTags = sOut;
+ }
+ }
+
+ sOut = '<';
+ (((sOut += OOO_STRING_SVTOOLS_HTML_image) += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aGrfNm, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
+
+ // Events
+ sOut.Erase();
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, TRUE, &pItem ))
+ {
+ const SvxMacroTableDtor& rMacTable =
+ ((const SvxMacroItem *)pItem)->GetMacroTable();
+ if( rMacTable.Count() )
+ HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable, aImageEventTable,
+ rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+
+ // ALT, ALIGN, WIDTH, HEIGHT, HSPACE, VSPACE
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, rAlternateTxt, aEndTags, nFrmOpts );
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) )
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmOpts );
+
+
+ if( nFrmOpts & HTML_FRMOPT_BORDER )
+ {
+ (((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += '=')
+ += ByteString::CreateFromInt32( nBorderWidth );
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+
+ if( pURLItem && pURLItem->IsServerMap() )
+ {
+ (sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_ismap;
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+ if( aIMapName.Len() )
+ {
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_usemap) += "=\"#";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aIMapName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
+ }
+
+ rHTMLWrt.Strm() << '>';
+
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ if( rHTMLWrt.aINetFmts.Count() )
+ {
+ // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
+ // werden muss
+ SwFmtINetFmt *pINetFmt =
+ rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
+ OutHTML_INetFmt( rWrt, *pINetFmt, TRUE );
+ }
+
+ return rHTMLWrt;
+}
+
+Writer& OutHTML_BulletImage( Writer& rWrt,
+ const sal_Char *pTag,
+ const SvxBrushItem* pBrush,
+ String &rGrfName,
+ const Size &rSize,
+ const SwFmtVertOrient* pVertOrient )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Wenn es ein BrushItem gibt, muss die Grafiknoch exportiert werden
+ const String *pLink = 0;
+ if( pBrush )
+ {
+ pLink = pBrush->GetGraphicLink();
+
+ // embeddete Grafik -> WriteEmbedded schreiben
+ if( !pLink )
+ {
+ const Graphic* pGrf = pBrush->GetGraphic();
+ if( pGrf )
+ {
+ // Grafik als (JPG-)File speichern
+ if( rHTMLWrt.GetOrigFileName() )
+ rGrfName = *rHTMLWrt.GetOrigFileName();
+ USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, rGrfName,
+ String::CreateFromAscii("JPG"),
+ (XOUTBMP_USE_GIF_IF_SENSIBLE |
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE));
+ if( !nErr )
+ {
+ rGrfName = URIHelper::SmartRel2Abs(
+ INetURLObject( rWrt.GetBaseURL() ), rGrfName,
+ URIHelper::GetMaybeFileHdl() );
+ pLink = &rGrfName;
+ }
+ else
+ {
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ }
+ }
+ }
+ else
+ {
+ rGrfName = *pLink;
+ if( rHTMLWrt.bCfgCpyLinkedGrfs )
+ {
+ rHTMLWrt.CopyLocalFileToINet( rGrfName );
+ pLink = &rGrfName;
+ }
+ }
+ }
+ else
+ {
+ pLink = &rGrfName;
+ }
+
+ ByteString sOut;
+ if( pTag )
+ (sOut += '<') += pTag;
+
+ if( pLink )
+ {
+ sOut += ' ';
+ String s( *pLink );
+ if( !HTMLOutFuncs::PrivateURLToInternalImg(s) )
+ s = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), s);
+ (sOut += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), s, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+
+ // Groesse des Objekts Twips ohne Raender
+ Size aPixelSz( 0, 0 );
+ if( (rSize.Width() || rSize.Height()) && Application::GetDefaultDevice() )
+ {
+ aPixelSz =
+ Application::GetDefaultDevice()->LogicToPixel( rSize,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSz.Width() && rSize.Width() )
+ aPixelSz.Width() = 1;
+ if( !aPixelSz.Height() && rSize.Height() )
+ aPixelSz.Height() = 1;
+ }
+
+ if( aPixelSz.Width() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Width() );
+
+ if( aPixelSz.Height() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Height() );
+
+ if( pVertOrient )
+ {
+ const sal_Char *pStr = 0;
+ switch( pVertOrient->GetVertOrient() )
+ {
+ case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
+ case text::VertOrientation::CHAR_TOP:
+ case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // geht nicht
+ case text::VertOrientation::LINE_CENTER:
+ case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // geht nicht
+ case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
+ case text::VertOrientation::LINE_BOTTOM:
+ case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // geht nicht
+ case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
+ case text::VertOrientation::NONE: break;
+ }
+ if( pStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
+ }
+ }
+
+ if( pTag )
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+
+ return rWrt;
+}
+
+
+//-----------------------------------------------------------------------
+
+static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ ULONG nEnd = rHTMLWrt.pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
+
+ String aCaption;
+ BOOL bTopCaption = FALSE;
+
+ // Nicht const, weil GetTable spater mal nicht const ist
+ SwNode *pNd = rHTMLWrt.pDoc->GetNodes()[ nStt ];
+ SwTableNode *pTblNd = pNd->GetTableNode();
+ const SwTxtNode *pTxtNd = pNd->GetTxtNode();
+ if( !pTblNd && pTxtNd )
+ {
+ // Tabelle mit Ueberschrift
+ bTopCaption = TRUE;
+ pTblNd = rHTMLWrt.pDoc->GetNodes()[nStt+1]->GetTableNode();
+ }
+ ASSERT( pTblNd, "Rahmen enthaelt keine Tabelle" );
+ if( pTblNd )
+ {
+ ULONG nTblEnd = pTblNd->EndOfSectionIndex();
+ ASSERT( nTblEnd == nEnd - 1 ||
+ (nTblEnd == nEnd - 2 && !bTopCaption),
+ "Ungeuelter Rahmen-Inhalt fuer Tabelle" );
+
+ if( nTblEnd == nEnd - 2 )
+ pTxtNd = rHTMLWrt.pDoc->GetNodes()[nTblEnd+1]->GetTxtNode();
+ }
+ if( pTxtNd )
+ aCaption = pTxtNd->GetTxt();
+
+ {
+ HTMLSaveData aSaveData( rHTMLWrt, pTblNd->GetIndex()+1,
+ pTblNd->EndOfSectionIndex(),
+ sal_True, &rFrmFmt );
+ rHTMLWrt.bOutFlyFrame = sal_True;
+ OutHTML_SwTblNode( rHTMLWrt, *pTblNd, &rFrmFmt, &aCaption,
+ bTopCaption );
+ }
+
+ return rWrt;
+}
+
+static Writer & OutHTML_FrmFmtAsMulticol( Writer& rWrt,
+ const SwFrmFmt& rFrmFmt,
+ BOOL bInCntnr )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ rHTMLWrt.ChangeParaToken( 0 );
+
+ // Die aktulle <DL> beenden!
+ rHTMLWrt.OutAndSetDefList( 0 );
+
+ // als Multicol ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_multicol;
+
+ const SwFmtCol& rFmtCol = rFrmFmt.GetCol();
+
+ // die Anzahl der Spalten als COLS ausgeben
+ USHORT nCols = rFmtCol.GetNumCols();
+ if( nCols )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=')
+ += ByteString::CreateFromInt32( nCols );
+
+ // die Gutter-Breite (Minimalwert) als GUTTER
+ USHORT nGutter = rFmtCol.GetGutterWidth( TRUE );
+ if( nGutter!=USHRT_MAX )
+ {
+ if( nGutter && Application::GetDefaultDevice() )
+ {
+ nGutter = (USHORT)Application::GetDefaultDevice()
+ ->LogicToPixel( Size(nGutter,0),
+ MapMode(MAP_TWIP) ).Width();
+ }
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_gutter) += '=')
+ += ByteString::CreateFromInt32( nGutter );
+ }
+
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // WIDTH
+ ULONG nFrmFlags = bInCntnr ? HTML_FRMOPTS_MULTICOL_CNTNR
+ : HTML_FRMOPTS_MULTICOL;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
+ nFrmFlags |= HTML_FRMOPTS_MULTICOL_CSS1;
+ ByteString aEndTags;
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags, nFrmFlags );
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
+
+ rWrt.Strm() << '>';
+
+ rHTMLWrt.bLFPossible = TRUE;
+ rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+ const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
+ ASSERT( pSttNd, "Wo ist der Start-Node" );
+
+ {
+ // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
+ // wieder hergestellt wird.
+ HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
+ pSttNd->EndOfSectionIndex(),
+ sal_True, &rFrmFmt );
+ rHTMLWrt.bOutFlyFrame = sal_True;
+ rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
+ }
+
+// rHTMLWrt.ChangeParaToken( 0 ); // MIB 8.7.97: Passiert jetzt in Out_SwDoc
+
+ rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_multicol, FALSE );
+ rHTMLWrt.bLFPossible = TRUE;
+
+ return rWrt;
+}
+
+static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFrmFmt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( TRUE );
+
+ ByteString sOut('<');
+ ((((sOut += OOO_STRING_SVTOOLS_HTML_spacer) += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=')
+ += OOO_STRING_SVTOOLS_HTML_SPTYPE_block;
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // ALIGN, WIDTH, HEIGHT
+ ByteString aEndTags;
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags,
+ HTML_FRMOPTS_SPACER );
+
+ rWrt.Strm() << '>';
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ return rWrt;
+}
+
+static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
+ const SwFrmFmt& rFrmFmt, BOOL bSpan)
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const sal_Char *pStr = 0;
+ if( !bSpan )
+ {
+ rHTMLWrt.ChangeParaToken( 0 );
+
+ // Die aktulle <DL> beenden!
+ rHTMLWrt.OutAndSetDefList( 0 );
+ pStr = OOO_STRING_SVTOOLS_HTML_division;
+ }
+ else
+ pStr = OOO_STRING_SVTOOLS_HTML_span;
+
+ // als DIV ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+
+ ByteString sOut( '<' );
+ sOut += pStr;
+
+ rWrt.Strm() << sOut.GetBuffer();
+ ByteString aEndTags;
+ ULONG nFrmFlags = HTML_FRMOPTS_DIV;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_BORDER_NONE ) )
+ nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags, nFrmFlags );
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
+ rWrt.Strm() << '>';
+
+ rHTMLWrt.IncIndentLevel(); // den Inhalt einruecken
+ rHTMLWrt.bLFPossible = TRUE;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+
+ // Am Start-Node verankerte Rahmen-gebundene Rahmen ausgeben
+ rHTMLWrt.OutFlyFrm( nStt, 0, HTML_POS_ANY );
+
+ const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
+ ASSERT( pSttNd, "Wo ist der Start-Node" );
+
+ {
+ // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
+ // wieder hergestellt wird.
+ HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
+ pSttNd->EndOfSectionIndex(),
+ sal_True, &rFrmFmt );
+ rHTMLWrt.bOutFlyFrame = sal_True;
+ rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
+ }
+
+ rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, FALSE );
+
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ return rWrt;
+}
+
+static Writer & OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL /*bInCntnr*/ )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ ImageMap aIMap;
+ Graphic aGrf( ((SwFrmFmt &)rFrmFmt).MakeGraphic( &aIMap ) );
+
+ String aGrfNm;
+ if( rHTMLWrt.GetOrigFileName() )
+ aGrfNm = *rHTMLWrt.GetOrigFileName();
+ if( aGrf.GetType() == GRAPHIC_NONE ||
+ XOutBitmap::WriteGraphic( aGrf, aGrfNm,
+ String::CreateFromAscii( "JPG" ),
+ (XOUTBMP_USE_GIF_IF_POSSIBLE|
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE) ) != 0 )
+ {
+ // leer oder fehlerhaft, da ist nichts auszugeben
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ return rWrt;
+ }
+
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(rWrt.GetBaseURL()), aGrfNm,
+ URIHelper::GetMaybeFileHdl() );
+ Size aSz( 0, 0 );
+ OutHTML_Image( rWrt, rFrmFmt, aGrfNm, rFrmFmt.GetName(), aSz,
+ HTML_FRMOPTS_GENIMG, pMarkToFrame,
+ aIMap.GetIMapObjectCount() ? &aIMap : 0 );
+ return rWrt;
+}
+
+
+static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL bInCntnr )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ SwGrfNode *pGrfNd = rHTMLWrt.pDoc->GetNodes()[ nStt ]->GetGrfNode();
+ ASSERT( pGrfNd, "Grf-Node erwartet" );
+ if( !pGrfNd )
+ return rWrt;
+
+ const SwMirrorGrf& rMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf();
+
+ String aGrfNm;
+ if( !pGrfNd->IsLinkedFile() || RES_MIRROR_GRAPH_DONT != rMirror.GetValue() )
+ {
+ // Grafik als File-Referenz speichern (als JPEG-Grafik speichern)
+ if( rHTMLWrt.GetOrigFileName() )
+ aGrfNm = *rHTMLWrt.GetOrigFileName();
+ pGrfNd->SwapIn( TRUE );
+
+ ULONG nFlags = XOUTBMP_USE_GIF_IF_SENSIBLE |
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE;
+ switch( rMirror.GetValue() )
+ {
+ case RES_MIRROR_GRAPH_VERT: nFlags = XOUTBMP_MIRROR_HORZ; break;
+ case RES_MIRROR_GRAPH_HOR: nFlags = XOUTBMP_MIRROR_VERT; break;
+ case RES_MIRROR_GRAPH_BOTH:
+ nFlags = XOUTBMP_MIRROR_VERT | XOUTBMP_MIRROR_HORZ;
+ break;
+ }
+
+ Size aMM100Size;
+ const SwFmtFrmSize& rSize = rFrmFmt.GetFrmSize();
+ aMM100Size = OutputDevice::LogicToLogic( rSize.GetSize(),
+ MapMode( MAP_TWIP ), MapMode( MAP_100TH_MM ));
+
+ USHORT nErr = XOutBitmap::WriteGraphic( pGrfNd->GetGrf(), aGrfNm,
+ String::CreateFromAscii("JPG"), nFlags, &aMM100Size );
+ if( nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ return rWrt;
+ }
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(rWrt.GetBaseURL()), aGrfNm,
+ URIHelper::GetMaybeFileHdl() );
+ }
+ else
+ {
+ pGrfNd->GetFileFilterNms( &aGrfNm, 0 );
+ if( rHTMLWrt.bCfgCpyLinkedGrfs )
+ rWrt.CopyLocalFileToINet( aGrfNm );
+ }
+
+ ULONG nFrmFlags = bInCntnr ? HTML_FRMOPTS_IMG_CNTNR : HTML_FRMOPTS_IMG;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
+ nFrmFlags |= HTML_FRMOPTS_IMG_CSS1;
+ OutHTML_Image( rWrt, rFrmFmt, aGrfNm, pGrfNd->GetTitle(),
+ pGrfNd->GetTwipSize(), nFrmFlags, pMarkToGraphic );
+
+ return rWrt;
+}
+
+
+static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ const SdrObject& rSdrObj )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // die Edit-Engine-Attribute des Objekts als SW-Attribute holen
+ // und als Hints einsortieren
+ const SfxItemSet& rFmtItemSet = rFrmFmt.GetAttrSet();
+ SfxItemSet aItemSet( *rFmtItemSet.GetPool(), RES_CHRATR_BEGIN,
+ RES_CHRATR_END );
+ SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, &rSdrObj, TRUE );
+ BOOL bCfgOutStylesOld = rHTMLWrt.bCfgOutStyles;
+ rHTMLWrt.bCfgOutStyles = FALSE;
+ rHTMLWrt.bTxtAttr = TRUE;
+ rHTMLWrt.bTagOn = TRUE;
+ Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, FALSE );
+ rHTMLWrt.bTxtAttr = FALSE;
+
+ OutHTML_DrawFrmFmtAsMarquee( rHTMLWrt,
+ (const SwDrawFrmFmt &)rFrmFmt,
+ rSdrObj );
+ rHTMLWrt.bTxtAttr = TRUE;
+ rHTMLWrt.bTagOn = FALSE;
+ Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, FALSE );
+ rHTMLWrt.bTxtAttr = FALSE;
+ rHTMLWrt.bCfgOutStyles = bCfgOutStylesOld;
+
+ return rWrt;
+}
+
+//-----------------------------------------------------------------------
+
+Writer& OutHTML_HeaderFooter( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL bHeader )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // als Multicol ausgeben
+ rHTMLWrt.OutNewLine();
+ ByteString sOut( OOO_STRING_SVTOOLS_HTML_division );
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=';
+ sOut += (bHeader ? "HEADER" : "FOOTER" );
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.GetBuffer() );
+
+ rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
+
+ // Einen Spacer fuer den Absatnd zusammenbasteln. Da durch das
+ // <DL> bzw. </DL> immer einer Absatz-Abstand entsteht, wird der
+ // ggf. abgezogen.
+ const SvxULSpaceItem& rULSpace = rFrmFmt.GetULSpace();
+ USHORT nSize = bHeader ? rULSpace.GetLower() : rULSpace.GetUpper();
+ rHTMLWrt.nHeaderFooterSpace = nSize;
+
+ ByteString aSpacer;
+ if( rHTMLWrt.IsHTMLMode(HTMLMODE_VERT_SPACER) &&
+ nSize > HTML_PARSPACE && Application::GetDefaultDevice() )
+ {
+ nSize -= HTML_PARSPACE;
+ nSize = (INT16)Application::GetDefaultDevice()
+ ->LogicToPixel( Size(nSize,0), MapMode(MAP_TWIP) ).Width();
+
+ ((((((((aSpacer = OOO_STRING_SVTOOLS_HTML_spacer) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_type) += '=') += OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_size) += '=') += ByteString::CreateFromInt32(nSize);
+ }
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+ const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
+ ASSERT( pSttNd, "Wo ist der Start-Node" );
+
+ if( !bHeader && aSpacer.Len() )
+ {
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.GetBuffer() );
+ }
+
+ {
+ // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
+ // wieder hergestellt wird. pFlyFmt braucht hier nicht gestzt zu
+ // werden, denn PageDesc-Attribute koennen hier nicht vorkommen
+ HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
+ pSttNd->EndOfSectionIndex() );
+
+ if( bHeader )
+ rHTMLWrt.bOutHeader = TRUE;
+ else
+ rHTMLWrt.bOutFooter = TRUE;
+
+ rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
+ }
+
+ if( bHeader && aSpacer.Len() )
+ {
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.GetBuffer() );
+ }
+
+ rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
+
+ rHTMLWrt.nHeaderFooterSpace = 0;
+
+ return rWrt;
+}
+
+
+void SwHTMLWriter::AddLinkTarget( const String& rURL )
+{
+ if( !rURL.Len() || rURL.GetChar(0) != '#' )
+ return;
+
+ // There might be a '|' as delimiter (if the link has been inserted
+ // freshly) or a '%7c' or a '%7C' if the document has been saved and
+ // loaded already.
+ xub_StrLen nPos = rURL.Len();
+ sal_Bool bFound = sal_False, bEncoded = sal_False;
+ while( !bFound && nPos > 0 )
+ {
+ sal_Unicode c = rURL.GetChar( --nPos );
+ switch( c )
+ {
+ case cMarkSeperator:
+ bFound = sal_True;
+ break;
+ case '%':
+ bFound = (rURL.Len() - nPos) >=3 &&
+ rURL.GetChar( nPos+1 ) == '7' &&
+ ((c =rURL.GetChar( nPos+2 )) == 'C' || c == 'c');
+ if( bFound )
+ bEncoded = sal_True;
+ }
+ }
+ if( !bFound || nPos < 2 ) // mindetsens "#a|..."
+ return;
+
+ String aURL( rURL.Copy( 1 ) );
+
+ String sCmp( aURL.Copy( bEncoded ? nPos+2 : nPos ) ); // nPos-1+1/3 (-1 wg. Erase)
+ sCmp.EraseAllChars();
+ if( !sCmp.Len() )
+ return;
+
+ sCmp.ToLowerAscii();
+
+ if( sCmp.EqualsAscii( pMarkToRegion ) ||
+ sCmp.EqualsAscii( pMarkToFrame ) ||
+ sCmp.EqualsAscii( pMarkToGraphic ) ||
+ sCmp.EqualsAscii( pMarkToOLE ) ||
+ sCmp.EqualsAscii( pMarkToTable ) )
+ {
+ // Einfach nur in einem sortierten Array merken
+ if( bEncoded )
+ {
+ aURL.Erase( nPos, 2 );
+ aURL.SetChar( nPos-1, cMarkSeperator );
+ }
+ aImplicitMarks.Insert( new String( aURL ) );
+ }
+ else if( sCmp.EqualsAscii( pMarkToOutline ) )
+ {
+ // Hier brauchen wir Position und Name. Deshalb sortieren wir
+ // ein USHORT und ein String-Array selbst
+ String aOutline( aURL.Copy( 0, nPos-1 ) );
+ SwPosition aPos( *pCurPam->GetPoint() );
+ if( pDoc->GotoOutline( aPos, aOutline ) )
+ {
+ ULONG nIdx = aPos.nNode.GetIndex();
+
+ USHORT nIns=0;
+ while( nIns < aOutlineMarkPoss.Count() &&
+ aOutlineMarkPoss[nIns] < nIdx )
+ nIns++;
+
+ aOutlineMarkPoss.Insert( nIdx, nIns );
+ if( bEncoded )
+ {
+ aURL.Erase( nPos, 2 );
+ aURL.SetChar( nPos-1, cMarkSeperator );
+ }
+ aOutlineMarks.Insert( new String( aURL ), nIns );
+ }
+ }
+ else if( sCmp.EqualsAscii( pMarkToText ) )
+ {
+ //
+ }
+}
+
+void SwHTMLWriter::CollectLinkTargets()
+{
+ const SwFmtINetFmt* pINetFmt;
+ const SwTxtINetFmt* pTxtAttr;
+ const SwTxtNode* pTxtNd;
+
+ sal_uInt32 n, nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
+ for( n = 0; n < nMaxItems; ++n )
+ {
+ if( 0 != (pINetFmt = (SwFmtINetFmt*)pDoc->GetAttrPool().GetItem2(
+ RES_TXTATR_INETFMT, n ) ) &&
+ 0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) &&
+ 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
+ pTxtNd->GetNodes().IsDocNodes() )
+ {
+ AddLinkTarget( pINetFmt->GetValue() );
+ }
+ }
+
+ const SwFmtURL *pURL;
+ nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_URL );
+ for( n = 0; n < nMaxItems; ++n )
+ {
+ if( 0 != (pURL = (SwFmtURL*)pDoc->GetAttrPool().GetItem2(
+ RES_URL, n ) ) )
+ {
+ AddLinkTarget( pURL->GetURL() );
+ const ImageMap *pIMap = pURL->GetMap();
+ if( pIMap )
+ {
+ for( USHORT i=0; i<pIMap->GetIMapObjectCount(); i++ )
+ {
+ const IMapObject* pObj = pIMap->GetIMapObject( i );
+ if( pObj )
+ {
+ AddLinkTarget( pObj->GetURL() );
+ }
+ }
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------
+
+SwHTMLPosFlyFrm::SwHTMLPosFlyFrm( const SwPosFlyFrm& rPosFly,
+ const SdrObject *pSdrObj,
+ BYTE nOutMode ) :
+ pFrmFmt( &rPosFly.GetFmt() ),
+ pSdrObject( pSdrObj ),
+ pNdIdx( new SwNodeIndex( rPosFly.GetNdIndex() ) ),
+ nOrdNum( rPosFly.GetOrdNum() ),
+ nCntntIdx( 0 ),
+ nOutputMode( nOutMode )
+{
+ const SwFmtAnchor& rAnchor = rPosFly.GetFmt().GetAnchor();
+ if ((FLY_AT_CHAR == rAnchor.GetAnchorId()) &&
+ HTML_POS_INSIDE == GetOutPos() )
+ {
+ // Auto-gebundene Rahmen werden ein Zeichen weiter hinten
+ // ausgegeben, weil dann die Positionierung mit Netscape
+ // uebereinstimmt.
+ ASSERT( rAnchor.GetCntntAnchor(), "Keine Anker-Position?" );
+ if( rAnchor.GetCntntAnchor() )
+ {
+ nCntntIdx = rAnchor.GetCntntAnchor()->nContent.GetIndex();
+ sal_Int16 eHoriRel = rPosFly.GetFmt().GetHoriOrient().
+ GetRelationOrient();
+ if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
+ {
+ const SwCntntNode *pCNd = pNdIdx->GetNode().GetCntntNode();
+ ASSERT( pCNd, "Kein Content-Node an PaM-Position" );
+ if( pCNd && nCntntIdx < pCNd->Len() )
+ nCntntIdx++;
+ }
+ }
+ }
+}
+
+BOOL SwHTMLPosFlyFrm::operator<( const SwHTMLPosFlyFrm& rFrm ) const
+{
+ if( pNdIdx->GetIndex() == rFrm.pNdIdx->GetIndex() )
+ {
+ if( nCntntIdx == rFrm.nCntntIdx )
+ {
+ if( GetOutPos() == rFrm.GetOutPos() )
+ return nOrdNum < rFrm.nOrdNum;
+ else
+ return GetOutPos() < rFrm.GetOutPos();
+ }
+ else
+ return nCntntIdx < rFrm.nCntntIdx;
+ }
+ else
+ return pNdIdx->GetIndex() < rFrm.pNdIdx->GetIndex();
+}
+
+