merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / html / htmlfly.cxx
blob880009e3a9f194d60197f0a6742910bff4b49b58
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: htmlfly.cxx,v $
10 * $Revision: 1.28 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <com/sun/star/text/HoriOrientation.hpp>
35 #include <com/sun/star/text/VertOrientation.hpp>
36 #include <com/sun/star/text/RelOrientation.hpp>
39 #include "hintids.hxx"
40 #include <tools/string.hxx>
41 #include <svtools/urihelper.hxx>
42 #ifndef _APP_HXX
43 #include <vcl/svapp.hxx>
44 #endif
45 #ifndef _WRKWIN_HXX //autogen
46 #include <vcl/wrkwin.hxx>
47 #endif
48 #include <svtools/htmlkywd.hxx>
49 #include <svtools/htmlout.hxx>
50 #include <svtools/imap.hxx>
51 #include <svtools/imapobj.hxx>
52 #include <svx/htmlcfg.hxx>
53 #include <svx/xoutbmp.hxx>
54 #include <svx/boxitem.hxx>
55 #include <svx/lrspitem.hxx>
56 #include <svx/ulspitem.hxx>
57 #include <svx/brshitem.hxx>
60 #include <fmtanchr.hxx>
61 #include <fmtornt.hxx>
62 #include <fmturl.hxx>
63 #include <fmtfsize.hxx>
64 #include <fmtclds.hxx>
65 #include <fmtcntnt.hxx>
66 #include <fmtsrnd.hxx>
67 #include <fmtinfmt.hxx>
68 #include <txtinet.hxx>
69 #include "frmatr.hxx"
70 #include <grfatr.hxx>
71 #include <flypos.hxx>
72 #include <docary.hxx>
73 #include <ndgrf.hxx>
75 #include "doc.hxx"
76 #include "ndtxt.hxx"
77 #include "pam.hxx"
78 #include "swerror.h"
79 #include "frmfmt.hxx"
80 #include "wrthtml.hxx"
81 #include "css1kywd.hxx"
82 #include "htmlfly.hxx"
84 using namespace ::com::sun::star;
86 ////////////////////////////////////////////////////////////
88 const ULONG HTML_FRMOPTS_IMG_ALL =
89 HTML_FRMOPT_ALT |
90 HTML_FRMOPT_SIZE |
91 HTML_FRMOPT_ANYSIZE |
92 HTML_FRMOPT_BORDER |
93 HTML_FRMOPT_NAME;
94 const ULONG HTML_FRMOPTS_IMG_CNTNR =
95 HTML_FRMOPTS_IMG_ALL |
96 HTML_FRMOPT_ABSSIZE;
97 const ULONG HTML_FRMOPTS_IMG =
98 HTML_FRMOPTS_IMG_ALL |
99 HTML_FRMOPT_ALIGN |
100 HTML_FRMOPT_SPACE |
101 HTML_FRMOPT_BRCLEAR;
102 const ULONG HTML_FRMOPTS_IMG_CSS1 =
103 HTML_FRMOPT_S_ALIGN |
104 HTML_FRMOPT_S_SPACE;
106 const ULONG HTML_FRMOPTS_DIV =
107 HTML_FRMOPT_ID |
108 HTML_FRMOPT_S_ALIGN |
109 HTML_FRMOPT_S_SIZE |
110 HTML_FRMOPT_ANYSIZE |
111 HTML_FRMOPT_ABSSIZE |
112 HTML_FRMOPT_S_SPACE |
113 HTML_FRMOPT_S_BORDER |
114 HTML_FRMOPT_S_BACKGROUND |
115 HTML_FRMOPT_BRCLEAR |
116 HTML_FRMOPT_DIR;
118 const ULONG HTML_FRMOPTS_MULTICOL =
119 HTML_FRMOPT_ID |
120 HTML_FRMOPT_WIDTH |
121 HTML_FRMOPT_ANYSIZE |
122 HTML_FRMOPT_ABSSIZE |
123 HTML_FRMOPT_DIR;
124 const ULONG HTML_FRMOPTS_MULTICOL_CNTNR =
125 HTML_FRMOPTS_MULTICOL;
126 const ULONG HTML_FRMOPTS_MULTICOL_CSS1 =
127 HTML_FRMOPT_S_ALIGN |
128 HTML_FRMOPT_S_SIZE |
129 HTML_FRMOPT_S_SPACE |
130 HTML_FRMOPT_S_BORDER|
131 HTML_FRMOPT_S_BACKGROUND;
133 const ULONG HTML_FRMOPTS_SPACER =
134 HTML_FRMOPT_ALIGN |
135 HTML_FRMOPT_SIZE |
136 HTML_FRMOPT_ANYSIZE |
137 HTML_FRMOPT_BRCLEAR |
138 HTML_FRMOPT_MARGINSIZE |
139 HTML_FRMOPT_ABSSIZE;
141 const ULONG HTML_FRMOPTS_CNTNR =
142 HTML_FRMOPT_S_ALIGN |
143 HTML_FRMOPT_S_SPACE |
144 HTML_FRMOPT_S_WIDTH |
145 HTML_FRMOPT_ANYSIZE |
146 HTML_FRMOPT_ABSSIZE |
147 HTML_FRMOPT_S_PIXSIZE;
150 static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt );
151 static Writer& OutHTML_FrmFmtAsMulticol( Writer& rWrt, const SwFrmFmt& rFmt,
152 BOOL bInCntnr );
153 static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFmt );
154 static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
155 const SwFrmFmt& rFrmFmt, BOOL bSpan );
156 static Writer& OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFmt,
157 BOOL bInCntnr );
159 static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFmt,
160 BOOL bInCntnr );
162 static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
163 const SdrObject& rSdrObj );
164 //-----------------------------------------------------------------------
166 extern HTMLOutEvent __FAR_DATA aAnchorEventTable[];
168 static HTMLOutEvent __FAR_DATA aImageEventTable[] =
170 { OOO_STRING_SVTOOLS_HTML_O_SDonload, OOO_STRING_SVTOOLS_HTML_O_onload, SVX_EVENT_IMAGE_LOAD },
171 { OOO_STRING_SVTOOLS_HTML_O_SDonabort, OOO_STRING_SVTOOLS_HTML_O_onabort, SVX_EVENT_IMAGE_ABORT },
172 { OOO_STRING_SVTOOLS_HTML_O_SDonerror, OOO_STRING_SVTOOLS_HTML_O_onerror, SVX_EVENT_IMAGE_ERROR },
173 { 0, 0, 0 }
176 static HTMLOutEvent __FAR_DATA aIMapEventTable[] =
178 { OOO_STRING_SVTOOLS_HTML_O_SDonmouseover, OOO_STRING_SVTOOLS_HTML_O_onmouseover, SFX_EVENT_MOUSEOVER_OBJECT },
179 { OOO_STRING_SVTOOLS_HTML_O_SDonmouseout, OOO_STRING_SVTOOLS_HTML_O_onmouseout, SFX_EVENT_MOUSEOUT_OBJECT },
180 { 0, 0, 0 }
185 SV_IMPL_OP_PTRARR_SORT( SwHTMLPosFlyFrms, SwHTMLPosFlyFrmPtr )
187 USHORT SwHTMLWriter::GuessFrmType( const SwFrmFmt& rFrmFmt,
188 const SdrObject*& rpSdrObj )
190 SwHTMLFrmType eType;
192 if( RES_DRAWFRMFMT == rFrmFmt.Which() )
194 // Als Default irgendein Zeichen-Objekt
195 eType = HTML_FRMTYPE_DRAW;
197 const SdrObject *pObj =
198 SwHTMLWriter::GetMarqueeTextObj( (const SwDrawFrmFmt &)rFrmFmt );
199 if( pObj )
201 // Laufschrift
202 rpSdrObj = pObj;
203 eType = HTML_FRMTYPE_MARQUEE;
205 else
207 pObj = GetHTMLControl( (const SwDrawFrmFmt &)rFrmFmt );
209 if( pObj )
211 // Form-Control
212 rpSdrObj = pObj;
213 eType = HTML_FRMTYPE_CONTROL;
217 else
219 // Als Default ein Textrahmen
220 eType = HTML_FRMTYPE_TEXT;
222 const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
223 ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
224 const SwNode* pNd = pDoc->GetNodes()[ nStt ];
226 if( pNd->IsGrfNode() )
228 // Grafik - Node
229 eType = HTML_FRMTYPE_GRF;
231 else if( pNd->IsOLENode() )
233 // Applet, Plugin, Floating-Frame
234 eType = (SwHTMLFrmType)GuessOLENodeFrmType( *pNd );
236 else
238 ULONG nEnd = pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
240 const SfxPoolItem* pItem;
241 const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
242 if( SFX_ITEM_SET == rItemSet.GetItemState( RES_COL,
243 TRUE, &pItem ) &&
244 ((const SwFmtCol *)pItem)->GetNumCols() > 1 )
246 // spaltiger Rahmen
247 eType = HTML_FRMTYPE_MULTICOL;
249 else if( pNd->IsTableNode() )
251 const SwTableNode *pTblNd = pNd->GetTableNode();
252 ULONG nTblEnd = pTblNd->EndOfSectionIndex();
254 if( nTblEnd+1 == nEnd )
256 // Tabelle
257 eType = HTML_FRMTYPE_TABLE;
259 else if( nTblEnd+2 == nEnd )
261 // Tabelle mit Unterschrft
262 eType = HTML_FRMTYPE_TABLE_CAP;
265 else if( pNd->IsTxtNode() )
267 const SwTxtNode *pTxtNd = pNd->GetTxtNode();
269 BOOL bEmpty = FALSE;
270 if( nStt==nEnd-1 && !pTxtNd->Len() )
272 // leerer Rahmen? Nur wenn kein Rahmen am
273 // Text- oder Start-Node verankert ist.
274 bEmpty = TRUE;
275 if( pHTMLPosFlyFrms )
277 for( USHORT i=0; i<pHTMLPosFlyFrms->Count(); i++ )
279 ULONG nIdx = (*pHTMLPosFlyFrms)[i]
280 ->GetNdIndex().GetIndex();
281 bEmpty = (nIdx != nStt) && (nIdx != nStt-1);
282 if( !bEmpty || nIdx > nStt )
283 break;
287 if( bEmpty )
289 const SvxBrushItem& rBrush = rFrmFmt.GetBackground();
290 /// OD 02.09.2002 #99657#
291 /// background is not empty, if it has a background graphic
292 /// or its background color is not "no fill"/"auto fill".
293 if( GPOS_NONE != rBrush.GetGraphicPos() ||
294 rBrush.GetColor() != COL_TRANSPARENT )
295 bEmpty = FALSE;
297 if( bEmpty )
299 // leerer Rahmen
300 eType = HTML_FRMTYPE_EMPTY;
302 else if( pDoc->GetNodes()[nStt+1]->IsTableNode() )
304 const SwTableNode *pTblNd =
305 pDoc->GetNodes()[nStt+1]->GetTableNode();
306 if( pTblNd->EndOfSectionIndex()+1 == nEnd )
308 // Tabelle mit Ueberschrift
309 eType = HTML_FRMTYPE_TABLE_CAP;
316 return static_cast< USHORT >(eType);
319 void SwHTMLWriter::CollectFlyFrms()
321 ASSERT( HTML_CFG_MAX+1 == MAX_BROWSERS,
322 "number of browser configurations has changed" );
324 BYTE nSz = (BYTE)Min( pDoc->GetSpzFrmFmts()->Count(), USHORT(255) );
325 SwPosFlyFrms aFlyPos( nSz, nSz );
326 pDoc->GetAllFlyFmts( aFlyPos, bWriteAll ? 0 : pCurPam, TRUE );
328 for( USHORT i=0; i< aFlyPos.Count(); i++ )
330 const SwFrmFmt& rFrmFmt = aFlyPos[i]->GetFmt();
331 const SdrObject *pSdrObj = 0;
332 const SwPosition *pAPos;
333 const SwCntntNode *pACNd;
334 SwHTMLFrmType eType = (SwHTMLFrmType)GuessFrmType( rFrmFmt, pSdrObj );
336 BYTE nMode;
337 const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
338 sal_Int16 eHoriRel = rFrmFmt.GetHoriOrient().GetRelationOrient();
339 switch( rAnchor.GetAnchorId() )
341 case FLY_PAGE:
342 case FLY_AT_FLY:
343 nMode = aHTMLOutFrmPageFlyTable[eType][nExportMode];
344 break;
346 case FLY_AT_CNTNT:
347 // Absatz-gebundene Rahmen werden nur dann vor den
348 // Absatz geschrieben, wenn der Absatz einen Abstand
349 // hat.
350 if( text::RelOrientation::FRAME == eHoriRel &&
351 (pAPos = rAnchor.GetCntntAnchor()) != 0 &&
352 (pACNd = pAPos->nNode.GetNode().GetCntntNode()) != 0 )
354 const SvxLRSpaceItem& rLRItem =
355 (const SvxLRSpaceItem&)pACNd->GetAttr(RES_LR_SPACE);
356 if( rLRItem.GetTxtLeft() || rLRItem.GetRight() )
358 nMode = aHTMLOutFrmParaFrameTable[eType][nExportMode];
359 break;
362 nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
363 break;
365 case FLY_AUTO_CNTNT:
366 if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
367 nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
368 else
369 nMode = aHTMLOutFrmParaOtherTable[eType][nExportMode];
370 break;
372 default:
373 nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
374 break;
377 if( !pHTMLPosFlyFrms )
378 pHTMLPosFlyFrms = new SwHTMLPosFlyFrms;
380 SwHTMLPosFlyFrm *pNew =
381 new SwHTMLPosFlyFrm( *aFlyPos[i], pSdrObj, nMode );
382 pHTMLPosFlyFrms->Insert( pNew );
386 BOOL SwHTMLWriter::OutFlyFrm( ULONG nNdIdx, xub_StrLen nCntntIdx, BYTE nPos,
387 HTMLOutContext *pContext )
389 BOOL bFlysLeft = FALSE; // Noch Flys an aktueller Node-Position da?
391 // OutFlyFrm kan rekursiv aufgerufen werden. Deshalb muss man
392 // manchmal wieder von vorne anfangen, nachdem ein Fly ausgegeben
393 // wurde.
394 BOOL bRestart = TRUE;
395 while( pHTMLPosFlyFrms && bRestart )
397 bFlysLeft = bRestart = FALSE;
399 // suche nach dem Anfang der FlyFrames
400 USHORT i;
402 for( i = 0; i < pHTMLPosFlyFrms->Count() &&
403 (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() < nNdIdx; i++ )
405 for( ; !bRestart && i < pHTMLPosFlyFrms->Count() &&
406 (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() == nNdIdx; i++ )
408 SwHTMLPosFlyFrm *pPosFly = (*pHTMLPosFlyFrms)[i];
409 if( ( HTML_POS_ANY == nPos ||
410 pPosFly->GetOutPos() == nPos ) &&
411 pPosFly->GetCntntIndex() == nCntntIdx )
413 // Erst entfernen ist wichtig, weil in tieferen
414 // Rekursionen evtl. weitere Eintraege oder das
415 // ganze Array geloscht werden koennte.
416 pHTMLPosFlyFrms->Remove( i, 1 );
417 i--;
418 if( !pHTMLPosFlyFrms->Count() )
420 delete pHTMLPosFlyFrms;
421 pHTMLPosFlyFrms = 0;
422 bRestart = TRUE; // nicht wirklich, nur raus
423 // aus der Schleife
426 if( pContext )
428 HTMLOutFuncs::FlushToAscii(Strm(), *pContext );
429 pContext = 0; // one time only
432 OutFrmFmt( pPosFly->GetOutMode(), pPosFly->GetFmt(),
433 pPosFly->GetSdrObject() );
434 switch( pPosFly->GetOutFn() )
436 case HTML_OUT_DIV:
437 case HTML_OUT_SPAN:
438 case HTML_OUT_MULTICOL:
439 case HTML_OUT_TBLNODE:
440 bRestart = TRUE; // Hier wird's evtl rekursiv
441 break;
443 delete pPosFly;
445 else
447 bFlysLeft = TRUE;
452 return bFlysLeft;
455 void SwHTMLWriter::OutFrmFmt( BYTE nMode, const SwFrmFmt& rFrmFmt,
456 const SdrObject *pSdrObject )
458 BYTE nCntnrMode = SwHTMLPosFlyFrm::GetOutCntnr( nMode );
459 BYTE nOutMode = SwHTMLPosFlyFrm::GetOutFn(nMode);
460 const sal_Char *pCntnrStr = 0;
461 if( HTML_CNTNR_NONE != nCntnrMode )
464 if( bLFPossible && HTML_CNTNR_DIV == nCntnrMode )
465 OutNewLine();
467 ByteString sOut( '<' );
468 pCntnrStr = (HTML_CNTNR_DIV == nCntnrMode)
469 ? OOO_STRING_SVTOOLS_HTML_division
470 : OOO_STRING_SVTOOLS_HTML_span;
471 sOut += pCntnrStr;
472 ((((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"")
473 += sCSS1_class_abs_pos) += '\"';
474 Strm() << sOut.GetBuffer();
476 // Fuer Nicht-Zeichenobekte eine Breite ausgeben
477 ULONG nFrmFlags = HTML_FRMOPTS_CNTNR;
479 // Fuer spaltige Rahmen koennen wir auch noch den Hintergrund ausgeben.
480 if( HTML_OUT_MULTICOL == nOutMode )
481 nFrmFlags |= HTML_FRMOPT_S_BACKGROUND|HTML_FRMOPT_S_BORDER;
483 if( IsHTMLMode( HTMLMODE_BORDER_NONE ) )
484 nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
485 OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags, pSdrObject );
486 Strm() << '>';
488 if( HTML_CNTNR_DIV == nCntnrMode )
490 IncIndentLevel();
491 bLFPossible = TRUE;
495 switch( nOutMode )
497 case HTML_OUT_TBLNODE: // OK
498 ASSERT( !pCntnrStr, "Table: Container ist hier nicht vorgesehen" );
499 OutHTML_FrmFmtTableNode( *this, rFrmFmt );
500 break;
501 case HTML_OUT_GRFNODE: // OK
502 OutHTML_FrmFmtGrfNode( *this, rFrmFmt, pCntnrStr != 0 );
503 break;
504 case HTML_OUT_OLENODE: // OK
505 OutHTML_FrmFmtOLENode( *this, rFrmFmt, pCntnrStr != 0 );
506 break;
507 case HTML_OUT_OLEGRF: // OK
508 OutHTML_FrmFmtOLENodeGrf( *this, rFrmFmt, pCntnrStr != 0 );
509 break;
510 case HTML_OUT_DIV:
511 case HTML_OUT_SPAN:
512 ASSERT( !pCntnrStr, "Div: Container ist hier nicht vorgesehen" );
513 OutHTML_FrmFmtAsDivOrSpan( *this, rFrmFmt, HTML_OUT_SPAN==nOutMode );
514 break;
515 case HTML_OUT_MULTICOL: // OK
516 OutHTML_FrmFmtAsMulticol( *this, rFrmFmt, pCntnrStr != 0 );
517 break;
518 case HTML_OUT_SPACER: // OK
519 ASSERT( !pCntnrStr, "Spacer: Container ist hier nicht vorgesehen" );
520 OutHTML_FrmFmtAsSpacer( *this, rFrmFmt );
521 break;
522 case HTML_OUT_CONTROL: // OK
523 OutHTML_DrawFrmFmtAsControl( *this,
524 (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject,
525 pCntnrStr != 0 );
526 break;
527 case HTML_OUT_AMARQUEE:
528 OutHTML_FrmFmtAsMarquee( *this, rFrmFmt, *pSdrObject );
529 break;
530 case HTML_OUT_MARQUEE:
531 ASSERT( !pCntnrStr, "Marquee: Container ist hier nicht vorgesehen" );
532 OutHTML_DrawFrmFmtAsMarquee( *this,
533 (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject );
534 break;
535 case HTML_OUT_GRFFRM:
536 OutHTML_FrmFmtAsImage( *this, rFrmFmt, pCntnrStr != 0 );
537 break;
540 if( HTML_CNTNR_DIV == nCntnrMode )
542 DecIndentLevel();
543 if( bLFPossible )
544 OutNewLine();
545 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
546 bLFPossible = TRUE;
548 else if( HTML_CNTNR_SPAN == nCntnrMode )
549 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, FALSE );
553 void SwHTMLWriter::OutFrmFmtOptions( const SwFrmFmt &rFrmFmt,
554 const String& rAlternateTxt,
555 ByteString &rEndTags,
556 sal_uInt32 nFrmOpts )
558 ByteString sOut;
559 const SfxPoolItem* pItem;
560 const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
562 // Name
563 if( (nFrmOpts & (HTML_FRMOPT_ID|HTML_FRMOPT_NAME)) &&
564 rFrmFmt.GetName().Len() )
566 const sal_Char *pStr =
567 (nFrmOpts & HTML_FRMOPT_ID) ? OOO_STRING_SVTOOLS_HTML_O_id : OOO_STRING_SVTOOLS_HTML_O_name;
568 ((sOut += ' ') += pStr) += "=\"";
569 Strm() << sOut.GetBuffer();
570 HTMLOutFuncs::Out_String( Strm(), rFrmFmt.GetName(), eDestEnc, &aNonConvertableCharacters );
571 sOut = '\"';
574 // Name
575 if( nFrmOpts & HTML_FRMOPT_DIR )
577 sal_uInt16 nDir = GetHTMLDirection( rItemSet );
578 Strm() << sOut.GetBuffer();
579 sOut.Erase();
580 OutDirection( nDir );
584 // ALT
585 if( (nFrmOpts & HTML_FRMOPT_ALT) && rAlternateTxt.Len() )
587 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_alt) += "=\"";
588 Strm() << sOut.GetBuffer();
589 HTMLOutFuncs::Out_String( Strm(), rAlternateTxt, eDestEnc, &aNonConvertableCharacters );
590 sOut = '\"';
593 // ALIGN
594 const sal_Char *pStr = 0;
595 RndStdIds eAnchorId = rFrmFmt.GetAnchor().GetAnchorId();
596 if( (nFrmOpts & HTML_FRMOPT_ALIGN) &&
597 (FLY_AT_CNTNT == eAnchorId || FLY_AUTO_CNTNT == eAnchorId) )
599 // MIB 12.3.98: Ist es nicht schlauer, absatzgebundene
600 // Rahmen notfalls links auszurichten als sie
601 // zeichengebunden einzufuegen???
602 const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient();
603 if( !(nFrmOpts & HTML_FRMOPT_S_ALIGN) ||
604 text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
605 text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
607 pStr = text::HoriOrientation::RIGHT == rHoriOri.GetHoriOrient()
608 ? OOO_STRING_SVTOOLS_HTML_AL_right
609 : OOO_STRING_SVTOOLS_HTML_AL_left;
612 if( (nFrmOpts & HTML_FRMOPT_ALIGN) && !pStr &&
613 ( (nFrmOpts & HTML_FRMOPT_S_ALIGN) == 0 ||
614 FLY_IN_CNTNT == eAnchorId ) &&
615 SFX_ITEM_SET == rItemSet.GetItemState( RES_VERT_ORIENT, TRUE, &pItem ))
617 switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
619 case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
620 case text::VertOrientation::CHAR_TOP:
621 case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // geht nicht
622 case text::VertOrientation::LINE_CENTER:
623 case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // geht nicht
624 case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
625 case text::VertOrientation::LINE_BOTTOM:
626 case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // geht nicht
627 case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
628 case text::VertOrientation::NONE: break;
631 if( pStr )
632 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
635 // HSPACE und VSPACE
636 Size aTwipSpc( 0, 0 );
637 if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
638 SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, TRUE, &pItem ))
640 aTwipSpc.Width() =
641 ( ((SvxLRSpaceItem*)pItem)->GetLeft() +
642 ((SvxLRSpaceItem*)pItem)->GetRight() ) / 2;
643 nDfltLeftMargin = nDfltRightMargin = aTwipSpc.Width();
645 if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
646 SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, TRUE, &pItem ))
648 aTwipSpc.Height() =
649 ( ((SvxULSpaceItem*)pItem)->GetUpper() +
650 ((SvxULSpaceItem*)pItem)->GetLower() ) / 2;
651 nDfltTopMargin = nDfltBottomMargin = (USHORT)aTwipSpc.Height();
654 if( (nFrmOpts & HTML_FRMOPT_SPACE) &&
655 (aTwipSpc.Width() || aTwipSpc.Height()) &&
656 Application::GetDefaultDevice() )
658 Size aPixelSpc =
659 Application::GetDefaultDevice()->LogicToPixel( aTwipSpc,
660 MapMode(MAP_TWIP) );
661 if( !aPixelSpc.Width() && aTwipSpc.Width() )
662 aPixelSpc.Width() = 1;
663 if( !aPixelSpc.Height() && aTwipSpc.Height() )
664 aPixelSpc.Height() = 1;
666 if( aPixelSpc.Width() )
668 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_hspace) += '=')
669 += ByteString::CreateFromInt32( aPixelSpc.Width() );
672 if( aPixelSpc.Height() )
674 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_vspace) += '=')
675 += ByteString::CreateFromInt32( aPixelSpc.Height() );
679 // Der Abstand muss bei der Groesse beruecksichtigt, wenn das entsprechende
680 // Flag gesetzt ist.
681 if( (nFrmOpts & HTML_FRMOPT_MARGINSIZE) )
683 aTwipSpc.Width() *= -2;
684 aTwipSpc.Height() *= -2;
686 else
688 aTwipSpc.Width() = 0;
689 aTwipSpc.Height() = 0;
692 if( !(nFrmOpts & HTML_FRMOPT_ABSSIZE) &&
693 SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, TRUE, &pItem ))
695 const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
697 aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_LEFT );
698 aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_RIGHT );
699 aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_TOP );
700 aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_BOTTOM );
703 // WIDTH und/oder HEIGHT
704 // ATT_VAR_SIZE/ATT_MIN_SIZE nur ausgeben, wenn ANYSIZE gesezut ist
705 if( (nFrmOpts & HTML_FRMOPT_SIZE) &&
706 SFX_ITEM_SET == rItemSet.GetItemState( RES_FRM_SIZE, TRUE, &pItem ) &&
707 ( (nFrmOpts & HTML_FRMOPT_ANYSIZE) ||
708 ATT_FIX_SIZE == ((const SwFmtFrmSize *)pItem)->GetHeightSizeType()) )
710 const SwFmtFrmSize *pFSItem = (const SwFmtFrmSize *)pItem;
711 BYTE nPrcWidth = pFSItem->GetWidthPercent();
712 BYTE nPrcHeight = pFSItem->GetHeightPercent();
714 // Groesse des Objekts Twips ohne Raender
715 Size aTwipSz( (nPrcWidth ? 0
716 : pFSItem->GetWidth()-aTwipSpc.Width()),
717 (nPrcHeight ? 0
718 : pFSItem->GetHeight()-aTwipSpc.Height()) );
720 ASSERT( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0,
721 "Rahmengroesse minus Abstand < 0!!!???" );
722 if( aTwipSz.Width() < 0 )
723 aTwipSz.Width() = 0;
724 if( aTwipSz.Height() < 0 )
725 aTwipSz.Height() = 0;
727 Size aPixelSz( 0, 0 );
728 if( (aTwipSz.Width() || aTwipSz.Height()) &&
729 Application::GetDefaultDevice() )
731 aPixelSz =
732 Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
733 MapMode(MAP_TWIP) );
734 if( !aPixelSz.Width() && aTwipSz.Width() )
735 aPixelSz.Width() = 1;
736 if( !aPixelSz.Height() && aTwipSz.Height() )
737 aPixelSz.Height() = 1;
740 if( (nFrmOpts & HTML_FRMOPT_WIDTH) &&
741 ((nPrcWidth && nPrcWidth!=255) || aPixelSz.Width()) )
743 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=';
744 if( nPrcWidth )
745 (sOut += ByteString::CreateFromInt32( nPrcWidth )) += '%';
746 else
747 sOut += ByteString::CreateFromInt32( aPixelSz.Width() );
750 if( (nFrmOpts & HTML_FRMOPT_HEIGHT) &&
751 ((nPrcHeight && nPrcHeight!=255) || aPixelSz.Height()) )
753 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=';
754 if( nPrcHeight )
755 (sOut += ByteString::CreateFromInt32( nPrcHeight )) += '%';
756 else
757 sOut += ByteString::CreateFromInt32( aPixelSz.Height() );
761 if( sOut.Len() )
762 Strm() << sOut.GetBuffer();
764 // Umlauf fuer absatzgeb. Grafiken als <BR CLEAR=...> in den String
765 // schreiben
766 if( (nFrmOpts & HTML_FRMOPT_BRCLEAR) &&
767 (FLY_AT_CNTNT== rFrmFmt.GetAnchor().GetAnchorId() ||
768 FLY_AUTO_CNTNT== rFrmFmt.GetAnchor().GetAnchorId()) &&
769 SFX_ITEM_SET == rItemSet.GetItemState( RES_SURROUND, TRUE, &pItem ))
771 const SwFmtSurround* pSurround = (const SwFmtSurround*)pItem;
772 sal_Int16 eHoriOri = rFrmFmt.GetHoriOrient().GetHoriOrient();
773 pStr = 0;
774 SwSurround eSurround = pSurround->GetSurround();
775 BOOL bAnchorOnly = pSurround->IsAnchorOnly();
776 switch( eHoriOri )
778 case text::HoriOrientation::RIGHT:
780 switch( eSurround )
782 case SURROUND_NONE:
783 case SURROUND_RIGHT:
784 pStr = OOO_STRING_SVTOOLS_HTML_AL_right;
785 break;
786 case SURROUND_LEFT:
787 case SURROUND_PARALLEL:
788 if( bAnchorOnly )
789 bClearRight = TRUE;
790 break;
791 default:
795 break;
797 default:
798 // #67508#: If a frame is centered, it gets left aligned. This
799 // should be taken into account here, too.
801 switch( eSurround )
803 case SURROUND_NONE:
804 case SURROUND_LEFT:
805 pStr = OOO_STRING_SVTOOLS_HTML_AL_left;
806 break;
807 case SURROUND_RIGHT:
808 case SURROUND_PARALLEL:
809 if( bAnchorOnly )
810 bClearLeft = TRUE;
811 break;
812 default:
816 break;
820 if( pStr )
822 (((((((sOut = '<') += OOO_STRING_SVTOOLS_HTML_linebreak) += ' ')
823 += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += pStr) += '>') += rEndTags;
824 rEndTags = sOut;
830 Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt,
831 const String &rGrfName, const String& rAlternateTxt,
832 const Size &rRealSize, sal_uInt32 nFrmOpts,
833 const sal_Char *pMarkType,
834 const ImageMap *pAltImgMap )
836 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
838 // ggf. ein noch offenes Attribut voruebergehend beenden
839 if( rHTMLWrt.aINetFmts.Count() )
841 SwFmtINetFmt *pINetFmt =
842 rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
843 OutHTML_INetFmt( rWrt, *pINetFmt, FALSE );
846 String aGrfNm( rGrfName );
847 if( !HTMLOutFuncs::PrivateURLToInternalImg(aGrfNm) )
848 aGrfNm = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), aGrfNm);
850 const SfxPoolItem* pItem;
851 const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
853 const SwFmtURL *pURLItem = 0;
855 // das URL-Attribut nur beruecksichtigen, wenn keine Image-Map
856 // uebergeben wurde
857 if( !pAltImgMap &&
858 SFX_ITEM_SET == rItemSet.GetItemState( RES_URL, TRUE, &pItem ))
860 pURLItem = (const SwFmtURL *)pItem;
863 // Image-Map rausschreiben
864 const ImageMap *pIMap = pAltImgMap;
865 if( !pIMap && pURLItem )
867 pIMap = pURLItem->GetMap();
870 String aIMapName;
871 if( pIMap )
873 // den Namen eindeutig machen
874 aIMapName = pIMap->GetName();
875 String aNameBase;
876 if( aIMapName.Len() )
877 aNameBase = aIMapName;
878 else
879 aNameBase.AssignAscii( OOO_STRING_SVTOOLS_HTML_map );
880 if( !aIMapName.Len() )
881 (aIMapName = aNameBase)
882 += String::CreateFromInt32( rHTMLWrt.nImgMapCnt );
884 BOOL bFound;
887 bFound = FALSE;
888 for( USHORT i=0; i<rHTMLWrt.aImgMapNames.Count(); i++ )
890 // TODO: Unicode: Comparison is case insensitive for ASCII
891 // characters only now!
892 if( aIMapName.EqualsIgnoreCaseAscii(*rHTMLWrt.aImgMapNames[i]) )
894 bFound = TRUE;
895 break;
898 if( bFound )
900 rHTMLWrt.nImgMapCnt++;
901 (aIMapName = aNameBase)
902 += String::CreateFromInt32( rHTMLWrt.nImgMapCnt );
905 } while( bFound );
907 BOOL bScale = FALSE;
908 //Size aGrfSize( rNode.GetTwipSize() );
909 Fraction aScaleX( 1, 1 );
910 Fraction aScaleY( 1, 1 );
912 const SwFmtFrmSize& rFrmSize = rFrmFmt.GetFrmSize();
913 const SvxBoxItem& rBox = rFrmFmt.GetBox();
915 if( !rFrmSize.GetWidthPercent() && rRealSize.Width() )
917 SwTwips nWidth = rFrmSize.GetWidth();
918 nWidth -= ( rBox.CalcLineSpace(BOX_LINE_LEFT) +
919 rBox.CalcLineSpace(BOX_LINE_RIGHT) );
921 ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
922 if( nWidth<=0 ) // sollte nicht passieren
923 nWidth = 1;
925 if( rRealSize.Width() != nWidth )
927 aScaleX = Fraction( nWidth, rRealSize.Width() );
928 bScale = TRUE;
931 if( !rFrmSize.GetHeightPercent() && rRealSize.Height() )
933 SwTwips nHeight = rFrmSize.GetHeight();
934 nHeight -= ( rBox.CalcLineSpace(BOX_LINE_TOP) +
935 rBox.CalcLineSpace(BOX_LINE_BOTTOM) );
937 ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
938 if( nHeight<=0 )
939 nHeight = 1;
941 if( rRealSize.Height() != nHeight )
943 aScaleY = Fraction( nHeight, rRealSize.Height() );
944 bScale = TRUE;
948 rHTMLWrt.aImgMapNames.Insert( new String(aIMapName),
949 rHTMLWrt.aImgMapNames.Count() );
951 ByteString aIndMap, aIndArea;
952 const sal_Char *pLF = 0, *pIndArea = 0, *pIndMap = 0;
953 #if defined(UNX)
954 sal_Char aLF[2] = "\x00";
955 #endif
957 if( rHTMLWrt.bLFPossible )
959 rHTMLWrt.OutNewLine( TRUE );
960 rHTMLWrt.GetIndentString( aIndMap );
961 rHTMLWrt.GetIndentString( aIndArea, 1 );
962 #if defined(UNX)
963 aLF[0] = SwHTMLWriter::sNewLine;
964 pLF = aLF;
965 #else
966 pLF = SwHTMLWriter::sNewLine;
967 #endif
968 pIndArea = aIndArea.GetBuffer();
969 pIndMap = aIndMap.GetBuffer();
972 if( bScale )
974 ImageMap aScaledIMap( *pIMap );
975 aScaledIMap.Scale( aScaleX, aScaleY );
976 HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), aScaledIMap, aIMapName,
977 aIMapEventTable,
978 rHTMLWrt.bCfgStarBasic,
979 pLF, pIndArea, pIndMap,
980 rHTMLWrt.eDestEnc,
981 &rHTMLWrt.aNonConvertableCharacters );
983 else
985 HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), *pIMap, aIMapName,
986 aIMapEventTable,
987 rHTMLWrt.bCfgStarBasic,
988 pLF, pIndArea, pIndMap,
989 rHTMLWrt.eDestEnc,
990 &rHTMLWrt.aNonConvertableCharacters );
994 // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
995 if( rHTMLWrt.bLFPossible )
996 rHTMLWrt.OutNewLine( TRUE );
998 // Attribute die ausserhelb der Grafik geschreiben werden muessen sammeln
999 ByteString sOut;
1000 ByteString aEndTags;
1002 // implizite Sprungmarke -> <A NAME=...></A>...<IMG ...>
1003 if( pMarkType && rFrmFmt.GetName().Len() )
1004 rHTMLWrt.OutImplicitMark( rFrmFmt.GetName(), pMarkType );
1006 // URL -> <A>...<IMG ... >...</A>
1007 const SvxMacroItem *pMacItem = 0;
1008 if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, TRUE, &pItem ))
1009 pMacItem = (const SvxMacroItem *)pItem;
1011 if( pURLItem || pMacItem )
1013 String aMapURL;
1014 String aName;
1015 String aTarget;
1016 if( pURLItem )
1018 aMapURL = pURLItem->GetURL();
1019 aName = pURLItem->GetName();
1020 aTarget = pURLItem->GetTargetFrameName();
1022 BOOL bEvents = pMacItem && pMacItem->GetMacroTable().Count();
1024 if( aMapURL.Len() || aName.Len() || aTarget.Len() || bEvents )
1026 (sOut = '<') += OOO_STRING_SVTOOLS_HTML_anchor;
1028 // Ein HREF nur Ausgaben, wenn es einen Link oder Makros gibt
1029 if( aMapURL.Len() || bEvents )
1031 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
1032 rWrt.Strm() << sOut.GetBuffer();
1033 rHTMLWrt.OutHyperlinkHRefValue( aMapURL );
1034 sOut = '\"';
1037 if( aName.Len() )
1039 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
1040 rWrt.Strm() << sOut.GetBuffer();
1041 HTMLOutFuncs::Out_String( rWrt.Strm(), aName,
1042 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1043 sOut = '\"';
1046 if( aTarget.Len() )
1048 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
1049 rWrt.Strm() << sOut.GetBuffer();
1050 HTMLOutFuncs::Out_String( rWrt.Strm(), aTarget,
1051 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1052 sOut = '\"';
1054 if( sOut.Len() )
1056 rWrt.Strm() << sOut.GetBuffer();
1057 sOut.Erase();
1060 if( pMacItem )
1062 const SvxMacroTableDtor& rMacTable = pMacItem->GetMacroTable();
1063 if( rMacTable.Count() )
1064 HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable,
1065 aAnchorEventTable,
1066 rHTMLWrt.bCfgStarBasic,
1067 rHTMLWrt.eDestEnc,
1068 &rHTMLWrt.aNonConvertableCharacters );
1071 rWrt.Strm() << ">";
1072 (((sOut = "</") += OOO_STRING_SVTOOLS_HTML_anchor) += ">") += aEndTags;
1073 aEndTags = sOut;
1077 // Umrandung -> <FONT COLOR = ...>...<IMG ... >...</FONT>
1078 USHORT nBorderWidth = 0;
1079 if( (nFrmOpts & HTML_FRMOPT_BORDER) &&
1080 SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, TRUE, &pItem ))
1082 Size aTwipBorder( 0, 0 );
1083 const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
1085 const SvxBorderLine *pColBorderLine = 0;
1086 const SvxBorderLine *pBorderLine = pBoxItem->GetLeft();
1087 if( pBorderLine )
1089 pColBorderLine = pBorderLine;
1090 aTwipBorder.Width() += pBorderLine->GetOutWidth();
1093 pBorderLine = pBoxItem->GetRight();
1094 if( pBorderLine )
1096 pColBorderLine = pBorderLine;
1097 aTwipBorder.Width() += pBorderLine->GetOutWidth();
1100 pBorderLine = pBoxItem->GetTop();
1101 if( pBorderLine )
1103 pColBorderLine = pBorderLine;
1104 aTwipBorder.Height() += pBorderLine->GetOutWidth();
1107 pBorderLine = pBoxItem->GetBottom();
1108 if( pBorderLine )
1110 pColBorderLine = pBorderLine;
1111 aTwipBorder.Height() += pBorderLine->GetOutWidth();
1114 aTwipBorder.Width() /= 2;
1115 aTwipBorder.Height() /= 2;
1117 if( (aTwipBorder.Width() || aTwipBorder.Height()) &&
1118 Application::GetDefaultDevice() )
1120 Size aPixelBorder =
1121 Application::GetDefaultDevice()->LogicToPixel( aTwipBorder,
1122 MapMode(MAP_TWIP) );
1123 if( !aPixelBorder.Width() && aTwipBorder.Width() )
1124 aPixelBorder.Width() = 1;
1125 if( !aPixelBorder.Height() && aTwipBorder.Height() )
1126 aPixelBorder.Height() = 1;
1128 if( aPixelBorder.Width() )
1129 aPixelBorder.Height() = 0;
1131 nBorderWidth =
1132 (USHORT)(aPixelBorder.Width() + aPixelBorder.Height());
1135 if( pColBorderLine )
1137 sOut = '<';
1138 (((sOut += OOO_STRING_SVTOOLS_HTML_font) += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
1139 rWrt.Strm() << sOut.GetBuffer();
1140 HTMLOutFuncs::Out_Color( rWrt.Strm(),
1141 pColBorderLine->GetColor(), rHTMLWrt.eDestEnc ) << '>';
1143 (((sOut = "</" ) += OOO_STRING_SVTOOLS_HTML_font) += '>') += aEndTags;
1144 aEndTags = sOut;
1148 sOut = '<';
1149 (((sOut += OOO_STRING_SVTOOLS_HTML_image) += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
1150 rWrt.Strm() << sOut.GetBuffer();
1151 HTMLOutFuncs::Out_String( rWrt.Strm(), aGrfNm, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
1153 // Events
1154 sOut.Erase();
1155 if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, TRUE, &pItem ))
1157 const SvxMacroTableDtor& rMacTable =
1158 ((const SvxMacroItem *)pItem)->GetMacroTable();
1159 if( rMacTable.Count() )
1160 HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable, aImageEventTable,
1161 rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc,
1162 &rHTMLWrt.aNonConvertableCharacters );
1165 // ALT, ALIGN, WIDTH, HEIGHT, HSPACE, VSPACE
1166 rHTMLWrt.OutFrmFmtOptions( rFrmFmt, rAlternateTxt, aEndTags, nFrmOpts );
1167 if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) )
1168 rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmOpts );
1171 if( nFrmOpts & HTML_FRMOPT_BORDER )
1173 (((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += '=')
1174 += ByteString::CreateFromInt32( nBorderWidth );
1175 rWrt.Strm() << sOut.GetBuffer();
1178 if( pURLItem && pURLItem->IsServerMap() )
1180 (sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_ismap;
1181 rWrt.Strm() << sOut.GetBuffer();
1183 if( aIMapName.Len() )
1185 ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_usemap) += "=\"#";
1186 rWrt.Strm() << sOut.GetBuffer();
1187 HTMLOutFuncs::Out_String( rWrt.Strm(), aIMapName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
1190 rHTMLWrt.Strm() << '>';
1192 if( aEndTags.Len() )
1193 rWrt.Strm() << aEndTags.GetBuffer();
1195 if( rHTMLWrt.aINetFmts.Count() )
1197 // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
1198 // werden muss
1199 SwFmtINetFmt *pINetFmt =
1200 rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
1201 OutHTML_INetFmt( rWrt, *pINetFmt, TRUE );
1204 return rHTMLWrt;
1207 Writer& OutHTML_BulletImage( Writer& rWrt,
1208 const sal_Char *pTag,
1209 const SvxBrushItem* pBrush,
1210 String &rGrfName,
1211 const Size &rSize,
1212 const SwFmtVertOrient* pVertOrient )
1214 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1216 // Wenn es ein BrushItem gibt, muss die Grafiknoch exportiert werden
1217 const String *pLink = 0;
1218 if( pBrush )
1220 pLink = pBrush->GetGraphicLink();
1222 // embeddete Grafik -> WriteEmbedded schreiben
1223 if( !pLink )
1225 const Graphic* pGrf = pBrush->GetGraphic();
1226 if( pGrf )
1228 // Grafik als (JPG-)File speichern
1229 if( rHTMLWrt.GetOrigFileName() )
1230 rGrfName = *rHTMLWrt.GetOrigFileName();
1231 USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, rGrfName,
1232 String::CreateFromAscii("JPG"),
1233 (XOUTBMP_USE_GIF_IF_SENSIBLE |
1234 XOUTBMP_USE_NATIVE_IF_POSSIBLE));
1235 if( !nErr )
1237 rGrfName = URIHelper::SmartRel2Abs(
1238 INetURLObject( rWrt.GetBaseURL() ), rGrfName,
1239 URIHelper::GetMaybeFileHdl() );
1240 pLink = &rGrfName;
1242 else
1244 rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
1248 else
1250 rGrfName = *pLink;
1251 if( rHTMLWrt.bCfgCpyLinkedGrfs )
1253 rHTMLWrt.CopyLocalFileToINet( rGrfName );
1254 pLink = &rGrfName;
1258 else
1260 pLink = &rGrfName;
1263 ByteString sOut;
1264 if( pTag )
1265 (sOut += '<') += pTag;
1267 if( pLink )
1269 sOut += ' ';
1270 String s( *pLink );
1271 if( !HTMLOutFuncs::PrivateURLToInternalImg(s) )
1272 s = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), s);
1273 (sOut += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
1274 rWrt.Strm() << sOut.GetBuffer();
1275 HTMLOutFuncs::Out_String( rWrt.Strm(), s, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1276 sOut = '\"';
1278 // Groesse des Objekts Twips ohne Raender
1279 Size aPixelSz( 0, 0 );
1280 if( (rSize.Width() || rSize.Height()) && Application::GetDefaultDevice() )
1282 aPixelSz =
1283 Application::GetDefaultDevice()->LogicToPixel( rSize,
1284 MapMode(MAP_TWIP) );
1285 if( !aPixelSz.Width() && rSize.Width() )
1286 aPixelSz.Width() = 1;
1287 if( !aPixelSz.Height() && rSize.Height() )
1288 aPixelSz.Height() = 1;
1291 if( aPixelSz.Width() )
1292 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=')
1293 += ByteString::CreateFromInt32( aPixelSz.Width() );
1295 if( aPixelSz.Height() )
1296 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
1297 += ByteString::CreateFromInt32( aPixelSz.Height() );
1299 if( pVertOrient )
1301 const sal_Char *pStr = 0;
1302 switch( pVertOrient->GetVertOrient() )
1304 case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
1305 case text::VertOrientation::CHAR_TOP:
1306 case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // geht nicht
1307 case text::VertOrientation::LINE_CENTER:
1308 case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // geht nicht
1309 case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
1310 case text::VertOrientation::LINE_BOTTOM:
1311 case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // geht nicht
1312 case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
1313 case text::VertOrientation::NONE: break;
1315 if( pStr )
1316 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
1320 if( pTag )
1321 sOut += '>';
1322 rWrt.Strm() << sOut.GetBuffer();
1324 return rWrt;
1328 //-----------------------------------------------------------------------
1330 static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt )
1332 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1334 const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1335 ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
1336 ULONG nEnd = rHTMLWrt.pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
1338 String aCaption;
1339 BOOL bTopCaption = FALSE;
1341 // Nicht const, weil GetTable spater mal nicht const ist
1342 SwNode *pNd = rHTMLWrt.pDoc->GetNodes()[ nStt ];
1343 SwTableNode *pTblNd = pNd->GetTableNode();
1344 const SwTxtNode *pTxtNd = pNd->GetTxtNode();
1345 if( !pTblNd && pTxtNd )
1347 // Tabelle mit Ueberschrift
1348 bTopCaption = TRUE;
1349 pTblNd = rHTMLWrt.pDoc->GetNodes()[nStt+1]->GetTableNode();
1351 ASSERT( pTblNd, "Rahmen enthaelt keine Tabelle" );
1352 if( pTblNd )
1354 ULONG nTblEnd = pTblNd->EndOfSectionIndex();
1355 ASSERT( nTblEnd == nEnd - 1 ||
1356 (nTblEnd == nEnd - 2 && !bTopCaption),
1357 "Ungeuelter Rahmen-Inhalt fuer Tabelle" );
1359 if( nTblEnd == nEnd - 2 )
1360 pTxtNd = rHTMLWrt.pDoc->GetNodes()[nTblEnd+1]->GetTxtNode();
1362 if( pTxtNd )
1363 aCaption = pTxtNd->GetTxt();
1366 HTMLSaveData aSaveData( rHTMLWrt, pTblNd->GetIndex()+1,
1367 pTblNd->EndOfSectionIndex(),
1368 sal_True, &rFrmFmt );
1369 rHTMLWrt.bOutFlyFrame = sal_True;
1370 OutHTML_SwTblNode( rHTMLWrt, *pTblNd, &rFrmFmt, &aCaption,
1371 bTopCaption );
1374 return rWrt;
1377 static Writer & OutHTML_FrmFmtAsMulticol( Writer& rWrt,
1378 const SwFrmFmt& rFrmFmt,
1379 BOOL bInCntnr )
1381 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1383 rHTMLWrt.ChangeParaToken( 0 );
1385 // Die aktulle <DL> beenden!
1386 rHTMLWrt.OutAndSetDefList( 0 );
1388 // als Multicol ausgeben
1389 if( rHTMLWrt.bLFPossible )
1390 rHTMLWrt.OutNewLine();
1392 ByteString sOut( '<' );
1393 sOut += OOO_STRING_SVTOOLS_HTML_multicol;
1395 const SwFmtCol& rFmtCol = rFrmFmt.GetCol();
1397 // die Anzahl der Spalten als COLS ausgeben
1398 USHORT nCols = rFmtCol.GetNumCols();
1399 if( nCols )
1400 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=')
1401 += ByteString::CreateFromInt32( nCols );
1403 // die Gutter-Breite (Minimalwert) als GUTTER
1404 USHORT nGutter = rFmtCol.GetGutterWidth( TRUE );
1405 if( nGutter!=USHRT_MAX )
1407 if( nGutter && Application::GetDefaultDevice() )
1409 nGutter = (USHORT)Application::GetDefaultDevice()
1410 ->LogicToPixel( Size(nGutter,0),
1411 MapMode(MAP_TWIP) ).Width();
1413 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_gutter) += '=')
1414 += ByteString::CreateFromInt32( nGutter );
1417 rWrt.Strm() << sOut.GetBuffer();
1419 // WIDTH
1420 ULONG nFrmFlags = bInCntnr ? HTML_FRMOPTS_MULTICOL_CNTNR
1421 : HTML_FRMOPTS_MULTICOL;
1422 if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1423 nFrmFlags |= HTML_FRMOPTS_MULTICOL_CSS1;
1424 ByteString aEndTags;
1425 rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags, nFrmFlags );
1426 if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1427 rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
1429 rWrt.Strm() << '>';
1431 rHTMLWrt.bLFPossible = TRUE;
1432 rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
1434 const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1435 ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
1436 const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
1437 ASSERT( pSttNd, "Wo ist der Start-Node" );
1440 // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
1441 // wieder hergestellt wird.
1442 HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
1443 pSttNd->EndOfSectionIndex(),
1444 sal_True, &rFrmFmt );
1445 rHTMLWrt.bOutFlyFrame = sal_True;
1446 rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
1449 // rHTMLWrt.ChangeParaToken( 0 ); // MIB 8.7.97: Passiert jetzt in Out_SwDoc
1451 rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
1452 if( rHTMLWrt.bLFPossible )
1453 rHTMLWrt.OutNewLine();
1454 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_multicol, FALSE );
1455 rHTMLWrt.bLFPossible = TRUE;
1457 return rWrt;
1460 static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFrmFmt )
1462 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1464 // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
1465 if( rHTMLWrt.bLFPossible )
1466 rHTMLWrt.OutNewLine( TRUE );
1468 ByteString sOut('<');
1469 ((((sOut += OOO_STRING_SVTOOLS_HTML_spacer) += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=')
1470 += OOO_STRING_SVTOOLS_HTML_SPTYPE_block;
1471 rWrt.Strm() << sOut.GetBuffer();
1473 // ALIGN, WIDTH, HEIGHT
1474 ByteString aEndTags;
1475 rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags,
1476 HTML_FRMOPTS_SPACER );
1478 rWrt.Strm() << '>';
1479 if( aEndTags.Len() )
1480 rWrt.Strm() << aEndTags.GetBuffer();
1482 return rWrt;
1485 static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
1486 const SwFrmFmt& rFrmFmt, BOOL bSpan)
1488 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1490 const sal_Char *pStr = 0;
1491 if( !bSpan )
1493 rHTMLWrt.ChangeParaToken( 0 );
1495 // Die aktulle <DL> beenden!
1496 rHTMLWrt.OutAndSetDefList( 0 );
1497 pStr = OOO_STRING_SVTOOLS_HTML_division;
1499 else
1500 pStr = OOO_STRING_SVTOOLS_HTML_span;
1502 // als DIV ausgeben
1503 if( rHTMLWrt.bLFPossible )
1504 rHTMLWrt.OutNewLine();
1506 ByteString sOut( '<' );
1507 sOut += pStr;
1509 rWrt.Strm() << sOut.GetBuffer();
1510 ByteString aEndTags;
1511 ULONG nFrmFlags = HTML_FRMOPTS_DIV;
1512 if( rHTMLWrt.IsHTMLMode( HTMLMODE_BORDER_NONE ) )
1513 nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
1514 rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags, nFrmFlags );
1515 rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
1516 rWrt.Strm() << '>';
1518 rHTMLWrt.IncIndentLevel(); // den Inhalt einruecken
1519 rHTMLWrt.bLFPossible = TRUE;
1521 const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1522 ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
1524 // Am Start-Node verankerte Rahmen-gebundene Rahmen ausgeben
1525 rHTMLWrt.OutFlyFrm( nStt, 0, HTML_POS_ANY );
1527 const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
1528 ASSERT( pSttNd, "Wo ist der Start-Node" );
1531 // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
1532 // wieder hergestellt wird.
1533 HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
1534 pSttNd->EndOfSectionIndex(),
1535 sal_True, &rFrmFmt );
1536 rHTMLWrt.bOutFlyFrame = sal_True;
1537 rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
1540 rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
1541 if( rHTMLWrt.bLFPossible )
1542 rHTMLWrt.OutNewLine();
1543 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, FALSE );
1545 if( aEndTags.Len() )
1546 rWrt.Strm() << aEndTags.GetBuffer();
1548 return rWrt;
1551 static Writer & OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1552 BOOL /*bInCntnr*/ )
1554 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1556 ImageMap aIMap;
1557 Graphic aGrf( ((SwFrmFmt &)rFrmFmt).MakeGraphic( &aIMap ) );
1559 String aGrfNm;
1560 if( rHTMLWrt.GetOrigFileName() )
1561 aGrfNm = *rHTMLWrt.GetOrigFileName();
1562 if( aGrf.GetType() == GRAPHIC_NONE ||
1563 XOutBitmap::WriteGraphic( aGrf, aGrfNm,
1564 String::CreateFromAscii( "JPG" ),
1565 (XOUTBMP_USE_GIF_IF_POSSIBLE|
1566 XOUTBMP_USE_NATIVE_IF_POSSIBLE) ) != 0 )
1568 // leer oder fehlerhaft, da ist nichts auszugeben
1569 rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
1570 return rWrt;
1573 aGrfNm = URIHelper::SmartRel2Abs(
1574 INetURLObject(rWrt.GetBaseURL()), aGrfNm,
1575 URIHelper::GetMaybeFileHdl() );
1576 Size aSz( 0, 0 );
1577 OutHTML_Image( rWrt, rFrmFmt, aGrfNm, rFrmFmt.GetName(), aSz,
1578 HTML_FRMOPTS_GENIMG, pMarkToFrame,
1579 aIMap.GetIMapObjectCount() ? &aIMap : 0 );
1580 return rWrt;
1584 static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1585 BOOL bInCntnr )
1587 SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
1589 const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1590 ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
1591 SwGrfNode *pGrfNd = rHTMLWrt.pDoc->GetNodes()[ nStt ]->GetGrfNode();
1592 ASSERT( pGrfNd, "Grf-Node erwartet" );
1593 if( !pGrfNd )
1594 return rWrt;
1596 const SwMirrorGrf& rMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf();
1598 String aGrfNm;
1599 if( !pGrfNd->IsLinkedFile() || RES_MIRROR_GRAPH_DONT != rMirror.GetValue() )
1601 // Grafik als File-Referenz speichern (als JPEG-Grafik speichern)
1602 if( rHTMLWrt.GetOrigFileName() )
1603 aGrfNm = *rHTMLWrt.GetOrigFileName();
1604 pGrfNd->SwapIn( TRUE );
1606 ULONG nFlags = XOUTBMP_USE_GIF_IF_SENSIBLE |
1607 XOUTBMP_USE_NATIVE_IF_POSSIBLE;
1608 switch( rMirror.GetValue() )
1610 case RES_MIRROR_GRAPH_VERT: nFlags = XOUTBMP_MIRROR_HORZ; break;
1611 case RES_MIRROR_GRAPH_HOR: nFlags = XOUTBMP_MIRROR_VERT; break;
1612 case RES_MIRROR_GRAPH_BOTH:
1613 nFlags = XOUTBMP_MIRROR_VERT | XOUTBMP_MIRROR_HORZ;
1614 break;
1617 Size aMM100Size;
1618 const SwFmtFrmSize& rSize = rFrmFmt.GetFrmSize();
1619 aMM100Size = OutputDevice::LogicToLogic( rSize.GetSize(),
1620 MapMode( MAP_TWIP ), MapMode( MAP_100TH_MM ));
1622 USHORT nErr = XOutBitmap::WriteGraphic( pGrfNd->GetGrf(), aGrfNm,
1623 String::CreateFromAscii("JPG"), nFlags, &aMM100Size );
1624 if( nErr ) // fehlerhaft, da ist nichts auszugeben
1626 rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
1627 return rWrt;
1629 aGrfNm = URIHelper::SmartRel2Abs(
1630 INetURLObject(rWrt.GetBaseURL()), aGrfNm,
1631 URIHelper::GetMaybeFileHdl() );
1633 else
1635 pGrfNd->GetFileFilterNms( &aGrfNm, 0 );
1636 if( rHTMLWrt.bCfgCpyLinkedGrfs )
1637 rWrt.CopyLocalFileToINet( aGrfNm );
1640 ULONG nFrmFlags = bInCntnr ? HTML_FRMOPTS_IMG_CNTNR : HTML_FRMOPTS_IMG;
1641 if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1642 nFrmFlags |= HTML_FRMOPTS_IMG_CSS1;
1643 OutHTML_Image( rWrt, rFrmFmt, aGrfNm, pGrfNd->GetTitle(),
1644 pGrfNd->GetTwipSize(), nFrmFlags, pMarkToGraphic );
1646 return rWrt;
1650 static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1651 const SdrObject& rSdrObj )
1653 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1655 // die Edit-Engine-Attribute des Objekts als SW-Attribute holen
1656 // und als Hints einsortieren
1657 const SfxItemSet& rFmtItemSet = rFrmFmt.GetAttrSet();
1658 SfxItemSet aItemSet( *rFmtItemSet.GetPool(), RES_CHRATR_BEGIN,
1659 RES_CHRATR_END );
1660 SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, &rSdrObj, TRUE );
1661 BOOL bCfgOutStylesOld = rHTMLWrt.bCfgOutStyles;
1662 rHTMLWrt.bCfgOutStyles = FALSE;
1663 rHTMLWrt.bTxtAttr = TRUE;
1664 rHTMLWrt.bTagOn = TRUE;
1665 Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, FALSE );
1666 rHTMLWrt.bTxtAttr = FALSE;
1668 OutHTML_DrawFrmFmtAsMarquee( rHTMLWrt,
1669 (const SwDrawFrmFmt &)rFrmFmt,
1670 rSdrObj );
1671 rHTMLWrt.bTxtAttr = TRUE;
1672 rHTMLWrt.bTagOn = FALSE;
1673 Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, FALSE );
1674 rHTMLWrt.bTxtAttr = FALSE;
1675 rHTMLWrt.bCfgOutStyles = bCfgOutStylesOld;
1677 return rWrt;
1680 //-----------------------------------------------------------------------
1682 Writer& OutHTML_HeaderFooter( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1683 BOOL bHeader )
1685 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1687 // als Multicol ausgeben
1688 rHTMLWrt.OutNewLine();
1689 ByteString sOut( OOO_STRING_SVTOOLS_HTML_division );
1690 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=';
1691 sOut += (bHeader ? "HEADER" : "FOOTER" );
1692 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.GetBuffer() );
1694 rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
1696 // Einen Spacer fuer den Absatnd zusammenbasteln. Da durch das
1697 // <DL> bzw. </DL> immer einer Absatz-Abstand entsteht, wird der
1698 // ggf. abgezogen.
1699 const SvxULSpaceItem& rULSpace = rFrmFmt.GetULSpace();
1700 USHORT nSize = bHeader ? rULSpace.GetLower() : rULSpace.GetUpper();
1701 rHTMLWrt.nHeaderFooterSpace = nSize;
1703 ByteString aSpacer;
1704 if( rHTMLWrt.IsHTMLMode(HTMLMODE_VERT_SPACER) &&
1705 nSize > HTML_PARSPACE && Application::GetDefaultDevice() )
1707 nSize -= HTML_PARSPACE;
1708 nSize = (INT16)Application::GetDefaultDevice()
1709 ->LogicToPixel( Size(nSize,0), MapMode(MAP_TWIP) ).Width();
1711 ((((((((aSpacer = OOO_STRING_SVTOOLS_HTML_spacer) += ' ')
1712 += OOO_STRING_SVTOOLS_HTML_O_type) += '=') += OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical) += ' ')
1713 += OOO_STRING_SVTOOLS_HTML_O_size) += '=') += ByteString::CreateFromInt32(nSize);
1716 const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1717 ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
1718 const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
1719 ASSERT( pSttNd, "Wo ist der Start-Node" );
1721 if( !bHeader && aSpacer.Len() )
1723 rHTMLWrt.OutNewLine();
1724 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.GetBuffer() );
1728 // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
1729 // wieder hergestellt wird. pFlyFmt braucht hier nicht gestzt zu
1730 // werden, denn PageDesc-Attribute koennen hier nicht vorkommen
1731 HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
1732 pSttNd->EndOfSectionIndex() );
1734 if( bHeader )
1735 rHTMLWrt.bOutHeader = TRUE;
1736 else
1737 rHTMLWrt.bOutFooter = TRUE;
1739 rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
1742 if( bHeader && aSpacer.Len() )
1744 rHTMLWrt.OutNewLine();
1745 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.GetBuffer() );
1748 rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
1749 rHTMLWrt.OutNewLine();
1750 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
1752 rHTMLWrt.nHeaderFooterSpace = 0;
1754 return rWrt;
1758 void SwHTMLWriter::AddLinkTarget( const String& rURL )
1760 if( !rURL.Len() || rURL.GetChar(0) != '#' )
1761 return;
1763 // There might be a '|' as delimiter (if the link has been inserted
1764 // freshly) or a '%7c' or a '%7C' if the document has been saved and
1765 // loaded already.
1766 xub_StrLen nPos = rURL.Len();
1767 sal_Bool bFound = sal_False, bEncoded = sal_False;
1768 while( !bFound && nPos > 0 )
1770 sal_Unicode c = rURL.GetChar( --nPos );
1771 switch( c )
1773 case cMarkSeperator:
1774 bFound = sal_True;
1775 break;
1776 case '%':
1777 bFound = (rURL.Len() - nPos) >=3 &&
1778 rURL.GetChar( nPos+1 ) == '7' &&
1779 ((c =rURL.GetChar( nPos+2 )) == 'C' || c == 'c');
1780 if( bFound )
1781 bEncoded = sal_True;
1784 if( !bFound || nPos < 2 ) // mindetsens "#a|..."
1785 return;
1787 String aURL( rURL.Copy( 1 ) );
1789 String sCmp( aURL.Copy( bEncoded ? nPos+2 : nPos ) ); // nPos-1+1/3 (-1 wg. Erase)
1790 sCmp.EraseAllChars();
1791 if( !sCmp.Len() )
1792 return;
1794 sCmp.ToLowerAscii();
1796 if( sCmp.EqualsAscii( pMarkToRegion ) ||
1797 sCmp.EqualsAscii( pMarkToFrame ) ||
1798 sCmp.EqualsAscii( pMarkToGraphic ) ||
1799 sCmp.EqualsAscii( pMarkToOLE ) ||
1800 sCmp.EqualsAscii( pMarkToTable ) )
1802 // Einfach nur in einem sortierten Array merken
1803 if( bEncoded )
1805 aURL.Erase( nPos, 2 );
1806 aURL.SetChar( nPos-1, cMarkSeperator );
1808 aImplicitMarks.Insert( new String( aURL ) );
1810 else if( sCmp.EqualsAscii( pMarkToOutline ) )
1812 // Hier brauchen wir Position und Name. Deshalb sortieren wir
1813 // ein USHORT und ein String-Array selbst
1814 String aOutline( aURL.Copy( 0, nPos-1 ) );
1815 SwPosition aPos( *pCurPam->GetPoint() );
1816 if( pDoc->GotoOutline( aPos, aOutline ) )
1818 ULONG nIdx = aPos.nNode.GetIndex();
1820 USHORT nIns=0;
1821 while( nIns < aOutlineMarkPoss.Count() &&
1822 aOutlineMarkPoss[nIns] < nIdx )
1823 nIns++;
1825 aOutlineMarkPoss.Insert( nIdx, nIns );
1826 if( bEncoded )
1828 aURL.Erase( nPos, 2 );
1829 aURL.SetChar( nPos-1, cMarkSeperator );
1831 aOutlineMarks.Insert( new String( aURL ), nIns );
1834 else if( sCmp.EqualsAscii( pMarkToText ) )
1840 void SwHTMLWriter::CollectLinkTargets()
1842 const SwFmtINetFmt* pINetFmt;
1843 const SwTxtINetFmt* pTxtAttr;
1844 const SwTxtNode* pTxtNd;
1846 USHORT n, nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_TXTATR_INETFMT );
1847 for( n = 0; n < nMaxItems; ++n )
1849 if( 0 != (pINetFmt = (SwFmtINetFmt*)pDoc->GetAttrPool().GetItem(
1850 RES_TXTATR_INETFMT, n ) ) &&
1851 0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) &&
1852 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
1853 pTxtNd->GetNodes().IsDocNodes() )
1855 AddLinkTarget( pINetFmt->GetValue() );
1859 const SwFmtURL *pURL;
1860 nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_URL );
1861 for( n = 0; n < nMaxItems; ++n )
1863 if( 0 != (pURL = (SwFmtURL*)pDoc->GetAttrPool().GetItem(
1864 RES_URL, n ) ) )
1866 AddLinkTarget( pURL->GetURL() );
1867 const ImageMap *pIMap = pURL->GetMap();
1868 if( pIMap )
1870 for( USHORT i=0; i<pIMap->GetIMapObjectCount(); i++ )
1872 const IMapObject* pObj = pIMap->GetIMapObject( i );
1873 if( pObj )
1875 AddLinkTarget( pObj->GetURL() );
1883 //-----------------------------------------------------------------------
1885 SwHTMLPosFlyFrm::SwHTMLPosFlyFrm( const SwPosFlyFrm& rPosFly,
1886 const SdrObject *pSdrObj,
1887 BYTE nOutMode ) :
1888 pFrmFmt( &rPosFly.GetFmt() ),
1889 pSdrObject( pSdrObj ),
1890 pNdIdx( new SwNodeIndex( rPosFly.GetNdIndex() ) ),
1891 nOrdNum( rPosFly.GetOrdNum() ),
1892 nCntntIdx( 0 ),
1893 nOutputMode( nOutMode )
1895 const SwFmtAnchor& rAnchor = rPosFly.GetFmt().GetAnchor();
1896 if( FLY_AUTO_CNTNT==rAnchor.GetAnchorId() &&
1897 HTML_POS_INSIDE == GetOutPos() )
1899 // Auto-gebundene Rahmen werden ein Zeichen weiter hinten
1900 // ausgegeben, weil dann die Positionierung mit Netscape
1901 // uebereinstimmt.
1902 ASSERT( rAnchor.GetCntntAnchor(), "Keine Anker-Position?" );
1903 if( rAnchor.GetCntntAnchor() )
1905 nCntntIdx = rAnchor.GetCntntAnchor()->nContent.GetIndex();
1906 sal_Int16 eHoriRel = rPosFly.GetFmt().GetHoriOrient().
1907 GetRelationOrient();
1908 if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
1910 const SwCntntNode *pCNd = pNdIdx->GetNode().GetCntntNode();
1911 ASSERT( pCNd, "Kein Content-Node an PaM-Position" );
1912 if( pCNd && nCntntIdx < pCNd->Len() )
1913 nCntntIdx++;
1919 BOOL SwHTMLPosFlyFrm::operator<( const SwHTMLPosFlyFrm& rFrm ) const
1921 if( pNdIdx->GetIndex() == rFrm.pNdIdx->GetIndex() )
1923 if( nCntntIdx == rFrm.nCntntIdx )
1925 if( GetOutPos() == rFrm.GetOutPos() )
1926 return nOrdNum < rFrm.nOrdNum;
1927 else
1928 return GetOutPos() < rFrm.GetOutPos();
1930 else
1931 return nCntntIdx < rFrm.nCntntIdx;
1933 else
1934 return pNdIdx->GetIndex() < rFrm.pNdIdx->GetIndex();