Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/text/HoriOrientation.hpp>
21 : #include <com/sun/star/text/VertOrientation.hpp>
22 : #include <com/sun/star/text/RelOrientation.hpp>
23 : #include <comphelper/string.hxx>
24 : #include <svx/svxids.hrc>
25 : #include "hintids.hxx"
26 : #include <svl/urihelper.hxx>
27 : #include <vcl/svapp.hxx>
28 : #include <vcl/wrkwin.hxx>
29 : #include <svtools/htmlkywd.hxx>
30 : #include <svtools/htmlout.hxx>
31 : #include <svtools/imap.hxx>
32 : #include <svtools/imapobj.hxx>
33 : #include <svtools/htmlcfg.hxx>
34 : #include <svx/xoutbmp.hxx>
35 : #include <editeng/boxitem.hxx>
36 : #include <editeng/lrspitem.hxx>
37 : #include <editeng/ulspitem.hxx>
38 : #include <editeng/brushitem.hxx>
39 :
40 : #include <fmtanchr.hxx>
41 : #include <fmtornt.hxx>
42 : #include <fmturl.hxx>
43 : #include <fmtfsize.hxx>
44 : #include <fmtclds.hxx>
45 : #include <fmtcntnt.hxx>
46 : #include <fmtsrnd.hxx>
47 : #include <fmtinfmt.hxx>
48 : #include <txtinet.hxx>
49 : #include "frmatr.hxx"
50 : #include <grfatr.hxx>
51 : #include <flypos.hxx>
52 : #include <docary.hxx>
53 : #include <ndgrf.hxx>
54 :
55 : #include "doc.hxx"
56 : #include "ndtxt.hxx"
57 : #include "pam.hxx"
58 : #include "swerror.h"
59 : #include "frmfmt.hxx"
60 : #include "wrthtml.hxx"
61 : #include "css1kywd.hxx"
62 : #include "htmlfly.hxx"
63 :
64 : using namespace css;
65 :
66 : const sal_uLong HTML_FRMOPTS_IMG_ALL =
67 : HTML_FRMOPT_ALT |
68 : HTML_FRMOPT_SIZE |
69 : HTML_FRMOPT_ANYSIZE |
70 : HTML_FRMOPT_BORDER |
71 : HTML_FRMOPT_NAME;
72 : const sal_uLong HTML_FRMOPTS_IMG_CNTNR =
73 : HTML_FRMOPTS_IMG_ALL |
74 : HTML_FRMOPT_ABSSIZE;
75 : const sal_uLong HTML_FRMOPTS_IMG =
76 : HTML_FRMOPTS_IMG_ALL |
77 : HTML_FRMOPT_ALIGN |
78 : HTML_FRMOPT_SPACE |
79 : HTML_FRMOPT_BRCLEAR;
80 : const sal_uLong HTML_FRMOPTS_IMG_CSS1 =
81 : HTML_FRMOPT_S_ALIGN |
82 : HTML_FRMOPT_S_SPACE;
83 :
84 : const sal_uLong HTML_FRMOPTS_DIV =
85 : HTML_FRMOPT_ID |
86 : HTML_FRMOPT_S_ALIGN |
87 : HTML_FRMOPT_S_SIZE |
88 : HTML_FRMOPT_ANYSIZE |
89 : HTML_FRMOPT_ABSSIZE |
90 : HTML_FRMOPT_S_SPACE |
91 : HTML_FRMOPT_S_BORDER |
92 : HTML_FRMOPT_S_BACKGROUND |
93 : HTML_FRMOPT_BRCLEAR |
94 : HTML_FRMOPT_DIR;
95 :
96 : const sal_uLong HTML_FRMOPTS_MULTICOL =
97 : HTML_FRMOPT_ID |
98 : HTML_FRMOPT_WIDTH |
99 : HTML_FRMOPT_ANYSIZE |
100 : HTML_FRMOPT_ABSSIZE |
101 : HTML_FRMOPT_DIR;
102 : const sal_uLong HTML_FRMOPTS_MULTICOL_CNTNR =
103 : HTML_FRMOPTS_MULTICOL;
104 : const sal_uLong HTML_FRMOPTS_MULTICOL_CSS1 =
105 : HTML_FRMOPT_S_ALIGN |
106 : HTML_FRMOPT_S_SIZE |
107 : HTML_FRMOPT_S_SPACE |
108 : HTML_FRMOPT_S_BORDER|
109 : HTML_FRMOPT_S_BACKGROUND;
110 :
111 : const sal_uLong HTML_FRMOPTS_SPACER =
112 : HTML_FRMOPT_ALIGN |
113 : HTML_FRMOPT_SIZE |
114 : HTML_FRMOPT_ANYSIZE |
115 : HTML_FRMOPT_BRCLEAR |
116 : HTML_FRMOPT_MARGINSIZE |
117 : HTML_FRMOPT_ABSSIZE;
118 :
119 : const sal_uLong HTML_FRMOPTS_CNTNR =
120 : HTML_FRMOPT_S_ALIGN |
121 : HTML_FRMOPT_S_SPACE |
122 : HTML_FRMOPT_S_WIDTH |
123 : HTML_FRMOPT_ANYSIZE |
124 : HTML_FRMOPT_ABSSIZE |
125 : HTML_FRMOPT_S_PIXSIZE;
126 :
127 : static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt );
128 : static Writer& OutHTML_FrmFmtAsMulticol( Writer& rWrt, const SwFrmFmt& rFmt,
129 : sal_Bool bInCntnr );
130 : static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFmt );
131 : static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
132 : const SwFrmFmt& rFrmFmt, sal_Bool bSpan );
133 : static Writer& OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFmt,
134 : sal_Bool bInCntnr );
135 :
136 : static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFmt,
137 : sal_Bool bInCntnr );
138 :
139 : static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
140 : const SdrObject& rSdrObj );
141 :
142 : extern HTMLOutEvent aAnchorEventTable[];
143 :
144 : static HTMLOutEvent aImageEventTable[] =
145 : {
146 : { OOO_STRING_SVTOOLS_HTML_O_SDonload, OOO_STRING_SVTOOLS_HTML_O_onload, SVX_EVENT_IMAGE_LOAD },
147 : { OOO_STRING_SVTOOLS_HTML_O_SDonabort, OOO_STRING_SVTOOLS_HTML_O_onabort, SVX_EVENT_IMAGE_ABORT },
148 : { OOO_STRING_SVTOOLS_HTML_O_SDonerror, OOO_STRING_SVTOOLS_HTML_O_onerror, SVX_EVENT_IMAGE_ERROR },
149 : { 0, 0, 0 }
150 : };
151 :
152 : static HTMLOutEvent aIMapEventTable[] =
153 : {
154 : { OOO_STRING_SVTOOLS_HTML_O_SDonmouseover, OOO_STRING_SVTOOLS_HTML_O_onmouseover, SFX_EVENT_MOUSEOVER_OBJECT },
155 : { OOO_STRING_SVTOOLS_HTML_O_SDonmouseout, OOO_STRING_SVTOOLS_HTML_O_onmouseout, SFX_EVENT_MOUSEOUT_OBJECT },
156 : { 0, 0, 0 }
157 : };
158 :
159 2 : sal_uInt16 SwHTMLWriter::GuessFrmType( const SwFrmFmt& rFrmFmt,
160 : const SdrObject*& rpSdrObj )
161 : {
162 : SwHTMLFrmType eType;
163 :
164 2 : if( RES_DRAWFRMFMT == rFrmFmt.Which() )
165 : {
166 : // Als Default irgendein Zeichen-Objekt
167 0 : eType = HTML_FRMTYPE_DRAW;
168 :
169 : const SdrObject *pObj =
170 0 : SwHTMLWriter::GetMarqueeTextObj( (const SwDrawFrmFmt &)rFrmFmt );
171 0 : if( pObj )
172 : {
173 : // Laufschrift
174 0 : rpSdrObj = pObj;
175 0 : eType = HTML_FRMTYPE_MARQUEE;
176 : }
177 : else
178 : {
179 0 : pObj = GetHTMLControl( (const SwDrawFrmFmt &)rFrmFmt );
180 :
181 0 : if( pObj )
182 : {
183 : // Form-Control
184 0 : rpSdrObj = pObj;
185 0 : eType = HTML_FRMTYPE_CONTROL;
186 : }
187 : }
188 : }
189 : else
190 : {
191 : // Als Default ein Textrahmen
192 2 : eType = HTML_FRMTYPE_TEXT;
193 :
194 2 : const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
195 2 : sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
196 2 : const SwNode* pNd = pDoc->GetNodes()[ nStt ];
197 :
198 2 : if( pNd->IsGrfNode() )
199 : {
200 : // Grafik - Node
201 2 : eType = HTML_FRMTYPE_GRF;
202 : }
203 0 : else if( pNd->IsOLENode() )
204 : {
205 : // Applet, Plugin, Floating-Frame
206 0 : eType = (SwHTMLFrmType)GuessOLENodeFrmType( *pNd );
207 : }
208 : else
209 : {
210 0 : sal_uLong nEnd = pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
211 :
212 : const SfxPoolItem* pItem;
213 0 : const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
214 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_COL,
215 0 : true, &pItem ) &&
216 0 : ((const SwFmtCol *)pItem)->GetNumCols() > 1 )
217 : {
218 : // spaltiger Rahmen
219 0 : eType = HTML_FRMTYPE_MULTICOL;
220 : }
221 0 : else if( pNd->IsTableNode() )
222 : {
223 0 : const SwTableNode *pTblNd = pNd->GetTableNode();
224 0 : sal_uLong nTblEnd = pTblNd->EndOfSectionIndex();
225 :
226 0 : if( nTblEnd+1 == nEnd )
227 : {
228 : // Tabelle
229 0 : eType = HTML_FRMTYPE_TABLE;
230 : }
231 0 : else if( nTblEnd+2 == nEnd )
232 : {
233 : // Tabelle mit Unterschrft
234 0 : eType = HTML_FRMTYPE_TABLE_CAP;
235 : }
236 : }
237 0 : else if( pNd->IsTxtNode() )
238 : {
239 0 : const SwTxtNode *pTxtNd = pNd->GetTxtNode();
240 :
241 0 : sal_Bool bEmpty = sal_False;
242 0 : if( nStt==nEnd-1 && !pTxtNd->Len() )
243 : {
244 : // leerer Rahmen? Nur wenn kein Rahmen am
245 : // Text- oder Start-Node verankert ist.
246 0 : bEmpty = sal_True;
247 0 : if( pHTMLPosFlyFrms )
248 : {
249 0 : for( sal_uInt16 i=0; i<pHTMLPosFlyFrms->size(); i++ )
250 : {
251 0 : sal_uLong nIdx = (*pHTMLPosFlyFrms)[i]
252 0 : ->GetNdIndex().GetIndex();
253 0 : bEmpty = (nIdx != nStt) && (nIdx != nStt-1);
254 0 : if( !bEmpty || nIdx > nStt )
255 : break;
256 : }
257 : }
258 : }
259 0 : if( bEmpty )
260 : {
261 0 : const SvxBrushItem& rBrush = rFrmFmt.GetBackground();
262 : /// background is not empty, if it has a background graphic
263 : /// or its background color is not "no fill"/"auto fill".
264 0 : if( GPOS_NONE != rBrush.GetGraphicPos() ||
265 0 : rBrush.GetColor() != COL_TRANSPARENT )
266 0 : bEmpty = sal_False;
267 : }
268 0 : if( bEmpty )
269 : {
270 : // leerer Rahmen
271 0 : eType = HTML_FRMTYPE_EMPTY;
272 : }
273 0 : else if( pDoc->GetNodes()[nStt+1]->IsTableNode() )
274 : {
275 : const SwTableNode *pTblNd =
276 0 : pDoc->GetNodes()[nStt+1]->GetTableNode();
277 0 : if( pTblNd->EndOfSectionIndex()+1 == nEnd )
278 : {
279 : // Tabelle mit Ueberschrift
280 0 : eType = HTML_FRMTYPE_TABLE_CAP;
281 : }
282 : }
283 : }
284 : }
285 : }
286 :
287 2 : return static_cast< sal_uInt16 >(eType);
288 : }
289 :
290 5 : void SwHTMLWriter::CollectFlyFrms()
291 : {
292 : OSL_ENSURE( HTML_CFG_MAX+1 == MAX_BROWSERS,
293 : "number of browser configurations has changed" );
294 :
295 5 : SwPosFlyFrms aFlyPos(pDoc->GetAllFlyFmts(bWriteAll ? 0 : pCurPam, true));
296 :
297 7 : for(SwPosFlyFrms::const_iterator aIter(aFlyPos.begin()); aIter != aFlyPos.end(); ++aIter)
298 : {
299 2 : const SwFrmFmt& rFrmFmt = (*aIter)->GetFmt();
300 2 : const SdrObject *pSdrObj = 0;
301 : const SwPosition *pAPos;
302 : const SwCntntNode *pACNd;
303 2 : SwHTMLFrmType eType = (SwHTMLFrmType)GuessFrmType( rFrmFmt, pSdrObj );
304 :
305 : sal_uInt8 nMode;
306 2 : const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
307 2 : sal_Int16 eHoriRel = rFrmFmt.GetHoriOrient().GetRelationOrient();
308 2 : switch( rAnchor.GetAnchorId() )
309 : {
310 : case FLY_AT_PAGE:
311 : case FLY_AT_FLY:
312 0 : nMode = aHTMLOutFrmPageFlyTable[eType][nExportMode];
313 0 : break;
314 :
315 : case FLY_AT_PARA:
316 : // Absatz-gebundene Rahmen werden nur dann vor den
317 : // Absatz geschrieben, wenn der Absatz einen Abstand
318 : // hat.
319 0 : if( text::RelOrientation::FRAME == eHoriRel &&
320 0 : (pAPos = rAnchor.GetCntntAnchor()) != 0 &&
321 0 : (pACNd = pAPos->nNode.GetNode().GetCntntNode()) != 0 )
322 : {
323 : const SvxLRSpaceItem& rLRItem =
324 0 : (const SvxLRSpaceItem&)pACNd->GetAttr(RES_LR_SPACE);
325 0 : if( rLRItem.GetTxtLeft() || rLRItem.GetRight() )
326 : {
327 0 : nMode = aHTMLOutFrmParaFrameTable[eType][nExportMode];
328 0 : break;
329 : }
330 : }
331 0 : nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
332 0 : break;
333 :
334 : case FLY_AT_CHAR:
335 2 : if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
336 2 : nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
337 : else
338 0 : nMode = aHTMLOutFrmParaOtherTable[eType][nExportMode];
339 2 : break;
340 :
341 : default:
342 0 : nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
343 0 : break;
344 : }
345 :
346 2 : if( !pHTMLPosFlyFrms )
347 2 : pHTMLPosFlyFrms = new SwHTMLPosFlyFrms;
348 :
349 2 : SwHTMLPosFlyFrm *pNew = new SwHTMLPosFlyFrm(**aIter, pSdrObj, nMode);
350 2 : pHTMLPosFlyFrms->insert( pNew );
351 5 : }
352 5 : }
353 :
354 276 : sal_Bool SwHTMLWriter::OutFlyFrm( sal_uLong nNdIdx, sal_Int32 nCntntIdx, sal_uInt8 nPos,
355 : HTMLOutContext *pContext )
356 : {
357 276 : sal_Bool bFlysLeft = sal_False; // Noch Flys an aktueller Node-Position da?
358 :
359 : // OutFlyFrm kan rekursiv aufgerufen werden. Deshalb muss man
360 : // manchmal wieder von vorne anfangen, nachdem ein Fly ausgegeben
361 : // wurde.
362 276 : sal_Bool bRestart = sal_True;
363 564 : while( pHTMLPosFlyFrms && bRestart )
364 : {
365 12 : bFlysLeft = bRestart = sal_False;
366 :
367 : // suche nach dem Anfang der FlyFrames
368 : sal_uInt16 i;
369 :
370 24 : for( i = 0; i < pHTMLPosFlyFrms->size() &&
371 12 : (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() < nNdIdx; i++ )
372 : ;
373 36 : for( ; !bRestart && i < pHTMLPosFlyFrms->size() &&
374 12 : (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() == nNdIdx; i++ )
375 : {
376 12 : SwHTMLPosFlyFrm *pPosFly = (*pHTMLPosFlyFrms)[i];
377 24 : if( ( HTML_POS_ANY == nPos ||
378 20 : pPosFly->GetOutPos() == nPos ) &&
379 8 : pPosFly->GetCntntIndex() == nCntntIdx )
380 : {
381 : // Erst entfernen ist wichtig, weil in tieferen
382 : // Rekursionen evtl. weitere Eintraege oder das
383 : // ganze Array geloscht werden koennte.
384 2 : pHTMLPosFlyFrms->erase(i);
385 2 : i--;
386 2 : if( pHTMLPosFlyFrms->empty() )
387 : {
388 2 : delete pHTMLPosFlyFrms;
389 2 : pHTMLPosFlyFrms = 0;
390 2 : bRestart = sal_True; // nicht wirklich, nur raus
391 : // aus der Schleife
392 : }
393 :
394 2 : if( pContext )
395 : {
396 0 : HTMLOutFuncs::FlushToAscii(Strm(), *pContext );
397 0 : pContext = 0; // one time only
398 : }
399 :
400 2 : OutFrmFmt( pPosFly->GetOutMode(), pPosFly->GetFmt(),
401 4 : pPosFly->GetSdrObject() );
402 2 : switch( pPosFly->GetOutFn() )
403 : {
404 : case HTML_OUT_DIV:
405 : case HTML_OUT_SPAN:
406 : case HTML_OUT_MULTICOL:
407 : case HTML_OUT_TBLNODE:
408 0 : bRestart = sal_True; // Hier wird's evtl rekursiv
409 0 : break;
410 : }
411 2 : delete pPosFly;
412 : }
413 : else
414 : {
415 10 : bFlysLeft = sal_True;
416 : }
417 : }
418 : }
419 :
420 276 : return bFlysLeft;
421 : }
422 :
423 2 : void SwHTMLWriter::OutFrmFmt( sal_uInt8 nMode, const SwFrmFmt& rFrmFmt,
424 : const SdrObject *pSdrObject )
425 : {
426 2 : sal_uInt8 nCntnrMode = SwHTMLPosFlyFrm::GetOutCntnr( nMode );
427 2 : sal_uInt8 nOutMode = SwHTMLPosFlyFrm::GetOutFn(nMode);
428 2 : const sal_Char *pCntnrStr = 0;
429 2 : if( HTML_CNTNR_NONE != nCntnrMode )
430 : {
431 :
432 0 : if( bLFPossible && HTML_CNTNR_DIV == nCntnrMode )
433 0 : OutNewLine();
434 :
435 0 : OStringBuffer sOut;
436 : pCntnrStr = (HTML_CNTNR_DIV == nCntnrMode)
437 : ? OOO_STRING_SVTOOLS_HTML_division
438 0 : : OOO_STRING_SVTOOLS_HTML_span;
439 0 : sOut.append('<').append(pCntnrStr).append(' ')
440 0 : .append(OOO_STRING_SVTOOLS_HTML_O_class).append("=\"")
441 0 : .append("sd-abs-pos").append('\"');
442 0 : Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
443 :
444 : // Fuer Nicht-Zeichenobekte eine Breite ausgeben
445 0 : sal_uLong nFrmFlags = HTML_FRMOPTS_CNTNR;
446 :
447 : // Fuer spaltige Rahmen koennen wir auch noch den Hintergrund ausgeben.
448 0 : if( HTML_OUT_MULTICOL == nOutMode )
449 0 : nFrmFlags |= HTML_FRMOPT_S_BACKGROUND|HTML_FRMOPT_S_BORDER;
450 :
451 0 : if( IsHTMLMode( HTMLMODE_BORDER_NONE ) )
452 0 : nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
453 0 : OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags, pSdrObject );
454 0 : Strm().WriteChar( '>' );
455 :
456 0 : if( HTML_CNTNR_DIV == nCntnrMode )
457 : {
458 0 : IncIndentLevel();
459 0 : bLFPossible = sal_True;
460 0 : }
461 : }
462 :
463 2 : switch( nOutMode )
464 : {
465 : case HTML_OUT_TBLNODE: // OK
466 : OSL_ENSURE( !pCntnrStr, "Table: Container ist hier nicht vorgesehen" );
467 0 : OutHTML_FrmFmtTableNode( *this, rFrmFmt );
468 0 : break;
469 : case HTML_OUT_GRFNODE: // OK
470 2 : OutHTML_FrmFmtGrfNode( *this, rFrmFmt, pCntnrStr != 0 );
471 2 : break;
472 : case HTML_OUT_OLENODE: // OK
473 0 : OutHTML_FrmFmtOLENode( *this, rFrmFmt, pCntnrStr != 0 );
474 0 : break;
475 : case HTML_OUT_OLEGRF: // OK
476 0 : OutHTML_FrmFmtOLENodeGrf( *this, rFrmFmt, pCntnrStr != 0 );
477 0 : break;
478 : case HTML_OUT_DIV:
479 : case HTML_OUT_SPAN:
480 : OSL_ENSURE( !pCntnrStr, "Div: Container ist hier nicht vorgesehen" );
481 0 : OutHTML_FrmFmtAsDivOrSpan( *this, rFrmFmt, HTML_OUT_SPAN==nOutMode );
482 0 : break;
483 : case HTML_OUT_MULTICOL: // OK
484 0 : OutHTML_FrmFmtAsMulticol( *this, rFrmFmt, pCntnrStr != 0 );
485 0 : break;
486 : case HTML_OUT_SPACER: // OK
487 : OSL_ENSURE( !pCntnrStr, "Spacer: Container ist hier nicht vorgesehen" );
488 0 : OutHTML_FrmFmtAsSpacer( *this, rFrmFmt );
489 0 : break;
490 : case HTML_OUT_CONTROL: // OK
491 : OutHTML_DrawFrmFmtAsControl( *this,
492 : (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject,
493 0 : pCntnrStr != 0 );
494 0 : break;
495 : case HTML_OUT_AMARQUEE:
496 0 : OutHTML_FrmFmtAsMarquee( *this, rFrmFmt, *pSdrObject );
497 0 : break;
498 : case HTML_OUT_MARQUEE:
499 : OSL_ENSURE( !pCntnrStr, "Marquee: Container ist hier nicht vorgesehen" );
500 : OutHTML_DrawFrmFmtAsMarquee( *this,
501 0 : (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject );
502 0 : break;
503 : case HTML_OUT_GRFFRM:
504 0 : OutHTML_FrmFmtAsImage( *this, rFrmFmt, pCntnrStr != 0 );
505 0 : break;
506 : }
507 :
508 2 : if( HTML_CNTNR_DIV == nCntnrMode )
509 : {
510 0 : DecIndentLevel();
511 0 : if( bLFPossible )
512 0 : OutNewLine();
513 0 : HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_division, false );
514 0 : bLFPossible = sal_True;
515 : }
516 2 : else if( HTML_CNTNR_SPAN == nCntnrMode )
517 0 : HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, false );
518 2 : }
519 :
520 1 : OString SwHTMLWriter::OutFrmFmtOptions( const SwFrmFmt &rFrmFmt,
521 : const OUString& rAlternateTxt,
522 : sal_uInt32 nFrmOpts,
523 : const OString &rEndTags )
524 : {
525 1 : OString sRetEndTags(rEndTags);
526 2 : OStringBuffer sOut;
527 : const SfxPoolItem* pItem;
528 1 : const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
529 :
530 : // Name
531 4 : if( (nFrmOpts & (HTML_FRMOPT_ID|HTML_FRMOPT_NAME)) &&
532 4 : !rFrmFmt.GetName().isEmpty() )
533 : {
534 : const sal_Char *pStr =
535 1 : (nFrmOpts & HTML_FRMOPT_ID) ? OOO_STRING_SVTOOLS_HTML_O_id : OOO_STRING_SVTOOLS_HTML_O_name;
536 1 : sOut.append(' ').append(pStr).
537 1 : append("=\"");
538 1 : Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
539 1 : HTMLOutFuncs::Out_String( Strm(), rFrmFmt.GetName(), eDestEnc, &aNonConvertableCharacters );
540 1 : sOut.append('\"');
541 : }
542 :
543 : // Name
544 1 : if( nFrmOpts & HTML_FRMOPT_DIR )
545 : {
546 0 : sal_uInt16 nDir = GetHTMLDirection( rItemSet );
547 0 : Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
548 0 : OutDirection( nDir );
549 : }
550 :
551 : // ALT
552 1 : if( (nFrmOpts & HTML_FRMOPT_ALT) && !rAlternateTxt.isEmpty() )
553 : {
554 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_alt).
555 0 : append("=\"");
556 0 : Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
557 0 : HTMLOutFuncs::Out_String( Strm(), rAlternateTxt, eDestEnc, &aNonConvertableCharacters );
558 0 : sOut.append('\"');
559 : }
560 :
561 : // ALIGN
562 1 : const sal_Char *pStr = 0;
563 1 : RndStdIds eAnchorId = rFrmFmt.GetAnchor().GetAnchorId();
564 1 : if( (nFrmOpts & HTML_FRMOPT_ALIGN) &&
565 1 : ((FLY_AT_PARA == eAnchorId) || (FLY_AT_CHAR == eAnchorId)) )
566 : {
567 : // MIB 12.3.98: Ist es nicht schlauer, absatzgebundene
568 : // Rahmen notfalls links auszurichten als sie
569 : // zeichengebunden einzufuegen???
570 1 : const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient();
571 3 : if( !(nFrmOpts & HTML_FRMOPT_S_ALIGN) ||
572 1 : text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
573 0 : text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
574 : {
575 1 : pStr = text::HoriOrientation::RIGHT == rHoriOri.GetHoriOrient()
576 : ? OOO_STRING_SVTOOLS_HTML_AL_right
577 1 : : OOO_STRING_SVTOOLS_HTML_AL_left;
578 : }
579 : }
580 3 : if( (nFrmOpts & HTML_FRMOPT_ALIGN) && !pStr &&
581 0 : ( (nFrmOpts & HTML_FRMOPT_S_ALIGN) == 0 ||
582 1 : (FLY_AS_CHAR == eAnchorId) ) &&
583 0 : SFX_ITEM_SET == rItemSet.GetItemState( RES_VERT_ORIENT, true, &pItem ))
584 : {
585 0 : switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
586 : {
587 0 : case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
588 : case text::VertOrientation::CHAR_TOP:
589 0 : case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // geht nicht
590 : case text::VertOrientation::LINE_CENTER:
591 0 : case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // geht nicht
592 0 : case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
593 : case text::VertOrientation::LINE_BOTTOM:
594 0 : case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // geht nicht
595 0 : case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
596 0 : case text::VertOrientation::NONE: break;
597 : }
598 : }
599 1 : if( pStr )
600 : {
601 1 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).append("=\"").
602 1 : append(pStr).append("\"");
603 : }
604 :
605 : // HSPACE und VSPACE
606 1 : Size aTwipSpc( 0, 0 );
607 2 : if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
608 1 : SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, true, &pItem ))
609 : {
610 1 : aTwipSpc.Width() =
611 2 : ( ((SvxLRSpaceItem*)pItem)->GetLeft() +
612 2 : ((SvxLRSpaceItem*)pItem)->GetRight() ) / 2;
613 1 : nDfltLeftMargin = nDfltRightMargin = aTwipSpc.Width();
614 : }
615 2 : if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
616 1 : SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, true, &pItem ))
617 : {
618 1 : aTwipSpc.Height() =
619 2 : ( ((SvxULSpaceItem*)pItem)->GetUpper() +
620 2 : ((SvxULSpaceItem*)pItem)->GetLower() ) / 2;
621 1 : nDfltTopMargin = nDfltBottomMargin = (sal_uInt16)aTwipSpc.Height();
622 : }
623 :
624 3 : if( (nFrmOpts & HTML_FRMOPT_SPACE) &&
625 2 : (aTwipSpc.Width() || aTwipSpc.Height()) &&
626 0 : Application::GetDefaultDevice() )
627 : {
628 : Size aPixelSpc =
629 : Application::GetDefaultDevice()->LogicToPixel( aTwipSpc,
630 0 : MapMode(MAP_TWIP) );
631 0 : if( !aPixelSpc.Width() && aTwipSpc.Width() )
632 0 : aPixelSpc.Width() = 1;
633 0 : if( !aPixelSpc.Height() && aTwipSpc.Height() )
634 0 : aPixelSpc.Height() = 1;
635 :
636 0 : if( aPixelSpc.Width() )
637 : {
638 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_hspace).
639 0 : append("=\"").append(static_cast<sal_Int32>(aPixelSpc.Width())).append("\"");
640 : }
641 :
642 0 : if( aPixelSpc.Height() )
643 : {
644 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_vspace).
645 0 : append("=\"").append(static_cast<sal_Int32>(aPixelSpc.Height())).append("\"");
646 : }
647 : }
648 :
649 : // Der Abstand muss bei der Groesse beruecksichtigt, wenn das entsprechende
650 : // Flag gesetzt ist.
651 1 : if( (nFrmOpts & HTML_FRMOPT_MARGINSIZE) )
652 : {
653 0 : aTwipSpc.Width() *= -2;
654 0 : aTwipSpc.Height() *= -2;
655 : }
656 : else
657 : {
658 1 : aTwipSpc.Width() = 0;
659 1 : aTwipSpc.Height() = 0;
660 : }
661 :
662 2 : if( !(nFrmOpts & HTML_FRMOPT_ABSSIZE) &&
663 1 : SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, true, &pItem ))
664 : {
665 1 : const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
666 :
667 1 : aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_LEFT );
668 1 : aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_RIGHT );
669 1 : aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_TOP );
670 1 : aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_BOTTOM );
671 : }
672 :
673 : // WIDTH und/oder HEIGHT
674 : // ATT_VAR_SIZE/ATT_MIN_SIZE nur ausgeben, wenn ANYSIZE gesezut ist
675 3 : if( (nFrmOpts & HTML_FRMOPT_SIZE) &&
676 3 : SFX_ITEM_SET == rItemSet.GetItemState( RES_FRM_SIZE, true, &pItem ) &&
677 1 : ( (nFrmOpts & HTML_FRMOPT_ANYSIZE) ||
678 0 : ATT_FIX_SIZE == ((const SwFmtFrmSize *)pItem)->GetHeightSizeType()) )
679 : {
680 1 : const SwFmtFrmSize *pFSItem = (const SwFmtFrmSize *)pItem;
681 1 : sal_uInt8 nPrcWidth = pFSItem->GetWidthPercent();
682 1 : sal_uInt8 nPrcHeight = pFSItem->GetHeightPercent();
683 :
684 : // Groesse des Objekts Twips ohne Raender
685 : Size aTwipSz( (nPrcWidth ? 0
686 1 : : pFSItem->GetWidth()-aTwipSpc.Width()),
687 : (nPrcHeight ? 0
688 2 : : pFSItem->GetHeight()-aTwipSpc.Height()) );
689 :
690 : OSL_ENSURE( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0,
691 : "Rahmengroesse minus Abstand < 0!!!???" );
692 1 : if( aTwipSz.Width() < 0 )
693 0 : aTwipSz.Width() = 0;
694 1 : if( aTwipSz.Height() < 0 )
695 0 : aTwipSz.Height() = 0;
696 :
697 1 : Size aPixelSz( 0, 0 );
698 2 : if( (aTwipSz.Width() || aTwipSz.Height()) &&
699 1 : Application::GetDefaultDevice() )
700 : {
701 : aPixelSz =
702 : Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
703 1 : MapMode(MAP_TWIP) );
704 1 : if( !aPixelSz.Width() && aTwipSz.Width() )
705 0 : aPixelSz.Width() = 1;
706 1 : if( !aPixelSz.Height() && aTwipSz.Height() )
707 0 : aPixelSz.Height() = 1;
708 : }
709 :
710 2 : if( (nFrmOpts & HTML_FRMOPT_WIDTH) &&
711 0 : ((nPrcWidth && nPrcWidth!=255) || aPixelSz.Width()) )
712 : {
713 1 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
714 1 : append("=\"");
715 1 : if( nPrcWidth )
716 0 : sOut.append(static_cast<sal_Int32>(nPrcWidth)).append('%');
717 : else
718 1 : sOut.append(static_cast<sal_Int32>(aPixelSz.Width()));
719 1 : sOut.append("\"");
720 : }
721 :
722 2 : if( (nFrmOpts & HTML_FRMOPT_HEIGHT) &&
723 0 : ((nPrcHeight && nPrcHeight!=255) || aPixelSz.Height()) )
724 : {
725 1 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_height).
726 1 : append("=\"");
727 1 : if( nPrcHeight )
728 0 : sOut.append(static_cast<sal_Int32>(nPrcHeight)).append('%');
729 : else
730 1 : sOut.append(static_cast<sal_Int32>(aPixelSz.Height()));
731 1 : sOut.append("\"");
732 : }
733 : }
734 :
735 1 : if (!sOut.isEmpty())
736 1 : Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
737 :
738 : // Umlauf fuer absatzgeb. Grafiken als <BR CLEAR=...> in den String
739 : // schreiben
740 3 : if( (nFrmOpts & HTML_FRMOPT_BRCLEAR) &&
741 2 : ((FLY_AT_PARA == rFrmFmt.GetAnchor().GetAnchorId()) ||
742 3 : (FLY_AT_CHAR == rFrmFmt.GetAnchor().GetAnchorId())) &&
743 1 : SFX_ITEM_SET == rItemSet.GetItemState( RES_SURROUND, true, &pItem ))
744 : {
745 1 : const SwFmtSurround* pSurround = (const SwFmtSurround*)pItem;
746 1 : sal_Int16 eHoriOri = rFrmFmt.GetHoriOrient().GetHoriOrient();
747 1 : pStr = 0;
748 1 : SwSurround eSurround = pSurround->GetSurround();
749 1 : sal_Bool bAnchorOnly = pSurround->IsAnchorOnly();
750 1 : switch( eHoriOri )
751 : {
752 : case text::HoriOrientation::RIGHT:
753 : {
754 0 : switch( eSurround )
755 : {
756 : case SURROUND_NONE:
757 : case SURROUND_RIGHT:
758 0 : pStr = OOO_STRING_SVTOOLS_HTML_AL_right;
759 0 : break;
760 : case SURROUND_LEFT:
761 : case SURROUND_PARALLEL:
762 0 : if( bAnchorOnly )
763 0 : bClearRight = sal_True;
764 0 : break;
765 : default:
766 : ;
767 : }
768 : }
769 0 : break;
770 :
771 : default:
772 : // If a frame is centered, it gets left aligned. This
773 : // should be taken into account here, too.
774 : {
775 1 : switch( eSurround )
776 : {
777 : case SURROUND_NONE:
778 : case SURROUND_LEFT:
779 0 : pStr = OOO_STRING_SVTOOLS_HTML_AL_left;
780 0 : break;
781 : case SURROUND_RIGHT:
782 : case SURROUND_PARALLEL:
783 0 : if( bAnchorOnly )
784 0 : bClearLeft = sal_True;
785 0 : break;
786 : default:
787 : ;
788 : }
789 : }
790 1 : break;
791 :
792 : }
793 :
794 1 : if( pStr )
795 : {
796 0 : sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_linebreak).
797 0 : append(' ').append(OOO_STRING_SVTOOLS_HTML_O_clear).
798 0 : append("=\"").append(pStr).append("\">").append(rEndTags);
799 0 : sRetEndTags = sOut.makeStringAndClear();
800 : }
801 : }
802 : assert(sRetEndTags.endsWith(rEndTags)); // fdo#58286
803 2 : return sRetEndTags;
804 : }
805 :
806 1 : Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt,
807 : Graphic& rGraphic, const OUString& rAlternateTxt,
808 : const Size &rRealSize, sal_uInt32 nFrmOpts,
809 : const sal_Char *pMarkType,
810 : const ImageMap *pAltImgMap )
811 : {
812 1 : SwHTMLWriter &rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
813 :
814 1 : if (rHTMLWrt.mbSkipImages)
815 0 : return rHTMLWrt;
816 :
817 : // ggf. ein noch offenes Attribut voruebergehend beenden
818 1 : if( !rHTMLWrt.aINetFmts.empty() )
819 : {
820 0 : SwFmtINetFmt *pINetFmt = rHTMLWrt.aINetFmts.back();
821 0 : OutHTML_INetFmt( rWrt, *pINetFmt, sal_False );
822 : }
823 :
824 : const SfxPoolItem* pItem;
825 1 : const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
826 :
827 1 : const SwFmtURL *pURLItem = 0;
828 :
829 : // das URL-Attribut nur beruecksichtigen, wenn keine Image-Map
830 : // uebergeben wurde
831 2 : if( !pAltImgMap &&
832 1 : SFX_ITEM_SET == rItemSet.GetItemState( RES_URL, true, &pItem ))
833 : {
834 0 : pURLItem = (const SwFmtURL *)pItem;
835 : }
836 :
837 : // Image-Map rausschreiben
838 1 : const ImageMap *pIMap = pAltImgMap;
839 1 : if( !pIMap && pURLItem )
840 : {
841 0 : pIMap = pURLItem->GetMap();
842 : }
843 :
844 1 : OUString aIMapName;
845 1 : if( pIMap )
846 : {
847 : // den Namen eindeutig machen
848 0 : aIMapName = pIMap->GetName();
849 0 : OUString aNameBase;
850 0 : if( !aIMapName.isEmpty() )
851 0 : aNameBase = aIMapName;
852 : else
853 0 : aNameBase = OOO_STRING_SVTOOLS_HTML_map;
854 0 : if( aIMapName.isEmpty() )
855 0 : aIMapName = aNameBase + OUString::number( rHTMLWrt.nImgMapCnt );
856 :
857 : sal_Bool bFound;
858 0 : do
859 : {
860 0 : bFound = sal_False;
861 0 : for(size_t i = 0; i < rHTMLWrt.aImgMapNames.size(); ++i)
862 : {
863 : // TODO: Unicode: Comparison is case insensitive for ASCII
864 : // characters only now!
865 0 : if( aIMapName.equalsIgnoreAsciiCase( rHTMLWrt.aImgMapNames[i] ) )
866 : {
867 0 : bFound = sal_True;
868 0 : break;
869 : }
870 : }
871 0 : if( bFound )
872 : {
873 0 : rHTMLWrt.nImgMapCnt++;
874 0 : aIMapName = aNameBase + OUString::number( rHTMLWrt.nImgMapCnt );
875 : }
876 :
877 : } while( bFound );
878 :
879 0 : sal_Bool bScale = sal_False;
880 0 : Fraction aScaleX( 1, 1 );
881 0 : Fraction aScaleY( 1, 1 );
882 :
883 0 : const SwFmtFrmSize& rFrmSize = rFrmFmt.GetFrmSize();
884 0 : const SvxBoxItem& rBox = rFrmFmt.GetBox();
885 :
886 0 : if( !rFrmSize.GetWidthPercent() && rRealSize.Width() )
887 : {
888 0 : SwTwips nWidth = rFrmSize.GetWidth();
889 0 : nWidth -= ( rBox.CalcLineSpace(BOX_LINE_LEFT) +
890 0 : rBox.CalcLineSpace(BOX_LINE_RIGHT) );
891 :
892 : OSL_ENSURE( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
893 0 : if( nWidth<=0 ) // sollte nicht passieren
894 0 : nWidth = 1;
895 :
896 0 : if( rRealSize.Width() != nWidth )
897 : {
898 0 : aScaleX = Fraction( nWidth, rRealSize.Width() );
899 0 : bScale = sal_True;
900 : }
901 : }
902 0 : if( !rFrmSize.GetHeightPercent() && rRealSize.Height() )
903 : {
904 0 : SwTwips nHeight = rFrmSize.GetHeight();
905 0 : nHeight -= ( rBox.CalcLineSpace(BOX_LINE_TOP) +
906 0 : rBox.CalcLineSpace(BOX_LINE_BOTTOM) );
907 :
908 : OSL_ENSURE( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
909 0 : if( nHeight<=0 )
910 0 : nHeight = 1;
911 :
912 0 : if( rRealSize.Height() != nHeight )
913 : {
914 0 : aScaleY = Fraction( nHeight, rRealSize.Height() );
915 0 : bScale = sal_True;
916 : }
917 : }
918 :
919 0 : rHTMLWrt.aImgMapNames.push_back(aIMapName);
920 :
921 0 : OString aIndMap, aIndArea;
922 0 : const sal_Char *pIndArea = 0, *pIndMap = 0;
923 :
924 0 : if( rHTMLWrt.bLFPossible )
925 : {
926 0 : rHTMLWrt.OutNewLine( sal_True );
927 0 : aIndMap = rHTMLWrt.GetIndentString();
928 0 : aIndArea = rHTMLWrt.GetIndentString(1);
929 0 : pIndArea = aIndArea.getStr();
930 0 : pIndMap = aIndMap.getStr();
931 : }
932 :
933 0 : if( bScale )
934 : {
935 0 : ImageMap aScaledIMap( *pIMap );
936 0 : aScaledIMap.Scale( aScaleX, aScaleY );
937 0 : HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), aScaledIMap, aIMapName,
938 : aIMapEventTable,
939 : rHTMLWrt.bCfgStarBasic,
940 : SAL_NEWLINE_STRING, pIndArea, pIndMap,
941 : rHTMLWrt.eDestEnc,
942 0 : &rHTMLWrt.aNonConvertableCharacters );
943 : }
944 : else
945 : {
946 0 : HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), *pIMap, aIMapName,
947 : aIMapEventTable,
948 : rHTMLWrt.bCfgStarBasic,
949 : SAL_NEWLINE_STRING, pIndArea, pIndMap,
950 : rHTMLWrt.eDestEnc,
951 0 : &rHTMLWrt.aNonConvertableCharacters );
952 0 : }
953 : }
954 :
955 : // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
956 1 : if( rHTMLWrt.bLFPossible )
957 0 : rHTMLWrt.OutNewLine( sal_True );
958 :
959 : // Attribute die ausserhelb der Grafik geschreiben werden muessen sammeln
960 2 : OStringBuffer sOut;
961 2 : OString aEndTags;
962 :
963 : // implizite Sprungmarke -> <A NAME=...></A>...<IMG ...>
964 1 : if( pMarkType && !rFrmFmt.GetName().isEmpty() )
965 1 : rHTMLWrt.OutImplicitMark( rFrmFmt.GetName(), pMarkType );
966 :
967 : // URL -> <A>...<IMG ... >...</A>
968 1 : const SvxMacroItem *pMacItem = 0;
969 1 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, true, &pItem ))
970 0 : pMacItem = (const SvxMacroItem *)pItem;
971 :
972 1 : if( pURLItem || pMacItem )
973 : {
974 0 : OUString aMapURL;
975 0 : OUString aName;
976 0 : OUString aTarget;
977 0 : if( pURLItem )
978 : {
979 0 : aMapURL = pURLItem->GetURL();
980 0 : aName = pURLItem->GetName();
981 0 : aTarget = pURLItem->GetTargetFrameName();
982 : }
983 0 : sal_Bool bEvents = pMacItem && !pMacItem->GetMacroTable().empty();
984 :
985 0 : if( !aMapURL.isEmpty() || !aName.isEmpty() || !aTarget.isEmpty() || bEvents )
986 : {
987 0 : sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_anchor);
988 :
989 : // Ein HREF nur Ausgaben, wenn es einen Link oder Makros gibt
990 0 : if( !aMapURL.isEmpty() || bEvents )
991 : {
992 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_href).
993 0 : append("=\"");
994 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
995 0 : rHTMLWrt.OutHyperlinkHRefValue( aMapURL );
996 0 : sOut.append('\"');
997 : }
998 :
999 0 : if( !aName.isEmpty() )
1000 : {
1001 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_name).
1002 0 : append("=\"");
1003 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1004 0 : HTMLOutFuncs::Out_String( rWrt.Strm(), aName,
1005 0 : rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1006 0 : sOut.append('\"');
1007 : }
1008 :
1009 0 : if( !aTarget.isEmpty() )
1010 : {
1011 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_target).
1012 0 : append("=\"");
1013 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1014 0 : HTMLOutFuncs::Out_String( rWrt.Strm(), aTarget,
1015 0 : rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1016 0 : sOut.append('\"');
1017 : }
1018 :
1019 0 : if (!sOut.isEmpty())
1020 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1021 :
1022 0 : if( pMacItem )
1023 : {
1024 0 : const SvxMacroTableDtor& rMacTable = pMacItem->GetMacroTable();
1025 0 : if( !rMacTable.empty() )
1026 0 : HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable,
1027 : aAnchorEventTable,
1028 : rHTMLWrt.bCfgStarBasic,
1029 : rHTMLWrt.eDestEnc,
1030 0 : &rHTMLWrt.aNonConvertableCharacters );
1031 : }
1032 :
1033 0 : rWrt.Strm().WriteCharPtr( ">" );
1034 0 : aEndTags = OStringBuffer().append("</").
1035 0 : append(OOO_STRING_SVTOOLS_HTML_anchor).
1036 0 : append(">").append(aEndTags).
1037 0 : makeStringAndClear();
1038 0 : }
1039 : }
1040 :
1041 : // Umrandung -> <FONT COLOR = ...>...<IMG ... >...</FONT>
1042 1 : sal_uInt16 nBorderWidth = 0;
1043 2 : if( (nFrmOpts & HTML_FRMOPT_BORDER) &&
1044 1 : SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, true, &pItem ))
1045 : {
1046 1 : Size aTwipBorder( 0, 0 );
1047 1 : const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
1048 :
1049 1 : const ::editeng::SvxBorderLine *pColBorderLine = 0;
1050 1 : const ::editeng::SvxBorderLine *pBorderLine = pBoxItem->GetLeft();
1051 1 : if( pBorderLine )
1052 : {
1053 0 : pColBorderLine = pBorderLine;
1054 0 : aTwipBorder.Width() += pBorderLine->GetOutWidth();
1055 : }
1056 :
1057 1 : pBorderLine = pBoxItem->GetRight();
1058 1 : if( pBorderLine )
1059 : {
1060 0 : pColBorderLine = pBorderLine;
1061 0 : aTwipBorder.Width() += pBorderLine->GetOutWidth();
1062 : }
1063 :
1064 1 : pBorderLine = pBoxItem->GetTop();
1065 1 : if( pBorderLine )
1066 : {
1067 0 : pColBorderLine = pBorderLine;
1068 0 : aTwipBorder.Height() += pBorderLine->GetOutWidth();
1069 : }
1070 :
1071 1 : pBorderLine = pBoxItem->GetBottom();
1072 1 : if( pBorderLine )
1073 : {
1074 0 : pColBorderLine = pBorderLine;
1075 0 : aTwipBorder.Height() += pBorderLine->GetOutWidth();
1076 : }
1077 :
1078 1 : aTwipBorder.Width() /= 2;
1079 1 : aTwipBorder.Height() /= 2;
1080 :
1081 1 : if( (aTwipBorder.Width() || aTwipBorder.Height()) &&
1082 0 : Application::GetDefaultDevice() )
1083 : {
1084 : Size aPixelBorder =
1085 : Application::GetDefaultDevice()->LogicToPixel( aTwipBorder,
1086 0 : MapMode(MAP_TWIP) );
1087 0 : if( !aPixelBorder.Width() && aTwipBorder.Width() )
1088 0 : aPixelBorder.Width() = 1;
1089 0 : if( !aPixelBorder.Height() && aTwipBorder.Height() )
1090 0 : aPixelBorder.Height() = 1;
1091 :
1092 0 : if( aPixelBorder.Width() )
1093 0 : aPixelBorder.Height() = 0;
1094 :
1095 : nBorderWidth =
1096 0 : (sal_uInt16)(aPixelBorder.Width() + aPixelBorder.Height());
1097 : }
1098 :
1099 1 : if( pColBorderLine )
1100 : {
1101 0 : sOut.append('<');
1102 0 : sOut.append(OOO_STRING_SVTOOLS_HTML_font).append(' ').
1103 0 : append(OOO_STRING_SVTOOLS_HTML_O_color).append("=");
1104 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1105 0 : HTMLOutFuncs::Out_Color( rWrt.Strm(),
1106 0 : pColBorderLine->GetColor(), rHTMLWrt.eDestEnc ).WriteChar( '>' );
1107 :
1108 0 : aEndTags = OStringBuffer().
1109 0 : append("</").
1110 0 : append(OOO_STRING_SVTOOLS_HTML_font).
1111 0 : append('>').append(aEndTags).makeStringAndClear();
1112 : }
1113 : }
1114 :
1115 1 : sOut.append('<');
1116 1 : sOut.append(OOO_STRING_SVTOOLS_HTML_image).append(' ').
1117 1 : append(OOO_STRING_SVTOOLS_HTML_O_src).
1118 1 : append("=\"").append(OOO_STRING_SVTOOLS_HTML_O_data).append(":");
1119 1 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1120 :
1121 2 : OUString aGraphicInBase64;
1122 1 : sal_uLong nErr = XOutBitmap::GraphicToBase64(rGraphic, aGraphicInBase64);
1123 1 : if( nErr )
1124 : {
1125 0 : rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
1126 : }
1127 1 : HTMLOutFuncs::Out_String( rWrt.Strm(), aGraphicInBase64, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ).WriteChar( '\"' );
1128 :
1129 : // Events
1130 1 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, true, &pItem ))
1131 : {
1132 : const SvxMacroTableDtor& rMacTable =
1133 0 : ((const SvxMacroItem *)pItem)->GetMacroTable();
1134 0 : if( !rMacTable.empty() )
1135 0 : HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable, aImageEventTable,
1136 : rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc,
1137 0 : &rHTMLWrt.aNonConvertableCharacters );
1138 : }
1139 :
1140 : // ALT, ALIGN, WIDTH, HEIGHT, HSPACE, VSPACE
1141 1 : aEndTags = rHTMLWrt.OutFrmFmtOptions( rFrmFmt, rAlternateTxt, nFrmOpts, aEndTags );
1142 1 : if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) )
1143 1 : rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmOpts );
1144 :
1145 1 : if( nFrmOpts & HTML_FRMOPT_BORDER )
1146 : {
1147 1 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_border).
1148 2 : append("=\"").append(static_cast<sal_Int32>(nBorderWidth)).append("\"");
1149 1 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1150 : }
1151 :
1152 1 : if( pURLItem && pURLItem->IsServerMap() )
1153 : {
1154 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_ismap);
1155 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1156 : }
1157 1 : if( !aIMapName.isEmpty() )
1158 : {
1159 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_usemap).
1160 0 : append("=\"#");
1161 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1162 0 : HTMLOutFuncs::Out_String( rWrt.Strm(), aIMapName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ).WriteChar( '\"' );
1163 : }
1164 :
1165 1 : rHTMLWrt.Strm().WriteChar( '>' );
1166 :
1167 1 : if( !aEndTags.isEmpty() )
1168 0 : rWrt.Strm().WriteCharPtr( aEndTags.getStr() );
1169 :
1170 1 : if( !rHTMLWrt.aINetFmts.empty() )
1171 : {
1172 : // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
1173 : // werden muss
1174 0 : SwFmtINetFmt *pINetFmt = rHTMLWrt.aINetFmts.back();
1175 0 : OutHTML_INetFmt( rWrt, *pINetFmt, sal_True );
1176 : }
1177 :
1178 2 : return rHTMLWrt;
1179 : }
1180 :
1181 0 : Writer& OutHTML_BulletImage( Writer& rWrt,
1182 : const sal_Char *pTag,
1183 : const SvxBrushItem* pBrush )
1184 : {
1185 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1186 :
1187 0 : OUString aGraphicInBase64;
1188 0 : if( pBrush )
1189 : {
1190 0 : const Graphic* pGrf = pBrush->GetGraphic();
1191 0 : if( pGrf )
1192 : {
1193 0 : sal_uLong nErr = XOutBitmap::GraphicToBase64(*pGrf, aGraphicInBase64);
1194 0 : if( nErr )
1195 : {
1196 0 : rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
1197 : }
1198 : }
1199 : }
1200 :
1201 0 : OStringBuffer sOut;
1202 0 : if( pTag )
1203 0 : sOut.append('<').append(pTag);
1204 :
1205 0 : sOut.append(' ');
1206 0 : sOut.append(OOO_STRING_SVTOOLS_HTML_O_style).append("=\"").
1207 0 : append("list-style-image: ").append("url(").
1208 0 : append(OOO_STRING_SVTOOLS_HTML_O_data).append(":");
1209 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1210 0 : HTMLOutFuncs::Out_String( rWrt.Strm(), aGraphicInBase64, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1211 0 : sOut.append(");").append('\"');
1212 :
1213 0 : if (pTag)
1214 0 : sOut.append('>');
1215 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1216 :
1217 0 : return rWrt;
1218 : }
1219 :
1220 0 : static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt )
1221 : {
1222 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1223 :
1224 0 : const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1225 0 : sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
1226 0 : sal_uLong nEnd = rHTMLWrt.pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
1227 :
1228 0 : OUString aCaption;
1229 0 : sal_Bool bTopCaption = sal_False;
1230 :
1231 : // Nicht const, weil GetTable spater mal nicht const ist
1232 0 : SwNode *pNd = rHTMLWrt.pDoc->GetNodes()[ nStt ];
1233 0 : SwTableNode *pTblNd = pNd->GetTableNode();
1234 0 : const SwTxtNode *pTxtNd = pNd->GetTxtNode();
1235 0 : if( !pTblNd && pTxtNd )
1236 : {
1237 : // Tabelle mit Ueberschrift
1238 0 : bTopCaption = sal_True;
1239 0 : pTblNd = rHTMLWrt.pDoc->GetNodes()[nStt+1]->GetTableNode();
1240 : }
1241 : OSL_ENSURE( pTblNd, "Rahmen enthaelt keine Tabelle" );
1242 0 : if( pTblNd )
1243 : {
1244 0 : sal_uLong nTblEnd = pTblNd->EndOfSectionIndex();
1245 : OSL_ENSURE( nTblEnd == nEnd - 1 ||
1246 : (nTblEnd == nEnd - 2 && !bTopCaption),
1247 : "Ungeuelter Rahmen-Inhalt fuer Tabelle" );
1248 :
1249 0 : if( nTblEnd == nEnd - 2 )
1250 0 : pTxtNd = rHTMLWrt.pDoc->GetNodes()[nTblEnd+1]->GetTxtNode();
1251 : }
1252 0 : if( pTxtNd )
1253 0 : aCaption = pTxtNd->GetTxt();
1254 :
1255 0 : if( pTblNd )
1256 : {
1257 0 : HTMLSaveData aSaveData( rHTMLWrt, pTblNd->GetIndex()+1,
1258 : pTblNd->EndOfSectionIndex(),
1259 0 : sal_True, &rFrmFmt );
1260 0 : rHTMLWrt.bOutFlyFrame = sal_True;
1261 : OutHTML_SwTblNode( rHTMLWrt, *pTblNd, &rFrmFmt, &aCaption,
1262 0 : bTopCaption );
1263 : }
1264 :
1265 0 : return rWrt;
1266 : }
1267 :
1268 0 : static Writer & OutHTML_FrmFmtAsMulticol( Writer& rWrt,
1269 : const SwFrmFmt& rFrmFmt,
1270 : sal_Bool bInCntnr )
1271 : {
1272 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1273 :
1274 0 : rHTMLWrt.ChangeParaToken( 0 );
1275 :
1276 : // Die aktulle <DL> beenden!
1277 0 : rHTMLWrt.OutAndSetDefList( 0 );
1278 :
1279 : // als Multicol ausgeben
1280 0 : if( rHTMLWrt.bLFPossible )
1281 0 : rHTMLWrt.OutNewLine();
1282 :
1283 0 : OStringBuffer sOut;
1284 0 : sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_multicol);
1285 :
1286 0 : const SwFmtCol& rFmtCol = rFrmFmt.GetCol();
1287 :
1288 : // die Anzahl der Spalten als COLS ausgeben
1289 0 : sal_uInt16 nCols = rFmtCol.GetNumCols();
1290 0 : if( nCols )
1291 : {
1292 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cols).
1293 0 : append("=\"").append(static_cast<sal_Int32>(nCols)).append("\"");
1294 : }
1295 :
1296 : // die Gutter-Breite (Minimalwert) als GUTTER
1297 0 : sal_uInt16 nGutter = rFmtCol.GetGutterWidth( sal_True );
1298 0 : if( nGutter!=USHRT_MAX )
1299 : {
1300 0 : if( nGutter && Application::GetDefaultDevice() )
1301 : {
1302 : nGutter = (sal_uInt16)Application::GetDefaultDevice()
1303 : ->LogicToPixel( Size(nGutter,0),
1304 0 : MapMode(MAP_TWIP) ).Width();
1305 : }
1306 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_gutter).
1307 0 : append("=\"").append(static_cast<sal_Int32>(nGutter)).append("\"");
1308 : }
1309 :
1310 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1311 :
1312 : // WIDTH
1313 : sal_uLong nFrmFlags = bInCntnr ? HTML_FRMOPTS_MULTICOL_CNTNR
1314 0 : : HTML_FRMOPTS_MULTICOL;
1315 0 : if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1316 0 : nFrmFlags |= HTML_FRMOPTS_MULTICOL_CSS1;
1317 0 : rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyOUStr, nFrmFlags );
1318 0 : if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1319 0 : rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
1320 :
1321 0 : rWrt.Strm().WriteChar( '>' );
1322 :
1323 0 : rHTMLWrt.bLFPossible = sal_True;
1324 0 : rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
1325 :
1326 0 : const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1327 0 : sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
1328 0 : const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
1329 : OSL_ENSURE( pSttNd, "Wo ist der Start-Node" );
1330 :
1331 : {
1332 : // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
1333 : // wieder hergestellt wird.
1334 : HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
1335 : pSttNd->EndOfSectionIndex(),
1336 0 : sal_True, &rFrmFmt );
1337 0 : rHTMLWrt.bOutFlyFrame = sal_True;
1338 0 : rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
1339 : }
1340 :
1341 0 : rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
1342 0 : if( rHTMLWrt.bLFPossible )
1343 0 : rHTMLWrt.OutNewLine();
1344 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_multicol, false );
1345 0 : rHTMLWrt.bLFPossible = sal_True;
1346 :
1347 0 : return rWrt;
1348 : }
1349 :
1350 0 : static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFrmFmt )
1351 : {
1352 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1353 :
1354 : // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
1355 0 : if( rHTMLWrt.bLFPossible )
1356 0 : rHTMLWrt.OutNewLine( sal_True );
1357 :
1358 0 : OStringBuffer sOut;
1359 0 : sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_spacer).append(' ')
1360 0 : .append(OOO_STRING_SVTOOLS_HTML_O_type).append("=\"")
1361 0 : .append(OOO_STRING_SVTOOLS_HTML_SPTYPE_block).append("\"");
1362 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1363 :
1364 : // ALIGN, WIDTH, HEIGHT
1365 0 : OString aEndTags = rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyOUStr, HTML_FRMOPTS_SPACER );
1366 :
1367 0 : rWrt.Strm().WriteChar( '>' );
1368 0 : if( !aEndTags.isEmpty() )
1369 0 : rWrt.Strm().WriteCharPtr( aEndTags.getStr() );
1370 :
1371 0 : return rWrt;
1372 : }
1373 :
1374 0 : static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
1375 : const SwFrmFmt& rFrmFmt, sal_Bool bSpan)
1376 : {
1377 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1378 :
1379 0 : const sal_Char *pStr = 0;
1380 0 : if( !bSpan )
1381 : {
1382 0 : rHTMLWrt.ChangeParaToken( 0 );
1383 :
1384 : // Die aktulle <DL> beenden!
1385 0 : rHTMLWrt.OutAndSetDefList( 0 );
1386 0 : pStr = OOO_STRING_SVTOOLS_HTML_division;
1387 : }
1388 : else
1389 0 : pStr = OOO_STRING_SVTOOLS_HTML_span;
1390 :
1391 : // als DIV ausgeben
1392 0 : if( rHTMLWrt.bLFPossible )
1393 0 : rHTMLWrt.OutNewLine();
1394 :
1395 0 : OStringBuffer sOut;
1396 0 : sOut.append('<').append(pStr);
1397 :
1398 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
1399 0 : sal_uLong nFrmFlags = HTML_FRMOPTS_DIV;
1400 0 : if( rHTMLWrt.IsHTMLMode( HTMLMODE_BORDER_NONE ) )
1401 0 : nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
1402 0 : OString aEndTags = rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyOUStr, nFrmFlags );
1403 0 : rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
1404 0 : rWrt.Strm().WriteChar( '>' );
1405 :
1406 0 : rHTMLWrt.IncIndentLevel(); // den Inhalt einruecken
1407 0 : rHTMLWrt.bLFPossible = sal_True;
1408 :
1409 0 : const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1410 0 : sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
1411 :
1412 : // Am Start-Node verankerte Rahmen-gebundene Rahmen ausgeben
1413 0 : rHTMLWrt.OutFlyFrm( nStt, 0, HTML_POS_ANY );
1414 :
1415 0 : const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
1416 : OSL_ENSURE( pSttNd, "Wo ist der Start-Node" );
1417 :
1418 : {
1419 : // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
1420 : // wieder hergestellt wird.
1421 : HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
1422 : pSttNd->EndOfSectionIndex(),
1423 0 : sal_True, &rFrmFmt );
1424 0 : rHTMLWrt.bOutFlyFrame = sal_True;
1425 0 : rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
1426 : }
1427 :
1428 0 : rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
1429 0 : if( rHTMLWrt.bLFPossible )
1430 0 : rHTMLWrt.OutNewLine();
1431 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, false );
1432 :
1433 0 : if( !aEndTags.isEmpty() )
1434 0 : rWrt.Strm().WriteCharPtr( aEndTags.getStr() );
1435 :
1436 0 : return rWrt;
1437 : }
1438 :
1439 0 : static Writer & OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1440 : sal_Bool /*bInCntnr*/ )
1441 : {
1442 0 : SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1443 :
1444 0 : if (rHTMLWrt.mbSkipImages)
1445 0 : return rWrt;
1446 :
1447 0 : ImageMap aIMap;
1448 0 : Graphic aGraphic( ((SwFrmFmt &)rFrmFmt).MakeGraphic( &aIMap ) );
1449 0 : Size aSz( 0, 0 );
1450 : OutHTML_Image( rWrt, rFrmFmt, aGraphic, rFrmFmt.GetName(), aSz,
1451 : HTML_FRMOPTS_GENIMG, "frame",
1452 0 : aIMap.GetIMapObjectCount() ? &aIMap : 0 );
1453 :
1454 0 : return rWrt;
1455 : }
1456 :
1457 2 : static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1458 : sal_Bool bInCntnr )
1459 : {
1460 2 : SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1461 :
1462 2 : if (rHTMLWrt.mbSkipImages)
1463 1 : return rWrt;
1464 :
1465 1 : const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1466 1 : sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
1467 1 : SwGrfNode *pGrfNd = rHTMLWrt.pDoc->GetNodes()[ nStt ]->GetGrfNode();
1468 : OSL_ENSURE( pGrfNd, "Grf-Node erwartet" );
1469 1 : if( !pGrfNd )
1470 0 : return rWrt;
1471 :
1472 1 : sal_uLong nFrmFlags = bInCntnr ? HTML_FRMOPTS_IMG_CNTNR : HTML_FRMOPTS_IMG;
1473 1 : if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1474 1 : nFrmFlags |= HTML_FRMOPTS_IMG_CSS1;
1475 :
1476 1 : Graphic aGraphic = pGrfNd->GetGraphic();
1477 : OutHTML_Image( rWrt, rFrmFmt, aGraphic, pGrfNd->GetTitle(),
1478 1 : pGrfNd->GetTwipSize(), nFrmFlags, "graphic" );
1479 :
1480 1 : return rWrt;
1481 : }
1482 :
1483 0 : static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1484 : const SdrObject& rSdrObj )
1485 : {
1486 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1487 :
1488 : // die Edit-Engine-Attribute des Objekts als SW-Attribute holen
1489 : // und als Hints einsortieren
1490 0 : const SfxItemSet& rFmtItemSet = rFrmFmt.GetAttrSet();
1491 0 : SfxItemSet aItemSet( *rFmtItemSet.GetPool(), RES_CHRATR_BEGIN,
1492 0 : RES_CHRATR_END );
1493 0 : SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, &rSdrObj, sal_True );
1494 0 : sal_Bool bCfgOutStylesOld = rHTMLWrt.bCfgOutStyles;
1495 0 : rHTMLWrt.bCfgOutStyles = sal_False;
1496 0 : rHTMLWrt.bTxtAttr = sal_True;
1497 0 : rHTMLWrt.bTagOn = sal_True;
1498 0 : Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, sal_False );
1499 0 : rHTMLWrt.bTxtAttr = sal_False;
1500 :
1501 : OutHTML_DrawFrmFmtAsMarquee( rHTMLWrt,
1502 : (const SwDrawFrmFmt &)rFrmFmt,
1503 0 : rSdrObj );
1504 0 : rHTMLWrt.bTxtAttr = sal_True;
1505 0 : rHTMLWrt.bTagOn = sal_False;
1506 0 : Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, sal_False );
1507 0 : rHTMLWrt.bTxtAttr = sal_False;
1508 0 : rHTMLWrt.bCfgOutStyles = bCfgOutStylesOld;
1509 :
1510 0 : return rWrt;
1511 : }
1512 :
1513 0 : Writer& OutHTML_HeaderFooter( Writer& rWrt, const SwFrmFmt& rFrmFmt,
1514 : sal_Bool bHeader )
1515 : {
1516 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1517 :
1518 : // als Multicol ausgeben
1519 0 : rHTMLWrt.OutNewLine();
1520 0 : OStringBuffer sOut;
1521 0 : sOut.append(OOO_STRING_SVTOOLS_HTML_division).append(' ')
1522 0 : .append(OOO_STRING_SVTOOLS_HTML_O_title).append("=\"")
1523 0 : .append( bHeader ? "header" : "footer" ).append("\"");
1524 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.makeStringAndClear().getStr() );
1525 :
1526 0 : rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
1527 :
1528 : // Einen Spacer fuer den Absatnd zusammenbasteln. Da durch das
1529 : // <DL> bzw. </DL> immer einer Absatz-Abstand entsteht, wird der
1530 : // ggf. abgezogen.
1531 0 : const SvxULSpaceItem& rULSpace = rFrmFmt.GetULSpace();
1532 0 : sal_uInt16 nSize = bHeader ? rULSpace.GetLower() : rULSpace.GetUpper();
1533 0 : rHTMLWrt.nHeaderFooterSpace = nSize;
1534 :
1535 0 : OString aSpacer;
1536 0 : if( rHTMLWrt.IsHTMLMode(HTMLMODE_VERT_SPACER) &&
1537 0 : nSize > HTML_PARSPACE && Application::GetDefaultDevice() )
1538 : {
1539 0 : nSize -= HTML_PARSPACE;
1540 : nSize = (sal_Int16)Application::GetDefaultDevice()
1541 0 : ->LogicToPixel( Size(nSize,0), MapMode(MAP_TWIP) ).Width();
1542 :
1543 0 : aSpacer = OStringBuffer(OOO_STRING_SVTOOLS_HTML_spacer).
1544 0 : append(' ').append(OOO_STRING_SVTOOLS_HTML_O_type).
1545 0 : append("=\"").append(OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical).append("\"").
1546 0 : append(' ').append(OOO_STRING_SVTOOLS_HTML_O_size).
1547 0 : append("=\"").append(static_cast<sal_Int32>(nSize)).append("\"").
1548 0 : makeStringAndClear();
1549 : }
1550 :
1551 0 : const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
1552 0 : sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
1553 0 : const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
1554 : OSL_ENSURE( pSttNd, "Wo ist der Start-Node" );
1555 :
1556 0 : if( !bHeader && !aSpacer.isEmpty() )
1557 : {
1558 0 : rHTMLWrt.OutNewLine();
1559 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.getStr() );
1560 : }
1561 :
1562 : {
1563 : // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
1564 : // wieder hergestellt wird. pFlyFmt braucht hier nicht gestzt zu
1565 : // werden, denn PageDesc-Attribute koennen hier nicht vorkommen
1566 : HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
1567 0 : pSttNd->EndOfSectionIndex() );
1568 :
1569 0 : if( bHeader )
1570 0 : rHTMLWrt.bOutHeader = sal_True;
1571 : else
1572 0 : rHTMLWrt.bOutFooter = sal_True;
1573 :
1574 0 : rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
1575 : }
1576 :
1577 0 : if( bHeader && !aSpacer.isEmpty() )
1578 : {
1579 0 : rHTMLWrt.OutNewLine();
1580 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.getStr() );
1581 : }
1582 :
1583 0 : rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
1584 0 : rHTMLWrt.OutNewLine();
1585 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_division, false );
1586 :
1587 0 : rHTMLWrt.nHeaderFooterSpace = 0;
1588 :
1589 0 : return rWrt;
1590 : }
1591 :
1592 0 : void SwHTMLWriter::AddLinkTarget( const OUString& rURL )
1593 : {
1594 0 : if( rURL.isEmpty() || rURL[0] != '#' )
1595 0 : return;
1596 :
1597 : // There might be a '|' as delimiter (if the link has been inserted
1598 : // freshly) or a '%7c' or a '%7C' if the document has been saved and
1599 : // loaded already.
1600 0 : sal_Int32 nPos = rURL.getLength();
1601 0 : sal_Bool bFound = sal_False, bEncoded = sal_False;
1602 0 : while( !bFound && nPos > 0 )
1603 : {
1604 0 : sal_Unicode c = rURL[ --nPos ];
1605 0 : switch( c )
1606 : {
1607 : case cMarkSeparator:
1608 0 : bFound = sal_True;
1609 0 : break;
1610 : case '%':
1611 0 : bFound = (rURL.getLength() - nPos) >=3 &&
1612 0 : rURL[ nPos+1 ] == '7' &&
1613 0 : ((c =rURL[ nPos+2 ]) == 'C' || c == 'c');
1614 0 : if( bFound )
1615 0 : bEncoded = sal_True;
1616 : }
1617 : }
1618 0 : if( !bFound || nPos < 2 ) // mindetsens "#a|..."
1619 0 : return;
1620 :
1621 0 : OUString aURL( rURL.copy( 1 ) );
1622 :
1623 : // nPos-1+1/3 (-1 wg. Erase)
1624 : OUString sCmp(comphelper::string::remove(aURL.copy(bEncoded ? nPos+2 : nPos),
1625 0 : ' '));
1626 0 : if( sCmp.isEmpty() )
1627 0 : return;
1628 :
1629 0 : sCmp = sCmp.toAsciiLowerCase();
1630 :
1631 0 : if( sCmp == "region" ||
1632 0 : sCmp == "frame" ||
1633 0 : sCmp == "graphic" ||
1634 0 : sCmp == "ole" ||
1635 0 : sCmp == "table" )
1636 : {
1637 : // Einfach nur in einem sortierten Array merken
1638 0 : if( bEncoded )
1639 : {
1640 0 : aURL = aURL.replaceAt( nPos - 1, 3, OUString(cMarkSeparator) );
1641 : }
1642 0 : aImplicitMarks.insert( aURL );
1643 : }
1644 0 : else if( sCmp == "outline" )
1645 : {
1646 : // Hier brauchen wir Position und Name. Deshalb sortieren wir
1647 : // ein sal_uInt16 und ein String-Array selbst
1648 0 : OUString aOutline( aURL.copy( 0, nPos-1 ) );
1649 0 : SwPosition aPos( *pCurPam->GetPoint() );
1650 0 : if( pDoc->GotoOutline( aPos, aOutline ) )
1651 : {
1652 0 : sal_uInt32 nIdx = aPos.nNode.GetIndex();
1653 :
1654 0 : sal_uInt32 nIns=0;
1655 0 : while( nIns < aOutlineMarkPoss.size() &&
1656 0 : aOutlineMarkPoss[nIns] < nIdx )
1657 0 : nIns++;
1658 :
1659 0 : aOutlineMarkPoss.insert( aOutlineMarkPoss.begin()+nIns, nIdx );
1660 0 : if( bEncoded )
1661 : {
1662 0 : aURL = aURL.replaceAt( nPos - 1, 3, OUString(cMarkSeparator) );
1663 : }
1664 0 : aOutlineMarks.insert( aOutlineMarks.begin()+nIns, aURL );
1665 0 : }
1666 : }
1667 0 : else if( sCmp == "text" )
1668 : {
1669 :
1670 0 : }
1671 : }
1672 :
1673 5 : void SwHTMLWriter::CollectLinkTargets()
1674 : {
1675 : const SwFmtINetFmt* pINetFmt;
1676 : const SwTxtINetFmt* pTxtAttr;
1677 : const SwTxtNode* pTxtNd;
1678 :
1679 5 : sal_uInt32 n, nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
1680 5 : for( n = 0; n < nMaxItems; ++n )
1681 : {
1682 0 : if( 0 != (pINetFmt = (SwFmtINetFmt*)pDoc->GetAttrPool().GetItem2(
1683 0 : RES_TXTATR_INETFMT, n ) ) &&
1684 0 : 0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) &&
1685 0 : 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
1686 0 : pTxtNd->GetNodes().IsDocNodes() )
1687 : {
1688 0 : AddLinkTarget( pINetFmt->GetValue() );
1689 : }
1690 : }
1691 :
1692 : const SwFmtURL *pURL;
1693 5 : nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_URL );
1694 5 : for( n = 0; n < nMaxItems; ++n )
1695 : {
1696 0 : if( 0 != (pURL = (SwFmtURL*)pDoc->GetAttrPool().GetItem2(
1697 0 : RES_URL, n ) ) )
1698 : {
1699 0 : AddLinkTarget( pURL->GetURL() );
1700 0 : const ImageMap *pIMap = pURL->GetMap();
1701 0 : if( pIMap )
1702 : {
1703 0 : for( sal_uInt16 i=0; i<pIMap->GetIMapObjectCount(); i++ )
1704 : {
1705 0 : const IMapObject* pObj = pIMap->GetIMapObject( i );
1706 0 : if( pObj )
1707 : {
1708 0 : AddLinkTarget( pObj->GetURL() );
1709 : }
1710 : }
1711 : }
1712 : }
1713 : }
1714 5 : }
1715 :
1716 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|