LibreOffice Module sw (master) 1
htmlflywriter.cxx
Go to the documentation of this file.
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 <com/sun/star/beans/XPropertySet.hpp>
24#include <hintids.hxx>
25#include <tools/fract.hxx>
26#include <svl/urihelper.hxx>
27#include <vcl/svapp.hxx>
28#include <sfx2/event.hxx>
29#include <svtools/htmlkywd.hxx>
30#include <svtools/htmlout.hxx>
31#include <svtools/htmltokn.h>
32#include <vcl/imap.hxx>
33#include <vcl/imapobj.hxx>
34#include <svtools/htmlcfg.hxx>
36#include <svx/svdouno.hxx>
37#include <svx/xoutbmp.hxx>
38#include <editeng/boxitem.hxx>
39#include <editeng/lrspitem.hxx>
40#include <editeng/ulspitem.hxx>
41#include <editeng/brushitem.hxx>
42#include <sal/log.hxx>
43#include <osl/diagnose.h>
44#include <svx/svdograf.hxx>
45
46#include <fmtanchr.hxx>
47#include <fmtornt.hxx>
48#include <fmturl.hxx>
49#include <fmtfsize.hxx>
50#include <fmtclds.hxx>
51#include <fmtcntnt.hxx>
52#include <fmtsrnd.hxx>
53#include <fmtinfmt.hxx>
54#include <txtinet.hxx>
55#include <frmatr.hxx>
56#include <grfatr.hxx>
57#include <flypos.hxx>
58#include <ndgrf.hxx>
59
60#include <doc.hxx>
61#include <ndtxt.hxx>
62#include <pam.hxx>
63#include <swerror.h>
64#include <frmfmt.hxx>
65#include "wrthtml.hxx"
66#include "htmlatr.hxx"
67#include "htmlfly.hxx"
68#include "htmlreqifreader.hxx"
69
70using namespace css;
71
89
101
108
115
123
131
132static SwHTMLWriter& OutHTML_FrameFormatTableNode( SwHTMLWriter& rWrt, const SwFrameFormat& rFrameFormat );
134 bool bInCntnr );
137 const SwFrameFormat& rFrameFormat, bool bSpan );
138static SwHTMLWriter& OutHTML_FrameFormatAsImage( SwHTMLWriter& rWrt, const SwFrameFormat& rFormat, bool bPNGFallback );
139
141 bool bInCntnr, bool bPNGFallback );
142
143static SwHTMLWriter& OutHTML_FrameFormatAsMarquee( SwHTMLWriter& rWrt, const SwFrameFormat& rFrameFormat,
144 const SdrObject& rSdrObj );
145
147{
148 { OOO_STRING_SVTOOLS_HTML_O_SDonload, OOO_STRING_SVTOOLS_HTML_O_onload, SvMacroItemId::OnImageLoadDone },
149 { OOO_STRING_SVTOOLS_HTML_O_SDonabort, OOO_STRING_SVTOOLS_HTML_O_onabort, SvMacroItemId::OnImageLoadCancel },
151 { nullptr, nullptr, SvMacroItemId::NONE }
152};
153
155{
158 { nullptr, nullptr, SvMacroItemId::NONE }
159};
160
161sal_uInt16 SwHTMLWriter::GuessFrameType( const SwFrameFormat& rFrameFormat,
162 const SdrObject*& rpSdrObj )
163{
165
166 if( RES_DRAWFRMFMT == rFrameFormat.Which() )
167 {
168 // use an arbitrary draw object as the default value
170
171 const SdrObject *pObj =
172 SwHTMLWriter::GetMarqueeTextObj( static_cast<const SwDrawFrameFormat &>(rFrameFormat) );
173 if( pObj )
174 {
175 // scrolling text
176 rpSdrObj = pObj;
178 }
179 else
180 {
181 pObj = GetHTMLControl( static_cast<const SwDrawFrameFormat &>(rFrameFormat) );
182
183 if( pObj )
184 {
185 // Form control
186 rpSdrObj = pObj;
188 }
189 }
190 }
191 else
192 {
193 // use a text frame as the default value
195
196 const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
197 SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex()+1;
198 const SwNode* pNd = m_pDoc->GetNodes()[ nStt ];
199
200 if( pNd->IsGrfNode() )
201 {
202 // graphic node
204 }
205 else if( pNd->IsOLENode() )
206 {
207 // applet, plugin, floating frame
208 eType = static_cast<SwHTMLFrameType>(GuessOLENodeFrameType( *pNd ));
209 }
210 else
211 {
212 SwNodeOffset nEnd = m_pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
213
214 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
215 const SwFormatCol* pFormatCol = rItemSet.GetItemIfSet( RES_COL );
216 if( pFormatCol && pFormatCol->GetNumCols() > 1 )
217 {
218 // frame with columns
220 }
221 else if( pNd->IsTableNode() )
222 {
223 const SwTableNode *pTableNd = pNd->GetTableNode();
224 SwNodeOffset nTableEnd = pTableNd->EndOfSectionIndex();
225
226 if( nTableEnd+1 == nEnd )
227 {
228 // table
230 }
231 else if( nTableEnd+2 == nEnd )
232 {
233 // table with caption
235 }
236 }
237 else if( pNd->IsTextNode() )
238 {
239 const SwTextNode *pTextNd = pNd->GetTextNode();
240
241 bool bEmpty = false;
242 if( nStt==nEnd-1 && !pTextNd->Len() )
243 {
244 // empty frame? Only if no frame is
245 // anchored to the text or start node.
246 bEmpty = true;
247 for( auto & pHTMLPosFlyFrame : m_aHTMLPosFlyFrames )
248 {
249 SwNodeOffset nIdx = pHTMLPosFlyFrame->GetNdIndex().GetIndex();
250 bEmpty = (nIdx != nStt) && (nIdx != nStt-1);
251 if( !bEmpty || nIdx > nStt )
252 break;
253 }
254 }
255 if( bEmpty )
256 {
257 std::unique_ptr<SvxBrushItem> aBrush = rFrameFormat.makeBackgroundBrushItem();
260 if( GPOS_NONE != aBrush->GetGraphicPos() ||
261 aBrush->GetColor() != COL_TRANSPARENT )
262 {
263 bEmpty = false;
264 }
265 }
266 if( bEmpty )
267 {
268 // empty frame
270 }
271 else if( m_pDoc->GetNodes()[nStt+1]->IsTableNode() )
272 {
273 const SwTableNode *pTableNd =
274 m_pDoc->GetNodes()[nStt+1]->GetTableNode();
275 if( pTableNd->EndOfSectionIndex()+1 == nEnd )
276 {
277 // table with heading
279 }
280 }
281 }
282 }
283 }
284
285 return static_cast< sal_uInt16 >(eType);
286}
287
289{
290 OSL_ENSURE( HTML_CFG_MAX+1 == MAX_BROWSERS,
291 "number of browser configurations has changed" );
292
293 SwPosFlyFrames aFlyPos(
294 m_pDoc->GetAllFlyFormats(m_bWriteAll ? nullptr : m_pCurrentPam.get(), true));
295
296 for(const SwPosFlyFrame& rItem : aFlyPos)
297 {
298 const SwFrameFormat& rFrameFormat = rItem.GetFormat();
299 const SdrObject *pSdrObj = nullptr;
300 const SwNode *pAnchorNode;
301 const SwContentNode *pACNd;
302 SwHTMLFrameType eType = static_cast<SwHTMLFrameType>(GuessFrameType( rFrameFormat, pSdrObj ));
303
304 AllHtmlFlags nMode;
305 const SwFormatAnchor& rAnchor = rFrameFormat.GetAnchor();
306 sal_Int16 eHoriRel = rFrameFormat.GetHoriOrient().GetRelationOrient();
307 switch( rAnchor.GetAnchorId() )
308 {
309 case RndStdIds::FLY_AT_PAGE:
310 case RndStdIds::FLY_AT_FLY:
312 break;
313
314 case RndStdIds::FLY_AT_PARA:
315 // frames that are anchored to a paragraph are only placed
316 // before the paragraph, if the paragraph has a
317 // spacing.
318 if( text::RelOrientation::FRAME == eHoriRel &&
319 (pAnchorNode = rAnchor.GetAnchorNode()) != nullptr &&
320 (pACNd = pAnchorNode->GetContentNode()) != nullptr )
321 {
322 const SvxTextLeftMarginItem& rTextLeftMargin =
324 const SvxRightMarginItem& rRightMargin =
326 if (rTextLeftMargin.GetTextLeft() || rRightMargin.GetRight())
327 {
329 break;
330 }
331 }
333 break;
334
335 case RndStdIds::FLY_AT_CHAR:
336 if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
338 else
340 break;
341
342 default:
344 break;
345 }
346
347 m_aHTMLPosFlyFrames.insert( std::make_unique<SwHTMLPosFlyFrame>(rItem, pSdrObj, nMode) );
348 }
349}
350
351bool SwHTMLWriter::OutFlyFrame( SwNodeOffset nNdIdx, sal_Int32 nContentIdx, HtmlPosition nPos )
352{
353 bool bFlysLeft = false; // Are there still Flys left at the current node position?
354
355 // OutFlyFrame can be called recursively. Thus, sometimes it is
356 // necessary to start over after a Fly was returned.
357 bool bRestart = true;
358 while( !m_aHTMLPosFlyFrames.empty() && bRestart )
359 {
360 bFlysLeft = bRestart = false;
361
362 // search for the beginning of the FlyFrames
363 size_t i {0};
364
365 for( ; i < m_aHTMLPosFlyFrames.size() &&
366 m_aHTMLPosFlyFrames[i]->GetNdIndex().GetIndex() < nNdIdx; i++ )
367 ;
368 for( ; !bRestart && i < m_aHTMLPosFlyFrames.size() &&
369 m_aHTMLPosFlyFrames[i]->GetNdIndex().GetIndex() == nNdIdx; i++ )
370 {
371 SwHTMLPosFlyFrame *pPosFly = m_aHTMLPosFlyFrames[i].get();
372 if( ( HtmlPosition::Any == nPos ||
373 pPosFly->GetOutPos() == nPos ) &&
374 pPosFly->GetContentIndex() == nContentIdx )
375 {
376 // It is important to remove it first, because additional
377 // elements or the whole array could be deleted on
378 // deeper recursion levels.
379 std::unique_ptr<SwHTMLPosFlyFrame> flyHolder = m_aHTMLPosFlyFrames.erase_extract(i);
380 i--;
382 {
383 bRestart = true; // not really, only exit the loop
384 }
385
386 HTMLOutFuncs::FlushToAscii(Strm()); // it was one time only; do we still need it?
387
388 OutFrameFormat( pPosFly->GetOutMode(), pPosFly->GetFormat(),
389 pPosFly->GetSdrObject() );
390 switch( pPosFly->GetOutFn() )
391 {
392 case HtmlOut::Div:
393 case HtmlOut::Span:
396 bRestart = true; // It could become recursive here
397 break;
398 default: break;
399 }
400 }
401 else
402 {
403 bFlysLeft = true;
404 }
405 }
406 }
407
408 return bFlysLeft;
409}
410
412 const SdrObject *pSdrObject )
413{
414 HtmlContainerFlags nCntnrMode = nMode.nContainer;
415 HtmlOut nOutMode = nMode.nOut;
416 OString aContainerStr;
417 if( HtmlContainerFlags::NONE != nCntnrMode )
418 {
419
420 if( m_bLFPossible && HtmlContainerFlags::Div == nCntnrMode )
421 OutNewLine();
422
423 OStringBuffer sOut;
424 aContainerStr = (HtmlContainerFlags::Div == nCntnrMode)
427 sOut.append("<" + GetNamespace() + aContainerStr + " "
429 "sd-abs-pos\"");
430 Strm().WriteOString( sOut );
431 sOut.setLength(0);
432
433 // Output a width for non-draw objects
434 HtmlFrmOpts nFrameFlags = HTML_FRMOPTS_CNTNR;
435
436 // For frames with columns we can also output the background
437 if( HtmlOut::MultiCol == nOutMode )
439
441 nFrameFlags |= HtmlFrmOpts::SNoBorder;
442 OutCSS1_FrameFormatOptions( rFrameFormat, nFrameFlags, pSdrObject );
443 Strm().WriteChar( '>' );
444
445 if( HtmlContainerFlags::Div == nCntnrMode )
446 {
448 m_bLFPossible = true;
449 }
450 }
451
452 switch( nOutMode )
453 {
454 case HtmlOut::TableNode: // OK
455 OSL_ENSURE( aContainerStr.isEmpty(), "Table: Container is not supposed to be here" );
456 OutHTML_FrameFormatTableNode( *this, rFrameFormat );
457 break;
458 case HtmlOut::GraphicNode: // OK
459 OutHTML_FrameFormatGrfNode( *this, rFrameFormat, !aContainerStr.isEmpty(), /*bPNGFallback=*/true );
460 break;
461 case HtmlOut::OleNode: // OK
462 OutHTML_FrameFormatOLENode( *this, rFrameFormat, !aContainerStr.isEmpty() );
463 break;
464 case HtmlOut::OleGraphic: // OK
465 OutHTML_FrameFormatOLENodeGrf( *this, rFrameFormat, !aContainerStr.isEmpty() );
466 break;
467 case HtmlOut::Div:
468 case HtmlOut::Span:
469 OSL_ENSURE( aContainerStr.isEmpty(), "Div: Container is not supposed to be here" );
470 OutHTML_FrameFormatAsDivOrSpan( *this, rFrameFormat, HtmlOut::Span==nOutMode );
471 break;
472 case HtmlOut::MultiCol: // OK
473 OutHTML_FrameFormatAsMulticol( *this, rFrameFormat, !aContainerStr.isEmpty() );
474 break;
475 case HtmlOut::Spacer: // OK
476 OSL_ENSURE( aContainerStr.isEmpty(), "Spacer: Container is not supposed to be here" );
477 OutHTML_FrameFormatAsSpacer( *this, rFrameFormat );
478 break;
479 case HtmlOut::Control: // OK
481 static_cast<const SwDrawFrameFormat &>(rFrameFormat), dynamic_cast<const SdrUnoObj&>(*pSdrObject),
482 !aContainerStr.isEmpty() );
483 break;
485 OutHTML_FrameFormatAsMarquee( *this, rFrameFormat, *pSdrObject );
486 break;
487 case HtmlOut::Marquee:
488 OSL_ENSURE( aContainerStr.isEmpty(), "Marquee: Container is not supposed to be here" );
490 static_cast<const SwDrawFrameFormat &>(rFrameFormat), *pSdrObject );
491 break;
493 OutHTML_FrameFormatAsImage( *this, rFrameFormat, /*bPNGFallback=*/true );
494 break;
495 }
496
497 if( HtmlContainerFlags::Div == nCntnrMode )
498 {
500 if( m_bLFPossible )
501 OutNewLine();
503 m_bLFPossible = true;
504 }
505 else if( HtmlContainerFlags::Span == nCntnrMode )
507}
508
510 const OUString& rAlternateText,
511 HtmlFrmOpts nFrameOpts )
512{
513 OString sRetEndTags;
514 OStringBuffer sOut;
515 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
516
517 // Name
518 if( (nFrameOpts & (HtmlFrmOpts::Id|HtmlFrmOpts::Name)) &&
519 !rFrameFormat.GetName().isEmpty() )
520 {
521 const char *pStr =
523 sOut.append(OString::Concat(" ") + pStr + "=\"");
524 Strm().WriteOString( sOut );
525 sOut.setLength(0);
526 HTMLOutFuncs::Out_String( Strm(), rFrameFormat.GetName() );
527 sOut.append('\"');
528 }
529
530 // Name
531 if( nFrameOpts & HtmlFrmOpts::Dir )
532 {
533 SvxFrameDirection nDir = GetHTMLDirection( rItemSet );
534 Strm().WriteOString( sOut );
535 sOut.setLength(0);
536 OutDirection( nDir );
537 }
538
539 // ALT
540 if( (nFrameOpts & HtmlFrmOpts::Alt) && !rAlternateText.isEmpty() )
541 {
542 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_alt "=\"");
543 Strm().WriteOString( sOut );
544 sOut.setLength(0);
545 HTMLOutFuncs::Out_String( Strm(), rAlternateText );
546 sOut.append('\"');
547 }
548
549 // ALIGN
550 const char *pStr = nullptr;
551 RndStdIds eAnchorId = rFrameFormat.GetAnchor().GetAnchorId();
552 if( (nFrameOpts & HtmlFrmOpts::Align) &&
553 ((RndStdIds::FLY_AT_PARA == eAnchorId) || (RndStdIds::FLY_AT_CHAR == eAnchorId)) )
554 {
555 // MIB 12.3.98: Wouldn't it be more clever to left-align frames that
556 // are anchored to a paragraph if necessary, instead of inserting them
557 // as being anchored to characters?
558 const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient();
559 if( !(nFrameOpts & HtmlFrmOpts::SAlign) ||
560 text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
561 text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
562 {
563 pStr = text::HoriOrientation::RIGHT == rHoriOri.GetHoriOrient()
566 }
567 }
568 const SwFormatVertOrient* pVertOrient;
569 if( (nFrameOpts & HtmlFrmOpts::Align) && !pStr &&
570 ( !(nFrameOpts & HtmlFrmOpts::SAlign) ||
571 (RndStdIds::FLY_AS_CHAR == eAnchorId) ) &&
572 (pVertOrient = rItemSet.GetItemIfSet( RES_VERT_ORIENT )) )
573 {
574 switch( pVertOrient->GetVertOrient() )
575 {
576 case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
577 case text::VertOrientation::CHAR_TOP:
578 case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // not possible
579 case text::VertOrientation::LINE_CENTER:
580 case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // not possible
581 case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
582 case text::VertOrientation::LINE_BOTTOM:
583 case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // not possible
584 case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
585 case text::VertOrientation::NONE: break;
586 }
587 }
588 if( pStr )
589 {
590 sOut.append(OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_align "=\"") +
591 pStr + "\"");
592 }
593
594 // HSPACE and VSPACE
595 Size aTwipSpc( 0, 0 );
596 const SvxLRSpaceItem* pLRSpaceItem;
597 if( (nFrameOpts & (HtmlFrmOpts::Space|HtmlFrmOpts::MarginSize)) &&
598 (pLRSpaceItem = rItemSet.GetItemIfSet( RES_LR_SPACE )) )
599 {
600 aTwipSpc.setWidth(
601 ( pLRSpaceItem->GetLeft() + pLRSpaceItem->GetRight() ) / 2 );
603 }
604 const SvxULSpaceItem* pULSpaceItem;
605 if( (nFrameOpts & (HtmlFrmOpts::Space|HtmlFrmOpts::MarginSize)) &&
606 (pULSpaceItem = rItemSet.GetItemIfSet( RES_UL_SPACE )) )
607 {
608 aTwipSpc.setHeight(
609 ( pULSpaceItem->GetUpper() + pULSpaceItem->GetLower() ) / 2 );
610 m_nDfltTopMargin = m_nDfltBottomMargin = o3tl::narrowing<sal_uInt16>(aTwipSpc.Height());
611 }
612
613 if( (nFrameOpts & HtmlFrmOpts::Space) &&
614 (aTwipSpc.Width() || aTwipSpc.Height()) &&
616 !mbReqIF )
617 {
618 Size aPixelSpc =
620 MapMode(MapUnit::MapTwip) );
621 if( !aPixelSpc.Width() && aTwipSpc.Width() )
622 aPixelSpc.setWidth( 1 );
623 if( !aPixelSpc.Height() && aTwipSpc.Height() )
624 aPixelSpc.setHeight( 1 );
625
626 if( aPixelSpc.Width() )
627 {
629 "=\"" + OString::number(aPixelSpc.Width()) + "\"");
630 }
631
632 if( aPixelSpc.Height() )
633 {
635 "=\"" + OString::number(aPixelSpc.Height()) + "\"");
636 }
637 }
638
639 // The spacing must be considered for the size, if the corresponding flag
640 // is set.
641 if( nFrameOpts & HtmlFrmOpts::MarginSize )
642 {
643 aTwipSpc.setWidth( aTwipSpc.Width() * -2 );
644 aTwipSpc.setHeight( aTwipSpc.Height() * -2 );
645 }
646 else
647 {
648 aTwipSpc.setWidth( 0 );
649 aTwipSpc.setHeight( 0 );
650 }
651
652 const SvxBoxItem* pBoxItem;
653 if( !(nFrameOpts & HtmlFrmOpts::AbsSize) &&
654 (pBoxItem = rItemSet.GetItemIfSet( RES_BOX )) )
655 {
656 aTwipSpc.AdjustWidth(pBoxItem->CalcLineSpace( SvxBoxItemLine::LEFT ) );
657 aTwipSpc.AdjustWidth(pBoxItem->CalcLineSpace( SvxBoxItemLine::RIGHT ) );
658 aTwipSpc.AdjustHeight(pBoxItem->CalcLineSpace( SvxBoxItemLine::TOP ) );
659 aTwipSpc.AdjustHeight(pBoxItem->CalcLineSpace( SvxBoxItemLine::BOTTOM ) );
660 }
661
662 // WIDTH and/or HEIGHT
663 // Output SwFrameSize::Variable/SwFrameSize::Minimum only, if ANYSIZE is set
664 const SwFormatFrameSize *pFSItem;
665 if( (nFrameOpts & HtmlFrmOpts::Size) &&
666 (pFSItem = rItemSet.GetItemIfSet( RES_FRM_SIZE )) &&
667 ( (nFrameOpts & HtmlFrmOpts::AnySize) ||
669 {
670 sal_uInt8 nPercentWidth = pFSItem->GetWidthPercent();
671 sal_uInt8 nPercentHeight = pFSItem->GetHeightPercent();
672
673 // Size of the object in Twips without margins
674 Size aTwipSz( (nPercentWidth ? 0
675 : pFSItem->GetWidth()-aTwipSpc.Width()),
676 (nPercentHeight ? 0
677 : pFSItem->GetHeight()-aTwipSpc.Height()) );
678
679 OSL_ENSURE( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0, "Frame size minus spacing < 0!!!???" );
680 if( aTwipSz.Width() < 0 )
681 aTwipSz.setWidth( 0 );
682 if( aTwipSz.Height() < 0 )
683 aTwipSz.setHeight( 0 );
684
685 Size aPixelSz( 0, 0 );
686 if( (aTwipSz.Width() || aTwipSz.Height()) &&
688 {
689 aPixelSz =
691 MapMode(MapUnit::MapTwip) );
692 if( !aPixelSz.Width() && aTwipSz.Width() )
693 aPixelSz.setWidth( 1 );
694 if( !aPixelSz.Height() && aTwipSz.Height() )
695 aPixelSz.setHeight( 1 );
696 }
697
698 if( (nFrameOpts & HtmlFrmOpts::Width) &&
699 ((nPercentWidth && nPercentWidth!=255) || aPixelSz.Width()) )
700 {
701 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_width "=\"");
702 if( nPercentWidth )
703 sOut.append(OString::number(static_cast<sal_Int32>(nPercentWidth)) + "%");
704 else
705 sOut.append(static_cast<sal_Int32>(aPixelSz.Width()));
706 sOut.append("\"");
707 }
708
709 if( (nFrameOpts & HtmlFrmOpts::Height) &&
710 ((nPercentHeight && nPercentHeight!=255) || aPixelSz.Height()) )
711 {
712 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_height "=\"");
713 if( nPercentHeight )
714 sOut.append(OString::number(static_cast<sal_Int32>(nPercentHeight)) + "%");
715 else
716 sOut.append(static_cast<sal_Int32>(aPixelSz.Height()));
717 sOut.append("\"");
718 }
719 }
720
721 if (!sOut.isEmpty())
722 {
723 Strm().WriteOString( sOut );
724 sOut.setLength(0);
725 }
726
727 // Insert wrap for graphics that are anchored to a paragraph as
728 // <BR CLEAR=...> in the string
729 const SwFormatSurround* pSurround;
730 if( (nFrameOpts & HtmlFrmOpts::BrClear) &&
731 ((RndStdIds::FLY_AT_PARA == rFrameFormat.GetAnchor().GetAnchorId()) ||
732 (RndStdIds::FLY_AT_CHAR == rFrameFormat.GetAnchor().GetAnchorId())) &&
733 (pSurround = rItemSet.GetItemIfSet( RES_SURROUND )) )
734 {
735 sal_Int16 eHoriOri = rFrameFormat.GetHoriOrient().GetHoriOrient();
736 pStr = nullptr;
737 css::text::WrapTextMode eSurround = pSurround->GetSurround();
738 bool bAnchorOnly = pSurround->IsAnchorOnly();
739 switch( eHoriOri )
740 {
741 case text::HoriOrientation::RIGHT:
742 {
743 switch( eSurround )
744 {
745 case css::text::WrapTextMode_NONE:
746 case css::text::WrapTextMode_RIGHT:
748 break;
749 case css::text::WrapTextMode_LEFT:
750 case css::text::WrapTextMode_PARALLEL:
751 if( bAnchorOnly )
752 m_bClearRight = true;
753 break;
754 default:
755 ;
756 }
757 }
758 break;
759
760 default:
761 // If a frame is centered, it gets left aligned. This
762 // should be taken into account here, too.
763 {
764 switch( eSurround )
765 {
766 case css::text::WrapTextMode_NONE:
767 case css::text::WrapTextMode_LEFT:
769 break;
770 case css::text::WrapTextMode_RIGHT:
771 case css::text::WrapTextMode_PARALLEL:
772 if( bAnchorOnly )
773 m_bClearLeft = true;
774 break;
775 default:
776 ;
777 }
778 }
779 break;
780
781 }
782
783 if( pStr )
784 {
787 "=\"" + OString::Concat(pStr) + "\">");
788 sRetEndTags = sOut.makeStringAndClear();
789 }
790 }
791 return sRetEndTags;
792}
793
794void SwHTMLWriter::writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameFormat& rFrameFormat, std::u16string_view rAlternateText, HtmlFrmOpts nFrameOptions)
795{
796 bool bReplacement = (nFrameOptions & HtmlFrmOpts::Replacement) || mbReqIF;
797 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
798
799 // Name
800 if( (nFrameOptions & (HtmlFrmOpts::Id|HtmlFrmOpts::Name)) &&
801 !rFrameFormat.GetName().isEmpty() && !bReplacement)
802 {
803 const char* pAttributeName = (nFrameOptions & HtmlFrmOpts::Id) ? OOO_STRING_SVTOOLS_HTML_O_id : OOO_STRING_SVTOOLS_HTML_O_name;
804 aHtml.attribute(pAttributeName, rFrameFormat.GetName());
805 }
806
807 // Name
808 if (nFrameOptions & HtmlFrmOpts::Dir)
809 {
810 SvxFrameDirection nCurrentDirection = GetHTMLDirection(rItemSet);
811 OString sDirection = convertDirection(nCurrentDirection);
812 aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_dir, sDirection);
813 }
814
815 // alt
816 if( (nFrameOptions & HtmlFrmOpts::Alt) && !rAlternateText.empty() && !bReplacement )
817 {
818 aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_alt, rAlternateText);
819 }
820
821 // align
822 const char* pAlignString = nullptr;
823 RndStdIds eAnchorId = rFrameFormat.GetAnchor().GetAnchorId();
824 if( (nFrameOptions & HtmlFrmOpts::Align) &&
825 ((RndStdIds::FLY_AT_PARA == eAnchorId) || (RndStdIds::FLY_AT_CHAR == eAnchorId)) && !bReplacement)
826 {
827 const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient();
828 if( !(nFrameOptions & HtmlFrmOpts::SAlign) ||
829 text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
830 text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
831 {
832 pAlignString = text::HoriOrientation::RIGHT == rHoriOri.GetHoriOrient()
835 }
836 }
837 const SwFormatVertOrient* pVertOrient;
838 if( (nFrameOptions & HtmlFrmOpts::Align) && !pAlignString &&
839 ( !(nFrameOptions & HtmlFrmOpts::SAlign) ||
840 (RndStdIds::FLY_AS_CHAR == eAnchorId) ) &&
841 (pVertOrient = rItemSet.GetItemIfSet( RES_VERT_ORIENT )) )
842 {
843 switch( pVertOrient->GetVertOrient() )
844 {
845 case text::VertOrientation::LINE_TOP: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_top; break;
846 case text::VertOrientation::CHAR_TOP:
847 case text::VertOrientation::BOTTOM: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_texttop; break;
848 case text::VertOrientation::LINE_CENTER:
849 case text::VertOrientation::CHAR_CENTER: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break;
850 case text::VertOrientation::CENTER: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
851 case text::VertOrientation::LINE_BOTTOM:
852 case text::VertOrientation::CHAR_BOTTOM: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break;
853 case text::VertOrientation::TOP: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
854 case text::VertOrientation::NONE: break;
855 }
856 }
857 if (pAlignString && !bReplacement)
858 {
859 aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_align, pAlignString);
860 }
861
862 // hspace and vspace
863 Size aTwipSpc( 0, 0 );
864 const SvxLRSpaceItem* pLRSpaceItem;
865 if( (nFrameOptions & (HtmlFrmOpts::Space | HtmlFrmOpts::MarginSize)) &&
866 (pLRSpaceItem = rItemSet.GetItemIfSet( RES_LR_SPACE )) )
867 {
868 aTwipSpc.setWidth(
869 ( pLRSpaceItem->GetLeft() + pLRSpaceItem->GetRight() ) / 2 );
871 }
872 const SvxULSpaceItem* pULSpaceItem;
873 if( (nFrameOptions & (HtmlFrmOpts::Space|HtmlFrmOpts::MarginSize)) &&
874 (pULSpaceItem = rItemSet.GetItemIfSet( RES_UL_SPACE )) )
875 {
876 aTwipSpc.setHeight(
877 ( pULSpaceItem->GetUpper() + pULSpaceItem->GetLower() ) / 2 );
878 m_nDfltTopMargin = m_nDfltBottomMargin = o3tl::narrowing<sal_uInt16>(aTwipSpc.Height());
879 }
880
881 if( (nFrameOptions & HtmlFrmOpts::Space) &&
882 (aTwipSpc.Width() || aTwipSpc.Height()) &&
884 !mbReqIF )
885 {
886 Size aPixelSpc =
888 MapMode(MapUnit::MapTwip) );
889 if( !aPixelSpc.Width() && aTwipSpc.Width() )
890 aPixelSpc.setWidth( 1 );
891 if( !aPixelSpc.Height() && aTwipSpc.Height() )
892 aPixelSpc.setHeight( 1 );
893
894 if (aPixelSpc.Width())
895 {
896 aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_hspace, static_cast<sal_Int32>(aPixelSpc.Width()));
897 }
898
899 if (aPixelSpc.Height())
900 {
901 aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_vspace, static_cast<sal_Int32>(aPixelSpc.Height()));
902 }
903 }
904
905 // The spacing must be considered for the size, if the corresponding flag
906 // is set.
907 if( nFrameOptions & HtmlFrmOpts::MarginSize )
908 {
909 aTwipSpc.setWidth( aTwipSpc.Width() * -2 );
910 aTwipSpc.setHeight( aTwipSpc.Height() * -2 );
911 }
912 else
913 {
914 aTwipSpc.setWidth( 0 );
915 aTwipSpc.setHeight( 0 );
916 }
917
918 const SvxBoxItem* pBoxItem;
919 if( !(nFrameOptions & HtmlFrmOpts::AbsSize) &&
920 (pBoxItem = rItemSet.GetItemIfSet( RES_BOX )) )
921 {
922 aTwipSpc.AdjustWidth(pBoxItem->CalcLineSpace( SvxBoxItemLine::LEFT ) );
923 aTwipSpc.AdjustWidth(pBoxItem->CalcLineSpace( SvxBoxItemLine::RIGHT ) );
924 aTwipSpc.AdjustHeight(pBoxItem->CalcLineSpace( SvxBoxItemLine::TOP ) );
925 aTwipSpc.AdjustHeight(pBoxItem->CalcLineSpace( SvxBoxItemLine::BOTTOM ) );
926 }
927
928 // "width" and/or "height"
929 // Only output SwFrameSize::Variable/SwFrameSize::Minimum if ANYSIZE is set
930 std::optional<SwFormatFrameSize> aFrameSize;
931 const SwFormatFrameSize* pFSItem = rItemSet.GetItemIfSet( RES_FRM_SIZE );
932 const SdrObject* pObject;
933 if (!pFSItem && (pObject = rFrameFormat.FindSdrObject()))
934 {
935 // Write size for Draw shapes as well.
936 const tools::Rectangle& rSnapRect = pObject->GetSnapRect();
937 aFrameSize.emplace();
938 aFrameSize->SetWidthSizeType(SwFrameSize::Fixed);
939 aFrameSize->SetWidth(rSnapRect.getOpenWidth());
940 aFrameSize->SetHeightSizeType(SwFrameSize::Fixed);
941 aFrameSize->SetHeight(rSnapRect.getOpenHeight());
942 pFSItem = &*aFrameSize;
943 }
944 if( (nFrameOptions & HtmlFrmOpts::Size) &&
945 pFSItem &&
946 ( (nFrameOptions & HtmlFrmOpts::AnySize) ||
948 {
949 sal_uInt8 nPercentWidth = pFSItem->GetWidthPercent();
950 sal_uInt8 nPercentHeight = pFSItem->GetHeightPercent();
951
952 // Size of the object in Twips without margins
953 Size aTwipSz( (nPercentWidth && nPercentWidth != 255 ? 0
954 : pFSItem->GetWidth()-aTwipSpc.Width()),
955 (nPercentHeight && nPercentHeight != 255 ? 0
956 : pFSItem->GetHeight()-aTwipSpc.Height()) );
957
958 OSL_ENSURE( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0, "Frame size minus spacing < 0!!!???" );
959 if( aTwipSz.Width() < 0 )
960 aTwipSz.setWidth( 0 );
961 if( aTwipSz.Height() < 0 )
962 aTwipSz.setHeight( 0 );
963
964 Size aPixelSz( 0, 0 );
965 if( (aTwipSz.Width() || aTwipSz.Height()) &&
967 {
968 aPixelSz =
970 MapMode(MapUnit::MapTwip) );
971 if( !aPixelSz.Width() && aTwipSz.Width() )
972 aPixelSz.setWidth( 1 );
973 if( !aPixelSz.Height() && aTwipSz.Height() )
974 aPixelSz.setHeight( 1 );
975 }
976
977 if( (nFrameOptions & HtmlFrmOpts::Width) &&
978 ((nPercentWidth && nPercentWidth!=255) || aPixelSz.Width()) )
979 {
980 OString sWidth;
981 if (nPercentWidth)
982 {
983 if (nPercentWidth == 255)
984 {
985 if (nPercentHeight)
986 {
987 sWidth = "auto";
988 }
989 else
990 {
991 sWidth = OString::number(static_cast<sal_Int32>(aPixelSz.Width()));
992 }
993 }
994 else
995 {
996 sWidth = OString::number(static_cast<sal_Int32>(nPercentWidth)) + "%";
997 }
998 }
999 else
1000 sWidth = OString::number(static_cast<sal_Int32>(aPixelSz.Width()));
1001 if (!mbXHTML || sWidth != "auto")
1002 {
1004 }
1005 }
1006
1007 if( (nFrameOptions & HtmlFrmOpts::Height) &&
1008 ((nPercentHeight && nPercentHeight!=255) || aPixelSz.Height()) )
1009 {
1010 OString sHeight;
1011 if (nPercentHeight)
1012 {
1013 if (nPercentHeight == 255)
1014 {
1015 if (nPercentWidth)
1016 {
1017 sHeight = "auto";
1018 }
1019 else
1020 {
1021 sHeight = OString::number(static_cast<sal_Int32>(aPixelSz.Height()));
1022 }
1023 }
1024 else
1025 {
1026 sHeight = OString::number(static_cast<sal_Int32>(nPercentHeight)) + "%";
1027 }
1028 }
1029 else
1030 sHeight = OString::number(static_cast<sal_Int32>(aPixelSz.Height()));
1031 if (!mbXHTML || sHeight != "auto")
1032 {
1034 }
1035 }
1036 }
1037
1038 // Insert wrap for graphics that are anchored to a paragraph as
1039 // <BR CLEAR=...> in the string
1040
1041 if( !(nFrameOptions & HtmlFrmOpts::BrClear) )
1042 return;
1043 RndStdIds nAnchorId = rFrameFormat.GetAnchor().GetAnchorId();
1044 if (RndStdIds::FLY_AT_PARA != nAnchorId && RndStdIds::FLY_AT_CHAR != nAnchorId)
1045 return;
1046 const SwFormatSurround* pSurround = rItemSet.GetItemIfSet( RES_SURROUND );
1047 if (!pSurround)
1048 return;
1049
1050 const char* pSurroundString = nullptr;
1051
1052 sal_Int16 eHoriOri = rFrameFormat.GetHoriOrient().GetHoriOrient();
1053 css::text::WrapTextMode eSurround = pSurround->GetSurround();
1054 bool bAnchorOnly = pSurround->IsAnchorOnly();
1055 switch( eHoriOri )
1056 {
1057 case text::HoriOrientation::RIGHT:
1058 {
1059 switch( eSurround )
1060 {
1061 case css::text::WrapTextMode_NONE:
1062 case css::text::WrapTextMode_RIGHT:
1063 pSurroundString = OOO_STRING_SVTOOLS_HTML_AL_right;
1064 break;
1065 case css::text::WrapTextMode_LEFT:
1066 case css::text::WrapTextMode_PARALLEL:
1067 if( bAnchorOnly )
1068 m_bClearRight = true;
1069 break;
1070 default:
1071 ;
1072 }
1073 }
1074 break;
1075
1076 default:
1077 // If a frame is centered, it gets left aligned. This
1078 // should be taken into account here, too.
1079 {
1080 switch( eSurround )
1081 {
1082 case css::text::WrapTextMode_NONE:
1083 case css::text::WrapTextMode_LEFT:
1084 pSurroundString = OOO_STRING_SVTOOLS_HTML_AL_left;
1085 break;
1086 case css::text::WrapTextMode_RIGHT:
1087 case css::text::WrapTextMode_PARALLEL:
1088 if( bAnchorOnly )
1089 m_bClearLeft = true;
1090 break;
1091 default:
1092 break;
1093 }
1094 }
1095 break;
1096 }
1097
1098 if (pSurroundString)
1099 {
1101 aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_clear, pSurroundString);
1102 aHtml.end();
1103 }
1104}
1105
1106namespace
1107{
1108
1109OUString lclWriteOutImap(SwHTMLWriter& rWrt, const SfxItemSet& rItemSet, const SwFrameFormat& rFrameFormat,
1110 const Size& rRealSize, const ImageMap* pAltImgMap, const SwFormatURL*& pURLItem)
1111{
1112 OUString aIMapName;
1113
1114 // Only consider the URL attribute if no ImageMap was supplied
1115 if (!pAltImgMap)
1116 pURLItem = rItemSet.GetItemIfSet( RES_URL );
1117
1118 // write ImageMap
1119 const ImageMap* pIMap = pAltImgMap;
1120 if( !pIMap && pURLItem )
1121 {
1122 pIMap = pURLItem->GetMap();
1123 }
1124
1125 if (pIMap)
1126 {
1127 // make the name unique
1128 aIMapName = pIMap->GetName();
1129 OUString aNameBase;
1130 if (!aIMapName.isEmpty())
1131 aNameBase = aIMapName;
1132 else
1133 aNameBase = OOO_STRING_SVTOOLS_HTML_map;
1134
1135 if (aIMapName.isEmpty())
1136 aIMapName = aNameBase + OUString::number(rWrt.m_nImgMapCnt);
1137
1138 bool bFound;
1139 do
1140 {
1141 bFound = false;
1142 for (const OUString & rImgMapName : rWrt.m_aImgMapNames)
1143 {
1144 // TODO: Unicode: Comparison is case insensitive for ASCII
1145 // characters only now!
1146 if (aIMapName.equalsIgnoreAsciiCase(rImgMapName))
1147 {
1148 bFound = true;
1149 break;
1150 }
1151 }
1152 if (bFound)
1153 {
1154 rWrt.m_nImgMapCnt++;
1155 aIMapName = aNameBase + OUString::number( rWrt.m_nImgMapCnt );
1156 }
1157 } while (bFound);
1158
1159 bool bScale = false;
1160 Fraction aScaleX(1, 1);
1161 Fraction aScaleY(1, 1);
1162
1163 const SwFormatFrameSize& rFrameSize = rFrameFormat.GetFrameSize();
1164 const SvxBoxItem& rBox = rFrameFormat.GetBox();
1165
1166 if (!rFrameSize.GetWidthPercent() && rRealSize.Width())
1167 {
1168 SwTwips nWidth = rFrameSize.GetWidth();
1169 nWidth -= rBox.CalcLineSpace(SvxBoxItemLine::LEFT) + rBox.CalcLineSpace(SvxBoxItemLine::RIGHT);
1170
1171 OSL_ENSURE( nWidth > 0, "Are there any graphics that are 0 twip wide!?" );
1172 if (nWidth <= 0) // should not happen
1173 nWidth = 1;
1174
1175 if (rRealSize.Width() != nWidth)
1176 {
1177 aScaleX = Fraction(nWidth, rRealSize.Width());
1178 bScale = true;
1179 }
1180 }
1181
1182 if (!rFrameSize.GetHeightPercent() && rRealSize.Height())
1183 {
1184 SwTwips nHeight = rFrameSize.GetHeight();
1185
1186 nHeight -= rBox.CalcLineSpace(SvxBoxItemLine::TOP) + rBox.CalcLineSpace(SvxBoxItemLine::BOTTOM);
1187
1188 OSL_ENSURE( nHeight > 0, "Are there any graphics that are 0 twip high!?" );
1189 if (nHeight <= 0)
1190 nHeight = 1;
1191
1192 if (rRealSize.Height() != nHeight)
1193 {
1194 aScaleY = Fraction(nHeight, rRealSize.Height());
1195 bScale = true;
1196 }
1197 }
1198
1199 rWrt.m_aImgMapNames.push_back(aIMapName);
1200
1201 OString aIndMap, aIndArea;
1202 const char *pIndArea = nullptr, *pIndMap = nullptr;
1203
1204 if (rWrt.m_bLFPossible)
1205 {
1206 rWrt.OutNewLine( true );
1207 aIndMap = rWrt.GetIndentString();
1208 aIndArea = rWrt.GetIndentString(1);
1209 pIndArea = aIndArea.getStr();
1210 pIndMap = aIndMap.getStr();
1211 }
1212
1213 if (bScale)
1214 {
1215 ImageMap aScaledIMap(*pIMap);
1216 aScaledIMap.Scale(aScaleX, aScaleY);
1217 HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), aScaledIMap, aIMapName,
1219 rWrt.m_bCfgStarBasic,
1220 SAL_NEWLINE_STRING, pIndArea, pIndMap );
1221 }
1222 else
1223 {
1224 HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), *pIMap, aIMapName,
1226 rWrt.m_bCfgStarBasic,
1227 SAL_NEWLINE_STRING, pIndArea, pIndMap );
1228 }
1229 }
1230 return aIMapName;
1231}
1232
1233}
1234
1236 const OUString& rGraphicURL,
1237 Graphic const & rGraphic, const OUString& rAlternateText,
1238 const Size &rRealSize, HtmlFrmOpts nFrameOpts,
1239 const char *pMarkType,
1240 const ImageMap *pAltImgMap,
1241 const OUString& rMimeType )
1242{
1243 // <object data="..."> instead of <img src="...">
1244 bool bReplacement = (nFrameOpts & HtmlFrmOpts::Replacement) || rWrt.mbReqIF;
1245
1246 if (rWrt.mbSkipImages)
1247 return rWrt;
1248
1249 // if necessary, temporarily close an open attribute
1250 if( !rWrt.m_aINetFormats.empty() )
1251 {
1252 SwFormatINetFormat* pINetFormat = rWrt.m_aINetFormats.back();
1253 OutHTML_INetFormat( rWrt, *pINetFormat, false );
1254 }
1255
1256 OUString aGraphicURL( rGraphicURL );
1257 if( !rWrt.mbEmbedImages && !HTMLOutFuncs::PrivateURLToInternalImg(aGraphicURL) && !rWrt.mpTempBaseURL )
1258 aGraphicURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), aGraphicURL);
1259
1260 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
1261
1262 const SwFormatURL* pURLItem = nullptr;
1263 OUString aIMapName = lclWriteOutImap(rWrt, rItemSet, rFrameFormat, rRealSize, pAltImgMap, pURLItem);
1264
1265 // put img into new line
1266 if( rWrt.m_bLFPossible )
1267 rWrt.OutNewLine( true );
1268
1269 // <a name=...></a>...<img ...>
1270 if( pMarkType && !rFrameFormat.GetName().isEmpty() )
1271 {
1272 rWrt.OutImplicitMark( rFrameFormat.GetName(), pMarkType );
1273 }
1274
1275 // URL -> <a>...<img ... >...</a>
1276 const SvxMacroItem *pMacItem = rItemSet.GetItemIfSet(RES_FRMMACRO);
1277
1278 if (pURLItem || pMacItem)
1279 {
1280 OUString aMapURL;
1281 OUString aName;
1282 OUString aTarget;
1283
1284 if(pURLItem)
1285 {
1286 aMapURL = pURLItem->GetURL();
1287 aName = pURLItem->GetName();
1288 aTarget = pURLItem->GetTargetFrameName();
1289 }
1290
1291 bool bEvents = pMacItem && !pMacItem->GetMacroTable().empty();
1292
1293 if( !aMapURL.isEmpty() || !aName.isEmpty() || !aTarget.isEmpty() || bEvents )
1294 {
1296
1297 // Output "href" element if a link or macro exists
1298 if( !aMapURL.isEmpty() || bEvents )
1299 {
1300 rHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_href, OUStringToOString(rWrt.convertHyperlinkHRefValue(aMapURL), RTL_TEXTENCODING_UTF8));
1301 }
1302
1303 if( !aName.isEmpty() )
1304 {
1305 rHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_name, OUStringToOString(aName, RTL_TEXTENCODING_UTF8));
1306 }
1307
1308 if( !aTarget.isEmpty() )
1309 {
1310 rHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_target, OUStringToOString(aTarget, RTL_TEXTENCODING_UTF8));
1311 }
1312
1313 if( pMacItem )
1314 {
1315 const SvxMacroTableDtor& rMacTable = pMacItem->GetMacroTable();
1316 if (!rMacTable.empty())
1317 {
1319 }
1320 }
1321 }
1322 }
1323
1324 // <font color = ...>...<img ... >...</font>
1325 sal_uInt16 nBorderWidth = 0;
1326 const SvxBoxItem* pBoxItem;
1327 if( (nFrameOpts & HtmlFrmOpts::Border) &&
1328 (pBoxItem = rItemSet.GetItemIfSet( RES_BOX )) )
1329 {
1330 Size aTwipBorder( 0, 0 );
1331 const ::editeng::SvxBorderLine *pColBorderLine = nullptr;
1332 const ::editeng::SvxBorderLine *pBorderLine = pBoxItem->GetLeft();
1333 if( pBorderLine )
1334 {
1335 pColBorderLine = pBorderLine;
1336 aTwipBorder.AdjustWidth(pBorderLine->GetOutWidth() );
1337 }
1338
1339 pBorderLine = pBoxItem->GetRight();
1340 if( pBorderLine )
1341 {
1342 pColBorderLine = pBorderLine;
1343 aTwipBorder.AdjustWidth(pBorderLine->GetOutWidth() );
1344 }
1345
1346 pBorderLine = pBoxItem->GetTop();
1347 if( pBorderLine )
1348 {
1349 pColBorderLine = pBorderLine;
1350 aTwipBorder.AdjustHeight(pBorderLine->GetOutWidth() );
1351 }
1352
1353 pBorderLine = pBoxItem->GetBottom();
1354 if( pBorderLine )
1355 {
1356 pColBorderLine = pBorderLine;
1357 aTwipBorder.AdjustHeight(pBorderLine->GetOutWidth() );
1358 }
1359
1360 aTwipBorder.setWidth( aTwipBorder.Width() / 2 );
1361 aTwipBorder.setHeight( aTwipBorder.Height() / 2 );
1362
1363 if( (aTwipBorder.Width() || aTwipBorder.Height()) &&
1365 {
1366 Size aPixelBorder =
1368 MapMode(MapUnit::MapTwip) );
1369 if( !aPixelBorder.Width() && aTwipBorder.Width() )
1370 aPixelBorder.setWidth( 1 );
1371 if( !aPixelBorder.Height() && aTwipBorder.Height() )
1372 aPixelBorder.setHeight( 1 );
1373
1374 if( aPixelBorder.Width() )
1375 aPixelBorder.setHeight( 0 );
1376
1377 nBorderWidth =
1378 o3tl::narrowing<sal_uInt16>(aPixelBorder.Width() + aPixelBorder.Height());
1379 }
1380
1381 if( pColBorderLine )
1382 {
1384 HtmlWriterHelper::applyColor(rHtml, OOO_STRING_SVTOOLS_HTML_O_color, pColBorderLine->GetColor());
1385 }
1386 }
1387
1388 OString aTag(OOO_STRING_SVTOOLS_HTML_image);
1389 if (bReplacement)
1390 // Write replacement graphic of OLE object as <object>.
1392 rHtml.start(aTag);
1393
1394 OStringBuffer sBuffer;
1395 if(rWrt.mbEmbedImages)
1396 {
1397 OUString aGraphicInBase64;
1398 if (XOutBitmap::GraphicToBase64(rGraphic, aGraphicInBase64))
1399 {
1400 sBuffer.append(OOO_STRING_SVTOOLS_HTML_O_data);
1401 sBuffer.append(":");
1402 sBuffer.append(OUStringToOString(aGraphicInBase64, RTL_TEXTENCODING_UTF8));
1403 rHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_src, sBuffer.makeStringAndClear().getStr());
1404 }
1405 else
1407 }
1408 else
1409 {
1410 sBuffer.append(OUStringToOString(aGraphicURL, RTL_TEXTENCODING_UTF8));
1411 OString aAttribute(OOO_STRING_SVTOOLS_HTML_O_src);
1412 if (bReplacement)
1413 aAttribute = OOO_STRING_SVTOOLS_HTML_O_data;
1414 rHtml.attribute(aAttribute, sBuffer.makeStringAndClear().getStr());
1415 }
1416
1417 if (bReplacement)
1418 {
1419 // Handle XHTML type attribute for OLE replacement images.
1420 if (!rMimeType.isEmpty())
1421 rHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_type, rMimeType.toUtf8());
1422 }
1423
1424 // Events
1425 if (const SvxMacroItem* pMacroItem = rItemSet.GetItemIfSet(RES_FRMMACRO))
1426 {
1427 const SvxMacroTableDtor& rMacTable = pMacroItem->GetMacroTable();
1428 if (!rMacTable.empty())
1429 {
1431 }
1432 }
1433
1434 // alt, align, width, height, hspace, vspace
1435 rWrt.writeFrameFormatOptions(rHtml, rFrameFormat, rAlternateText, nFrameOpts);
1436 if( rWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) )
1437 rWrt.OutCSS1_FrameFormatOptions( rFrameFormat, nFrameOpts );
1438
1439 if ((nFrameOpts & HtmlFrmOpts::Border) && !bReplacement)
1440 {
1442 }
1443
1444 if( pURLItem && pURLItem->IsServerMap() )
1445 {
1447 }
1448
1449 if( !aIMapName.isEmpty() )
1450 {
1451 rHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_usemap, Concat2View("#" + aIMapName));
1452 }
1453
1454 if (bReplacement)
1455 {
1456 // XHTML object replacement image's alternate text doesn't use the
1457 // "alt" attribute.
1458 if (rAlternateText.isEmpty())
1459 // Empty alternate text is not valid.
1460 rHtml.characters(" ");
1461 else
1462 rHtml.characters(rAlternateText.toUtf8());
1463 }
1464
1465 return rWrt;
1466}
1467
1469{
1470 rHtml.flushStack();
1471
1472 if( !rWrt.m_aINetFormats.empty() )
1473 {
1474 // There is still an attribute on the stack that has to be reopened
1475 SwFormatINetFormat *pINetFormat = rWrt.m_aINetFormats.back();
1476 OutHTML_INetFormat( rWrt, *pINetFormat, true );
1477 }
1478
1479 return rWrt;
1480}
1481
1483 const char *pTag,
1484 const SvxBrushItem* pBrush,
1485 const OUString &rGraphicURL)
1486{
1487 OUString aGraphicInBase64;
1488 OUString aLink;
1489 if( pBrush )
1490 {
1491 aLink = pBrush->GetGraphicLink();
1492 if(rWrt.mbEmbedImages || aLink.isEmpty())
1493 {
1494 const Graphic* pGrf = pBrush->GetGraphic();
1495 if( pGrf )
1496 {
1497 if( !XOutBitmap::GraphicToBase64(*pGrf, aGraphicInBase64) )
1498 {
1500 }
1501 }
1502 }
1503 else if(!aLink.isEmpty())
1504 {
1505 if( rWrt.m_bCfgCpyLinkedGrfs )
1506 {
1507 rWrt.CopyLocalFileToINet( aLink );
1508 }
1509
1510 }
1511 }
1512 else if(!rWrt.mbEmbedImages)
1513 {
1514 aLink = rGraphicURL;
1515 }
1516 if(!aLink.isEmpty())
1517 {
1520 }
1521
1522 OStringBuffer sOut;
1523 if( pTag )
1524 sOut.append(OString::Concat("<") + pTag);
1525
1526 sOut.append(' ');
1527 sOut.append(OOO_STRING_SVTOOLS_HTML_O_style "=\"");
1528 if(!aLink.isEmpty())
1529 {
1530 sOut.append(OOO_STRING_SVTOOLS_HTML_O_src "=\"");
1531 rWrt.Strm().WriteOString( sOut );
1532 sOut.setLength(0);
1533 HTMLOutFuncs::Out_String( rWrt.Strm(), aLink );
1534 }
1535 else
1536 {
1537 sOut.append("list-style-image: url("
1539 rWrt.Strm().WriteOString( sOut );
1540 sOut.setLength(0);
1541 HTMLOutFuncs::Out_String( rWrt.Strm(), aGraphicInBase64 );
1542 sOut.append(");");
1543 }
1544 sOut.append('\"');
1545
1546 if (pTag)
1547 sOut.append('>');
1548 rWrt.Strm().WriteOString( sOut );
1549
1550 return rWrt;
1551}
1552
1554{
1555 const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
1556 SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex()+1;
1557 SwNodeOffset nEnd = rWrt.m_pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
1558
1559 OUString aCaption;
1560 bool bTopCaption = false;
1561
1562 // Not const, because GetTable won't be const sometime later
1563 SwNode *pNd = rWrt.m_pDoc->GetNodes()[ nStt ];
1564 SwTableNode *pTableNd = pNd->GetTableNode();
1565 const SwTextNode *pTextNd = pNd->GetTextNode();
1566 if( !pTableNd && pTextNd )
1567 {
1568 // Table with heading
1569 bTopCaption = true;
1570 pTableNd = rWrt.m_pDoc->GetNodes()[nStt+1]->GetTableNode();
1571 }
1572 OSL_ENSURE( pTableNd, "Frame does not contain a table" );
1573 if( pTableNd )
1574 {
1575 SwNodeOffset nTableEnd = pTableNd->EndOfSectionIndex();
1576 OSL_ENSURE( nTableEnd == nEnd - 1 ||
1577 (nTableEnd == nEnd - 2 && !bTopCaption),
1578 "Invalid frame content for a table" );
1579
1580 if( nTableEnd == nEnd - 2 )
1581 pTextNd = rWrt.m_pDoc->GetNodes()[nTableEnd+1]->GetTextNode();
1582 }
1583 if( pTextNd )
1584 aCaption = pTextNd->GetText();
1585
1586 if( pTableNd )
1587 {
1588 HTMLSaveData aSaveData( rWrt, pTableNd->GetIndex()+1,
1589 pTableNd->EndOfSectionIndex(),
1590 true, &rFrameFormat );
1591 rWrt.m_bOutFlyFrame = true;
1592 OutHTML_SwTableNode( rWrt, *pTableNd, &rFrameFormat, &aCaption,
1593 bTopCaption );
1594 }
1595
1596 return rWrt;
1597}
1598
1600 const SwFrameFormat& rFrameFormat,
1601 bool bInCntnr )
1602{
1603 rWrt.ChangeParaToken( HtmlTokenId::NONE );
1604
1605 // Close the current <DL>!
1606 rWrt.OutAndSetDefList( 0 );
1607
1608 // output as Multicol
1609 if( rWrt.m_bLFPossible )
1610 rWrt.OutNewLine();
1611
1612 OStringBuffer sOut("<" + rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_multicol);
1613
1614 const SwFormatCol& rFormatCol = rFrameFormat.GetCol();
1615
1616 // output the number of columns as COLS
1617 sal_uInt16 nCols = rFormatCol.GetNumCols();
1618 if( nCols )
1619 {
1620 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_cols
1621 "=\"" + OString::number(nCols) + "\"");
1622 }
1623
1624 // the Gutter width (minimum value) as GUTTER
1625 sal_uInt16 nGutter = rFormatCol.GetGutterWidth( true );
1626 if( nGutter!=USHRT_MAX )
1627 {
1628 if( nGutter && Application::GetDefaultDevice() )
1629 {
1630 nGutter = o3tl::narrowing<sal_uInt16>(Application::GetDefaultDevice()
1631 ->LogicToPixel( Size(nGutter,0),
1632 MapMode(MapUnit::MapTwip) ).Width());
1633 }
1634 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_gutter
1635 "=\"" + OString::number(nGutter) + "\"");
1636 }
1637
1638 rWrt.Strm().WriteOString( sOut );
1639 sOut.setLength(0);
1640
1641 // WIDTH
1642 HtmlFrmOpts nFrameFlags = HTML_FRMOPTS_MULTICOL;
1643 if( rWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1644 nFrameFlags |= HTML_FRMOPTS_MULTICOL_CSS1;
1645 rWrt.OutFrameFormatOptions(rFrameFormat, OUString(), nFrameFlags);
1646 if( rWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1647 rWrt.OutCSS1_FrameFormatOptions( rFrameFormat, nFrameFlags );
1648
1649 rWrt.Strm().WriteChar( '>' );
1650
1651 rWrt.m_bLFPossible = true;
1652 rWrt.IncIndentLevel(); // indent the content of Multicol
1653
1654 const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
1655 SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex();
1656 const SwStartNode* pSttNd = rWrt.m_pDoc->GetNodes()[nStt]->GetStartNode();
1657 OSL_ENSURE( pSttNd, "Where is the start node" );
1658
1659 {
1660 // in a block, so that the old state can be restored in time
1661 // before the end
1662 HTMLSaveData aSaveData( rWrt, nStt+1,
1663 pSttNd->EndOfSectionIndex(),
1664 true, &rFrameFormat );
1665 rWrt.m_bOutFlyFrame = true;
1666 rWrt.Out_SwDoc( rWrt.m_pCurrentPam.get() );
1667 }
1668
1669 rWrt.DecIndentLevel(); // indent the content of Multicol;
1670 if( rWrt.m_bLFPossible )
1671 rWrt.OutNewLine();
1672 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_multicol), false );
1673 rWrt.m_bLFPossible = true;
1674
1675 return rWrt;
1676}
1677
1679{
1680 // if possible, output a line break before the graphic
1681 if( rWrt.m_bLFPossible )
1682 rWrt.OutNewLine( true );
1683
1684 OString sOut =
1688 rWrt.Strm().WriteOString( sOut );
1689
1690 // ALIGN, WIDTH, HEIGHT
1691 OString aEndTags = rWrt.OutFrameFormatOptions(rFrameFormat, OUString(), HTML_FRMOPTS_SPACER);
1692
1693 rWrt.Strm().WriteChar( '>' );
1694 if( !aEndTags.isEmpty() )
1695 rWrt.Strm().WriteOString( aEndTags );
1696
1697 return rWrt;
1698}
1699
1701 const SwFrameFormat& rFrameFormat, bool bSpan)
1702{
1703 OString aTag;
1704 if( !bSpan )
1705 {
1706 rWrt.ChangeParaToken( HtmlTokenId::NONE );
1707
1708 // Close the current <DL>!
1709 rWrt.OutAndSetDefList( 0 );
1711 }
1712 else
1714
1715 // output as DIV
1716 if( rWrt.m_bLFPossible )
1717 rWrt.OutNewLine();
1718
1719 OStringBuffer sOut("<" + rWrt.GetNamespace() + aTag);
1720
1721 rWrt.Strm().WriteOString( sOut );
1722 sOut.setLength(0);
1723 HtmlFrmOpts nFrameFlags = HTML_FRMOPTS_DIV;
1724 if( rWrt.IsHTMLMode( HTMLMODE_BORDER_NONE ) )
1725 nFrameFlags |= HtmlFrmOpts::SNoBorder;
1726 OString aEndTags = rWrt.OutFrameFormatOptions(rFrameFormat, OUString(), nFrameFlags);
1727 rWrt.OutCSS1_FrameFormatOptions( rFrameFormat, nFrameFlags );
1728 rWrt.Strm().WriteChar( '>' );
1729
1730 rWrt.IncIndentLevel(); // indent the content
1731 rWrt.m_bLFPossible = true;
1732
1733 const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
1734 SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex();
1735
1736 // Output frame-anchored frames that are anchored to the start node
1737 rWrt.OutFlyFrame( nStt, 0, HtmlPosition::Any );
1738
1739 const SwStartNode* pSttNd = rWrt.m_pDoc->GetNodes()[nStt]->GetStartNode();
1740 OSL_ENSURE( pSttNd, "Where is the start node" );
1741
1742 {
1743 // in a block, so that the old state can be restored in time
1744 // before the end
1745 HTMLSaveData aSaveData( rWrt, nStt+1,
1746 pSttNd->EndOfSectionIndex(),
1747 true, &rFrameFormat );
1748 rWrt.m_bOutFlyFrame = true;
1749 rWrt.Out_SwDoc( rWrt.m_pCurrentPam.get() );
1750 }
1751
1752 rWrt.DecIndentLevel(); // indent the content of Multicol;
1753 if( rWrt.m_bLFPossible )
1754 rWrt.OutNewLine();
1755 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + aTag), false );
1756
1757 if( !aEndTags.isEmpty() )
1758 rWrt.Strm().WriteOString( aEndTags );
1759
1760 return rWrt;
1761}
1762
1764static void OutHTML_ImageOLEStart(SwHTMLWriter& rWrt, const Graphic& rGraphic,
1765 const SwFrameFormat& rFrameFormat)
1766{
1767 if (!rWrt.mbReqIF || !rWrt.m_bExportImagesAsOLE)
1768 return;
1769
1770 // Write the original image as an RTF fragment.
1771 OUString aFileName;
1772 if (rWrt.GetOrigFileName())
1773 aFileName = *rWrt.GetOrigFileName();
1774 INetURLObject aURL(aFileName);
1775 OUString aName = aURL.getBase() + "_" + aURL.getExtension() + "_"
1776 + OUString::number(rGraphic.GetChecksum(), 16);
1777 aURL.setBase(aName);
1778 aURL.setExtension(u"ole");
1779 aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
1780
1781 SvFileStream aOutStream(aFileName, StreamMode::WRITE);
1782 if (!SwReqIfReader::WrapGraphicInRtf(rGraphic, rFrameFormat, aOutStream))
1783 SAL_WARN("sw.html", "SwReqIfReader::WrapGraphicInRtf() failed");
1784
1785 // Refer to this data.
1786 aFileName = URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aFileName);
1787 rWrt.Strm().WriteOString(
1788 Concat2View("<" + rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object));
1789 rWrt.Strm().WriteOString(Concat2View(" data=\"" + aFileName.toUtf8() + "\""));
1790 rWrt.Strm().WriteOString(" type=\"text/rtf\"");
1791 rWrt.Strm().WriteOString(">");
1792 rWrt.OutNewLine();
1793}
1794
1797{
1798 if (rWrt.mbReqIF && rWrt.m_bExportImagesAsOLE)
1799 {
1800 rWrt.Strm().WriteOString(
1801 Concat2View("</" + rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object ">"));
1802 }
1803}
1804
1805static SwHTMLWriter & OutHTML_FrameFormatAsImage( SwHTMLWriter& rWrt, const SwFrameFormat& rFrameFormat, bool bPNGFallback)
1806{
1807 bool bWritePNGFallback = rWrt.mbReqIF && !rWrt.m_bExportImagesAsOLE && bPNGFallback;
1808
1809 if (rWrt.mbSkipImages)
1810 return rWrt;
1811
1812 ImageMap aIMap;
1813 std::optional<Size> aDPI;
1814 if (rWrt.m_nShapeDPI.has_value())
1815 {
1816 aDPI.emplace(*rWrt.m_nShapeDPI, *rWrt.m_nShapeDPI);
1817 }
1818 Graphic aGraphic( const_cast<SwFrameFormat &>(rFrameFormat).MakeGraphic( &aIMap, /*nMaximumQuadraticPixels=*/2100000, aDPI ) );
1819
1820 if (rWrt.mbReqIF)
1821 {
1822 // ImageMap doesn't seem to be allowed in reqif.
1823 if (auto pGrafObj = dynamic_cast<const SdrGrafObj*>(rFrameFormat.FindSdrObject()))
1824 {
1825 aGraphic = pGrafObj->GetGraphic();
1826 }
1827 else
1828 {
1829 // We only have a bitmap, write that as PNG without any fallback.
1830 bWritePNGFallback = false;
1831 }
1832 }
1833
1834 Size aSz( 0, 0 );
1835 OUString GraphicURL;
1836 OUString aMimeType("image/jpeg");
1837 if(!rWrt.mbEmbedImages)
1838 {
1839 if( rWrt.GetOrigFileName() )
1840 GraphicURL = *rWrt.GetOrigFileName();
1841
1842 OUString aFilterName("JPG");
1843 XOutFlags nFlags = XOutFlags::UseGifIfPossible | XOutFlags::UseNativeIfPossible;
1844
1845 if (rWrt.mbReqIF && !bWritePNGFallback)
1846 {
1847 // Writing image without fallback PNG in ReqIF mode: force PNG output.
1848 aFilterName = "PNG";
1849 nFlags = XOutFlags::NONE;
1850 aMimeType = "image/png";
1851 }
1852 else if (rWrt.mbReqIF)
1853 {
1854 // Original format is wanted, don't force JPG.
1855 aFilterName.clear();
1856 aMimeType.clear();
1857 }
1858
1859 if( aGraphic.GetType() == GraphicType::NONE ||
1860 XOutBitmap::WriteGraphic( aGraphic, GraphicURL,
1861 aFilterName,
1862 nFlags ) != ERRCODE_NONE )
1863 {
1864 // empty or incorrect, because there is nothing to output
1866 return rWrt;
1867 }
1868
1869 GraphicURL = URIHelper::SmartRel2Abs(
1870 INetURLObject(rWrt.GetBaseURL()), GraphicURL,
1872
1873 }
1874 uno::Reference<beans::XPropertySet> xGraphic(aGraphic.GetXGraphic(), uno::UNO_QUERY);
1875 if (xGraphic.is() && aMimeType.isEmpty())
1876 xGraphic->getPropertyValue("MimeType") >>= aMimeType;
1877
1878 OutHTML_ImageOLEStart(rWrt, aGraphic, rFrameFormat);
1879
1880 HtmlWriter aHtml(rWrt.Strm(), rWrt.maNamespace);
1881 OutHTML_ImageStart( aHtml, rWrt, rFrameFormat, GraphicURL, aGraphic, rFrameFormat.GetName(), aSz,
1882 HtmlFrmOpts::GenImgMask, "frame",
1883 aIMap.GetIMapObjectCount() ? &aIMap : nullptr, aMimeType );
1884
1885 GfxLink aLink = aGraphic.GetGfxLink();
1886 if (bWritePNGFallback && aLink.GetType() != GfxLinkType::NativePng)
1887 {
1888 OutHTML_FrameFormatAsImage( rWrt, rFrameFormat, /*bPNGFallback=*/false);
1889 }
1890
1891 OutHTML_ImageEnd(aHtml, rWrt);
1892
1893 OutHTML_ImageOLEEnd(rWrt);
1894
1895 return rWrt;
1896}
1897
1899 bool bInCntnr, bool bPNGFallback )
1900{
1901 bool bWritePNGFallback = rWrt.mbReqIF && !rWrt.m_bExportImagesAsOLE && bPNGFallback;
1902
1903 if (rWrt.mbSkipImages)
1904 return rWrt;
1905
1906 const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
1907 SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex()+1;
1908 SwGrfNode *pGrfNd = rWrt.m_pDoc->GetNodes()[ nStt ]->GetGrfNode();
1909 OSL_ENSURE( pGrfNd, "Grf node expected" );
1910 if( !pGrfNd )
1911 return rWrt;
1912
1913 HtmlFrmOpts nFrameFlags = bInCntnr ? HTML_FRMOPTS_IMG_CNTNR : HTML_FRMOPTS_IMG;
1914 if( rWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
1915 nFrameFlags |= HTML_FRMOPTS_IMG_CSS1;
1916
1917 Graphic aGraphic = pGrfNd->GetGraphic();
1918
1919 if (aGraphic.GetType() == GraphicType::GdiMetafile)
1920 {
1921 // We only have a metafile, write that as PNG without any fallback.
1922 bWritePNGFallback = false;
1923 }
1924
1925 OUString aGraphicURL;
1926 OUString aMimeType;
1927 if(!rWrt.mbEmbedImages)
1928 {
1929 const SwMirrorGrf& rMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf();
1930
1931 if( !pGrfNd->IsLinkedFile() || MirrorGraph::Dont != rMirror.GetValue() )
1932 {
1933 // create a (mirrored) jpeg file
1934 if( rWrt.GetOrigFileName() )
1935 aGraphicURL = *rWrt.GetOrigFileName();
1936 else
1937 aGraphicURL = rWrt.GetBaseURL();
1938 pGrfNd->GetGrf( true );
1939
1940 XOutFlags nFlags = XOutFlags::UseGifIfSensible |
1941 XOutFlags::UseNativeIfPossible;
1942 switch( rMirror.GetValue() )
1943 {
1944 case MirrorGraph::Vertical: nFlags = XOutFlags::MirrorHorz; break;
1945 case MirrorGraph::Horizontal: nFlags = XOutFlags::MirrorVert; break;
1946 case MirrorGraph::Both:
1947 nFlags = XOutFlags::MirrorVert | XOutFlags::MirrorHorz;
1948 break;
1949 default: break;
1950 }
1951
1952 const SwFormatFrameSize& rSize = rFrameFormat.GetFrameSize();
1953 Size aMM100Size = o3tl::convert( rSize.GetSize(),
1955
1956 OUString aFilterName("");
1957
1958 if (rWrt.mbReqIF && !bWritePNGFallback)
1959 {
1960 // Writing image without fallback PNG in ReqIF mode: force PNG
1961 // output.
1962 // But don't force it when writing the original format and we'll write PNG inside
1963 // that.
1964 aFilterName = "PNG";
1965 nFlags &= ~XOutFlags::UseNativeIfPossible;
1966 nFlags &= ~XOutFlags::UseGifIfSensible;
1967 aMimeType = "image/png";
1968 }
1969
1970 const Graphic& rGraphic = pGrfNd->GetGrf();
1971
1972 // So that Graphic::IsTransparent() can report true.
1973 if (!rGraphic.isAvailable())
1974 const_cast<Graphic&>(rGraphic).makeAvailable();
1975
1976 if (rWrt.mbReqIF && bWritePNGFallback)
1977 {
1978 // ReqIF: force native data if possible.
1979 const std::shared_ptr<VectorGraphicData>& pVectorGraphicData = rGraphic.getVectorGraphicData();
1980 if (pVectorGraphicData && pVectorGraphicData->getType() == VectorGraphicDataType::Svg)
1981 {
1982 aFilterName = "svg";
1983 }
1984 else if (rGraphic.GetGfxLink().IsEMF())
1985 {
1986 aFilterName = "emf";
1987 aMimeType = "image/x-emf"; // avoid image/x-wmf
1988 }
1989 else if (pVectorGraphicData && pVectorGraphicData->getType() == VectorGraphicDataType::Wmf)
1990 {
1991 aFilterName = "wmf";
1992 }
1993 else if (rGraphic.GetGfxLink().GetType() == GfxLinkType::NativeTif)
1994 {
1995 aFilterName = "tif";
1996 aMimeType = "image/tiff"; // avoid image/x-vclgraphic
1997 }
1998 }
1999
2000 ErrCode nErr = XOutBitmap::WriteGraphic( rGraphic, aGraphicURL,
2001 aFilterName, nFlags, &aMM100Size );
2002 if( nErr )
2003 {
2005 return rWrt;
2006 }
2007 aGraphicURL = URIHelper::SmartRel2Abs(
2008 INetURLObject(rWrt.GetBaseURL()), aGraphicURL,
2010 }
2011 else
2012 {
2013 pGrfNd->GetFileFilterNms( &aGraphicURL, nullptr );
2014 if( rWrt.m_bCfgCpyLinkedGrfs )
2015 rWrt.CopyLocalFileToINet( aGraphicURL );
2016 }
2017
2018 }
2019 uno::Reference<beans::XPropertySet> xGraphic(aGraphic.GetXGraphic(), uno::UNO_QUERY);
2020 if (xGraphic.is() && aMimeType.isEmpty())
2021 xGraphic->getPropertyValue("MimeType") >>= aMimeType;
2022
2023 OutHTML_ImageOLEStart(rWrt, aGraphic, rFrameFormat);
2024
2025 HtmlWriter aHtml(rWrt.Strm(), rWrt.maNamespace);
2026 OutHTML_ImageStart( aHtml, rWrt, rFrameFormat, aGraphicURL, aGraphic, pGrfNd->GetTitle(),
2027 pGrfNd->GetTwipSize(), nFrameFlags, "graphic", nullptr, aMimeType );
2028
2029 GfxLink aLink = aGraphic.GetGfxLink();
2030 if (bWritePNGFallback && aLink.GetType() != GfxLinkType::NativePng)
2031 {
2032 // Not OLE mode, outer format is not PNG: write inner PNG.
2033 OutHTML_FrameFormatGrfNode( rWrt, rFrameFormat,
2034 bInCntnr, /*bPNGFallback=*/false );
2035 }
2036
2037 OutHTML_ImageEnd(aHtml, rWrt);
2038
2039 OutHTML_ImageOLEEnd(rWrt);
2040
2041 return rWrt;
2042}
2043
2045 const SdrObject& rSdrObj )
2046{
2047 // get the edit engine attributes of the object as SW attributes and
2048 // sort them as Hints
2049 const SfxItemSet& rFormatItemSet = rFrameFormat.GetAttrSet();
2050 SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END> aItemSet( *rFormatItemSet.GetPool() );
2051 SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, &rSdrObj );
2052 bool bCfgOutStylesOld = rWrt.m_bCfgOutStyles;
2053 rWrt.m_bCfgOutStyles = false;
2054 rWrt.m_bTextAttr = true;
2055 rWrt.m_bTagOn = true;
2056 Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, false );
2057 rWrt.m_bTextAttr = false;
2058
2060 static_cast<const SwDrawFrameFormat &>(rFrameFormat),
2061 rSdrObj );
2062 rWrt.m_bTextAttr = true;
2063 rWrt.m_bTagOn = false;
2064 Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, false );
2065 rWrt.m_bTextAttr = false;
2066 rWrt.m_bCfgOutStyles = bCfgOutStylesOld;
2067
2068 return rWrt;
2069}
2070
2072 bool bHeader )
2073{
2074 // output as Multicol
2075 rWrt.OutNewLine();
2076 OStringBuffer sOut;
2077 sOut.append(OOO_STRING_SVTOOLS_HTML_division " "
2079 .append( bHeader ? "header" : "footer" ).append("\"");
2080 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + sOut) );
2081
2082 rWrt.IncIndentLevel(); // indent the content of Multicol;
2083
2084 // Piece a spacer for the spacing together. Because the
2085 // <DL> or </DL> always produces a space between paragraphs, it is
2086 // subtracted if necessary.
2087 const SvxULSpaceItem& rULSpace = rFrameFormat.GetULSpace();
2088 sal_uInt16 nSize = bHeader ? rULSpace.GetLower() : rULSpace.GetUpper();
2089 rWrt.m_nHeaderFooterSpace = nSize;
2090
2091 OString aSpacer;
2092 if( rWrt.IsHTMLMode(HTMLMODE_VERT_SPACER) &&
2094 {
2095 nSize -= HTML_PARSPACE;
2096 nSize = static_cast<sal_Int16>(Application::GetDefaultDevice()
2097 ->LogicToPixel( Size(nSize,0), MapMode(MapUnit::MapTwip) ).Width());
2098
2103 "=\"" + OString::number(nSize) + "\"";
2104 }
2105
2106 const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
2107 SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex();
2108 const SwStartNode* pSttNd = rWrt.m_pDoc->GetNodes()[nStt]->GetStartNode();
2109 OSL_ENSURE( pSttNd, "Where is the start node" );
2110
2111 if( !bHeader && !aSpacer.isEmpty() )
2112 {
2113 rWrt.OutNewLine();
2114 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + aSpacer) );
2115 }
2116
2117 {
2118 // in a block, so that the old state can be restored in time
2119 // before the end. pFlyFormat doesn't need to be set here, because
2120 // PageDesc attributes cannot occur here
2121 HTMLSaveData aSaveData( rWrt, nStt+1,
2122 pSttNd->EndOfSectionIndex() );
2123
2124 if( bHeader )
2125 rWrt.m_bOutHeader = true;
2126 else
2127 rWrt.m_bOutFooter = true;
2128
2129 rWrt.Out_SwDoc( rWrt.m_pCurrentPam.get() );
2130 }
2131
2132 if( bHeader && !aSpacer.isEmpty() )
2133 {
2134 rWrt.OutNewLine();
2135 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + aSpacer) );
2136 }
2137
2138 rWrt.DecIndentLevel(); // indent the content of Multicol;
2139 rWrt.OutNewLine();
2140 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_division), false );
2141
2142 rWrt.m_nHeaderFooterSpace = 0;
2143
2144 return rWrt;
2145}
2146
2147void SwHTMLWriter::AddLinkTarget( std::u16string_view aURL )
2148{
2149 if( aURL.empty() || aURL[0] != '#' )
2150 return;
2151
2152 // There might be a '|' as delimiter (if the link has been inserted
2153 // freshly) or a '%7c' or a '%7C' if the document has been saved and
2154 // loaded already.
2155 sal_Int32 nPos = aURL.size();
2156 bool bFound = false, bEncoded = false;
2157 while( !bFound && nPos > 0 )
2158 {
2159 sal_Unicode c = aURL[ --nPos ];
2160 switch( c )
2161 {
2162 case cMarkSeparator:
2163 bFound = true;
2164 break;
2165 case '%':
2166 bFound = (aURL.size() - nPos) >=3 && aURL[ nPos+1 ] == '7';
2167 if(bFound)
2168 {
2169 c = aURL[ nPos+2 ];
2170 bFound = (c == 'C' || c == 'c');
2171 }
2172 if( bFound )
2173 bEncoded = true;
2174 }
2175 }
2176 if( !bFound || nPos < 2 ) // at least "#a|..."
2177 return;
2178
2179 aURL = aURL.substr( 1 );
2180
2181 // nPos-1+1/3 (-1 because of Erase)
2182 OUString sCmp = OUString(aURL.substr(bEncoded ? nPos+2 : nPos)).replaceAll(" ","");
2183 if( sCmp.isEmpty() )
2184 return;
2185
2186 sCmp = sCmp.toAsciiLowerCase();
2187
2188 if( sCmp == "region" ||
2189 sCmp == "frame" ||
2190 sCmp == "graphic" ||
2191 sCmp == "ole" ||
2192 sCmp == "table" )
2193 {
2194 // Just remember it in a sorted array
2195 OUString aURL2(aURL);
2196 if( bEncoded )
2197 {
2198 aURL2 = aURL2.replaceAt( nPos - 1, 3, rtl::OUStringChar(cMarkSeparator) );
2199 }
2200 m_aImplicitMarks.insert( aURL2 );
2201 }
2202 else if( sCmp == "outline" )
2203 {
2204 // Here, we need position and name. That's why we sort a
2205 // sal_uInt16 and a string array ourselves.
2206 OUString aOutline( aURL.substr( 0, nPos-1 ) );
2207 SwPosition aPos( *m_pCurrentPam->GetPoint() );
2208 if( m_pDoc->GotoOutline( aPos, aOutline ) )
2209 {
2210 SwNodeOffset nIdx = aPos.GetNodeIndex();
2211
2212 decltype(m_aOutlineMarkPoss)::size_type nIns=0;
2213 while( nIns < m_aOutlineMarkPoss.size() &&
2214 m_aOutlineMarkPoss[nIns] < nIdx )
2215 nIns++;
2216
2217 m_aOutlineMarkPoss.insert( m_aOutlineMarkPoss.begin()+nIns, nIdx );
2218 OUString aURL2(aURL);
2219 if( bEncoded )
2220 {
2221 aURL2 = aURL2.replaceAt( nPos - 1, 3, rtl::OUStringChar(cMarkSeparator) );
2222 }
2223 m_aOutlineMarks.insert( m_aOutlineMarks.begin()+nIns, aURL2 );
2224 }
2225 }
2226}
2227
2229{
2230 const SwTextINetFormat* pTextAttr;
2231
2233 {
2234 auto pINetFormat = dynamic_cast<const SwFormatINetFormat*>(pItem);
2235 const SwTextNode* pTextNd;
2236
2237 if( pINetFormat &&
2238 nullptr != ( pTextAttr = pINetFormat->GetTextINetFormat()) &&
2239 nullptr != ( pTextNd = pTextAttr->GetpTextNode() ) &&
2240 pTextNd->GetNodes().IsDocNodes() )
2241 {
2242 AddLinkTarget( pINetFormat->GetValue() );
2243 }
2244 }
2245
2246 for (const SfxPoolItem* pItem : m_pDoc->GetAttrPool().GetItemSurrogates(RES_URL))
2247 {
2248 auto pURL = dynamic_cast<const SwFormatURL*>(pItem);
2249 if( pURL )
2250 {
2251 AddLinkTarget( pURL->GetURL() );
2252 const ImageMap *pIMap = pURL->GetMap();
2253 if( pIMap )
2254 {
2255 for( size_t i=0; i<pIMap->GetIMapObjectCount(); ++i )
2256 {
2257 const IMapObject* pObj = pIMap->GetIMapObject( i );
2258 if( pObj )
2259 {
2260 AddLinkTarget( pObj->GetURL() );
2261 }
2262 }
2263 }
2264 }
2265 }
2266}
2267
2268/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
GPOS_NONE
constexpr int nBorderWidth
static OutputDevice * GetDefaultDevice()
bool isAvailable() const
css::uno::Reference< css::graphic::XGraphic > GetXGraphic() const
GraphicType GetType() const
GfxLink GetGfxLink() const
BitmapChecksum GetChecksum() const
const std::shared_ptr< VectorGraphicData > & getVectorGraphicData() const
void attribute(std::string_view aAttribute, const char *aValue)
void flushStack()
bool end(const OString &aElement)
void start(const OString &aElement)
void characters(std::string_view rChars)
const OUString & GetURL() const
const OUString & GetName() const
IMapObject * GetIMapObject(size_t nPos) const
size_t GetIMapObjectCount() const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
EnumT GetValue() const
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
SfxItemPool * GetPool() const
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
void setWidth(tools::Long nWidth)
tools::Long AdjustWidth(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
SvStream & WriteOString(std::string_view rStr)
SvStream & WriteChar(char nChar)
const editeng::SvxBorderLine * GetTop() const
sal_Int16 CalcLineSpace(SvxBoxItemLine nLine, bool bEvenIfNoLine=false, bool bAllowNegative=false) const
const editeng::SvxBorderLine * GetRight() const
const editeng::SvxBorderLine * GetLeft() const
const editeng::SvxBorderLine * GetBottom() const
const Graphic * GetGraphic(OUString const &referer=OUString()) const
const OUString & GetGraphicLink() const
tools::Long GetRight() const
tools::Long GetLeft() const
const SvxMacroTableDtor & GetMacroTable() const
bool empty() const
tools::Long GetRight() const
tools::Long GetHeight() const
tools::Long GetWidth() const
const Size & GetSize() const
tools::Long GetTextLeft() const
sal_uInt16 GetUpper() const
sal_uInt16 GetLower() const
const SwMirrorGrf & GetMirrorGrf(bool=true) const
Definition: grfatr.hxx:282
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:770
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:765
bool GotoOutline(SwPosition &rPos, const OUString &rName, SwRootFrame const *=nullptr) const
Definition: docnum.cxx:733
SwNodes & GetNodes()
Definition: doc.hxx:420
SwPosFlyFrames GetAllFlyFormats(const SwPaM *, bool bDrawAlso, bool bAsCharAlso=false) const
Returns positions of all FlyFrames in the document.
Definition: doclay.cxx:498
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1331
FlyAnchors.
Definition: fmtanchr.hxx:37
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1606
sal_uInt16 GetGutterWidth(bool bMin=false) const
Definition: atrfrm.cxx:918
sal_uInt16 GetNumCols() const
Definition: fmtclds.hxx:114
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:32
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
SwFrameSize GetHeightSizeType() const
Definition: fmtfsize.hxx:80
sal_uInt8 GetHeightPercent() const
Definition: fmtfsize.hxx:88
Defines the horizontal position of a fly frame.
Definition: fmtornt.hxx:73
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:94
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:95
bool IsAnchorOnly() const
Definition: fmtsrnd.hxx:52
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
const ImageMap * GetMap() const
Definition: fmturl.hxx:68
const OUString & GetName() const
Definition: fmturl.hxx:71
const OUString & GetTargetFrameName() const
Definition: fmturl.hxx:65
const OUString & GetURL() const
Definition: fmturl.hxx:66
bool IsServerMap() const
Definition: fmturl.hxx:67
Defines the vertical position of a fly frame.
Definition: fmtornt.hxx:37
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:57
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:108
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const OUString & GetName() const
Definition: format.hxx:131
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:88
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:115
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:100
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
std::unique_ptr< SvxBrushItem > makeBackgroundBrushItem(bool=true) const
Definition: format.cxx:736
Style of a layout element.
Definition: frmfmt.hxx:62
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:141
virtual Size GetTwipSize() const override
Definition: ndgrf.cxx:432
bool IsLinkedFile() const
Definition: ndgrf.hxx:164
const Graphic & GetGrf(bool bWait=false) const
Definition: ndgrf.cxx:373
bool GetFileFilterNms(OUString *pFileNm, OUString *pFilterNm) const
Definition: ndgrf.cxx:493
HtmlOut GetOutFn() const
Definition: htmlfly.hxx:120
const SdrObject * GetSdrObject() const
Definition: htmlfly.hxx:116
const SwFrameFormat & GetFormat() const
Definition: htmlfly.hxx:115
sal_Int32 GetContentIndex() const
Definition: htmlfly.hxx:118
AllHtmlFlags const & GetOutMode() const
Definition: htmlfly.hxx:119
HtmlPosition GetOutPos() const
Definition: htmlfly.hxx:121
bool mbXHTML
If XHTML markup should be written instead of HTML.
Definition: wrthtml.hxx:410
std::vector< OUString > m_aOutlineMarks
Definition: wrthtml.hxx:302
bool m_bOutHeader
Definition: wrthtml.hxx:378
void CollectLinkTargets()
void OutAndSetDefList(sal_uInt16 nNewLvl)
Definition: htmlatr.cxx:120
SwHTMLPosFlyFrames m_aHTMLPosFlyFrames
Definition: wrthtml.hxx:274
sal_uInt16 GuessFrameType(const SwFrameFormat &rFrameFormat, const SdrObject *&rpStrObj)
void ChangeParaToken(HtmlTokenId nNew)
Definition: htmlatr.cxx:158
static const SdrObject * GetMarqueeTextObj(const SwDrawFrameFormat &rFormat)
sal_uInt16 m_nImgMapCnt
Definition: wrthtml.hxx:328
std::set< OUString > m_aImplicitMarks
Definition: wrthtml.hxx:298
bool mbSkipImages
Definition: wrthtml.hxx:403
static OString convertDirection(SvxFrameDirection nDirection)
Definition: wrthtml.cxx:1499
std::vector< OUString > m_aImgMapNames
Definition: wrthtml.hxx:297
bool mbEmbedImages
Definition: wrthtml.hxx:406
void IncIndentLevel()
Definition: wrthtml.hxx:526
void OutDirection(SvxFrameDirection nDir)
Definition: wrthtml.cxx:1487
static sal_uInt16 GuessOLENodeFrameType(const SwNode &rNd)
Definition: htmlplug.cxx:1193
void OutFrameFormat(AllHtmlFlags nType, const SwFrameFormat &rFormat, const SdrObject *pSdrObj)
bool m_bLFPossible
Definition: wrthtml.hxx:395
ErrCode m_nWarn
Definition: wrthtml.hxx:323
OUString convertHyperlinkHRefValue(const OUString &rURL)
Definition: wrthtml.cxx:1340
bool m_bTextAttr
Definition: wrthtml.hxx:373
bool m_bClearRight
Definition: wrthtml.hxx:394
std::optional< sal_Int32 > m_nShapeDPI
DPI used when exporting a vector shape as a bitmap.
Definition: wrthtml.hxx:431
std::vector< SwNodeOffset > m_aOutlineMarkPoss
Definition: wrthtml.hxx:303
std::unique_ptr< utl::TempFileNamed > mpTempBaseURL
Temporary base URL for paste of images.
Definition: wrthtml.hxx:408
bool m_bTagOn
Definition: wrthtml.hxx:364
bool m_bOutFlyFrame
Definition: wrthtml.hxx:380
bool m_bCfgOutStyles
Definition: wrthtml.hxx:355
void AddLinkTarget(std::u16string_view aURL)
bool m_bExportImagesAsOLE
ReqIF mode: export images as OLE objects.
Definition: wrthtml.hxx:428
sal_Int32 m_nDfltRightMargin
Definition: wrthtml.hxx:334
std::vector< SwFormatINetFormat * > m_aINetFormats
Definition: wrthtml.hxx:307
void DecIndentLevel()
Definition: wrthtml.hxx:530
OString GetNamespace() const
Determines the prefix string needed to respect the requested namespace alias.
Definition: wrthtml.cxx:1583
void Out_SwDoc(SwPaM *)
Definition: wrthtml.cxx:895
sal_uInt16 m_nExportMode
Definition: wrthtml.hxx:345
sal_Int32 m_nDfltLeftMargin
Definition: wrthtml.hxx:333
bool mbReqIF
If the ReqIF subset of XHTML should be written.
Definition: wrthtml.hxx:414
OString OutFrameFormatOptions(const SwFrameFormat &rFrameFormat, const OUString &rAltText, HtmlFrmOpts nFrameOpts)
OString GetIndentString(sal_uInt16 nIncLvl=0)
Definition: wrthtml.cxx:1517
void OutCSS1_FrameFormatOptions(const SwFrameFormat &rFrameFormat, HtmlFrmOpts nFrameOpts, const SdrObject *pSdrObj=nullptr, const SfxItemSet *pItemSet=nullptr)
Definition: css1atr.cxx:1842
void CollectFlyFrames()
sal_uInt16 m_nDfltTopMargin
Definition: wrthtml.hxx:337
bool m_bClearLeft
Definition: wrthtml.hxx:393
sal_uInt16 m_nHeaderFooterSpace
Definition: wrthtml.hxx:343
sal_uInt16 m_nDfltBottomMargin
Definition: wrthtml.hxx:338
void OutNewLine(bool bCheck=false)
Definition: wrthtml.cxx:1534
OString maNamespace
XML namespace, in case of XHTML.
Definition: wrthtml.hxx:412
void writeFrameFormatOptions(HtmlWriter &aHtml, const SwFrameFormat &rFrameFormat, std::u16string_view rAltText, HtmlFrmOpts nFrameOpts)
bool m_bCfgStarBasic
Definition: wrthtml.hxx:358
static const SdrObject * GetHTMLControl(const SwDrawFrameFormat &rFormat)
Definition: htmlforw.cxx:614
bool IsHTMLMode(sal_uInt32 nMode) const
Definition: wrthtml.hxx:599
SvxFrameDirection GetHTMLDirection(SvxFrameDirection nDir) const
Definition: wrthtml.cxx:1468
static void GetEEAttrsFromDrwObj(SfxItemSet &rItemSet, const SdrObject *pObj)
bool m_bCfgCpyLinkedGrfs
Definition: wrthtml.hxx:359
void OutImplicitMark(std::u16string_view rMark, const char *pMarkType)
Definition: wrthtml.cxx:1327
bool OutFlyFrame(SwNodeOffset nNdIdx, sal_Int32 nContentIdx, HtmlPosition nPos)
bool m_bOutFooter
Definition: wrthtml.hxx:379
OUString GetTitle() const
Definition: ndnotxt.cxx:258
Graphic GetGraphic() const
Definition: ndnotxt.cxx:229
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
Base class of the Writer document model elements.
Definition: node.hxx:98
bool IsGrfNode() const
Definition: node.hxx:707
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:903
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:744
bool IsTableNode() const
Definition: node.hxx:691
bool IsTextNode() const
Definition: node.hxx:687
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:728
SwContentNode * GetContentNode()
Definition: node.hxx:666
SwTableNode * GetTableNode()
Definition: node.hxx:650
bool IsOLENode() const
Definition: node.hxx:703
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc....
Definition: nodes.cxx:2538
For querying current flys in document.
Definition: flypos.hxx:31
Starts a section of nodes in the document model.
Definition: node.hxx:348
const SwTextNode * GetpTextNode() const
Definition: txtinet.hxx:45
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:291
const OUString & GetText() const
Definition: ndtxt.hxx:244
const OUString * GetOrigFileName() const
Definition: shellio.hxx:438
SvStream & Strm()
Definition: writer.cxx:214
SwDoc * m_pDoc
Definition: shellio.hxx:407
std::shared_ptr< SwUnoCursor > m_pCurrentPam
Definition: shellio.hxx:409
bool m_bWriteAll
Definition: shellio.hxx:410
const OUString & GetBaseURL() const
Definition: shellio.hxx:443
bool CopyLocalFileToINet(OUString &rFileNm)
Definition: writer.cxx:299
static ErrCode WriteGraphic(const Graphic &rGraphic, OUString &rFileName, const OUString &rFilterName, const XOutFlags nFlags, const Size *pMtfSize_100TH_MM=nullptr, const css::uno::Sequence< css::beans::PropertyValue > *pFilterData=nullptr)
static bool GraphicToBase64(const Graphic &rGraphic, OUString &rOUString, bool bAddPrefix=true, ConvertDataFormat aTargetFormat=ConvertDataFormat::Unknown)
Value erase_extract(size_t index)
bool empty() const
size_type size() const
std::pair< const_iterator, bool > insert(Value &&x)
tools::Long getOpenHeight() const
tools::Long getOpenWidth() const
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
URL aURL
float u
EmbeddedObjectRef * pObject
#define ERRCODE_NONE
std::set< SwPosFlyFrame, SwPosFlyFrameCmp > SwPosFlyFrames
Definition: flypos.hxx:45
DocumentType eType
@ Fixed
Frame cannot be moved in Var-direction.
SvxFrameDirection
constexpr TypedWhichId< SwFormatURL > RES_URL(117)
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
constexpr TypedWhichId< SwFormatCol > RES_COL(115)
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(108)
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
constexpr TypedWhichId< SvxMacroItem > RES_FRMMACRO(114)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(165)
constexpr TypedWhichId< SvxBoxItem > RES_BOX(112)
constexpr TypedWhichId< SvxRightMarginItem > RES_MARGIN_RIGHT(93)
constexpr TypedWhichId< SvxTextLeftMarginItem > RES_MARGIN_TEXTLEFT(92)
constexpr TypedWhichId< SwFormatSurround > RES_SURROUND(107)
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(97)
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(98)
HTMLOutEvent const aAnchorEventTable[]
Definition: htmlatr.cxx:86
SwAttrFnTab aHTMLAttrFnTab
Definition: htmlatr.cxx:3211
SwHTMLWriter & OutHTML_INetFormat(SwHTMLWriter &rWrt, const SwFormatINetFormat &rINetFormat, bool bOn)
Definition: htmlatr.cxx:2950
#define HTML_CFG_MAX
SwHTMLWriter & OutHTML_DrawFrameFormatAsMarquee(SwHTMLWriter &rWrt, const SwDrawFrameFormat &rFormat, const SdrObject &rSdrObject)
HtmlContainerFlags
Definition: htmlfly.hxx:73
SwHTMLFrameType
Definition: htmlfly.hxx:34
@ HTML_FRMTYPE_GRF
Definition: htmlfly.hxx:40
@ HTML_FRMTYPE_MARQUEE
Definition: htmlfly.hxx:45
@ HTML_FRMTYPE_MULTICOL
Definition: htmlfly.hxx:37
@ HTML_FRMTYPE_EMPTY
Definition: htmlfly.hxx:38
@ HTML_FRMTYPE_CONTROL
Definition: htmlfly.hxx:46
@ HTML_FRMTYPE_DRAW
Definition: htmlfly.hxx:47
@ HTML_FRMTYPE_TABLE
Definition: htmlfly.hxx:35
@ HTML_FRMTYPE_TEXT
Definition: htmlfly.hxx:39
@ HTML_FRMTYPE_TABLE_CAP
Definition: htmlfly.hxx:36
const sal_uInt16 MAX_BROWSERS
Definition: htmlfly.hxx:83
AllHtmlFlags const aHTMLOutFramePageFlyTable[MAX_FRMTYPES][MAX_BROWSERS]
Definition: htmlflyt.cxx:24
AllHtmlFlags const aHTMLOutFrameParaFrameTable[MAX_FRMTYPES][MAX_BROWSERS]
Definition: htmlflyt.cxx:120
HtmlPosition
Definition: htmlfly.hxx:66
HtmlOut
Definition: htmlfly.hxx:51
@ GraphicFrame
AllHtmlFlags const aHTMLOutFrameParaOtherTable[MAX_FRMTYPES][MAX_BROWSERS]
Definition: htmlflyt.cxx:313
AllHtmlFlags const aHTMLOutFrameParaPrtAreaTable[MAX_FRMTYPES][MAX_BROWSERS]
Definition: htmlflyt.cxx:217
SwHTMLWriter & OutHTML_HeaderFooter(SwHTMLWriter &rWrt, const SwFrameFormat &rFrameFormat, bool bHeader)
static SwHTMLWriter & OutHTML_FrameFormatAsDivOrSpan(SwHTMLWriter &rWrt, const SwFrameFormat &rFrameFormat, bool bSpan)
SwHTMLWriter & OutHTML_BulletImage(SwHTMLWriter &rWrt, const char *pTag, const SvxBrushItem *pBrush, const OUString &rGraphicURL)
static SwHTMLWriter & OutHTML_FrameFormatTableNode(SwHTMLWriter &rWrt, const SwFrameFormat &rFrameFormat)
HTMLOutEvent const aIMapEventTable[]
HTMLOutEvent const aImageEventTable[]
const HtmlFrmOpts HTML_FRMOPTS_SPACER
static SwHTMLWriter & OutHTML_FrameFormatAsMulticol(SwHTMLWriter &rWrt, const SwFrameFormat &rFormat, bool bInCntnr)
SwHTMLWriter & OutHTML_ImageStart(HtmlWriter &rHtml, SwHTMLWriter &rWrt, const SwFrameFormat &rFrameFormat, const OUString &rGraphicURL, Graphic const &rGraphic, const OUString &rAlternateText, const Size &rRealSize, HtmlFrmOpts nFrameOpts, const char *pMarkType, const ImageMap *pAltImgMap, const OUString &rMimeType)
const HtmlFrmOpts HTML_FRMOPTS_IMG_CNTNR
SwHTMLWriter & OutHTML_ImageEnd(HtmlWriter &rHtml, SwHTMLWriter &rWrt)
static SwHTMLWriter & OutHTML_FrameFormatGrfNode(SwHTMLWriter &rWrt, const SwFrameFormat &rFormat, bool bInCntnr, bool bPNGFallback)
const HtmlFrmOpts HTML_FRMOPTS_IMG
static void OutHTML_ImageOLEEnd(SwHTMLWriter &rWrt)
Ends the OLE version of an image in the ReqIF + OLE case.
const HtmlFrmOpts HTML_FRMOPTS_DIV
const HtmlFrmOpts HTML_FRMOPTS_MULTICOL
static SwHTMLWriter & OutHTML_FrameFormatAsImage(SwHTMLWriter &rWrt, const SwFrameFormat &rFormat, bool bPNGFallback)
const HtmlFrmOpts HTML_FRMOPTS_CNTNR
const HtmlFrmOpts HTML_FRMOPTS_MULTICOL_CSS1
static SwHTMLWriter & OutHTML_FrameFormatAsMarquee(SwHTMLWriter &rWrt, const SwFrameFormat &rFrameFormat, const SdrObject &rSdrObj)
const HtmlFrmOpts HTML_FRMOPTS_IMG_CSS1
const HtmlFrmOpts HTML_FRMOPTS_IMG_ALL
static void OutHTML_ImageOLEStart(SwHTMLWriter &rWrt, const Graphic &rGraphic, const SwFrameFormat &rFrameFormat)
Starts the OLE version of an image in the ReqIF + OLE case.
static SwHTMLWriter & OutHTML_FrameFormatAsSpacer(SwHTMLWriter &rWrt, const SwFrameFormat &rFormat)
SwHTMLWriter & OutHTML_DrawFrameFormatAsControl(SwHTMLWriter &rWrt, const SwDrawFrameFormat &rFormat, const SdrUnoObj &rFormObj, bool bInCntnr)
Definition: htmlforw.cxx:673
#define OOO_STRING_SVTOOLS_HTML_O_height
#define OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical
#define OOO_STRING_SVTOOLS_HTML_O_data
#define OOO_STRING_SVTOOLS_HTML_O_target
#define OOO_STRING_SVTOOLS_HTML_O_clear
#define OOO_STRING_SVTOOLS_HTML_O_color
#define OOO_STRING_SVTOOLS_HTML_AL_left
#define OOO_STRING_SVTOOLS_HTML_O_SDonmouseover
#define OOO_STRING_SVTOOLS_HTML_O_align
#define OOO_STRING_SVTOOLS_HTML_division
#define OOO_STRING_SVTOOLS_HTML_O_title
#define OOO_STRING_SVTOOLS_HTML_O_SDonerror
#define OOO_STRING_SVTOOLS_HTML_VA_middle
#define OOO_STRING_SVTOOLS_HTML_O_SDonmouseout
#define OOO_STRING_SVTOOLS_HTML_O_onmouseout
#define OOO_STRING_SVTOOLS_HTML_O_dir
#define OOO_STRING_SVTOOLS_HTML_spacer
#define OOO_STRING_SVTOOLS_HTML_O_onmouseover
#define OOO_STRING_SVTOOLS_HTML_VA_absmiddle
#define OOO_STRING_SVTOOLS_HTML_O_size
#define OOO_STRING_SVTOOLS_HTML_SPTYPE_block
#define OOO_STRING_SVTOOLS_HTML_anchor
#define OOO_STRING_SVTOOLS_HTML_VA_bottom
#define OOO_STRING_SVTOOLS_HTML_O_onerror
#define OOO_STRING_SVTOOLS_HTML_multicol
#define OOO_STRING_SVTOOLS_HTML_span
#define OOO_STRING_SVTOOLS_HTML_VA_absbottom
#define OOO_STRING_SVTOOLS_HTML_O_src
#define OOO_STRING_SVTOOLS_HTML_VA_top
#define OOO_STRING_SVTOOLS_HTML_O_cols
#define OOO_STRING_SVTOOLS_HTML_O_SDonabort
#define OOO_STRING_SVTOOLS_HTML_image
#define OOO_STRING_SVTOOLS_HTML_O_SDonload
#define OOO_STRING_SVTOOLS_HTML_map
#define OOO_STRING_SVTOOLS_HTML_O_class
#define OOO_STRING_SVTOOLS_HTML_O_href
#define OOO_STRING_SVTOOLS_HTML_O_onabort
#define OOO_STRING_SVTOOLS_HTML_O_hspace
#define OOO_STRING_SVTOOLS_HTML_VA_texttop
#define OOO_STRING_SVTOOLS_HTML_AL_right
#define OOO_STRING_SVTOOLS_HTML_O_ismap
#define OOO_STRING_SVTOOLS_HTML_O_border
#define OOO_STRING_SVTOOLS_HTML_O_vspace
#define OOO_STRING_SVTOOLS_HTML_O_type
#define OOO_STRING_SVTOOLS_HTML_O_onload
#define OOO_STRING_SVTOOLS_HTML_O_name
#define OOO_STRING_SVTOOLS_HTML_font
#define OOO_STRING_SVTOOLS_HTML_O_id
#define OOO_STRING_SVTOOLS_HTML_O_gutter
#define OOO_STRING_SVTOOLS_HTML_O_width
#define OOO_STRING_SVTOOLS_HTML_object
#define OOO_STRING_SVTOOLS_HTML_linebreak
#define OOO_STRING_SVTOOLS_HTML_O_usemap
#define OOO_STRING_SVTOOLS_HTML_O_alt
#define OOO_STRING_SVTOOLS_HTML_O_style
SwHTMLWriter & OutHTML_FrameFormatOLENode(SwHTMLWriter &rWrt, const SwFrameFormat &rFrameFormat, bool bInCntnr)
Definition: htmlplug.cxx:1221
SwHTMLWriter & OutHTML_FrameFormatOLENodeGrf(SwHTMLWriter &rWrt, const SwFrameFormat &rFrameFormat, bool bInCntnr)
Definition: htmlplug.cxx:1487
SwHTMLWriter & OutHTML_SwTableNode(SwHTMLWriter &rWrt, SwTableNode &rNode, const SwFrameFormat *pFlyFrameFormat, const OUString *pCaption, bool bTopCaption)
Definition: htmltabw.cxx:914
OUString aName
sal_uInt16 nPos
#define SAL_WARN(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
bool WrapGraphicInRtf(const Graphic &rGraphic, const SwFrameFormat &rFormat, SvStream &rRtf)
Wraps an image in an RTF fragment.
SVL_DLLPUBLIC Link< OUString *, bool > const & GetMaybeFileHdl()
SVL_DLLPUBLIC OUString SmartRel2Abs(INetURLObject const &rTheBaseURIRef, OUString const &rTheRelURIRef, Link< OUString *, bool > const &rMaybeFileHdl=Link< OUString *, bool >(), bool bCheckFileExists=true, bool bIgnoreFragment=false, INetURLObject::EncodeMechanism eEncodeMechanism=INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism eDecodeMechanism=INetURLObject::DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
SVL_DLLPUBLIC OUString simpleNormalizedMakeRelative(OUString const &baseUriReference, OUString const &uriReference)
int i
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
const sal_Unicode *const aMimeType[]
HtmlOut nOut
Definition: htmlfly.hxx:86
HtmlContainerFlags nContainer
Definition: htmlfly.hxx:88
static SVT_DLLPUBLIC SvStream & Out_AsciiTag(SvStream &, std::string_view rStr, bool bOn=true)
static SVT_DLLPUBLIC SvStream & Out_String(SvStream &, const OUString &, OUString *pNonConvertableChars=nullptr)
static SVT_DLLPUBLIC bool PrivateURLToInternalImg(OUString &rURL)
static SVT_DLLPUBLIC SvStream & Out_ImageMap(SvStream &, const OUString &, const ImageMap &, const OUString &, const HTMLOutEvent *pEventTable, bool bOutStarBasic, const char *pDelim, const char *pIndentArea, const char *pIndentMap)
static SVT_DLLPUBLIC SvStream & FlushToAscii(SvStream &)
static SVT_DLLPUBLIC void applyEvents(HtmlWriter &rHtmlWriter, const SvxMacroTableDtor &rMacroTable, const HTMLOutEvent *pEventTable, bool bOutStarBasic)
static SVT_DLLPUBLIC void applyColor(HtmlWriter &rHtmlWriter, std::string_view aAttributeName, const Color &rColor)
Marks a position in the document model.
Definition: pam.hxx:37
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
#define WARN_SWG_POOR_LOAD
Definition: swerror.h:39
RndStdIds
tools::Long SwTwips
Definition: swtypes.hxx:51
const sal_Unicode cMarkSeparator
Definition: swtypes.hxx:124
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
SwHTMLWriter & Out_SfxItemSet(const SwAttrFnTab, SwHTMLWriter &, const SfxItemSet &, bool bDeep)
Definition: wrt_fn.cxx:42
HtmlFrmOpts
Definition: wrthtml.hxx:76
@ Replacement
The graphic frame is a replacement image of an OLE object.
#define HTML_PARSPACE
Definition: wrthtml.hxx:70
#define HTMLMODE_BORDER_NONE
Definition: wrthtml.hxx:126
#define HTMLMODE_ABS_POS_FLY
Definition: wrthtml.hxx:123
#define HTMLMODE_VERT_SPACER
Definition: wrthtml.hxx:118
XOutFlags