1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include <hintids.hxx>
25 #include <comphelper/string.hxx>
26 #include <comphelper/xmlencode.hxx>
27 #include <vcl/svapp.hxx>
28 #include <svl/whiter.hxx>
29 #include <editeng/boxitem.hxx>
30 #include <editeng/ulspitem.hxx>
31 #include <editeng/udlnitem.hxx>
32 #include <editeng/crossedoutitem.hxx>
33 #include <editeng/blinkitem.hxx>
34 #include <editeng/cmapitem.hxx>
35 #include <editeng/colritem.hxx>
36 #include <editeng/fontitem.hxx>
37 #include <editeng/fhgtitem.hxx>
38 #include <editeng/postitem.hxx>
39 #include <editeng/kernitem.hxx>
40 #include <editeng/wghtitem.hxx>
41 #include <editeng/lspcitem.hxx>
42 #include <editeng/adjustitem.hxx>
43 #include <editeng/lrspitem.hxx>
44 #include <editeng/brushitem.hxx>
45 #include <editeng/formatbreakitem.hxx>
46 #include <editeng/keepitem.hxx>
47 #include <editeng/widwitem.hxx>
48 #include <editeng/spltitem.hxx>
49 #include <editeng/orphitem.hxx>
50 #include <editeng/charhiddenitem.hxx>
51 #include <svx/xoutbmp.hxx>
52 #include <svx/svdobj.hxx>
53 #include <editeng/langitem.hxx>
54 #include <editeng/frmdiritem.hxx>
55 #include <svtools/htmlout.hxx>
56 #include <svtools/htmlkywd.hxx>
57 #include <svl/urihelper.hxx>
58 #include <unotools/charclass.hxx>
59 #include <i18nlangtag/languagetag.hxx>
60 #include <charfmt.hxx>
61 #include <fmtclds.hxx>
63 #include <fmtfsize.hxx>
64 #include <fmtornt.hxx>
65 #include <fmtpdsc.hxx>
66 #include <fmtlsplt.hxx>
67 #include <pagedesc.hxx>
68 #include <fmtanchr.hxx>
72 #include <viewopt.hxx>
73 #include <swtable.hxx>
75 #include <ftninfo.hxx>
81 #include <IDocumentSettingAccess.hxx>
82 #include <IDocumentLayoutAccess.hxx>
86 #include <poolfmt.hxx>
87 #include "css1kywd.hxx"
88 #include "wrthtml.hxx"
89 #include "htmlnum.hxx"
90 #include "css1atr.hxx"
92 #include <IDocumentStylePoolAccess.hxx>
93 #include <numrule.hxx>
94 #include <o3tl/typed_flags_set.hxx>
95 #include <o3tl/unit_conversion.hxx>
97 #include <rtl/strbuf.hxx>
98 #include <osl/diagnose.h>
101 using editeng::SvxBorderLine
;
103 #define HTML_HEADSPACE (12*20)
107 enum class Css1FrameSize
{
118 template<> struct typed_flags
<Css1FrameSize
> : is_typed_flags
<Css1FrameSize
, 0x17> {};
121 constexpr int DOT_LEADERS_MAX_WIDTH
= 18; // cm
123 static SwHTMLWriter
& OutCSS1_SwFormat( SwHTMLWriter
& rWrt
, const SwFormat
& rFormat
,
124 IDocumentStylePoolAccess
/*SwDoc*/ *pDoc
, SwDoc
*pTemplate
);
125 static SwHTMLWriter
& OutCSS1_SwPageDesc( SwHTMLWriter
& rWrt
, const SwPageDesc
& rFormat
,
126 IDocumentStylePoolAccess
/*SwDoc*/ *pDoc
, SwDoc
*pTemplate
,
127 sal_uInt16 nRefPoolId
, bool bExtRef
,
129 static SwHTMLWriter
& OutCSS1_SwFootnoteInfo( SwHTMLWriter
& rWrt
, const SwEndNoteInfo
& rInfo
,
130 SwDoc
*pDoc
, bool bHasNotes
, bool bEndNote
);
131 static void OutCSS1_SwFormatDropAttrs( SwHTMLWriter
& rHWrt
,
132 const SwFormatDrop
& rDrop
,
133 const SfxItemSet
*pCharFormatItemSet
=nullptr );
134 static SwHTMLWriter
& OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( SwHTMLWriter
& rWrt
,
135 const SvxUnderlineItem
*pUItem
,
136 const SvxOverlineItem
*pOItem
,
137 const SvxCrossedOutItem
*pCOItem
,
138 const SvxBlinkItem
*pBItem
);
139 static SwHTMLWriter
& OutCSS1_SvxFontWeight( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
140 static SwHTMLWriter
& OutCSS1_SvxPosture( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
141 static SwHTMLWriter
& OutCSS1_SvxULSpace( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
142 static SwHTMLWriter
& OutCSS1_SvxFirstLineIndent(SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
143 static SwHTMLWriter
& OutCSS1_SvxTextLeftMargin(SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
144 static SwHTMLWriter
& OutCSS1_SvxRightMargin(SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
145 static SwHTMLWriter
& OutCSS1_SvxLRSpace( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
146 static SwHTMLWriter
& OutCSS1_SvxULSpace_SvxLRSpace( SwHTMLWriter
& rWrt
,
147 const SvxULSpaceItem
*pULSpace
,
148 const SvxLRSpaceItem
*pLRSpace
);
149 static SwHTMLWriter
& OutCSS1_SvxULSpace_SvxLRSpace( SwHTMLWriter
& rWrt
,
150 const SfxItemSet
& rItemSet
);
151 static SwHTMLWriter
& OutCSS1_SvxBrush( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
,
152 sw::Css1Background nMode
,
153 const OUString
*pGraphicName
);
154 static SwHTMLWriter
& OutCSS1_SvxBrush( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
155 static SwHTMLWriter
& OutCSS1_SwFormatFrameSize( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
,
156 Css1FrameSize nMode
);
157 static SwHTMLWriter
& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( SwHTMLWriter
& rWrt
,
158 const SfxItemSet
& rItemSet
,
160 static SwHTMLWriter
& OutCSS1_SwFormatLayoutSplit( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
);
165 const char sCSS1_rule_end
[] = " }";
166 const char sCSS1_span_tag_end
[] = "\">";
167 const char cCSS1_style_opt_end
= '\"';
169 const char* const sHTML_FTN_fontheight
= "57%";
171 OString
lclConvToHex(sal_uInt16 nHex
)
173 char aNToABuf
[] = "00";
175 // set pointer to end of buffer
176 char *pStr
= aNToABuf
+ (sizeof(aNToABuf
)-1);
177 for( sal_uInt8 n
= 0; n
< 2; ++n
)
179 *(--pStr
) = static_cast<char>(nHex
& 0xf ) + 48;
185 return OString(aNToABuf
, 2);
189 bool IgnorePropertyForReqIF(bool bReqIF
, std::string_view rProperty
, std::string_view rValue
,
190 std::optional
<sw::Css1Background
> oMode
)
195 if (oMode
.has_value() && *oMode
!= sw::Css1Background::TableCell
)
198 if (rProperty
== sCSS1_P_background
&& rValue
== "transparent")
200 // This is the default already.
207 // Only allow these two keys, nothing else in ReqIF mode.
208 if (rProperty
== sCSS1_P_text_decoration
)
210 // Deny other text-decoration values (e.g. "none").
211 if (rValue
== "underline" || rValue
== "line-through")
219 if (rProperty
== sCSS1_P_color
)
225 OString
GetCSS1_Color(const Color
& rColor
)
227 return "#" + lclConvToHex(rColor
.GetRed()) + lclConvToHex(rColor
.GetGreen()) + lclConvToHex(rColor
.GetBlue());
239 SwCSS1OutMode( SwHTMLWriter
& rHWrt
, sal_uInt16 nMode
,
240 const OUString
*pSelector
) :
242 nOldMode( rHWrt
.m_nCSS1OutMode
)
244 rWrt
.m_nCSS1OutMode
= nMode
;
245 rWrt
.m_bFirstCSS1Property
= true;
247 rWrt
.m_aCSS1Selector
= *pSelector
;
252 rWrt
.m_nCSS1OutMode
= nOldMode
;
258 void SwHTMLWriter::OutCSS1_Property( std::string_view pProp
,
259 std::string_view sVal
,
260 const OUString
*pSVal
,
261 std::optional
<sw::Css1Background
> oMode
)
263 OString
aPropertyValue(sVal
);
264 if (aPropertyValue
.isEmpty() && pSVal
)
266 aPropertyValue
= OUStringToOString(*pSVal
, RTL_TEXTENCODING_UTF8
);
268 if (IgnorePropertyForReqIF(mbReqIF
, pProp
, aPropertyValue
, oMode
))
273 if( m_bFirstCSS1Rule
&& (m_nCSS1OutMode
& CSS1_OUTMODE_RULE_ON
)!=0 )
275 m_bFirstCSS1Rule
= false;
277 sOut
.append("<" + GetNamespace() + OOO_STRING_SVTOOLS_HTML_style
" "
278 OOO_STRING_SVTOOLS_HTML_O_type
"=\"text/css\">");
279 // Optional CSS2 code for dot leaders (dotted line between the Table of Contents titles and page numbers):
280 // (More information: http://www.w3.org/Style/Examples/007/leaders.en.html)
284 // (1) dots line up vertically only in the paragraphs with the same alignment/level
285 // (2) max-width = 18 cm instead of 80em; possible improvement with the new CSS3 calc() */
286 // max-width: 18cm; /* note: need to overwrite max-width with max-width - border-left_of_the_actual_paragraph */
288 // overflow-x: hidden;
289 // line-height: 120%; /* note: avoid HTML scrollbars and missing descenders of the letters */
294 // white-space: nowrap;
295 // content: ". . . . . . . . . . . . . . . . . . ...";
297 // p.leaders span:first-child {
298 // padding-right: 0.33em;
299 // background: white;
301 // p.leaders span + span {
303 // padding-left: 0.33em;
304 // background: white;
305 // position: relative;
309 if (m_bCfgPrintLayout
) {
311 "p." sCSS2_P_CLASS_leaders
"{max-width:" + OString::number(DOT_LEADERS_MAX_WIDTH
) +
312 "cm;padding:0;overflow-x:hidden;line-height:120%}"
313 "p." sCSS2_P_CLASS_leaders
":after{float:left;width:0;white-space:nowrap;content:\"");
314 for (int i
= 0; i
< 100; i
++ )
317 "\"}p." sCSS2_P_CLASS_leaders
" span:first-child{padding-right:0.33em;background:white}"
318 "p." sCSS2_P_CLASS_leaders
" span+span{float:right;padding-left:0.33em;"
319 "background:white;position:relative;z-index:1}");
321 Strm().WriteOString( sOut
);
327 if( m_bFirstCSS1Property
)
329 switch( m_nCSS1OutMode
& CSS1_OUTMODE_ANY_ON
)
331 case CSS1_OUTMODE_SPAN_TAG_ON
:
332 case CSS1_OUTMODE_SPAN_TAG1_ON
:
335 sOut
.append("<" + GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
336 " " OOO_STRING_SVTOOLS_HTML_O_style
"=\"");
340 HTMLOutFuncs::Out_AsciiTag( Strm(), Concat2View(GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
), false );
345 case CSS1_OUTMODE_RULE_ON
:
348 sOut
.append(OUStringToOString(m_aCSS1Selector
, RTL_TEXTENCODING_UTF8
) + " { ");
352 case CSS1_OUTMODE_STYLE_OPT_ON
:
353 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_style
"=\"");
356 m_bFirstCSS1Property
= false;
363 sOut
.append(pProp
+ OString::Concat(": "));
364 if( m_nCSS1OutMode
& CSS1_OUTMODE_ENCODE
)
366 // for STYLE-Option encode string
367 Strm().WriteOString( sOut
);
370 HTMLOutFuncs::Out_String( Strm(), OUString::createFromAscii(sVal
) );
372 HTMLOutFuncs::Out_String( Strm(), *pSVal
);
376 // for STYLE-Tag print string directly
377 sOut
.append(aPropertyValue
);
381 Strm().WriteOString( sOut
);
384 static void AddUnitPropertyValue(OStringBuffer
&rOut
, tools::Long nVal
,
389 // special-case sign symbol
395 int nFac
; // used to get specific number of decimals
396 std::string_view pUnit
;
399 case FieldUnit::MM_100TH
:
400 OSL_ENSURE( FieldUnit::MM
== eUnit
, "Measuring unit not supported" );
403 eTo
= o3tl::Length::mm
;
405 pUnit
= sCSS1_UNIT_mm
;
410 OSL_ENSURE( FieldUnit::CM
== eUnit
, "Measuring unit not supported" );
413 eTo
= o3tl::Length::cm
;
415 pUnit
= sCSS1_UNIT_cm
;
418 case FieldUnit::TWIP
:
419 OSL_ENSURE( FieldUnit::POINT
== eUnit
, "Measuring unit not supported" );
421 case FieldUnit::POINT
:
422 eTo
= o3tl::Length::pt
;
424 pUnit
= sCSS1_UNIT_pt
;
427 case FieldUnit::PICA
:
428 eTo
= o3tl::Length::pc
;
430 pUnit
= sCSS1_UNIT_pc
;
433 case FieldUnit::NONE
:
434 case FieldUnit::FOOT
:
435 case FieldUnit::MILE
:
436 case FieldUnit::CUSTOM
:
437 case FieldUnit::PERCENT
:
438 case FieldUnit::INCH
:
440 OSL_ENSURE( FieldUnit::INCH
== eUnit
, "Measuring unit not supported" );
441 eTo
= o3tl::Length::in
;
443 pUnit
= sCSS1_UNIT_inch
;
447 sal_Int64 nResult
= o3tl::convert(nVal
* nFac
, o3tl::Length::twip
, eTo
);
448 rOut
.append(nResult
/nFac
);
449 if ((nResult
% nFac
) != 0)
452 while (nFac
> 1 && (nResult
% nFac
) != 0)
455 rOut
.append((nResult
/ nFac
) % 10);
462 void SwHTMLWriter::OutCSS1_UnitProperty( std::string_view pProp
, tools::Long nVal
)
465 AddUnitPropertyValue(sOut
, nVal
, m_eCSS1Unit
);
466 OutCSS1_PropertyAscii(pProp
, sOut
);
469 void SwHTMLWriter::OutCSS1_PixelProperty( std::string_view pProp
, tools::Long nTwips
)
471 OString
sOut(OString::number(ToPixel(nTwips
)) + sCSS1_UNIT_px
);
472 OutCSS1_PropertyAscii(pProp
, sOut
);
475 void SwHTMLWriter::OutStyleSheet( const SwPageDesc
& rPageDesc
)
477 m_bFirstCSS1Rule
= true;
480 if( IsHTMLMode(HTMLMODE_PRINT_EXT
) )
482 const SwPageDesc
*pFirstPageDesc
= nullptr;
483 sal_uInt16 nFirstRefPoolId
= RES_POOLPAGE_HTML
;
484 m_bCSS1IgnoreFirstPageDesc
= true;
486 // First we try to guess how the document is constructed.
487 // Allowed are only the templates: HTML, 1st page, left page, and right page.
488 // A first page is only exported, if it matches the template "1st page".
489 // Left and right pages are only exported, if their templates are linked.
490 // If other templates are used, only very simple cases are exported.
491 const SwPageDesc
*pPageDesc
= &rPageDesc
;
492 const SwPageDesc
*pFollow
= rPageDesc
.GetFollow();
493 if( RES_POOLPAGE_FIRST
== pPageDesc
->GetPoolFormatId() &&
494 pFollow
!= pPageDesc
&&
495 !IsPoolUserFormat( pFollow
->GetPoolFormatId() ) )
497 // the document has a first page
498 pFirstPageDesc
= pPageDesc
;
500 pFollow
= pPageDesc
->GetFollow();
503 IDocumentStylePoolAccess
* pStylePoolAccess
= &getIDocumentStylePoolAccess();
504 if( pPageDesc
== pFollow
)
506 // The document is one-sided; no matter what page, we do not create a 2-sided doc.
507 // The attribute is exported relative to the HTML page template.
508 OutCSS1_SwPageDesc( *this, *pPageDesc
, pStylePoolAccess
, m_xTemplate
.get(),
509 RES_POOLPAGE_HTML
, true, false );
510 nFirstRefPoolId
= pFollow
->GetPoolFormatId();
512 else if( (RES_POOLPAGE_LEFT
== pPageDesc
->GetPoolFormatId() &&
513 RES_POOLPAGE_RIGHT
== pFollow
->GetPoolFormatId()) ||
514 (RES_POOLPAGE_RIGHT
== pPageDesc
->GetPoolFormatId() &&
515 RES_POOLPAGE_LEFT
== pFollow
->GetPoolFormatId()) )
517 // the document is double-sided
518 OutCSS1_SwPageDesc( *this, *pPageDesc
, pStylePoolAccess
, m_xTemplate
.get(),
519 RES_POOLPAGE_HTML
, true );
520 OutCSS1_SwPageDesc( *this, *pFollow
, pStylePoolAccess
, m_xTemplate
.get(),
521 RES_POOLPAGE_HTML
, true );
522 nFirstRefPoolId
= RES_POOLPAGE_RIGHT
;
523 m_bCSS1IgnoreFirstPageDesc
= false;
525 // other cases we miss
528 OutCSS1_SwPageDesc( *this, *pFirstPageDesc
, pStylePoolAccess
, m_xTemplate
.get(),
529 nFirstRefPoolId
, false );
532 // The text body style has to be exported always (if it is changed compared
533 // to the template), because it is used as reference for any style
534 // that maps to <P>, and that's especially the standard style
535 getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_TEXT
, false );
537 // the Default-TextStyle is not also exported !!
538 // 0-Style is the Default; is never exported !!
539 const size_t nTextFormats
= m_pDoc
->GetTextFormatColls()->size();
540 for( size_t i
= 1; i
< nTextFormats
; ++i
)
542 const SwTextFormatColl
* pColl
= (*m_pDoc
->GetTextFormatColls())[i
];
543 sal_uInt16 nPoolId
= pColl
->GetPoolFormatId();
544 if( nPoolId
== RES_POOLCOLL_TEXT
|| m_pDoc
->IsUsed( *pColl
) )
545 OutCSS1_SwFormat( *this, *pColl
, &m_pDoc
->getIDocumentStylePoolAccess(), m_xTemplate
.get() );
548 // the Default-TextStyle is not also exported !!
549 const size_t nCharFormats
= m_pDoc
->GetCharFormats()->size();
550 for( size_t i
= 1; i
< nCharFormats
; ++i
)
552 const SwCharFormat
*pCFormat
= (*m_pDoc
->GetCharFormats())[i
];
553 sal_uInt16 nPoolId
= pCFormat
->GetPoolFormatId();
554 if( nPoolId
== RES_POOLCHR_INET_NORMAL
||
555 nPoolId
== RES_POOLCHR_INET_VISIT
||
556 m_pDoc
->IsUsed( *pCFormat
) )
557 OutCSS1_SwFormat( *this, *pCFormat
, &m_pDoc
->getIDocumentStylePoolAccess(), m_xTemplate
.get() );
560 bool bHasEndNotes
{false};
561 bool bHasFootNotes
{false};
562 const SwFootnoteIdxs
& rIdxs
= m_pDoc
->GetFootnoteIdxs();
563 for( auto pIdx
: rIdxs
)
565 if( pIdx
->GetFootnote().IsEndNote() )
573 bHasFootNotes
= true;
578 OutCSS1_SwFootnoteInfo( *this, m_pDoc
->GetFootnoteInfo(), m_pDoc
, bHasFootNotes
, false );
579 OutCSS1_SwFootnoteInfo( *this, m_pDoc
->GetEndNoteInfo(), m_pDoc
, bHasEndNotes
, true );
581 if( !m_bFirstCSS1Rule
)
586 HTMLOutFuncs::Out_AsciiTag( Strm(), Concat2View(GetNamespace() + OOO_STRING_SVTOOLS_HTML_style
), false );
590 m_bFirstCSS1Rule
= false;
593 m_nDfltTopMargin
= 0;
594 m_nDfltBottomMargin
= 0;
597 // if pPseudo is set, Styles-Sheets will be exported;
598 // otherwise we only search for Token and Class for a Format
599 sal_uInt16
SwHTMLWriter::GetCSS1Selector( const SwFormat
*pFormat
, OString
& rToken
,
600 OUString
& rClass
, sal_uInt16
& rRefPoolId
,
603 sal_uInt16 nDeep
= 0;
610 bool bChrFormat
= RES_CHRFMT
==pFormat
->Which();
612 // search formats above for the nearest standard or HTML-Tag template
613 const SwFormat
*pPFormat
= pFormat
;
614 while( pPFormat
&& !pPFormat
->IsDefault() )
617 sal_uInt16 nPoolId
= pPFormat
->GetPoolFormatId();
618 if( USER_FMT
& nPoolId
)
621 const OUString
& aNm(pPFormat
->GetName());
623 if (!bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_blockquote
)
625 rRefPoolId
= RES_POOLCOLL_HTML_BLOCKQUOTE
;
626 rToken
= OOO_STRING_SVTOOLS_HTML_blockquote
""_ostr
;
628 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_citation
)
630 rRefPoolId
= RES_POOLCHR_HTML_CITATION
;
631 rToken
= OOO_STRING_SVTOOLS_HTML_citation
""_ostr
;
633 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_code
)
635 rRefPoolId
= RES_POOLCHR_HTML_CODE
;
636 rToken
= OOO_STRING_SVTOOLS_HTML_code
""_ostr
;
638 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_definstance
)
640 rRefPoolId
= RES_POOLCHR_HTML_DEFINSTANCE
;
641 rToken
= OOO_STRING_SVTOOLS_HTML_definstance
""_ostr
;
643 else if (!bChrFormat
&& (aNm
== OOO_STRING_SVTOOLS_HTML_dd
||
644 aNm
== OOO_STRING_SVTOOLS_HTML_dt
))
646 sal_uInt16 nDefListLvl
= GetDefListLvl(aNm
, nPoolId
);
647 // Export the templates DD 1/DT 1,
648 // but none of their derived templates,
649 // also not DD 2/DT 2 etc.
652 if (pPseudo
&& (nDeep
|| (nDefListLvl
& 0x0fff) > 1))
656 else if (nDefListLvl
& HTML_DLCOLL_DD
)
658 rRefPoolId
= RES_POOLCOLL_HTML_DD
;
659 rToken
= OOO_STRING_SVTOOLS_HTML_dd
""_ostr
;
663 rRefPoolId
= RES_POOLCOLL_HTML_DT
;
664 rToken
= OOO_STRING_SVTOOLS_HTML_dt
""_ostr
;
668 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_emphasis
)
670 rRefPoolId
= RES_POOLCHR_HTML_EMPHASIS
;
671 rToken
= OOO_STRING_SVTOOLS_HTML_emphasis
""_ostr
;
673 else if (!bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_horzrule
)
675 // do not export HR !
678 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_keyboard
)
680 rRefPoolId
= RES_POOLCHR_HTML_KEYBOARD
;
681 rToken
= OOO_STRING_SVTOOLS_HTML_keyboard
""_ostr
;
683 else if (!bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_listing
)
685 // Export Listings as PRE or PRE-derived template
686 rToken
= OOO_STRING_SVTOOLS_HTML_preformtxt
""_ostr
;
687 rRefPoolId
= RES_POOLCOLL_HTML_PRE
;
688 nDeep
= CSS1_FMT_CMPREF
;
690 else if (!bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_preformtxt
)
692 rRefPoolId
= RES_POOLCOLL_HTML_PRE
;
693 rToken
= OOO_STRING_SVTOOLS_HTML_preformtxt
""_ostr
;
695 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_sample
)
697 rRefPoolId
= RES_POOLCHR_HTML_SAMPLE
;
698 rToken
= OOO_STRING_SVTOOLS_HTML_sample
""_ostr
;
700 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_strong
)
702 rRefPoolId
= RES_POOLCHR_HTML_STRONG
;
703 rToken
= OOO_STRING_SVTOOLS_HTML_strong
""_ostr
;
705 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_teletype
)
707 rRefPoolId
= RES_POOLCHR_HTML_TELETYPE
;
708 rToken
= OOO_STRING_SVTOOLS_HTML_teletype
""_ostr
;
710 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_variable
)
712 rRefPoolId
= RES_POOLCHR_HTML_VARIABLE
;
713 rToken
= OOO_STRING_SVTOOLS_HTML_variable
""_ostr
;
715 else if (!bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_xmp
)
717 // export XMP as PRE (but not the template as Style)
718 rToken
= OOO_STRING_SVTOOLS_HTML_preformtxt
""_ostr
;
719 rRefPoolId
= RES_POOLCOLL_HTML_PRE
;
720 nDeep
= CSS1_FMT_CMPREF
;
723 // if a PoolId is set, the Name of the template is that of the related Token
724 OSL_ENSURE( (rRefPoolId
!= 0) == (!rToken
.isEmpty()),
732 // paragraph templates
733 case RES_POOLCOLL_HEADLINE_BASE
:
734 case RES_POOLCOLL_STANDARD
:
735 // do not export this template
736 case RES_POOLCOLL_HTML_HR
:
737 // do not export HR !
740 case RES_POOLCOLL_TEXT
:
741 rToken
= OOO_STRING_SVTOOLS_HTML_parabreak
""_ostr
;
743 case RES_POOLCOLL_HEADLINE1
:
744 rToken
= OOO_STRING_SVTOOLS_HTML_head1
""_ostr
;
746 case RES_POOLCOLL_HEADLINE2
:
747 rToken
= OOO_STRING_SVTOOLS_HTML_head2
""_ostr
;
749 case RES_POOLCOLL_HEADLINE3
:
750 rToken
= OOO_STRING_SVTOOLS_HTML_head3
""_ostr
;
752 case RES_POOLCOLL_HEADLINE4
:
753 rToken
= OOO_STRING_SVTOOLS_HTML_head4
""_ostr
;
755 case RES_POOLCOLL_HEADLINE5
:
756 rToken
= OOO_STRING_SVTOOLS_HTML_head5
""_ostr
;
758 case RES_POOLCOLL_HEADLINE6
:
759 rToken
= OOO_STRING_SVTOOLS_HTML_head6
""_ostr
;
761 case RES_POOLCOLL_SEND_ADDRESS
:
762 rToken
= OOO_STRING_SVTOOLS_HTML_address
""_ostr
;
764 case RES_POOLCOLL_HTML_BLOCKQUOTE
:
765 rToken
= OOO_STRING_SVTOOLS_HTML_blockquote
""_ostr
;
767 case RES_POOLCOLL_HTML_PRE
:
768 rToken
= OOO_STRING_SVTOOLS_HTML_preformtxt
""_ostr
;
771 case RES_POOLCOLL_HTML_DD
:
772 rToken
= OOO_STRING_SVTOOLS_HTML_dd
""_ostr
;
774 case RES_POOLCOLL_HTML_DT
:
775 rToken
= OOO_STRING_SVTOOLS_HTML_dt
""_ostr
;
778 case RES_POOLCOLL_TABLE
:
781 rToken
= OOO_STRING_SVTOOLS_HTML_tabledata
" "
782 OOO_STRING_SVTOOLS_HTML_parabreak
""_ostr
;
785 rToken
= OOO_STRING_SVTOOLS_HTML_parabreak
""_ostr
;
787 case RES_POOLCOLL_TABLE_HDLN
:
790 rToken
= OOO_STRING_SVTOOLS_HTML_tableheader
" "
791 OOO_STRING_SVTOOLS_HTML_parabreak
""_ostr
;
794 rToken
= OOO_STRING_SVTOOLS_HTML_parabreak
""_ostr
;
796 case RES_POOLCOLL_FOOTNOTE
:
799 rToken
= OOO_STRING_SVTOOLS_HTML_parabreak
""_ostr
;
800 rClass
= OOO_STRING_SVTOOLS_HTML_sdfootnote
;
801 rRefPoolId
= RES_POOLCOLL_TEXT
;
802 nDeep
= CSS1_FMT_CMPREF
;
805 case RES_POOLCOLL_ENDNOTE
:
808 rToken
= OOO_STRING_SVTOOLS_HTML_parabreak
""_ostr
;
809 rClass
= OOO_STRING_SVTOOLS_HTML_sdendnote
;
810 rRefPoolId
= RES_POOLCOLL_TEXT
;
811 nDeep
= CSS1_FMT_CMPREF
;
815 // character templates
816 case RES_POOLCHR_HTML_EMPHASIS
:
817 rToken
= OOO_STRING_SVTOOLS_HTML_emphasis
""_ostr
;
819 case RES_POOLCHR_HTML_CITATION
:
820 rToken
= OOO_STRING_SVTOOLS_HTML_citation
""_ostr
;
822 case RES_POOLCHR_HTML_STRONG
:
823 rToken
= OOO_STRING_SVTOOLS_HTML_strong
""_ostr
;
825 case RES_POOLCHR_HTML_CODE
:
826 rToken
= OOO_STRING_SVTOOLS_HTML_code
""_ostr
;
828 case RES_POOLCHR_HTML_SAMPLE
:
829 rToken
= OOO_STRING_SVTOOLS_HTML_sample
""_ostr
;
831 case RES_POOLCHR_HTML_KEYBOARD
:
832 rToken
= OOO_STRING_SVTOOLS_HTML_keyboard
""_ostr
;
834 case RES_POOLCHR_HTML_VARIABLE
:
835 rToken
= OOO_STRING_SVTOOLS_HTML_variable
""_ostr
;
837 case RES_POOLCHR_HTML_DEFINSTANCE
:
838 rToken
= OOO_STRING_SVTOOLS_HTML_definstance
""_ostr
;
840 case RES_POOLCHR_HTML_TELETYPE
:
841 rToken
= OOO_STRING_SVTOOLS_HTML_teletype
""_ostr
;
844 case RES_POOLCHR_INET_NORMAL
:
847 rToken
= OOO_STRING_SVTOOLS_HTML_anchor
""_ostr
;
848 *pPseudo
= sCSS1_link
;
851 case RES_POOLCHR_INET_VISIT
:
854 rToken
= OOO_STRING_SVTOOLS_HTML_anchor
""_ostr
;
855 *pPseudo
= sCSS1_visited
;
860 // if a token is set, PoolId contains the related template
861 if( !rToken
.isEmpty() && !rRefPoolId
)
862 rRefPoolId
= nPoolId
;
865 if( !rToken
.isEmpty() || bStop
)
867 // stop if a HTML-Tag template was found
872 // continue otherwise
874 pPFormat
= pPFormat
->DerivedFrom();
878 if( !rToken
.isEmpty() )
880 // this is a HTML-Tag template
882 nDeep
= CSS1_FMT_ISTAG
;
886 // this is not a HTML-Tag template nor derived from one
889 if( nDeep
> 0 && nDeep
< CSS1_FMT_SPECIAL
)
891 // If the template is derived from a HTML template,
892 // we export it as <TOKEN>.<CLASS>, otherwise as .<CLASS>.
893 // <CLASS> is the name of the template after removing all characters
894 // before and including the first '.'
895 rClass
= pFormat
->GetName();
896 sal_Int32 nPos
= rClass
.indexOf( '.' );
897 if( nPos
>= 0 && rClass
.getLength() > nPos
+1 )
899 rClass
= rClass
.replaceAt( 0, nPos
+1, u
"" );
902 rClass
= GetAppCharClass().lowercase( rClass
);
903 rClass
= rClass
.replaceAll( ".", "-" );
904 rClass
= rClass
.replaceAll( " ", "-" );
905 rClass
= rClass
.replaceAll( "_", "-" );
911 static sal_uInt16
GetCSS1Selector( const SwFormat
*pFormat
, OUString
& rSelector
,
912 sal_uInt16
& rRefPoolId
)
918 sal_uInt16 nDeep
= SwHTMLWriter::GetCSS1Selector( pFormat
, aToken
, aClass
,
919 rRefPoolId
, &aPseudo
);
922 if( !aToken
.isEmpty() )
923 rSelector
= OStringToOUString(aToken
, RTL_TEXTENCODING_ASCII_US
);
927 if( !aClass
.isEmpty() )
928 rSelector
+= "." + aClass
;
929 if( !aPseudo
.isEmpty() )
930 rSelector
+= ":" + aPseudo
;
936 const SwFormat
*SwHTMLWriter::GetTemplateFormat( sal_uInt16 nPoolFormatId
,
937 IDocumentStylePoolAccess
* pTemplate
/*SwDoc *pTemplate*/)
939 const SwFormat
*pRefFormat
= nullptr;
943 OSL_ENSURE( !(USER_FMT
& nPoolFormatId
),
944 "No user templates found" );
945 if( POOLGRP_NOCOLLID
& nPoolFormatId
)
946 pRefFormat
= pTemplate
->GetCharFormatFromPool( nPoolFormatId
);
948 pRefFormat
= pTemplate
->GetTextCollFromPool( nPoolFormatId
, false );
954 const SwFormat
*SwHTMLWriter::GetParentFormat( const SwFormat
& rFormat
, sal_uInt16 nDeep
)
956 OSL_ENSURE( nDeep
!= USHRT_MAX
, "Called GetParent for HTML-template!" );
957 const SwFormat
*pRefFormat
= nullptr;
961 // get the pointer for the HTML-Tag template, from which the template is derived
962 pRefFormat
= &rFormat
;
963 for( sal_uInt16 i
=nDeep
; i
>0; i
-- )
964 pRefFormat
= pRefFormat
->DerivedFrom();
966 if( pRefFormat
&& pRefFormat
->IsDefault() )
967 pRefFormat
= nullptr;
973 bool swhtml_css1atr_equalFontItems( const SfxPoolItem
& r1
, const SfxPoolItem
& r2
)
975 return static_cast<const SvxFontItem
&>(r1
).GetFamilyName() ==
976 static_cast<const SvxFontItem
&>(r2
).GetFamilyName() &&
977 static_cast<const SvxFontItem
&>(r1
).GetFamily() ==
978 static_cast<const SvxFontItem
&>(r2
).GetFamily();
981 void SwHTMLWriter::SubtractItemSet( SfxItemSet
& rItemSet
,
982 const SfxItemSet
& rRefItemSet
,
985 const SfxItemSet
*pRefScriptItemSet
)
987 OSL_ENSURE( bSetDefaults
|| bClearSame
,
988 "SwHTMLWriter::SubtractItemSet: No action for this Flag" );
989 SfxItemSet
aRefItemSet( *rRefItemSet
.GetPool(), rRefItemSet
.GetRanges() );
990 aRefItemSet
.Set( rRefItemSet
);
992 // compare with the Attr-Set of the template
993 SfxWhichIter
aIter( rItemSet
);
994 sal_uInt16 nWhich
= aIter
.FirstWhich();
997 const SfxPoolItem
*pRefItem
, *pItem
;
998 bool bItemSet
= ( SfxItemState::SET
==
999 aIter
.GetItemState( false, &pItem
) );
1002 if( pRefScriptItemSet
)
1006 case RES_CHRATR_FONT
:
1007 case RES_CHRATR_FONTSIZE
:
1008 case RES_CHRATR_LANGUAGE
:
1009 case RES_CHRATR_POSTURE
:
1010 case RES_CHRATR_WEIGHT
:
1011 case RES_CHRATR_CJK_FONT
:
1012 case RES_CHRATR_CJK_FONTSIZE
:
1013 case RES_CHRATR_CJK_LANGUAGE
:
1014 case RES_CHRATR_CJK_POSTURE
:
1015 case RES_CHRATR_CJK_WEIGHT
:
1016 case RES_CHRATR_CTL_FONT
:
1017 case RES_CHRATR_CTL_FONTSIZE
:
1018 case RES_CHRATR_CTL_LANGUAGE
:
1019 case RES_CHRATR_CTL_POSTURE
:
1020 case RES_CHRATR_CTL_WEIGHT
:
1021 bRefItemSet
= ( SfxItemState::SET
==
1022 pRefScriptItemSet
->GetItemState( nWhich
, true, &pRefItem
) );
1025 bRefItemSet
= ( SfxItemState::SET
==
1026 aRefItemSet
.GetItemState( nWhich
, false, &pRefItem
) );
1032 bRefItemSet
= ( SfxItemState::SET
==
1033 aRefItemSet
.GetItemState( nWhich
, false, &pRefItem
) );
1038 if( (bClearSame
|| pRefScriptItemSet
) && bRefItemSet
&&
1039 ( *pItem
== *pRefItem
||
1040 ((RES_CHRATR_FONT
== nWhich
||
1041 RES_CHRATR_CJK_FONT
== nWhich
||
1042 RES_CHRATR_CTL_FONT
== nWhich
) &&
1043 swhtml_css1atr_equalFontItems( *pItem
, *pRefItem
)) ) )
1045 // the Attribute is in both templates with the same value
1046 // and does not need to be exported
1047 rItemSet
.ClearItem( nWhich
);
1052 if( (bSetDefaults
|| pRefScriptItemSet
) && bRefItemSet
)
1054 // the Attribute exists only in the reference; the default
1055 // might have to be exported
1056 rItemSet
.Put( rItemSet
.GetPool()->GetUserOrPoolDefaultItem(nWhich
) );
1060 nWhich
= aIter
.NextWhich();
1064 void SwHTMLWriter::PrepareFontList( const SvxFontItem
& rFontItem
,
1066 sal_Unicode cQuote
, bool bGeneric
)
1069 const OUString
& rName
= rFontItem
.GetFamilyName();
1070 bool bContainsKeyword
= false;
1071 if( !rName
.isEmpty() )
1073 sal_Int32 nStrPos
= 0;
1074 while( nStrPos
!= -1 )
1076 OUString aName
= rName
.getToken( 0, ';', nStrPos
);
1077 aName
= comphelper::string::encodeForXml(comphelper::string::strip(aName
, ' '));
1078 if( aName
.isEmpty() )
1081 bool bIsKeyword
= false;
1086 bIsKeyword
= aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_cursive
);
1091 bIsKeyword
= aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_fantasy
);
1096 bIsKeyword
= aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_monospace
);
1102 aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_serif
) ||
1103 aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_sans_serif
);
1107 bContainsKeyword
|= bIsKeyword
;
1109 if( !rNames
.isEmpty() )
1111 if( cQuote
&& !bIsKeyword
)
1112 rNames
+= OUStringChar( cQuote
);
1114 if( cQuote
&& !bIsKeyword
)
1115 rNames
+= OUStringChar( cQuote
);
1119 if( bContainsKeyword
|| !bGeneric
)
1122 std::string_view pStr
;
1123 switch( rFontItem
.GetFamily() )
1125 case FAMILY_ROMAN
: pStr
= sCSS1_PV_serif
; break;
1126 case FAMILY_SWISS
: pStr
= sCSS1_PV_sans_serif
; break;
1127 case FAMILY_SCRIPT
: pStr
= sCSS1_PV_cursive
; break;
1128 case FAMILY_DECORATIVE
: pStr
= sCSS1_PV_fantasy
; break;
1129 case FAMILY_MODERN
: pStr
= sCSS1_PV_monospace
; break;
1136 if( !rNames
.isEmpty() )
1138 rNames
+= OStringToOUString( pStr
, RTL_TEXTENCODING_ASCII_US
);
1142 bool SwHTMLWriter::HasScriptDependentItems( const SfxItemSet
& rItemSet
,
1143 bool bCheckDropCap
)
1145 static const sal_uInt16 aWhichIds
[] =
1147 RES_CHRATR_FONT
, RES_CHRATR_CJK_FONT
, RES_CHRATR_CTL_FONT
,
1148 RES_CHRATR_FONTSIZE
, RES_CHRATR_CJK_FONTSIZE
, RES_CHRATR_CTL_FONTSIZE
,
1149 RES_CHRATR_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
, RES_CHRATR_CTL_LANGUAGE
,
1150 RES_CHRATR_POSTURE
, RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CTL_POSTURE
,
1151 RES_CHRATR_WEIGHT
, RES_CHRATR_CJK_WEIGHT
, RES_CHRATR_CTL_WEIGHT
,
1155 for( int i
=0; aWhichIds
[i
]; i
+= 3 )
1157 const SfxPoolItem
*pItem
= nullptr, *pItemCJK
= nullptr, *pItemCTL
= nullptr, *pTmp
;
1159 if( SfxItemState::SET
== rItemSet
.GetItemState( aWhichIds
[i
], false,
1165 if( SfxItemState::SET
== rItemSet
.GetItemState( aWhichIds
[i
+1], false,
1171 if( SfxItemState::SET
== rItemSet
.GetItemState( aWhichIds
[i
+2], false,
1178 // If some of the items are set, but not all, we need script dependent
1180 if( nItemCount
> 0 && nItemCount
< 3 )
1183 if( 3 == nItemCount
)
1185 // If all items are set, but some of them have different values,
1186 // we need script dependent styles, too. For font items, we have
1187 // to take care about their special HTML/CSS1 representation.
1188 if( RES_CHRATR_FONT
== aWhichIds
[i
] )
1190 if( !swhtml_css1atr_equalFontItems( *pItem
, *pItemCJK
) ||
1191 !swhtml_css1atr_equalFontItems( *pItem
, *pItemCTL
) ||
1192 !swhtml_css1atr_equalFontItems( *pItemCJK
, *pItemCTL
) )
1197 if( *pItem
!= *pItemCJK
||
1198 *pItem
!= *pItemCTL
||
1199 *pItemCJK
!= *pItemCTL
)
1205 const SwFormatDrop
*pDrop
;
1206 if( bCheckDropCap
&&
1207 (pDrop
= rItemSet
.GetItemIfSet( RES_PARATR_DROP
)) )
1209 const SwCharFormat
*pDCCharFormat
= pDrop
->GetCharFormat();
1212 //sequence of (start, end) property ranges we want to
1215 RES_CHRATR_FONT
, RES_CHRATR_FONT
,
1216 RES_CHRATR_POSTURE
, RES_CHRATR_POSTURE
,
1217 RES_CHRATR_WEIGHT
, RES_CHRATR_WEIGHT
,
1218 RES_CHRATR_CJK_FONT
, RES_CHRATR_CJK_FONT
,
1219 RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CTL_FONT
,
1220 RES_CHRATR_CTL_POSTURE
, RES_CHRATR_CTL_WEIGHT
>
1221 aTstItemSet(*pDCCharFormat
->GetAttrSet().GetPool());
1222 aTstItemSet
.Set( pDCCharFormat
->GetAttrSet() );
1223 return HasScriptDependentItems( aTstItemSet
, false );
1230 static bool OutCSS1Rule( SwHTMLWriter
& rWrt
, const OUString
& rSelector
,
1231 const SfxItemSet
& rItemSet
, bool bHasClass
,
1232 bool bCheckForPseudo
)
1234 bool bScriptDependent
= false;
1235 if( SwHTMLWriter::HasScriptDependentItems( rItemSet
, bHasClass
) )
1237 bScriptDependent
= true;
1238 std::u16string_view
aSelector( rSelector
);
1240 std::u16string_view aPseudo
;
1241 if( bCheckForPseudo
)
1243 size_t nPos
= aSelector
.rfind( ':' );
1244 if( nPos
!= std::u16string_view::npos
)
1246 aPseudo
= aSelector
.substr( nPos
);
1247 aSelector
=aSelector
.substr( 0, nPos
);
1253 // If we are exporting styles for a tag we have to export a tag
1254 // rule for all properties that aren't style dependent and
1255 // some class rule for the additional style dependen properties
1257 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_NO_SCRIPT
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1259 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1262 //sequence of (start, end) property ranges we want to
1264 SfxItemSetFixed
<RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
,
1265 RES_CHRATR_LANGUAGE
, RES_CHRATR_POSTURE
,
1266 RES_CHRATR_WEIGHT
, RES_CHRATR_WEIGHT
,
1267 RES_CHRATR_CJK_FONT
, RES_CHRATR_CTL_WEIGHT
>
1268 aScriptItemSet( *rItemSet
.GetPool() );
1269 aScriptItemSet
.Put( rItemSet
);
1271 OUString aNewSelector
= OUString::Concat(aSelector
) + ".western" + aPseudo
;
1273 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1275 rWrt
.OutCSS1_SfxItemSet( aScriptItemSet
, false );
1278 aNewSelector
= OUString::Concat(aSelector
) + ".cjk" + aPseudo
;
1280 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1282 rWrt
.OutCSS1_SfxItemSet( aScriptItemSet
, false );
1285 aNewSelector
= OUString::Concat(aSelector
) + ".ctl" + aPseudo
;
1287 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1289 rWrt
.OutCSS1_SfxItemSet( aScriptItemSet
, false );
1294 // If there are script dependencies and we are derived from a tag,
1295 // when we have to export a style dependent class for all
1297 OUString aNewSelector
= OUString::Concat(aSelector
) + "-western" + aPseudo
;
1299 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1301 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1304 aNewSelector
= OUString::Concat(aSelector
) + "-cjk" + aPseudo
;
1306 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1308 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1311 aNewSelector
= OUString::Concat(aSelector
) + "-ctl" + aPseudo
;
1313 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1315 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1321 // If there are no script dependencies, when all items are
1322 // exported in one step. For hyperlinks only, a script information
1323 // must be there, because these two chr formats don't support
1324 // script dependencies by now.
1325 SwCSS1OutMode
aMode( rWrt
,
1326 rWrt
.m_nCSS1Script
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1328 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1331 return bScriptDependent
;
1334 static void OutCSS1DropCapRule(
1335 SwHTMLWriter
& rWrt
, const OUString
& rSelector
,
1336 const SwFormatDrop
& rDrop
, bool bHasClass
,
1337 bool bHasScriptDependencies
)
1339 const SwCharFormat
*pDCCharFormat
= rDrop
.GetCharFormat();
1340 if( (bHasScriptDependencies
&& bHasClass
) ||
1341 (pDCCharFormat
&& SwHTMLWriter::HasScriptDependentItems( pDCCharFormat
->GetAttrSet(), false ) ) )
1343 std::u16string_view
aSelector( rSelector
);
1345 std::u16string_view aPseudo
;
1346 size_t nPos
= aSelector
.rfind( ':' );
1347 if( nPos
!= std::u16string_view::npos
)
1349 aPseudo
= aSelector
.substr( nPos
);
1350 aSelector
= aSelector
.substr( 0, nPos
);
1355 // If we are exporting styles for a tag we have to export a tag
1356 // rule for all properties that aren't style dependent and
1357 // some class rule for the additional style dependen properties
1359 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_NO_SCRIPT
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1361 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1364 SfxItemSetFixed
<RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
,
1365 RES_CHRATR_LANGUAGE
, RES_CHRATR_POSTURE
,
1366 RES_CHRATR_WEIGHT
, RES_CHRATR_WEIGHT
,
1367 RES_CHRATR_CJK_FONT
, RES_CHRATR_CTL_WEIGHT
>
1368 aScriptItemSet( rWrt
.m_pDoc
->GetAttrPool() );
1370 aScriptItemSet
.Set( pDCCharFormat
->GetAttrSet() );
1372 OUString aNewSelector
= OUString::Concat(aSelector
) + ".western" + aPseudo
;
1374 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1376 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
, &aScriptItemSet
);
1379 aNewSelector
= OUString::Concat(aSelector
) + ".cjk" + aPseudo
;
1381 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1383 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
, &aScriptItemSet
);
1386 aNewSelector
= OUString::Concat(aSelector
) + ".ctl" + aPseudo
;
1388 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1390 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
, &aScriptItemSet
);
1395 // If there are script dependencies and we are derived from a tag,
1396 // when we have to export a style dependent class for all
1398 OUString aNewSelector
= OUString::Concat(aSelector
) + "-western" + aPseudo
;
1400 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1402 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1405 aNewSelector
= OUString::Concat(aSelector
) + "-cjk" + aPseudo
;
1407 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1409 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1412 aNewSelector
= OUString::Concat(aSelector
) + "-ctl" + aPseudo
;
1414 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1416 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1422 // If there are no script dependencies, when all items are
1423 // exported in one step. For hyperlinks only, a script information
1424 // must be there, because these two chr formats don't support
1425 // script dependencies by now.
1426 SwCSS1OutMode
aMode( rWrt
,
1427 rWrt
.m_nCSS1Script
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1429 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1433 static SwHTMLWriter
& OutCSS1_SwFormat( SwHTMLWriter
& rWrt
, const SwFormat
& rFormat
,
1434 IDocumentStylePoolAccess
/*SwDoc*/ *pDoc
, SwDoc
*pTemplate
)
1436 bool bCharFormat
= false;
1437 switch( rFormat
.Which() )
1443 case RES_TXTFMTCOLL
:
1444 case RES_CONDTXTFMTCOLL
:
1445 // these template-types can be exported
1453 // determine Selector and the to-be-exported Attr-Set-depth
1455 sal_uInt16 nRefPoolId
= 0;
1456 sal_uInt16 nDeep
= GetCSS1Selector( &rFormat
, aSelector
, nRefPoolId
);
1458 return rWrt
; // not derived from a HTML-template
1460 sal_uInt16 nPoolFormatId
= rFormat
.GetPoolFormatId();
1462 // Determine the to-be-exported Attr-Set. We have to distinguish 3 cases:
1463 // - HTML-Tag templates (nDeep==USHRT_MAX):
1465 // - that are set in the template, but not in the original of the HTML template
1466 // - the Default-Attrs for the Attrs, that are set in the Original of the
1467 // HTML template, but not in the current template.
1468 // - templates directly derived from HTML templates (nDeep==1):
1469 // Export only Attributes of the template Item-Set w/o its parents.
1470 // - templates in-directly derived from HTML templates (nDeep>1):
1471 // Export Attributes of the template Item-Set incl. its Parents,
1472 // but w/o Attributes that are set in the HTML-Tag template.
1474 // create Item-Set with all Attributes from the template
1475 // (all but for nDeep==1)
1476 const SfxItemSet
& rFormatItemSet
= rFormat
.GetAttrSet();
1477 SfxItemSet
aItemSet( *rFormatItemSet
.GetPool(), rFormatItemSet
.GetRanges() );
1478 aItemSet
.Set( rFormatItemSet
); // Was nDeep!=1 that is not working
1479 // for script dependent items but should
1480 // not make a difference for any other
1482 bool bSetDefaults
= true, bClearSame
= true;
1483 const SwFormat
*pRefFormat
= nullptr;
1484 const SwFormat
*pRefFormatScript
= nullptr;
1487 case CSS1_FMT_ISTAG
:
1488 pRefFormat
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pTemplate
== nullptr ? nullptr : &pTemplate
->getIDocumentStylePoolAccess() );
1490 case CSS1_FMT_CMPREF
:
1491 pRefFormat
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pDoc
);
1492 pRefFormatScript
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pTemplate
== nullptr ? nullptr : &pTemplate
->getIDocumentStylePoolAccess() );
1496 pRefFormat
= SwHTMLWriter::GetParentFormat( rFormat
, nDeep
);
1497 pRefFormatScript
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pTemplate
== nullptr ? nullptr : &pTemplate
->getIDocumentStylePoolAccess() );
1498 bSetDefaults
= false;
1504 // subtract Item-Set of the Reference template (incl. its Parents)
1505 SwHTMLWriter::SubtractItemSet( aItemSet
, pRefFormat
->GetAttrSet(),
1506 bSetDefaults
, bClearSame
,
1508 ? &pRefFormatScript
->GetAttrSet()
1513 const SvxULSpaceItem
& rULItem
= pRefFormat
->GetULSpace();
1514 rWrt
.m_nDfltTopMargin
= rULItem
.GetUpper();
1515 rWrt
.m_nDfltBottomMargin
= rULItem
.GetLower();
1518 else if( CSS1_FMT_ISTAG
==nDeep
&& !bCharFormat
)
1520 // set Default-distance above and below (for the
1521 // case that there is no reference template)
1522 rWrt
.m_nDfltTopMargin
= 0;
1523 rWrt
.m_nDfltBottomMargin
= HTML_PARSPACE
;
1524 if( USER_FMT
& nPoolFormatId
)
1527 const OUString
& aNm(rFormat
.GetName());
1529 if (aNm
== "DD 1" || aNm
== "DT 1")
1530 rWrt
.m_nDfltBottomMargin
= 0;
1531 else if (aNm
== OOO_STRING_SVTOOLS_HTML_listing
)
1532 rWrt
.m_nDfltBottomMargin
= 0;
1533 else if (aNm
== OOO_STRING_SVTOOLS_HTML_preformtxt
)
1534 rWrt
.m_nDfltBottomMargin
= 0;
1535 else if (aNm
== OOO_STRING_SVTOOLS_HTML_xmp
)
1536 rWrt
.m_nDfltBottomMargin
= 0;
1541 switch( nPoolFormatId
)
1543 case RES_POOLCOLL_HEADLINE1
:
1544 case RES_POOLCOLL_HEADLINE2
:
1545 case RES_POOLCOLL_HEADLINE3
:
1546 case RES_POOLCOLL_HEADLINE4
:
1547 case RES_POOLCOLL_HEADLINE5
:
1548 case RES_POOLCOLL_HEADLINE6
:
1549 rWrt
.m_nDfltTopMargin
= HTML_HEADSPACE
;
1551 case RES_POOLCOLL_SEND_ADDRESS
:
1552 case RES_POOLCOLL_HTML_DT
:
1553 case RES_POOLCOLL_HTML_DD
:
1554 case RES_POOLCOLL_HTML_PRE
:
1555 rWrt
.m_nDfltBottomMargin
= 0;
1561 // if nothing is to be exported ...
1562 if( !aItemSet
.Count() )
1565 // There is no support for script dependent hyperlinks by now.
1566 bool bCheckForPseudo
= false;
1568 (RES_POOLCHR_INET_NORMAL
==nRefPoolId
||
1569 RES_POOLCHR_INET_VISIT
==nRefPoolId
) )
1570 bCheckForPseudo
= true;
1572 // export now the Attributes (incl. selector)
1573 bool bHasScriptDependencies
= false;
1574 if( OutCSS1Rule( rWrt
, aSelector
, aItemSet
, CSS1_FMT_ISTAG
!= nDeep
,
1578 rWrt
.m_aScriptTextStyles
.insert( rFormat
.GetName() );
1581 if( nPoolFormatId
==RES_POOLCOLL_TEXT
)
1582 rWrt
.m_aScriptParaStyles
.insert( pDoc
->GetTextCollFromPool( RES_POOLCOLL_STANDARD
, false )->GetName() );
1583 rWrt
.m_aScriptParaStyles
.insert( rFormat
.GetName() );
1585 bHasScriptDependencies
= true;
1589 if( const SwFormatDrop
*pDrop
= aItemSet
.GetItemIfSet( RES_PARATR_DROP
, false ) )
1591 OUString sOut
= aSelector
+ ":" + sCSS1_first_letter
;
1592 OutCSS1DropCapRule( rWrt
, sOut
, *pDrop
, CSS1_FMT_ISTAG
!= nDeep
, bHasScriptDependencies
);
1598 static SwHTMLWriter
& OutCSS1_SwPageDesc( SwHTMLWriter
& rWrt
, const SwPageDesc
& rPageDesc
,
1599 IDocumentStylePoolAccess
/*SwDoc*/ *pDoc
, SwDoc
*pTemplate
,
1600 sal_uInt16 nRefPoolId
, bool bExtRef
,
1603 const SwPageDesc
* pRefPageDesc
= nullptr;
1605 pRefPageDesc
= pDoc
->GetPageDescFromPool( nRefPoolId
, false );
1606 else if( pTemplate
)
1607 pRefPageDesc
= pTemplate
->getIDocumentStylePoolAccess().GetPageDescFromPool( nRefPoolId
, false );
1609 OUString aSelector
= OUString::Concat("@") + sCSS1_page
;
1613 std::u16string_view pPseudo
;
1614 switch( rPageDesc
.GetPoolFormatId() )
1616 case RES_POOLPAGE_FIRST
: pPseudo
= sCSS1_first
; break;
1617 case RES_POOLPAGE_LEFT
: pPseudo
= sCSS1_left
; break;
1618 case RES_POOLPAGE_RIGHT
: pPseudo
= sCSS1_right
; break;
1620 if( !pPseudo
.empty() )
1621 aSelector
+= OUString::Concat(":") + pPseudo
;
1624 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_RULE_ON
|CSS1_OUTMODE_TEMPLATE
,
1627 // Size: If the only difference is the Landscape-Flag,
1628 // only export Portrait or Landscape. Otherwise export size.
1629 bool bRefLandscape
= pRefPageDesc
&& pRefPageDesc
->GetLandscape();
1631 const Size
& rSz
= rPageDesc
.GetMaster().GetFrameSize().GetSize();
1634 aRefSz
= pRefPageDesc
->GetMaster().GetFrameSize().GetSize();
1635 if( bRefLandscape
!= rPageDesc
.GetLandscape() )
1637 tools::Long nTmp
= aRefSz
.Height();
1638 aRefSz
.setHeight( aRefSz
.Width() );
1639 aRefSz
.setWidth( nTmp
);
1643 // TODO: Bad Hack: On the Page-Tabpage there are small rounding errors
1644 // for the page size. Partially because of bug 25535, we stupidly still
1645 // use the Size-Item from Dialog, even if nothing changed.
1646 // Thus: once one visited the Page-Dialog and left it with OK, we get a
1647 // new page size that then gets exported here. To avoid that, we allow
1648 // here small deviations.
1649 if( std::abs( rSz
.Width() - aRefSz
.Width() ) <= 2 &&
1650 std::abs( rSz
.Height() - aRefSz
.Height() ) <= 2 )
1652 if( bRefLandscape
!= rPageDesc
.GetLandscape() )
1654 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_size
,
1655 rPageDesc
.GetLandscape() ? sCSS1_PV_landscape
1656 : sCSS1_PV_portrait
);
1662 AddUnitPropertyValue(sVal
, rSz
.Width(), rWrt
.GetCSS1Unit());
1664 AddUnitPropertyValue(sVal
, rSz
.Height(), rWrt
.GetCSS1Unit());
1665 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_size
, sVal
);
1668 // Export the distance-Attributes as normally
1669 const SwFrameFormat
&rMaster
= rPageDesc
.GetMaster();
1670 SfxItemSetFixed
<RES_LR_SPACE
, RES_UL_SPACE
> aItemSet( *rMaster
.GetAttrSet().GetPool() );
1671 aItemSet
.Set( rMaster
.GetAttrSet() );
1675 SwHTMLWriter::SubtractItemSet( aItemSet
,
1676 pRefPageDesc
->GetMaster().GetAttrSet(),
1680 OutCSS1_SvxULSpace_SvxLRSpace( rWrt
, aItemSet
);
1682 // If for a Pseudo-Selector no Property had been set, we still
1683 // have to export something, so that the corresponding template is
1684 // created on the next import.
1685 if( rWrt
.m_bFirstCSS1Property
&& bPseudo
)
1688 OString
sTmp(OUStringToOString(aSelector
, RTL_TEXTENCODING_UTF8
));
1689 rWrt
.Strm().WriteOString( sTmp
).WriteOString( " {" );
1690 rWrt
.m_bFirstCSS1Property
= false;
1693 if( !rWrt
.m_bFirstCSS1Property
)
1694 rWrt
.Strm().WriteOString( sCSS1_rule_end
);
1699 static SwHTMLWriter
& OutCSS1_SwFootnoteInfo( SwHTMLWriter
& rWrt
, const SwEndNoteInfo
& rInfo
,
1700 SwDoc
*pDoc
, bool bHasNotes
, bool bEndNote
)
1706 aSelector
= OUString::Concat(OOO_STRING_SVTOOLS_HTML_anchor
".") +
1707 ( bEndNote
? std::u16string_view(u
"" OOO_STRING_SVTOOLS_HTML_sdendnote_anc
)
1708 : std::u16string_view(u
"" OOO_STRING_SVTOOLS_HTML_sdfootnote_anc
) );
1709 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1711 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_size
,
1712 sHTML_FTN_fontheight
);
1713 rWrt
.Strm().WriteOString( sCSS1_rule_end
);
1716 const SwCharFormat
*pSymCharFormat
= rInfo
.GetCharFormat( *pDoc
);
1717 if( pSymCharFormat
)
1719 const SfxItemSet
& rFormatItemSet
= pSymCharFormat
->GetAttrSet();
1720 SfxItemSet
aItemSet( *rFormatItemSet
.GetPool(), rFormatItemSet
.GetRanges() );
1721 aItemSet
.Set( rFormatItemSet
);
1723 // If there are footnotes or endnotes, then all Attributes have to be
1724 // exported, so that Netscape displays the document correctly.
1725 // Otherwise it is sufficient, to export the differences to the
1726 // footnote and endnote template.
1727 if( !bHasNotes
&& rWrt
.m_xTemplate
.is() )
1729 SwFormat
*pRefFormat
= rWrt
.m_xTemplate
->getIDocumentStylePoolAccess().GetCharFormatFromPool(
1730 static_cast< sal_uInt16
>(bEndNote
? RES_POOLCHR_ENDNOTE
: RES_POOLCHR_FOOTNOTE
) );
1732 SwHTMLWriter::SubtractItemSet( aItemSet
, pRefFormat
->GetAttrSet(),
1735 if( aItemSet
.Count() )
1737 aSelector
= OUString::Concat(OOO_STRING_SVTOOLS_HTML_anchor
".") +
1738 ( bEndNote
? std::u16string_view(u
"" OOO_STRING_SVTOOLS_HTML_sdendnote_sym
)
1739 : std::u16string_view(
1740 u
"" OOO_STRING_SVTOOLS_HTML_sdfootnote_sym
));
1741 if( OutCSS1Rule( rWrt
, aSelector
, aItemSet
, true, false ))
1742 rWrt
.m_aScriptTextStyles
.insert( pSymCharFormat
->GetName() );
1749 SwHTMLWriter
& OutCSS1_BodyTagStyleOpt( SwHTMLWriter
& rWrt
, const SfxItemSet
& rItemSet
)
1751 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT_ON
|
1752 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_BODY
, nullptr );
1754 // Only export the attributes of the page template.
1755 // The attributes of the default paragraph template were
1756 // considered already when exporting the paragraph template.
1758 const SfxPoolItem
*pItem
;
1759 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_BACKGROUND
, false,
1762 OUString rEmbeddedGraphicName
;
1763 OutCSS1_SvxBrush( rWrt
, *pItem
, sw::Css1Background::Page
, &rEmbeddedGraphicName
);
1766 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_BOX
, false,
1769 OutCSS1_SvxBox( rWrt
, *pItem
);
1772 if( !rWrt
.m_bFirstCSS1Property
)
1774 // if a Property was exported as part of a Style-Option,
1775 // the Option still needs to be finished
1776 rWrt
.Strm().WriteChar( '\"' );
1782 SwHTMLWriter
& OutCSS1_ParaTagStyleOpt( SwHTMLWriter
& rWrt
, const SfxItemSet
& rItemSet
, std::string_view rAdd
)
1784 SwCSS1OutMode
aMode( rWrt
, rWrt
.m_nCSS1Script
|CSS1_OUTMODE_STYLE_OPT
|
1785 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_PARA
, nullptr );
1786 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false, rAdd
);
1791 SwHTMLWriter
& OutCSS1_TableBGStyleOpt( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
1793 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT_ON
|
1794 CSS1_OUTMODE_ENCODE
|
1795 CSS1_OUTMODE_TABLEBOX
, nullptr );
1796 OutCSS1_SvxBrush( rWrt
, rHt
, sw::Css1Background::TableRow
, nullptr );
1798 if (!rWrt
.m_bFirstCSS1Property
)
1799 rWrt
.Strm().WriteChar(cCSS1_style_opt_end
);
1804 SwHTMLWriter
& OutCSS1_NumberBulletListStyleOpt( SwHTMLWriter
& rWrt
, const SwNumRule
& rNumRule
,
1807 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT
|
1808 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_PARA
, nullptr );
1810 const SwNumFormat
& rNumFormat
= rNumRule
.Get( nLevel
);
1812 tools::Long nLSpace
= rNumFormat
.GetAbsLSpace();
1813 tools::Long nFirstLineOffset
= rNumFormat
.GetFirstLineOffset();
1814 tools::Long nDfltFirstLineOffset
= HTML_NUMBER_BULLET_INDENT
;
1817 const SwNumFormat
& rPrevNumFormat
= rNumRule
.Get( nLevel
-1 );
1818 nLSpace
-= rPrevNumFormat
.GetAbsLSpace();
1819 nDfltFirstLineOffset
= rPrevNumFormat
.GetFirstLineOffset();
1822 if( rWrt
.IsHTMLMode(HTMLMODE_LSPACE_IN_NUMBER_BULLET
) &&
1823 nLSpace
!= HTML_NUMBER_BULLET_MARGINLEFT
)
1824 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_left
, nLSpace
);
1826 if( rWrt
.IsHTMLMode(HTMLMODE_FRSTLINE_IN_NUMBER_BULLET
) &&
1827 nFirstLineOffset
!= nDfltFirstLineOffset
)
1828 rWrt
.OutCSS1_UnitProperty( sCSS1_P_text_indent
, nFirstLineOffset
);
1830 if( !rWrt
.m_bFirstCSS1Property
)
1831 rWrt
.Strm().WriteChar( '\"' );
1836 void SwHTMLWriter::OutCSS1_FrameFormatOptions( const SwFrameFormat
& rFrameFormat
,
1837 HtmlFrmOpts nFrameOpts
,
1838 const SdrObject
*pSdrObj
,
1839 const SfxItemSet
*pItemSet
)
1841 SwCSS1OutMode
aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON
|
1842 CSS1_OUTMODE_ENCODE
|
1843 CSS1_OUTMODE_FRAME
, nullptr );
1845 const SwFormatHoriOrient
& rHoriOri
= rFrameFormat
.GetHoriOrient();
1846 SvxLRSpaceItem
aLRItem( rFrameFormat
.GetLRSpace() );
1847 SvxULSpaceItem
aULItem( rFrameFormat
.GetULSpace() );
1848 if( nFrameOpts
& HtmlFrmOpts::SAlign
)
1850 const SwFormatAnchor
& rAnchor
= rFrameFormat
.GetAnchor();
1851 switch( rAnchor
.GetAnchorId() )
1853 case RndStdIds::FLY_AT_PARA
:
1854 case RndStdIds::FLY_AT_CHAR
:
1855 if( text::RelOrientation::FRAME
== rHoriOri
.GetRelationOrient() ||
1856 text::RelOrientation::PRINT_AREA
== rHoriOri
.GetRelationOrient() )
1858 if( !(nFrameOpts
& HtmlFrmOpts::Align
) )
1861 std::string_view pStr
= text::HoriOrientation::RIGHT
==rHoriOri
.GetHoriOrient()
1864 OutCSS1_PropertyAscii( sCSS1_P_float
, pStr
);
1870 case RndStdIds::FLY_AT_PAGE
:
1871 case RndStdIds::FLY_AT_FLY
:
1874 OutCSS1_PropertyAscii( sCSS1_P_position
, sCSS1_PV_absolute
);
1876 // For top/left we need to subtract the distance to the frame
1877 // from the position, as in CSS1 it is added to the position.
1878 // This works also for automatically aligned frames, even that
1879 // in this case Writer also adds the distance; because in this
1880 // case the Orient-Attribute contains the correct position.
1883 tools::Long nXPos
=0, nYPos
=0;
1884 bool bOutXPos
= false, bOutYPos
= false;
1885 if( RES_DRAWFRMFMT
== rFrameFormat
.Which() )
1887 OSL_ENSURE( pSdrObj
, "Do not pass a SdrObject. Inefficient" );
1889 pSdrObj
= rFrameFormat
.FindSdrObject();
1890 OSL_ENSURE( pSdrObj
, "Where is the SdrObject" );
1893 Point
aPos( pSdrObj
->GetRelativePos() );
1897 bOutXPos
= bOutYPos
= true;
1901 bOutXPos
= text::RelOrientation::CHAR
!= rHoriOri
.GetRelationOrient();
1902 nXPos
= text::HoriOrientation::NONE
== rHoriOri
.GetHoriOrient()
1903 ? rHoriOri
.GetPos() : 0;
1905 const SwFormatVertOrient
& rVertOri
= rFrameFormat
.GetVertOrient();
1906 bOutYPos
= text::RelOrientation::CHAR
!= rVertOri
.GetRelationOrient();
1907 nYPos
= text::VertOrientation::NONE
== rVertOri
.GetVertOrient()
1908 ? rVertOri
.GetPos() : 0;
1913 if( IsHTMLMode( HTMLMODE_FLY_MARGINS
) )
1915 nYPos
-= aULItem
.GetUpper();
1918 aULItem
.SetUpper( o3tl::narrowing
<sal_uInt16
>(aULItem
.GetUpper() + nYPos
) );
1923 OutCSS1_UnitProperty( sCSS1_P_top
, nYPos
);
1929 if( IsHTMLMode( HTMLMODE_FLY_MARGINS
) )
1931 nXPos
-= aLRItem
.ResolveLeft({});
1934 aLRItem
.SetLeft(SvxIndentValue::twips(
1935 o3tl::narrowing
<sal_uInt16
>(aLRItem
.ResolveLeft({}) + nXPos
)));
1940 OutCSS1_UnitProperty( sCSS1_P_left
, nXPos
);
1951 if( nFrameOpts
& HtmlFrmOpts::SSize
)
1953 if( RES_DRAWFRMFMT
== rFrameFormat
.Which() )
1955 OSL_ENSURE( pSdrObj
, "Do not pass a SdrObject. Inefficient" );
1957 pSdrObj
= rFrameFormat
.FindSdrObject();
1958 OSL_ENSURE( pSdrObj
, "Where is the SdrObject" );
1961 Size
aTwipSz( pSdrObj
->GetLogicRect().GetSize() );
1962 if( nFrameOpts
& HtmlFrmOpts::SWidth
)
1964 if( nFrameOpts
& HtmlFrmOpts::SPixSize
)
1965 OutCSS1_PixelProperty( sCSS1_P_width
, aTwipSz
.Width() );
1967 OutCSS1_UnitProperty( sCSS1_P_width
, aTwipSz
.Width() );
1969 if( nFrameOpts
& HtmlFrmOpts::SHeight
)
1971 if( nFrameOpts
& HtmlFrmOpts::SPixSize
)
1972 OutCSS1_PixelProperty( sCSS1_P_height
, aTwipSz
.Height() );
1974 OutCSS1_UnitProperty( sCSS1_P_height
, aTwipSz
.Height() );
1980 OSL_ENSURE( HtmlFrmOpts::AbsSize
& nFrameOpts
,
1981 "Export absolute size" );
1982 OSL_ENSURE( HtmlFrmOpts::AnySize
& nFrameOpts
,
1983 "Export every size" );
1984 Css1FrameSize nMode
= Css1FrameSize::NONE
;
1985 if( nFrameOpts
& HtmlFrmOpts::SWidth
)
1986 nMode
|= Css1FrameSize::Width
;
1987 if( nFrameOpts
& HtmlFrmOpts::SHeight
)
1988 nMode
|= Css1FrameSize::MinHeight
|Css1FrameSize::FixHeight
;
1989 if( nFrameOpts
& HtmlFrmOpts::SPixSize
)
1990 nMode
|= Css1FrameSize::Pixel
;
1992 OutCSS1_SwFormatFrameSize( *this, rFrameFormat
.GetFrameSize(), nMode
);
1996 const SfxItemSet
& rItemSet
= rFrameFormat
.GetAttrSet();
1998 if( (nFrameOpts
& HtmlFrmOpts::SSpace
) &&
1999 IsHTMLMode( HTMLMODE_FLY_MARGINS
) )
2001 const SvxLRSpaceItem
*pLRItem
= nullptr;
2002 const SvxULSpaceItem
*pULItem
= nullptr;
2003 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_LR_SPACE
) )
2005 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_UL_SPACE
) )
2007 if( pLRItem
|| pULItem
)
2008 OutCSS1_SvxULSpace_SvxLRSpace( *this, pULItem
, pLRItem
);
2012 if( nFrameOpts
& HtmlFrmOpts::SBorder
)
2014 const SfxPoolItem
* pItem
;
2015 if( nFrameOpts
& HtmlFrmOpts::SNoBorder
)
2016 OutCSS1_SvxBox( *this, rFrameFormat
.GetBox() );
2017 else if( SfxItemState::SET
==rItemSet
.GetItemState( RES_BOX
, true, &pItem
) )
2018 OutCSS1_SvxBox( *this, *pItem
);
2021 // background (if, then the color must be set also)
2022 if( nFrameOpts
& HtmlFrmOpts::SBackground
)
2023 OutCSS1_FrameFormatBackground( rFrameFormat
);
2026 OutCSS1_SfxItemSet( *pItemSet
, false );
2028 if( !m_bFirstCSS1Property
)
2029 Strm().WriteChar( '\"' );
2032 void SwHTMLWriter::OutCSS1_TableFrameFormatOptions( const SwFrameFormat
& rFrameFormat
)
2034 SwCSS1OutMode
aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON
|
2035 CSS1_OUTMODE_ENCODE
|
2036 CSS1_OUTMODE_TABLE
, nullptr );
2038 const SfxPoolItem
*pItem
;
2039 const SfxItemSet
& rItemSet
= rFrameFormat
.GetAttrSet();
2040 if( SfxItemState::SET
==rItemSet
.GetItemState( RES_BACKGROUND
, false, &pItem
) )
2041 OutCSS1_SvxBrush( *this, *pItem
, sw::Css1Background::Table
, nullptr );
2043 if( IsHTMLMode( HTMLMODE_PRINT_EXT
) )
2044 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet
, false );
2046 if( SfxItemState::SET
==rItemSet
.GetItemState( RES_LAYOUT_SPLIT
, false, &pItem
) )
2047 OutCSS1_SwFormatLayoutSplit( *this, *pItem
);
2051 sal_Int16 eTabHoriOri
= rFrameFormat
.GetHoriOrient().GetHoriOrient();
2052 if (eTabHoriOri
== text::HoriOrientation::CENTER
)
2054 // Emit XHTML's center using inline CSS.
2055 OutCSS1_Property(sCSS1_P_margin_left
, "auto", nullptr, sw::Css1Background::Table
);
2056 OutCSS1_Property(sCSS1_P_margin_right
, "auto", nullptr, sw::Css1Background::Table
);
2060 if( !m_bFirstCSS1Property
)
2061 Strm().WriteChar( '\"' );
2064 void SwHTMLWriter::OutCSS1_TableCellBordersAndBG(SwFrameFormat
const& rFrameFormat
, const SvxBrushItem
*pBrushItem
)
2066 SwCSS1OutMode
const aMode( *this,
2067 CSS1_OUTMODE_STYLE_OPT_ON
|CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_TABLEBOX
, nullptr );
2069 OutCSS1_SvxBrush(*this, *pBrushItem
, sw::Css1Background::TableCell
, nullptr);
2070 OutCSS1_SvxBox(*this, rFrameFormat
.GetBox());
2071 if (!m_bFirstCSS1Property
)
2072 Strm().WriteChar(cCSS1_style_opt_end
);
2075 void SwHTMLWriter::OutCSS1_SectionFormatOptions( const SwFrameFormat
& rFrameFormat
, const SwFormatCol
*pCol
)
2077 SwCSS1OutMode
aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON
|
2078 CSS1_OUTMODE_ENCODE
|
2079 CSS1_OUTMODE_SECTION
, nullptr );
2081 const SfxPoolItem
*pItem
;
2082 const SfxItemSet
& rItemSet
= rFrameFormat
.GetAttrSet();
2083 if( SfxItemState::SET
==rItemSet
.GetItemState( RES_BACKGROUND
, false, &pItem
) )
2084 OutCSS1_SvxBrush( *this, *pItem
, sw::Css1Background::Section
, nullptr );
2088 SvxFrameDirection nDir
= GetHTMLDirection(rFrameFormat
.GetAttrSet());
2089 OString sConvertedDirection
= convertDirection(nDir
);
2090 if (!sConvertedDirection
.isEmpty())
2092 OutCSS1_Property(sCSS1_P_dir
, sConvertedDirection
, nullptr,
2093 sw::Css1Background::Section
);
2099 OString
sColumnCount(OString::number(static_cast<sal_Int32
>(pCol
->GetNumCols())));
2100 OutCSS1_PropertyAscii(sCSS1_P_column_count
, sColumnCount
);
2103 if( !m_bFirstCSS1Property
)
2104 Strm().WriteChar( '\"' );
2107 static bool OutCSS1_FrameFormatBrush( SwHTMLWriter
& rWrt
,
2108 const SvxBrushItem
& rBrushItem
)
2110 bool bWritten
= false;
2111 /// output brush of frame format, if its background color is not "no fill"/"auto fill"
2112 /// or it has a background graphic.
2113 if( rBrushItem
.GetColor() != COL_TRANSPARENT
||
2114 !rBrushItem
.GetGraphicLink().isEmpty() ||
2115 0 != rBrushItem
.GetGraphicPos() )
2117 OutCSS1_SvxBrush( rWrt
, rBrushItem
, sw::Css1Background::Fly
, nullptr );
2123 void SwHTMLWriter::OutCSS1_FrameFormatBackground( const SwFrameFormat
& rFrameFormat
)
2125 // If the frame itself has a background, then export.
2126 if( OutCSS1_FrameFormatBrush( *this, *rFrameFormat
.makeBackgroundBrushItem() ) )
2129 // If the frame is not linked to a page, we use the background of the anchor.
2130 const SwFormatAnchor
& rAnchor
= rFrameFormat
.GetAnchor();
2131 RndStdIds eAnchorId
= rAnchor
.GetAnchorId();
2132 const SwNode
*pAnchorNode
= rAnchor
.GetAnchorNode();
2133 if (RndStdIds::FLY_AT_PAGE
!= eAnchorId
&& pAnchorNode
)
2135 if( pAnchorNode
->IsContentNode() )
2137 // If the frame is linked to a content-node,
2138 // we take the background of the content-node, if it has one.
2139 if( OutCSS1_FrameFormatBrush( *this,
2140 pAnchorNode
->GetContentNode()->GetSwAttrSet().GetBackground()) )
2143 // Otherwise we also could be in a table
2144 const SwTableNode
*pTableNd
= pAnchorNode
->FindTableNode();
2147 const SwStartNode
*pBoxSttNd
= pAnchorNode
->FindTableBoxStartNode();
2148 const SwTableBox
*pBox
=
2149 pTableNd
->GetTable().GetTableBox( pBoxSttNd
->GetIndex() );
2151 // If the box has a background, we take it.
2152 if( OutCSS1_FrameFormatBrush( *this,
2153 *pBox
->GetFrameFormat()->makeBackgroundBrushItem() ) )
2156 // Otherwise we use that of the lines
2157 const SwTableLine
*pLine
= pBox
->GetUpper();
2160 if( OutCSS1_FrameFormatBrush( *this,
2161 *pLine
->GetFrameFormat()->makeBackgroundBrushItem() ) )
2163 pBox
= pLine
->GetUpper();
2164 pLine
= pBox
? pBox
->GetUpper() : nullptr;
2167 // If there was none either, we use the background of the table.
2168 if( OutCSS1_FrameFormatBrush( *this,
2169 *pTableNd
->GetTable().GetFrameFormat()->makeBackgroundBrushItem() ) )
2175 // If the anchor is again in a Fly-Frame, use the background of the Fly-Frame.
2176 const SwFrameFormat
*pFrameFormat
= pAnchorNode
->GetFlyFormat();
2179 OutCSS1_FrameFormatBackground( *pFrameFormat
);
2184 // At last there is the background of the page, and as the final rescue
2185 // the value of the Config.
2186 assert(m_pCurrPageDesc
&& "no page template found");
2187 if( OutCSS1_FrameFormatBrush( *this,
2188 *m_pCurrPageDesc
->GetMaster().makeBackgroundBrushItem() ) )
2191 Color
aColor( COL_WHITE
);
2193 // The background color is normally only used in Browse-Mode.
2194 // We always use it for a HTML document, but for a text document
2195 // only if viewed in Browse-Mode.
2196 if( m_pDoc
->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE
) ||
2197 m_pDoc
->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE
))
2199 SwViewShell
*pVSh
= m_pDoc
->getIDocumentLayoutAccess().GetCurrentViewShell();
2201 COL_TRANSPARENT
!= pVSh
->GetViewOptions()->GetRetoucheColor())
2202 aColor
= pVSh
->GetViewOptions()->GetRetoucheColor();
2205 OutCSS1_PropertyAscii(sCSS1_P_background
, GetCSS1_Color(aColor
));
2208 static SwHTMLWriter
& OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( SwHTMLWriter
& rWrt
,
2209 const SvxUnderlineItem
*pUItem
,
2210 const SvxOverlineItem
*pOItem
,
2211 const SvxCrossedOutItem
*pCOItem
,
2212 const SvxBlinkItem
*pBItem
)
2219 switch( pUItem
->GetLineStyle() )
2221 case LINESTYLE_NONE
:
2224 case LINESTYLE_DONTKNOW
:
2227 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2229 // this also works in HTML does not need to be written as
2230 // a STYLE-Options, and must not be written as Hint
2231 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) || rWrt
.mbReqIF
,
2232 "write underline as Hint?" );
2233 sOut
.append(sCSS1_PV_underline
);
2241 switch( pOItem
->GetLineStyle() )
2243 case LINESTYLE_NONE
:
2246 case LINESTYLE_DONTKNOW
:
2249 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2251 // this also works in HTML does not need to be written as
2252 // a STYLE-Options, and must not be written as Hint
2253 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2254 "write overline as Hint?" );
2255 if (!sOut
.isEmpty())
2257 sOut
.append(sCSS1_PV_overline
);
2265 switch( pCOItem
->GetStrikeout() )
2267 case STRIKEOUT_NONE
:
2270 case STRIKEOUT_DONTKNOW
:
2273 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2275 // this also works in HTML does not need to be written as
2276 // a STYLE-Options, and must not be written as Hint
2277 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) || rWrt
.mbReqIF
,
2278 "write crossedOut as Hint?" );
2279 if (!sOut
.isEmpty())
2281 sOut
.append(sCSS1_PV_line_through
);
2289 if( !pBItem
->GetValue() )
2293 else if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2295 // this also works in HTML does not need to be written as
2296 // a STYLE-Options, and must not be written as Hint
2297 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2298 "write blink as Hint?" );
2299 if (!sOut
.isEmpty())
2301 sOut
.append(sCSS1_PV_blink
);
2305 if (!sOut
.isEmpty())
2306 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_decoration
, sOut
);
2308 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_decoration
, sCSS1_PV_none
);
2313 static SwHTMLWriter
& OutCSS1_SvxCaseMap( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2315 switch( static_cast<const SvxCaseMapItem
&>(rHt
).GetCaseMap() )
2317 case SvxCaseMap::NotMapped
:
2318 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_variant
, sCSS1_PV_normal
);
2320 case SvxCaseMap::SmallCaps
:
2321 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_variant
, sCSS1_PV_small_caps
);
2323 case SvxCaseMap::Uppercase
:
2324 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_transform
, sCSS1_PV_uppercase
);
2326 case SvxCaseMap::Lowercase
:
2327 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_transform
, sCSS1_PV_lowercase
);
2329 case SvxCaseMap::Capitalize
:
2330 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_transform
, sCSS1_PV_capitalize
);
2339 static SwHTMLWriter
& OutCSS1_SvxColor( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2341 // Colors do not need to be exported for Style-Option.
2342 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) &&
2343 !rWrt
.m_bCfgPreferStyles
)
2345 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2346 "write color as Hint?" );
2348 Color
aColor( static_cast<const SvxColorItem
&>(rHt
).GetValue() );
2349 if( COL_AUTO
== aColor
)
2352 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_color
, GetCSS1_Color(aColor
));
2357 static SwHTMLWriter
& OutCSS1_SvxCrossedOut( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2359 // This function only exports Hints!
2360 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2362 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2363 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2364 nullptr, nullptr, static_cast<const SvxCrossedOutItem
*>(&rHt
), nullptr );
2369 static SwHTMLWriter
& OutCSS1_SvxFont( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2371 // No need to export Fonts for the Style-Option.
2372 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2375 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2376 switch( rHt
.Which() )
2378 case RES_CHRATR_CJK_FONT
: nScript
= CSS1_OUTMODE_CJK
; break;
2379 case RES_CHRATR_CTL_FONT
: nScript
= CSS1_OUTMODE_CTL
; break;
2381 if( !rWrt
.IsCSS1Script( nScript
) )
2384 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2385 "write Font as Hint?" );
2388 // MS IE3b1 has problems with single quotes
2389 sal_uInt16 nMode
= rWrt
.m_nCSS1OutMode
& CSS1_OUTMODE_ANY_ON
;
2390 sal_Unicode cQuote
= nMode
== CSS1_OUTMODE_RULE_ON
? '\"' : '\'';
2391 SwHTMLWriter::PrepareFontList( static_cast<const SvxFontItem
&>(rHt
), sOut
, cQuote
,
2394 rWrt
.OutCSS1_Property( sCSS1_P_font_family
, sOut
);
2399 static SwHTMLWriter
& OutCSS1_SvxFontHeight( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2401 // Font-Height need not be exported in the Style-Option.
2402 // For Drop-Caps another Font-Size is exported.
2403 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) ||
2404 rWrt
.IsCSS1Source( CSS1_OUTMODE_DROPCAP
) )
2407 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2408 switch( rHt
.Which() )
2410 case RES_CHRATR_CJK_FONTSIZE
: nScript
= CSS1_OUTMODE_CJK
; break;
2411 case RES_CHRATR_CTL_FONTSIZE
: nScript
= CSS1_OUTMODE_CTL
; break;
2413 if( !rWrt
.IsCSS1Script( nScript
) )
2416 sal_uInt32 nHeight
= static_cast<const SvxFontHeightItem
&>(rHt
).GetHeight();
2417 OString
sHeight(OString::number(nHeight
/20) + sCSS1_UNIT_pt
);
2418 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_font_size
, sHeight
);
2423 static SwHTMLWriter
& OutCSS1_SvxPosture( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2425 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2426 switch( rHt
.Which() )
2428 case RES_CHRATR_CJK_POSTURE
: nScript
= CSS1_OUTMODE_CJK
; break;
2429 case RES_CHRATR_CTL_POSTURE
: nScript
= CSS1_OUTMODE_CTL
; break;
2431 if( !rWrt
.IsCSS1Script( nScript
) )
2434 std::string_view pStr
;
2435 switch( static_cast<const SvxPostureItem
&>(rHt
).GetPosture() )
2437 case ITALIC_NONE
: pStr
= sCSS1_PV_normal
; break;
2438 case ITALIC_OBLIQUE
: pStr
= sCSS1_PV_oblique
; break;
2440 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2442 // this also works in HTML does not need to be written as
2443 // a STYLE-Options, and must not be written as Hint
2444 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2445 "write italic as Hint?" );
2446 pStr
= sCSS1_PV_italic
;
2454 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_style
, pStr
);
2459 static SwHTMLWriter
& OutCSS1_SvxKerning( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2461 sal_Int16 nValue
= static_cast<const SvxKerningItem
&>(rHt
).GetValue();
2472 nValue
= (nValue
+ 1) / 2; // 1/10pt
2473 sOut
.append(OString::number(nValue
/ 10) + "." + OString::number(nValue
% 10) +
2476 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_letter_spacing
, sOut
);
2481 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing
,
2488 static SwHTMLWriter
& OutCSS1_SvxLanguage( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2490 // Only export Language rules
2491 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2494 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2495 switch( rHt
.Which() )
2497 case RES_CHRATR_CJK_LANGUAGE
: nScript
= CSS1_OUTMODE_CJK
; break;
2498 case RES_CHRATR_CTL_LANGUAGE
: nScript
= CSS1_OUTMODE_CTL
; break;
2500 if( !rWrt
.IsCSS1Script( nScript
) )
2503 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2504 "write Language as Hint?" );
2506 LanguageType eLang
= static_cast<const SvxLanguageItem
&>(rHt
).GetLanguage();
2507 if( LANGUAGE_DONTKNOW
== eLang
)
2510 OUString sOut
= LanguageTag::convertToBcp47( eLang
);
2512 rWrt
.OutCSS1_Property( sCSS1_P_so_language
, sOut
);
2517 static SwHTMLWriter
& OutCSS1_SvxUnderline( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2519 // This function only exports Hints!
2520 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2522 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2523 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2524 static_cast<const SvxUnderlineItem
*>(&rHt
), nullptr, nullptr, nullptr );
2529 static SwHTMLWriter
& OutCSS1_SvxOverline( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2531 // This function only exports Hints!
2532 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2534 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2535 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2536 nullptr, static_cast<const SvxOverlineItem
*>(&rHt
), nullptr, nullptr );
2541 static SwHTMLWriter
& OutCSS1_SvxHidden( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2543 if ( static_cast<const SvxCharHiddenItem
&>(rHt
).GetValue() )
2544 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_display
, sCSS1_PV_none
);
2549 static SwHTMLWriter
& OutCSS1_SvxFontWeight( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2551 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2552 switch( rHt
.Which() )
2554 case RES_CHRATR_CJK_WEIGHT
: nScript
= CSS1_OUTMODE_CJK
; break;
2555 case RES_CHRATR_CTL_WEIGHT
: nScript
= CSS1_OUTMODE_CTL
; break;
2557 if( !rWrt
.IsCSS1Script( nScript
) )
2560 std::string_view pStr
;
2561 switch( static_cast<const SvxWeightItem
&>(rHt
).GetWeight() )
2563 case WEIGHT_ULTRALIGHT
: pStr
= sCSS1_PV_extra_light
; break;
2564 case WEIGHT_LIGHT
: pStr
= sCSS1_PV_light
; break;
2565 case WEIGHT_SEMILIGHT
: pStr
= sCSS1_PV_demi_light
; break;
2566 case WEIGHT_NORMAL
: pStr
= sCSS1_PV_normal
; break;
2567 case WEIGHT_SEMIBOLD
: pStr
= sCSS1_PV_demi_bold
; break;
2569 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2571 // this also works in HTML does not need to be written as
2572 // a STYLE-Options, and must not be written as Hint
2573 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2574 "write bold as Hint?" );
2575 pStr
= sCSS1_PV_bold
;
2578 case WEIGHT_ULTRABOLD
: pStr
= sCSS1_PV_extra_bold
; break;
2580 pStr
= sCSS1_PV_normal
;
2584 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_weight
, pStr
);
2589 static SwHTMLWriter
& OutCSS1_SvxBlink( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2591 // This function only exports Hints!
2592 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2594 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2595 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2596 nullptr, nullptr, nullptr, static_cast<const SvxBlinkItem
*>(&rHt
) );
2601 static SwHTMLWriter
& OutCSS1_SvxLineSpacing( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2603 // Netscape4 has big problems with cell heights if the line spacing is
2604 // changed within a table and the width of the table is not calculated
2605 // automatically (== if there is a WIDTH-Option)
2606 if( rWrt
.m_bOutTable
&& rWrt
.m_bCfgNetscape4
)
2609 const SvxLineSpacingItem
& rLSItem
= static_cast<const SvxLineSpacingItem
&>(rHt
);
2611 sal_uInt16 nHeight
= 0;
2612 sal_uInt16 nPercentHeight
= 0;
2613 SvxLineSpaceRule eLineSpace
= rLSItem
.GetLineSpaceRule();
2614 switch( rLSItem
.GetInterLineSpaceRule() )
2616 case SvxInterLineSpaceRule::Off
:
2617 case SvxInterLineSpaceRule::Fix
:
2619 switch( eLineSpace
)
2621 case SvxLineSpaceRule::Min
:
2622 case SvxLineSpaceRule::Fix
:
2623 nHeight
= rLSItem
.GetLineHeight();
2625 case SvxLineSpaceRule::Auto
:
2626 nPercentHeight
= 100;
2633 case SvxInterLineSpaceRule::Prop
:
2634 nPercentHeight
= rLSItem
.GetPropLineSpace();
2642 rWrt
.OutCSS1_UnitProperty( sCSS1_P_line_height
, static_cast<tools::Long
>(nHeight
) );
2643 else if( nPercentHeight
&&
2644 !(nPercentHeight
< 115 && rWrt
.m_bParaDotLeaders
)) // avoid HTML scrollbars and missing descenders
2646 OString
sHeight(OString::number(nPercentHeight
) + "%");
2647 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_line_height
, sHeight
);
2653 static SwHTMLWriter
& OutCSS1_SvxAdjust( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2655 // Export Alignment in Style-Option only if the Tag does not allow ALIGN=xxx
2656 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) &&
2660 std::string_view pStr
;
2661 switch( static_cast<const SvxAdjustItem
&>(rHt
).GetAdjust() )
2663 case SvxAdjust::Left
: pStr
= sCSS1_PV_left
; break;
2664 case SvxAdjust::Right
: pStr
= sCSS1_PV_right
; break;
2665 case SvxAdjust::Block
: pStr
= sCSS1_PV_justify
; break;
2666 case SvxAdjust::Center
: pStr
= sCSS1_PV_center
; break;
2672 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_align
, pStr
);
2677 static SwHTMLWriter
& OutCSS1_SvxFormatSplit( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2679 std::string_view pStr
= static_cast<const SvxFormatSplitItem
&>(rHt
).GetValue()
2682 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside
, pStr
);
2687 static SwHTMLWriter
& OutCSS1_SwFormatLayoutSplit( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2689 std::string_view pStr
= static_cast<const SwFormatLayoutSplit
&>(rHt
).GetValue()
2692 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside
, pStr
);
2697 static SwHTMLWriter
& OutCSS1_SvxWidows( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2699 OString
aStr(OString::number(static_cast<const SvxWidowsItem
&>(rHt
).GetValue()));
2700 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_widows
, aStr
);
2705 static SwHTMLWriter
& OutCSS1_SvxOrphans( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2707 OString
aStr(OString::number(static_cast<const SvxOrphansItem
&>(rHt
).GetValue()));
2708 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_orphans
, aStr
);
2713 static void OutCSS1_SwFormatDropAttrs( SwHTMLWriter
& rHWrt
,
2714 const SwFormatDrop
& rDrop
,
2715 const SfxItemSet
*pCharFormatItemSet
)
2717 // Text flows around on right side
2718 rHWrt
.OutCSS1_PropertyAscii( sCSS1_P_float
, sCSS1_PV_left
);
2720 // number of lines -> use % for Font-Height!
2721 OString
sOut(OString::number(rDrop
.GetLines()*100) + "%");
2722 rHWrt
.OutCSS1_PropertyAscii(sCSS1_P_font_size
, sOut
);
2724 // distance to Text = right margin
2725 sal_uInt16 nDistance
= rDrop
.GetDistance();
2727 rHWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_right
, nDistance
);
2729 const SwCharFormat
*pDCCharFormat
= rDrop
.GetCharFormat();
2730 if( pCharFormatItemSet
)
2731 rHWrt
.OutCSS1_SfxItemSet( *pCharFormatItemSet
);
2732 else if( pDCCharFormat
)
2733 rHWrt
.OutCSS1_SfxItemSet( pDCCharFormat
->GetAttrSet() );
2734 else if( (rHWrt
.m_nCSS1OutMode
& CSS1_OUTMODE_ANY_OFF
) == CSS1_OUTMODE_RULE_OFF
)
2735 rHWrt
.Strm().WriteOString( sCSS1_rule_end
);
2739 static SwHTMLWriter
& OutCSS1_SwFormatDrop( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2741 // never export as an Option of a paragraph, but only as Hints
2742 if( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2747 SwCSS1OutMode
aMode( rWrt
,
2748 rWrt
.m_nCSS1Script
|CSS1_OUTMODE_SPAN_TAG1_ON
|CSS1_OUTMODE_ENCODE
|
2749 CSS1_OUTMODE_DROPCAP
, nullptr );
2751 OutCSS1_SwFormatDropAttrs( rWrt
, static_cast<const SwFormatDrop
&>(rHt
) );
2752 // A "> is already printed by the calling OutCSS1_HintAsSpanTag.
2756 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
), false );
2762 static SwHTMLWriter
& OutCSS1_SwFormatFrameSize( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
,
2763 Css1FrameSize nMode
)
2765 const SwFormatFrameSize
& rFSItem
= static_cast<const SwFormatFrameSize
&>(rHt
);
2767 if( nMode
& Css1FrameSize::Width
)
2769 sal_uInt8 nPercentWidth
= rFSItem
.GetWidthPercent();
2772 OString
sOut(OString::number(nPercentWidth
) + "%");
2773 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_width
, sOut
);
2775 else if( nMode
& Css1FrameSize::Pixel
)
2777 rWrt
.OutCSS1_PixelProperty( sCSS1_P_width
,
2778 rFSItem
.GetSize().Width() );
2782 rWrt
.OutCSS1_UnitProperty( sCSS1_P_width
,
2783 rFSItem
.GetSize().Width() );
2790 static SwHTMLWriter
& OutCSS1_SvxFirstLineIndent(SwHTMLWriter
& rWrt
, SfxPoolItem
const& rHt
)
2792 const SvxFirstLineIndentItem
& rFirstLine(static_cast<const SvxFirstLineIndentItem
&>(rHt
));
2794 // No Export of a firm attribute is needed if the new values
2795 // match that of the current template
2797 // The LineIndent of the first line might contain the room for numbering
2798 tools::Long nFirstLineIndent
2799 = static_cast<tools::Long
>(rFirstLine
.ResolveTextFirstLineOffset({}))
2800 - rWrt
.m_nFirstLineIndent
;
2801 if (rWrt
.m_nDfltFirstLineIndent
!= nFirstLineIndent
)
2803 rWrt
.OutCSS1_UnitProperty(sCSS1_P_text_indent
, nFirstLineIndent
);
2809 static SwHTMLWriter
& OutCSS1_SvxTextLeftMargin(SwHTMLWriter
& rWrt
, SfxPoolItem
const& rHt
)
2811 const SvxTextLeftMarginItem
& rLeftMargin(static_cast<const SvxTextLeftMarginItem
&>(rHt
));
2813 // No Export of a firm attribute is needed if the new values
2814 // match that of the current template
2816 // A left margin can exist because of a list nearby
2817 tools::Long nLeftMargin
= rLeftMargin
.ResolveTextLeft({}) - rWrt
.m_nLeftMargin
;
2818 if (rWrt
.m_nDfltLeftMargin
!= nLeftMargin
)
2820 rWrt
.OutCSS1_UnitProperty(sCSS1_P_margin_left
, nLeftMargin
);
2822 // max-width = max-width - margin-left for TOC paragraphs with dot leaders
2823 if (rWrt
.m_bParaDotLeaders
)
2824 rWrt
.OutCSS1_UnitProperty(sCSS1_P_max_width
, o3tl::convert(DOT_LEADERS_MAX_WIDTH
, o3tl::Length::cm
, o3tl::Length::twip
) - nLeftMargin
);
2831 static SwHTMLWriter
& OutCSS1_SvxRightMargin(SwHTMLWriter
& rWrt
, SfxPoolItem
const& rHt
)
2833 const SvxRightMarginItem
& rRightMargin(static_cast<const SvxRightMarginItem
&>(rHt
));
2835 // No Export of a firm attribute is needed if the new values
2836 // match that of the current template
2838 if (rWrt
.m_nDfltRightMargin
!= rRightMargin
.ResolveRight({}))
2840 rWrt
.OutCSS1_UnitProperty(sCSS1_P_margin_right
, rRightMargin
.ResolveRight({}));
2846 static SwHTMLWriter
& OutCSS1_SvxLRSpace( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2848 const SvxLRSpaceItem
& rLRItem
= static_cast<const SvxLRSpaceItem
&>(rHt
);
2850 // No Export of a firm attribute is needed if the new values
2851 // match that of the current template
2853 // A left margin can exist because of a list nearby
2854 tools::Long nLeftMargin
= rLRItem
.ResolveTextLeft({}) - rWrt
.m_nLeftMargin
;
2855 if( rWrt
.m_nDfltLeftMargin
!= nLeftMargin
)
2857 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_left
, nLeftMargin
);
2859 // max-width = max-width - margin-left for TOC paragraphs with dot leaders
2860 if( rWrt
.m_bParaDotLeaders
)
2861 rWrt
.OutCSS1_UnitProperty( sCSS1_P_max_width
, o3tl::convert(DOT_LEADERS_MAX_WIDTH
, o3tl::Length::cm
, o3tl::Length::twip
) - nLeftMargin
);
2865 if (rWrt
.m_nDfltRightMargin
!= rLRItem
.ResolveRight({}))
2867 rWrt
.OutCSS1_UnitProperty(sCSS1_P_margin_right
, rLRItem
.ResolveRight({}));
2870 // The LineIndent of the first line might contain the room for numbering
2871 tools::Long nFirstLineIndent
= static_cast<tools::Long
>(rLRItem
.ResolveTextFirstLineOffset({}))
2872 - rWrt
.m_nFirstLineIndent
;
2873 if( rWrt
.m_nDfltFirstLineIndent
!= nFirstLineIndent
)
2875 rWrt
.OutCSS1_UnitProperty( sCSS1_P_text_indent
,
2882 static SwHTMLWriter
& OutCSS1_SvxULSpace( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2884 const SvxULSpaceItem
& rULItem
= static_cast<const SvxULSpaceItem
&>(rHt
);
2886 if( rWrt
.m_nDfltTopMargin
!= rULItem
.GetUpper() )
2888 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_top
,
2889 static_cast<tools::Long
>(rULItem
.GetUpper()) );
2892 if( rWrt
.m_nDfltBottomMargin
!= rULItem
.GetLower() )
2894 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_bottom
,
2895 static_cast<tools::Long
>(rULItem
.GetLower()) );
2901 static SwHTMLWriter
& OutCSS1_SvxULSpace_SvxLRSpace( SwHTMLWriter
& rWrt
,
2902 const SvxULSpaceItem
*pULItem
,
2903 const SvxLRSpaceItem
*pLRItem
)
2905 if (pLRItem
&& pULItem
&& pLRItem
->GetLeft() == pLRItem
->GetRight()
2906 && pLRItem
->GetLeft() == SvxIndentValue::twips(pULItem
->GetUpper())
2907 && pLRItem
->GetLeft() == SvxIndentValue::twips(pULItem
->GetLower())
2908 && pLRItem
->GetLeft() != SvxIndentValue::twips(rWrt
.m_nDfltLeftMargin
)
2909 && pLRItem
->GetRight() != SvxIndentValue::twips(rWrt
.m_nDfltRightMargin
)
2910 && pULItem
->GetUpper() != rWrt
.m_nDfltTopMargin
2911 && pULItem
->GetLower() != rWrt
.m_nDfltBottomMargin
)
2913 rWrt
.OutCSS1_UnitProperty(sCSS1_P_margin
, pLRItem
->ResolveLeft({}));
2918 OutCSS1_SvxLRSpace( rWrt
, *pLRItem
);
2920 OutCSS1_SvxULSpace( rWrt
, *pULItem
);
2926 static SwHTMLWriter
& OutCSS1_SvxULSpace_SvxLRSpace( SwHTMLWriter
& rWrt
,
2927 const SfxItemSet
& rItemSet
)
2929 const SvxLRSpaceItem
*pLRSpace
= rItemSet
.GetItemIfSet( RES_LR_SPACE
, false/*bDeep*/ );
2930 const SvxULSpaceItem
*pULSpace
= rItemSet
.GetItemIfSet( RES_UL_SPACE
, false/*bDeep*/ );
2932 if( pLRSpace
|| pULSpace
)
2933 OutCSS1_SvxULSpace_SvxLRSpace( rWrt
, pULSpace
, pLRSpace
);
2938 static SwHTMLWriter
& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( SwHTMLWriter
& rWrt
,
2939 const SvxFormatBreakItem
*pBreakItem
,
2940 const SwFormatPageDesc
*pPDescItem
,
2941 const SvxFormatKeepItem
*pKeepItem
)
2943 if( !rWrt
.IsHTMLMode(HTMLMODE_PRINT_EXT
) )
2946 std::string_view pBreakBefore
;
2947 std::string_view pBreakAfter
;
2951 pBreakAfter
= pKeepItem
->GetValue() ? sCSS1_PV_avoid
: sCSS1_PV_auto
;
2955 switch( pBreakItem
->GetBreak() )
2957 case SvxBreak::NONE
:
2958 pBreakBefore
= sCSS1_PV_auto
;
2959 if( pBreakAfter
.empty() )
2960 pBreakAfter
= sCSS1_PV_auto
;
2963 case SvxBreak::PageBefore
:
2964 pBreakBefore
= sCSS1_PV_always
;
2967 case SvxBreak::PageAfter
:
2968 pBreakAfter
= sCSS1_PV_always
;
2977 const SwPageDesc
*pPDesc
= pPDescItem
->GetPageDesc();
2980 switch( pPDesc
->GetPoolFormatId() )
2982 case RES_POOLPAGE_LEFT
: pBreakBefore
= sCSS1_PV_left
; break;
2983 case RES_POOLPAGE_RIGHT
: pBreakBefore
= sCSS1_PV_right
; break;
2984 default: pBreakBefore
= sCSS1_PV_always
; break;
2987 else if( pBreakBefore
.empty() )
2989 pBreakBefore
= sCSS1_PV_auto
;
2993 if (rWrt
.mbSkipHeaderFooter
)
2994 // No page break when writing only a fragment.
2997 if( !pBreakBefore
.empty() )
2998 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_before
,
3000 if( !pBreakAfter
.empty() )
3001 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_after
,
3007 static SwHTMLWriter
& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( SwHTMLWriter
& rWrt
,
3008 const SfxItemSet
& rItemSet
,
3011 const SvxFormatBreakItem
*pBreakItem
= rItemSet
.GetItemIfSet( RES_BREAK
, bDeep
);
3013 const SwFormatPageDesc
*pPDescItem
= nullptr;
3014 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) ||
3015 !rWrt
.m_bCSS1IgnoreFirstPageDesc
||
3016 rWrt
.m_pStartNdIdx
->GetIndex() !=
3017 rWrt
.m_pCurrentPam
->GetPoint()->GetNodeIndex() )
3018 pPDescItem
= rItemSet
.GetItemIfSet( RES_PAGEDESC
, bDeep
);
3020 const SvxFormatKeepItem
*pKeepItem
= rItemSet
.GetItemIfSet( RES_KEEP
, bDeep
);
3022 if( pBreakItem
|| pPDescItem
|| pKeepItem
)
3023 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( rWrt
, pBreakItem
,
3024 pPDescItem
, pKeepItem
);
3029 // Wrapper for OutCSS1_SfxItemSet etc.
3030 static SwHTMLWriter
& OutCSS1_SvxBrush( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3032 OutCSS1_SvxBrush( rWrt
, rHt
, sw::Css1Background::Attr
, nullptr );
3036 static SwHTMLWriter
& OutCSS1_SvxBrush( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
,
3037 sw::Css1Background nMode
,
3038 const OUString
* pGraphicName
)
3040 // The Character-Attribute is skipped, if we are about to
3041 // exporting options
3042 if( rHt
.Which() < RES_CHRATR_END
&&
3043 rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
3046 // start getting a few values
3047 // const Brush &rBrush = static_cast<const SvxBrushItem &>(rHt).GetBrush();
3048 const Color
& rColor
= static_cast<const SvxBrushItem
&>(rHt
).GetColor();
3049 OUString aLink
= pGraphicName
? *pGraphicName
3050 : static_cast<const SvxBrushItem
&>(rHt
).GetGraphicLink();
3052 SvxGraphicPosition ePos
= static_cast<const SvxBrushItem
&>(rHt
).GetGraphicPos();
3053 if( sw::Css1Background::Page
== nMode
&& !rWrt
.mbEmbedImages
)
3055 // page style images are exported if not tiled
3056 if( aLink
.isEmpty() || GPOS_TILED
==ePos
)
3061 bool bColor
= false;
3062 /// set <bTransparent> to true, if color is "no fill"/"auto fill"
3063 bool bTransparent
= (rColor
== COL_TRANSPARENT
);
3071 // and now the Graphic
3072 OUString aGraphicInBase64
;
3074 // Embedded Graphic -> export WriteEmbedded
3075 const Graphic
* pGrf
= nullptr;
3076 if( rWrt
.mbEmbedImages
|| aLink
.isEmpty())
3078 pGrf
= static_cast<const SvxBrushItem
&>(rHt
).GetGraphic();
3081 if( !XOutBitmap::GraphicToBase64(*pGrf
, aGraphicInBase64
) )
3083 rWrt
.m_nWarn
= WARN_SWG_POOR_LOAD
;
3088 else if( !pGraphicName
&& rWrt
.m_bCfgCpyLinkedGrfs
)
3090 OUString aGraphicAsLink
= aLink
;
3091 bOwn
= rWrt
.CopyLocalFileToINet( aGraphicAsLink
);
3092 aLink
= aGraphicAsLink
;
3094 // In tables we only export something if there is a Graphic
3095 if( (nMode
== sw::Css1Background::Table
|| nMode
== sw::Css1Background::TableRow
) && !pGrf
&& !aLink
.isEmpty())
3098 // if necessary, add the orientation of the Graphic
3099 std::u16string_view pRepeat
, pHori
;
3100 std::string_view pVert
;
3101 if( pGrf
|| !aLink
.isEmpty() )
3103 if( GPOS_TILED
==ePos
)
3105 pRepeat
= sCSS1_PV_repeat
;
3114 pHori
= sCSS1_PV_top
;
3120 pHori
= sCSS1_PV_middle
;
3126 pHori
= sCSS1_PV_bottom
;
3138 pVert
= sCSS1_PV_left
;
3144 pVert
= sCSS1_PV_center
;
3150 pVert
= sCSS1_PV_right
;
3157 if( !pHori
.empty() || !pVert
.empty() )
3158 pRepeat
= sCSS1_PV_no_repeat
;
3162 // now build the string
3164 if( !pGrf
&& aLink
.isEmpty() && !bColor
)
3166 // no color and no Link, but a transparent Brush
3167 if( bTransparent
&& sw::Css1Background::Fly
!= nMode
)
3168 sOut
+= sCSS1_PV_transparent
;
3174 OString
sTmp(GetCSS1_Color(aColor
));
3175 sOut
+= OStringToOUString(sTmp
, RTL_TEXTENCODING_ASCII_US
);
3178 if( pGrf
|| !aLink
.isEmpty() )
3185 sOut
+= OUString::Concat(sCSS1_url
) +
3186 "(\'" OOO_STRING_SVTOOLS_HTML_O_data
":" + aGraphicInBase64
+ "\')";
3190 sOut
+= OUString::Concat(sCSS1_url
) + "(" + rWrt
.normalizeURL(aLink
, bOwn
) + ")";
3193 if( !pRepeat
.empty() )
3195 sOut
+= OUString::Concat(" ") + pRepeat
;
3198 if( !pHori
.empty() )
3200 sOut
+= OUString::Concat(" ") + pHori
;
3202 if( !pVert
.empty() )
3204 sOut
+= " " + OStringToOUString(pVert
, RTL_TEXTENCODING_ASCII_US
);
3207 sOut
+= OUString::Concat(" ") + sCSS1_PV_scroll
+ " ";
3211 if( !sOut
.isEmpty() )
3213 rWrt
.OutCSS1_Property(sCSS1_P_background
, std::string_view(), &sOut
,
3220 static void OutCSS1_SvxBorderLine( SwHTMLWriter
& rWrt
,
3221 std::string_view pProperty
,
3222 const SvxBorderLine
*pLine
)
3224 if( !pLine
|| pLine
->isEmpty() )
3226 rWrt
.OutCSS1_PropertyAscii( pProperty
, sCSS1_PV_none
);
3230 sal_Int32 nWidth
= pLine
->GetWidth();
3233 if( nWidth
<= o3tl::convert(1, o3tl::Length::px
, o3tl::Length::twip
) )
3235 // If the width is smaller than one pixel, then export as 1px
3236 // so that Netscape and IE show the line.
3241 nWidth
*= 5; // 1/100pt
3244 sOut
.append(OString::number(nWidth
/ 100) + "." + OString::number((nWidth
/10) % 10) +
3245 OString::number(nWidth
% 10) + sCSS1_UNIT_pt
);
3248 // Line-Style: solid or double
3250 switch (pLine
->GetBorderLineStyle())
3252 case SvxBorderLineStyle::SOLID
:
3253 sOut
.append(sCSS1_PV_solid
);
3255 case SvxBorderLineStyle::DOTTED
:
3256 sOut
.append(sCSS1_PV_dotted
);
3258 case SvxBorderLineStyle::DASHED
:
3259 sOut
.append(sCSS1_PV_dashed
);
3261 case SvxBorderLineStyle::DOUBLE
:
3262 case SvxBorderLineStyle::THINTHICK_SMALLGAP
:
3263 case SvxBorderLineStyle::THINTHICK_MEDIUMGAP
:
3264 case SvxBorderLineStyle::THINTHICK_LARGEGAP
:
3265 case SvxBorderLineStyle::THICKTHIN_SMALLGAP
:
3266 case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
:
3267 case SvxBorderLineStyle::THICKTHIN_LARGEGAP
:
3268 sOut
.append(sCSS1_PV_double
);
3270 case SvxBorderLineStyle::EMBOSSED
:
3271 sOut
.append(sCSS1_PV_ridge
);
3273 case SvxBorderLineStyle::ENGRAVED
:
3274 sOut
.append(sCSS1_PV_groove
);
3276 case SvxBorderLineStyle::INSET
:
3277 sOut
.append(sCSS1_PV_inset
);
3279 case SvxBorderLineStyle::OUTSET
:
3280 sOut
.append(sCSS1_PV_outset
);
3283 sOut
.append(sCSS1_PV_none
);
3287 // and also the color
3288 sOut
.append(GetCSS1_Color(pLine
->GetColor()));
3290 rWrt
.OutCSS1_PropertyAscii(pProperty
, sOut
);
3293 SwHTMLWriter
& OutCSS1_SvxBox( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3295 // Avoid interference between character and paragraph attributes
3296 if( rHt
.Which() < RES_CHRATR_END
&&
3297 rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
3300 if( rHt
.Which() == RES_CHRATR_BOX
)
3302 static constexpr std::string_view
inline_block("inline-block");
3305 // Inline-block to make the line height changing correspond to the character border
3306 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_display
, inline_block
);
3310 if (!IgnorePropertyForReqIF(rWrt
.mbReqIF
, sCSS1_P_display
, inline_block
))
3311 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
), false );
3316 const SvxBoxItem
& rBoxItem
= static_cast<const SvxBoxItem
&>(rHt
);
3317 const SvxBorderLine
*pTop
= rBoxItem
.GetTop();
3318 const SvxBorderLine
*pBottom
= rBoxItem
.GetBottom();
3319 const SvxBorderLine
*pLeft
= rBoxItem
.GetLeft();
3320 const SvxBorderLine
*pRight
= rBoxItem
.GetRight();
3322 if( (pTop
&& pBottom
&& pLeft
&& pRight
&&
3323 *pTop
== *pBottom
&& *pTop
== *pLeft
&& *pTop
== *pRight
) ||
3324 (!pTop
&& !pBottom
&& !pLeft
&& !pRight
) )
3326 // all Lines are set and equal, or all Lines are not set
3328 OutCSS1_SvxBorderLine( rWrt
, sCSS1_P_border
, pTop
);
3332 // otherwise export all Lines separately
3333 OutCSS1_SvxBorderLine( rWrt
, sCSS1_P_border_top
, pTop
);
3334 OutCSS1_SvxBorderLine( rWrt
, sCSS1_P_border_bottom
, pBottom
);
3335 OutCSS1_SvxBorderLine( rWrt
, sCSS1_P_border_left
, pLeft
);
3336 OutCSS1_SvxBorderLine( rWrt
, sCSS1_P_border_right
, pRight
);
3339 tools::Long nTopDist
= pTop
? rBoxItem
.GetDistance( SvxBoxItemLine::TOP
) : 0;
3340 tools::Long nBottomDist
= pBottom
? rBoxItem
.GetDistance( SvxBoxItemLine::BOTTOM
) : 0;
3341 tools::Long nLeftDist
= pLeft
? rBoxItem
.GetDistance( SvxBoxItemLine::LEFT
) : 0;
3342 tools::Long nRightDist
= pRight
? rBoxItem
.GetDistance( SvxBoxItemLine::RIGHT
) : 0;
3344 if( nTopDist
== nBottomDist
&& nLeftDist
== nRightDist
)
3347 AddUnitPropertyValue(sVal
, nTopDist
, rWrt
.GetCSS1Unit());
3348 if( nTopDist
!= nLeftDist
)
3351 AddUnitPropertyValue(sVal
, nLeftDist
, rWrt
.GetCSS1Unit());
3353 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_padding
, sVal
);
3357 rWrt
.OutCSS1_UnitProperty( sCSS1_P_padding_top
, nTopDist
);
3358 rWrt
.OutCSS1_UnitProperty( sCSS1_P_padding_bottom
, nBottomDist
);
3359 rWrt
.OutCSS1_UnitProperty( sCSS1_P_padding_left
, nLeftDist
);
3360 rWrt
.OutCSS1_UnitProperty( sCSS1_P_padding_right
, nRightDist
);
3366 static SwHTMLWriter
& OutCSS1_SvxFrameDirection( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3368 // Language will be exported rules only
3369 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_TEMPLATE
) )
3372 SvxFrameDirection nDir
=
3373 static_cast< const SvxFrameDirectionItem
& >( rHt
).GetValue();
3374 std::string_view pStr
;
3377 case SvxFrameDirection::Horizontal_LR_TB
:
3378 case SvxFrameDirection::Vertical_LR_TB
:
3379 pStr
= sCSS1_PV_ltr
;
3381 case SvxFrameDirection::Horizontal_RL_TB
:
3382 case SvxFrameDirection::Vertical_RL_TB
:
3383 pStr
= sCSS1_PV_rtl
;
3385 case SvxFrameDirection::Environment
:
3386 pStr
= sCSS1_PV_inherit
;
3392 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_direction
, pStr
);
3398 * Place here the table for the HTML-Function-Pointer to the
3400 * They are local structures, only needed within the HTML-DLL.
3403 SwAttrFnTab
const aCSS1AttrFnTab
= {
3404 /* RES_CHRATR_CASEMAP */ OutCSS1_SvxCaseMap
,
3405 /* RES_CHRATR_CHARSETCOLOR */ nullptr,
3406 /* RES_CHRATR_COLOR */ OutCSS1_SvxColor
,
3407 /* RES_CHRATR_CONTOUR */ nullptr,
3408 /* RES_CHRATR_CROSSEDOUT */ OutCSS1_SvxCrossedOut
,
3409 /* RES_CHRATR_ESCAPEMENT */ nullptr,
3410 /* RES_CHRATR_FONT */ OutCSS1_SvxFont
,
3411 /* RES_CHRATR_FONTSIZE */ OutCSS1_SvxFontHeight
,
3412 /* RES_CHRATR_KERNING */ OutCSS1_SvxKerning
,
3413 /* RES_CHRATR_LANGUAGE */ OutCSS1_SvxLanguage
,
3414 /* RES_CHRATR_POSTURE */ OutCSS1_SvxPosture
,
3415 /* RES_CHRATR_UNUSED1*/ nullptr,
3416 /* RES_CHRATR_SHADOWED */ nullptr,
3417 /* RES_CHRATR_UNDERLINE */ OutCSS1_SvxUnderline
,
3418 /* RES_CHRATR_WEIGHT */ OutCSS1_SvxFontWeight
,
3419 /* RES_CHRATR_WORDLINEMODE */ nullptr,
3420 /* RES_CHRATR_AUTOKERN */ nullptr,
3421 /* RES_CHRATR_BLINK */ OutCSS1_SvxBlink
,
3422 /* RES_CHRATR_NOHYPHEN */ nullptr, // new: don't separate
3423 /* RES_CHRATR_UNUSED2 */ nullptr,
3424 /* RES_CHRATR_BACKGROUND */ OutCSS1_SvxBrush
, // new: character background
3425 /* RES_CHRATR_CJK_FONT */ OutCSS1_SvxFont
,
3426 /* RES_CHRATR_CJK_FONTSIZE */ OutCSS1_SvxFontHeight
,
3427 /* RES_CHRATR_CJK_LANGUAGE */ OutCSS1_SvxLanguage
,
3428 /* RES_CHRATR_CJK_POSTURE */ OutCSS1_SvxPosture
,
3429 /* RES_CHRATR_CJK_WEIGHT */ OutCSS1_SvxFontWeight
,
3430 /* RES_CHRATR_CTL_FONT */ OutCSS1_SvxFont
,
3431 /* RES_CHRATR_CTL_FONTSIZE */ OutCSS1_SvxFontHeight
,
3432 /* RES_CHRATR_CTL_LANGUAGE */ OutCSS1_SvxLanguage
,
3433 /* RES_CHRATR_CTL_POSTURE */ OutCSS1_SvxPosture
,
3434 /* RES_CHRATR_CTL_WEIGHT */ OutCSS1_SvxFontWeight
,
3435 /* RES_CHRATR_ROTATE */ nullptr,
3436 /* RES_CHRATR_EMPHASIS_MARK */ nullptr,
3437 /* RES_CHRATR_TWO_LINES */ nullptr,
3438 /* RES_CHRATR_SCALEW */ nullptr,
3439 /* RES_CHRATR_RELIEF */ nullptr,
3440 /* RES_CHRATR_HIDDEN */ OutCSS1_SvxHidden
,
3441 /* RES_CHRATR_OVERLINE */ OutCSS1_SvxOverline
,
3442 /* RES_CHRATR_RSID */ nullptr,
3443 /* RES_CHRATR_BOX */ OutCSS1_SvxBox
,
3444 /* RES_CHRATR_SHADOW */ nullptr,
3445 /* RES_CHRATR_HIGHLIGHT */ nullptr,
3446 /* RES_CHRATR_GRABBAG */ nullptr,
3447 /* RES_CHRATR_BIDIRTL */ nullptr,
3448 /* RES_CHRATR_IDCTHINT */ nullptr,
3450 /* RES_TXTATR_REFMARK */ nullptr,
3451 /* RES_TXTATR_TOXMARK */ nullptr,
3452 /* RES_TXTATR_META */ nullptr,
3453 /* RES_TXTATR_METAFIELD */ nullptr,
3454 /* RES_TXTATR_AUTOFMT */ nullptr,
3455 /* RES_TXTATR_INETFMT */ nullptr,
3456 /* RES_TXTATR_CHARFMT */ nullptr,
3457 /* RES_TXTATR_CJK_RUBY */ nullptr,
3458 /* RES_TXTATR_UNKNOWN_CONTAINER */ nullptr,
3459 /* RES_TXTATR_INPUTFIELD */ nullptr,
3460 /* RES_TXTATR_CONTENTCONTROL */ nullptr,
3462 /* RES_TXTATR_FIELD */ nullptr,
3463 /* RES_TXTATR_FLYCNT */ nullptr,
3464 /* RES_TXTATR_FTN */ nullptr,
3465 /* RES_TXTATR_ANNOTATION */ nullptr,
3466 /* RES_TXTATR_LINEBREAK */ nullptr,
3467 /* RES_TXTATR_DUMMY1 */ nullptr, // Dummy:
3469 /* RES_PARATR_LINESPACING */ OutCSS1_SvxLineSpacing
,
3470 /* RES_PARATR_ADJUST */ OutCSS1_SvxAdjust
,
3471 /* RES_PARATR_SPLIT */ OutCSS1_SvxFormatSplit
,
3472 /* RES_PARATR_ORPHANS */ OutCSS1_SvxOrphans
,
3473 /* RES_PARATR_WIDOWS */ OutCSS1_SvxWidows
,
3474 /* RES_PARATR_TABSTOP */ nullptr,
3475 /* RES_PARATR_HYPHENZONE*/ nullptr,
3476 /* RES_PARATR_DROP */ OutCSS1_SwFormatDrop
,
3477 /* RES_PARATR_REGISTER */ nullptr, // new: register-true
3478 /* RES_PARATR_NUMRULE */ nullptr,
3479 /* RES_PARATR_SCRIPTSPACE */ nullptr,
3480 /* RES_PARATR_HANGINGPUNCTUATION */ nullptr,
3481 /* RES_PARATR_FORBIDDEN_RULES */ nullptr, // new
3482 /* RES_PARATR_VERTALIGN */ nullptr, // new
3483 /* RES_PARATR_SNAPTOGRID*/ nullptr, // new
3484 /* RES_PARATR_CONNECT_TO_BORDER */ nullptr, // new
3485 /* RES_PARATR_OUTLINELEVEL */ nullptr, // new since cws outlinelevel
3486 /* RES_PARATR_RSID */ nullptr, // new
3487 /* RES_PARATR_GRABBAG */ nullptr,
3489 /* RES_PARATR_LIST_ID */ nullptr, // new
3490 /* RES_PARATR_LIST_LEVEL */ nullptr, // new
3491 /* RES_PARATR_LIST_ISRESTART */ nullptr, // new
3492 /* RES_PARATR_LIST_RESTARTVALUE */ nullptr, // new
3493 /* RES_PARATR_LIST_ISCOUNTED */ nullptr, // new
3494 /* RES_PARATR_LIST_AUTOFMT */ nullptr, // new
3496 /* RES_FILL_ORDER */ nullptr,
3497 /* RES_FRM_SIZE */ nullptr,
3498 /* RES_PAPER_BIN */ nullptr,
3499 /* RES_MARGIN_FIRSTLINE */ OutCSS1_SvxFirstLineIndent
,
3500 /* RES_MARGIN_TEXTLEFT */ OutCSS1_SvxTextLeftMargin
,
3501 /* RES_MARGIN_RIGHT */ OutCSS1_SvxRightMargin
,
3502 /* RES_MARGIN_LEFT */ nullptr,
3503 /* RES_MARGIN_GUTTER */ nullptr,
3504 /* RES_MARGIN_GUTTER_RIGHT */ nullptr,
3505 /* RES_LR_SPACE */ OutCSS1_SvxLRSpace
,
3506 /* RES_UL_SPACE */ OutCSS1_SvxULSpace
,
3507 /* RES_PAGEDESC */ nullptr,
3508 /* RES_BREAK */ nullptr,
3509 /* RES_CNTNT */ nullptr,
3510 /* RES_HEADER */ nullptr,
3511 /* RES_FOOTER */ nullptr,
3512 /* RES_PRINT */ nullptr,
3513 /* RES_OPAQUE */ nullptr,
3514 /* RES_PROTECT */ nullptr,
3515 /* RES_SURROUND */ nullptr,
3516 /* RES_VERT_ORIENT */ nullptr,
3517 /* RES_HORI_ORIENT */ nullptr,
3518 /* RES_ANCHOR */ nullptr,
3519 /* RES_BACKGROUND */ OutCSS1_SvxBrush
,
3520 /* RES_BOX */ OutCSS1_SvxBox
,
3521 /* RES_SHADOW */ nullptr,
3522 /* RES_FRMMACRO */ nullptr,
3523 /* RES_COL */ nullptr,
3524 /* RES_KEEP */ nullptr,
3525 /* RES_URL */ nullptr,
3526 /* RES_EDIT_IN_READONLY */ nullptr,
3527 /* RES_LAYOUT_SPLIT */ nullptr,
3528 /* RES_CHAIN */ nullptr,
3529 /* RES_TEXTGRID */ nullptr,
3530 /* RES_LINENUMBER */ nullptr,
3531 /* RES_FTN_AT_TXTEND */ nullptr,
3532 /* RES_END_AT_TXTEND */ nullptr,
3533 /* RES_COLUMNBALANCE */ nullptr,
3534 /* RES_FRAMEDIR */ OutCSS1_SvxFrameDirection
,
3535 /* RES_HEADER_FOOTER_EAT_SPACING */ nullptr,
3536 /* RES_ROW_SPLIT */ nullptr,
3537 /* RES_FLY_SPLIT */ nullptr,
3538 /* RES_FOLLOW_TEXT_FLOW */ nullptr,
3539 /* RES_COLLAPSING_BORDERS */ nullptr,
3540 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ nullptr,
3541 /* RES_AUTO_STYLE */ nullptr,
3542 /* RES_FRMATR_STYLE_NAME */ nullptr,
3543 /* RES_FRMATR_CONDITIONAL_STYLE_NAME */ nullptr,
3544 /* RES_FRMATR_GRABBAG */ nullptr,
3545 /* RES_TEXT_VERT_ADJUST */ nullptr,
3546 /* RES_BACKGROUND_FULL_SIZE */ nullptr,
3547 /* RES_RTL_GUTTER */ nullptr,
3548 /* RES_DECORATIVE */ nullptr,
3550 /* RES_GRFATR_MIRRORGRF */ nullptr,
3551 /* RES_GRFATR_CROPGRF */ nullptr,
3552 /* RES_GRFATR_ROTATION */ nullptr,
3553 /* RES_GRFATR_LUMINANCE */ nullptr,
3554 /* RES_GRFATR_CONTRAST */ nullptr,
3555 /* RES_GRFATR_CHANNELR */ nullptr,
3556 /* RES_GRFATR_CHANNELG */ nullptr,
3557 /* RES_GRFATR_CHANNELB */ nullptr,
3558 /* RES_GRFATR_GAMMA */ nullptr,
3559 /* RES_GRFATR_INVERT */ nullptr,
3560 /* RES_GRFATR_TRANSPARENCY */ nullptr,
3561 /* RES_GRFATR_DRWAMODE */ nullptr,
3562 /* RES_GRFATR_DUMMY3 */ nullptr,
3563 /* RES_GRFATR_DUMMY4 */ nullptr,
3564 /* RES_GRFATR_DUMMY5 */ nullptr,
3566 /* RES_BOXATR_FORMAT */ nullptr,
3567 /* RES_BOXATR_FORMULA */ nullptr,
3568 /* RES_BOXATR_VALUE */ nullptr
3571 static_assert(SAL_N_ELEMENTS(aCSS1AttrFnTab
) == RES_BOXATR_END
);
3573 void SwHTMLWriter::OutCSS1_SfxItemSet( const SfxItemSet
& rItemSet
,
3574 bool bDeep
, std::string_view rAdd
)
3576 // print ItemSet, including all attributes
3577 Out_SfxItemSet( aCSS1AttrFnTab
, *this, rItemSet
, bDeep
);
3579 // some Attributes require special treatment
3581 // Underline, Overline, CrossedOut and Blink form together a CSS1-Property
3582 // (doesn't work of course for Hints)
3583 if( !IsCSS1Source(CSS1_OUTMODE_HINT
) )
3585 const SvxUnderlineItem
*pUnderlineItem
=
3586 rItemSet
.GetItemIfSet( RES_CHRATR_UNDERLINE
, bDeep
);
3588 const SvxOverlineItem
*pOverlineItem
=
3589 rItemSet
.GetItemIfSet( RES_CHRATR_OVERLINE
, bDeep
);
3591 const SvxCrossedOutItem
*pCrossedOutItem
=
3592 rItemSet
.GetItemIfSet( RES_CHRATR_CROSSEDOUT
, bDeep
);
3594 const SvxBlinkItem
*pBlinkItem
=
3595 rItemSet
.GetItemIfSet( RES_CHRATR_BLINK
, bDeep
);
3597 if( pUnderlineItem
|| pOverlineItem
|| pCrossedOutItem
|| pBlinkItem
)
3598 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( *this, pUnderlineItem
,
3603 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet
, bDeep
);
3608 for (std::size_t index
= 0; index
!= std::string_view::npos
;)
3610 std::string_view attr
= o3tl::trim(o3tl::getToken(rAdd
, ':', index
));
3611 assert(!attr
.empty());
3612 assert(index
!= std::string_view::npos
);
3614 std::string_view val
= o3tl::trim(o3tl::getToken(rAdd
, ':', index
));
3615 assert(!val
.empty());
3616 OutCSS1_PropertyAscii(attr
, val
);
3620 if( m_bFirstCSS1Property
)
3623 // if a Property was exported as part of a Style-Option,
3624 // the Option still needs to be finished
3626 switch( m_nCSS1OutMode
& CSS1_OUTMODE_ANY_OFF
)
3628 case CSS1_OUTMODE_SPAN_TAG_OFF
:
3629 sOut
.append(sCSS1_span_tag_end
);
3632 case CSS1_OUTMODE_STYLE_OPT_OFF
:
3633 sOut
.append(cCSS1_style_opt_end
);
3636 case CSS1_OUTMODE_RULE_OFF
:
3637 sOut
.append(sCSS1_rule_end
);
3640 if (!sOut
.isEmpty())
3641 Strm().WriteOString( sOut
);
3644 SwHTMLWriter
& OutCSS1_HintSpanTag( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3646 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_SPAN_TAG
|
3647 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_HINT
, nullptr );
3649 Out( aCSS1AttrFnTab
, rHt
, rWrt
);
3651 if( !rWrt
.m_bFirstCSS1Property
&& rWrt
.m_bTagOn
)
3652 rWrt
.Strm().WriteOString( sCSS1_span_tag_end
);
3657 SwHTMLWriter
& OutCSS1_HintStyleOpt( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3659 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT_ON
|
3660 CSS1_OUTMODE_ENCODE
|
3661 CSS1_OUTMODE_HINT
, nullptr );
3663 Out( aCSS1AttrFnTab
, rHt
, rWrt
);
3665 if( !rWrt
.m_bFirstCSS1Property
)
3666 rWrt
.Strm().WriteChar( '\"' );
3671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */