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 #define DOT_LEADERS_MAX_WIDTH 18
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
= OString(OOO_STRING_SVTOOLS_HTML_blockquote
);
628 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_citation
)
630 rRefPoolId
= RES_POOLCHR_HTML_CITATION
;
631 rToken
= OString(OOO_STRING_SVTOOLS_HTML_citation
);
633 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_code
)
635 rRefPoolId
= RES_POOLCHR_HTML_CODE
;
636 rToken
= OString(OOO_STRING_SVTOOLS_HTML_code
);
638 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_definstance
)
640 rRefPoolId
= RES_POOLCHR_HTML_DEFINSTANCE
;
641 rToken
= OString(OOO_STRING_SVTOOLS_HTML_definstance
);
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
= OString(OOO_STRING_SVTOOLS_HTML_dd
);
663 rRefPoolId
= RES_POOLCOLL_HTML_DT
;
664 rToken
= OString(OOO_STRING_SVTOOLS_HTML_dt
);
668 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_emphasis
)
670 rRefPoolId
= RES_POOLCHR_HTML_EMPHASIS
;
671 rToken
= OString(OOO_STRING_SVTOOLS_HTML_emphasis
);
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
= OString(OOO_STRING_SVTOOLS_HTML_keyboard
);
683 else if (!bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_listing
)
685 // Export Listings as PRE or PRE-derived template
686 rToken
= OString(OOO_STRING_SVTOOLS_HTML_preformtxt
);
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
= OString(OOO_STRING_SVTOOLS_HTML_preformtxt
);
695 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_sample
)
697 rRefPoolId
= RES_POOLCHR_HTML_SAMPLE
;
698 rToken
= OString(OOO_STRING_SVTOOLS_HTML_sample
);
700 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_strong
)
702 rRefPoolId
= RES_POOLCHR_HTML_STRONG
;
703 rToken
= OString(OOO_STRING_SVTOOLS_HTML_strong
);
705 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_teletype
)
707 rRefPoolId
= RES_POOLCHR_HTML_TELETYPE
;
708 rToken
= OString(OOO_STRING_SVTOOLS_HTML_teletype
);
710 else if (bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_variable
)
712 rRefPoolId
= RES_POOLCHR_HTML_VARIABLE
;
713 rToken
= OString(OOO_STRING_SVTOOLS_HTML_variable
);
715 else if (!bChrFormat
&& aNm
== OOO_STRING_SVTOOLS_HTML_xmp
)
717 // export XMP as PRE (but not the template as Style)
718 rToken
= OString(OOO_STRING_SVTOOLS_HTML_preformtxt
);
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
738 case RES_POOLCOLL_TEXT
:
739 rToken
= OString(OOO_STRING_SVTOOLS_HTML_parabreak
);
741 case RES_POOLCOLL_HEADLINE1
:
742 rToken
= OString(OOO_STRING_SVTOOLS_HTML_head1
);
744 case RES_POOLCOLL_HEADLINE2
:
745 rToken
= OString(OOO_STRING_SVTOOLS_HTML_head2
);
747 case RES_POOLCOLL_HEADLINE3
:
748 rToken
= OString(OOO_STRING_SVTOOLS_HTML_head3
);
750 case RES_POOLCOLL_HEADLINE4
:
751 rToken
= OString(OOO_STRING_SVTOOLS_HTML_head4
);
753 case RES_POOLCOLL_HEADLINE5
:
754 rToken
= OString(OOO_STRING_SVTOOLS_HTML_head5
);
756 case RES_POOLCOLL_HEADLINE6
:
757 rToken
= OString(OOO_STRING_SVTOOLS_HTML_head6
);
759 case RES_POOLCOLL_SEND_ADDRESS
:
760 rToken
= OString(OOO_STRING_SVTOOLS_HTML_address
);
762 case RES_POOLCOLL_HTML_BLOCKQUOTE
:
763 rToken
= OString(OOO_STRING_SVTOOLS_HTML_blockquote
);
765 case RES_POOLCOLL_HTML_PRE
:
766 rToken
= OString(OOO_STRING_SVTOOLS_HTML_preformtxt
);
769 case RES_POOLCOLL_HTML_DD
:
770 rToken
= OString(OOO_STRING_SVTOOLS_HTML_dd
);
772 case RES_POOLCOLL_HTML_DT
:
773 rToken
= OString(OOO_STRING_SVTOOLS_HTML_dt
);
776 case RES_POOLCOLL_TABLE
:
779 rToken
= OOO_STRING_SVTOOLS_HTML_tabledata
" "
780 OOO_STRING_SVTOOLS_HTML_parabreak
;
783 rToken
= OOO_STRING_SVTOOLS_HTML_parabreak
;
785 case RES_POOLCOLL_TABLE_HDLN
:
788 rToken
= OOO_STRING_SVTOOLS_HTML_tableheader
" "
789 OOO_STRING_SVTOOLS_HTML_parabreak
;
792 rToken
= OString(OOO_STRING_SVTOOLS_HTML_parabreak
);
794 case RES_POOLCOLL_HTML_HR
:
795 // do not export HR !
798 case RES_POOLCOLL_FOOTNOTE
:
801 rToken
= OString(OOO_STRING_SVTOOLS_HTML_parabreak
);
802 rClass
= OOO_STRING_SVTOOLS_HTML_sdfootnote
;
803 rRefPoolId
= RES_POOLCOLL_TEXT
;
804 nDeep
= CSS1_FMT_CMPREF
;
807 case RES_POOLCOLL_ENDNOTE
:
810 rToken
= OString(OOO_STRING_SVTOOLS_HTML_parabreak
);
811 rClass
= OOO_STRING_SVTOOLS_HTML_sdendnote
;
812 rRefPoolId
= RES_POOLCOLL_TEXT
;
813 nDeep
= CSS1_FMT_CMPREF
;
817 // character templates
818 case RES_POOLCHR_HTML_EMPHASIS
:
819 rToken
= OString(OOO_STRING_SVTOOLS_HTML_emphasis
);
821 case RES_POOLCHR_HTML_CITATION
:
822 rToken
= OString(OOO_STRING_SVTOOLS_HTML_citation
);
824 case RES_POOLCHR_HTML_STRONG
:
825 rToken
= OString(OOO_STRING_SVTOOLS_HTML_strong
);
827 case RES_POOLCHR_HTML_CODE
:
828 rToken
= OString(OOO_STRING_SVTOOLS_HTML_code
);
830 case RES_POOLCHR_HTML_SAMPLE
:
831 rToken
= OString(OOO_STRING_SVTOOLS_HTML_sample
);
833 case RES_POOLCHR_HTML_KEYBOARD
:
834 rToken
= OString(OOO_STRING_SVTOOLS_HTML_keyboard
);
836 case RES_POOLCHR_HTML_VARIABLE
:
837 rToken
= OString(OOO_STRING_SVTOOLS_HTML_variable
);
839 case RES_POOLCHR_HTML_DEFINSTANCE
:
840 rToken
= OString(OOO_STRING_SVTOOLS_HTML_definstance
);
842 case RES_POOLCHR_HTML_TELETYPE
:
843 rToken
= OString(OOO_STRING_SVTOOLS_HTML_teletype
);
846 case RES_POOLCHR_INET_NORMAL
:
849 rToken
= OString(OOO_STRING_SVTOOLS_HTML_anchor
);
850 *pPseudo
= OStringToOUString( sCSS1_link
, RTL_TEXTENCODING_ASCII_US
);
853 case RES_POOLCHR_INET_VISIT
:
856 rToken
= OString(OOO_STRING_SVTOOLS_HTML_anchor
);
857 *pPseudo
= OStringToOUString( sCSS1_visited
, RTL_TEXTENCODING_ASCII_US
);
862 // if a token is set, PoolId contains the related template
863 if( !rToken
.isEmpty() && !rRefPoolId
)
864 rRefPoolId
= nPoolId
;
867 if( !rToken
.isEmpty() || bStop
)
869 // stop if a HTML-Tag template was found
874 // continue otherwise
876 pPFormat
= pPFormat
->DerivedFrom();
880 if( !rToken
.isEmpty() )
882 // this is a HTML-Tag template
884 nDeep
= CSS1_FMT_ISTAG
;
888 // this is not a HTML-Tag template nor derived from one
891 if( nDeep
> 0 && nDeep
< CSS1_FMT_SPECIAL
)
893 // If the template is derived from a HTML template,
894 // we export it as <TOKEN>.<CLASS>, otherwise as .<CLASS>.
895 // <CLASS> is the name of the template after removing all characters
896 // before and including the first '.'
897 rClass
= pFormat
->GetName();
898 sal_Int32 nPos
= rClass
.indexOf( '.' );
899 if( nPos
>= 0 && rClass
.getLength() > nPos
+1 )
901 rClass
= rClass
.replaceAt( 0, nPos
+1, u
"" );
904 rClass
= GetAppCharClass().lowercase( rClass
);
905 rClass
= rClass
.replaceAll( ".", "-" );
906 rClass
= rClass
.replaceAll( " ", "-" );
907 rClass
= rClass
.replaceAll( "_", "-" );
913 static sal_uInt16
GetCSS1Selector( const SwFormat
*pFormat
, OUString
& rSelector
,
914 sal_uInt16
& rRefPoolId
)
920 sal_uInt16 nDeep
= SwHTMLWriter::GetCSS1Selector( pFormat
, aToken
, aClass
,
921 rRefPoolId
, &aPseudo
);
924 if( !aToken
.isEmpty() )
925 rSelector
= OStringToOUString(aToken
, RTL_TEXTENCODING_ASCII_US
);
929 if( !aClass
.isEmpty() )
930 rSelector
+= "." + aClass
;
931 if( !aPseudo
.isEmpty() )
932 rSelector
+= ":" + aPseudo
;
938 const SwFormat
*SwHTMLWriter::GetTemplateFormat( sal_uInt16 nPoolFormatId
,
939 IDocumentStylePoolAccess
* pTemplate
/*SwDoc *pTemplate*/)
941 const SwFormat
*pRefFormat
= nullptr;
945 OSL_ENSURE( !(USER_FMT
& nPoolFormatId
),
946 "No user templates found" );
947 if( POOLGRP_NOCOLLID
& nPoolFormatId
)
948 pRefFormat
= pTemplate
->GetCharFormatFromPool( nPoolFormatId
);
950 pRefFormat
= pTemplate
->GetTextCollFromPool( nPoolFormatId
, false );
956 const SwFormat
*SwHTMLWriter::GetParentFormat( const SwFormat
& rFormat
, sal_uInt16 nDeep
)
958 OSL_ENSURE( nDeep
!= USHRT_MAX
, "Called GetParent for HTML-template!" );
959 const SwFormat
*pRefFormat
= nullptr;
963 // get the pointer for the HTML-Tag template, from which the template is derived
964 pRefFormat
= &rFormat
;
965 for( sal_uInt16 i
=nDeep
; i
>0; i
-- )
966 pRefFormat
= pRefFormat
->DerivedFrom();
968 if( pRefFormat
&& pRefFormat
->IsDefault() )
969 pRefFormat
= nullptr;
975 bool swhtml_css1atr_equalFontItems( const SfxPoolItem
& r1
, const SfxPoolItem
& r2
)
977 return static_cast<const SvxFontItem
&>(r1
).GetFamilyName() ==
978 static_cast<const SvxFontItem
&>(r2
).GetFamilyName() &&
979 static_cast<const SvxFontItem
&>(r1
).GetFamily() ==
980 static_cast<const SvxFontItem
&>(r2
).GetFamily();
983 void SwHTMLWriter::SubtractItemSet( SfxItemSet
& rItemSet
,
984 const SfxItemSet
& rRefItemSet
,
987 const SfxItemSet
*pRefScriptItemSet
)
989 OSL_ENSURE( bSetDefaults
|| bClearSame
,
990 "SwHTMLWriter::SubtractItemSet: No action for this Flag" );
991 SfxItemSet
aRefItemSet( *rRefItemSet
.GetPool(), rRefItemSet
.GetRanges() );
992 aRefItemSet
.Set( rRefItemSet
);
994 // compare with the Attr-Set of the template
995 SfxWhichIter
aIter( rItemSet
);
996 sal_uInt16 nWhich
= aIter
.FirstWhich();
999 const SfxPoolItem
*pRefItem
, *pItem
;
1000 bool bItemSet
= ( SfxItemState::SET
==
1001 aIter
.GetItemState( false, &pItem
) );
1004 if( pRefScriptItemSet
)
1008 case RES_CHRATR_FONT
:
1009 case RES_CHRATR_FONTSIZE
:
1010 case RES_CHRATR_LANGUAGE
:
1011 case RES_CHRATR_POSTURE
:
1012 case RES_CHRATR_WEIGHT
:
1013 case RES_CHRATR_CJK_FONT
:
1014 case RES_CHRATR_CJK_FONTSIZE
:
1015 case RES_CHRATR_CJK_LANGUAGE
:
1016 case RES_CHRATR_CJK_POSTURE
:
1017 case RES_CHRATR_CJK_WEIGHT
:
1018 case RES_CHRATR_CTL_FONT
:
1019 case RES_CHRATR_CTL_FONTSIZE
:
1020 case RES_CHRATR_CTL_LANGUAGE
:
1021 case RES_CHRATR_CTL_POSTURE
:
1022 case RES_CHRATR_CTL_WEIGHT
:
1023 bRefItemSet
= ( SfxItemState::SET
==
1024 pRefScriptItemSet
->GetItemState( nWhich
, true, &pRefItem
) );
1027 bRefItemSet
= ( SfxItemState::SET
==
1028 aRefItemSet
.GetItemState( nWhich
, false, &pRefItem
) );
1034 bRefItemSet
= ( SfxItemState::SET
==
1035 aRefItemSet
.GetItemState( nWhich
, false, &pRefItem
) );
1040 if( (bClearSame
|| pRefScriptItemSet
) && bRefItemSet
&&
1041 ( *pItem
== *pRefItem
||
1042 ((RES_CHRATR_FONT
== nWhich
||
1043 RES_CHRATR_CJK_FONT
== nWhich
||
1044 RES_CHRATR_CTL_FONT
== nWhich
) &&
1045 swhtml_css1atr_equalFontItems( *pItem
, *pRefItem
)) ) )
1047 // the Attribute is in both templates with the same value
1048 // and does not need to be exported
1049 rItemSet
.ClearItem( nWhich
);
1054 if( (bSetDefaults
|| pRefScriptItemSet
) && bRefItemSet
)
1056 // the Attribute exists only in the reference; the default
1057 // might have to be exported
1058 rItemSet
.Put( rItemSet
.GetPool()->GetDefaultItem(nWhich
) );
1062 nWhich
= aIter
.NextWhich();
1066 void SwHTMLWriter::PrepareFontList( const SvxFontItem
& rFontItem
,
1068 sal_Unicode cQuote
, bool bGeneric
)
1071 const OUString
& rName
= rFontItem
.GetFamilyName();
1072 bool bContainsKeyword
= false;
1073 if( !rName
.isEmpty() )
1075 sal_Int32 nStrPos
= 0;
1076 while( nStrPos
!= -1 )
1078 OUString aName
= rName
.getToken( 0, ';', nStrPos
);
1079 aName
= comphelper::string::encodeForXml(comphelper::string::strip(aName
, ' '));
1080 if( aName
.isEmpty() )
1083 bool bIsKeyword
= false;
1088 bIsKeyword
= aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_cursive
);
1093 bIsKeyword
= aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_fantasy
);
1098 bIsKeyword
= aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_monospace
);
1104 aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_serif
) ||
1105 aName
.equalsIgnoreAsciiCaseAscii( sCSS1_PV_sans_serif
);
1109 bContainsKeyword
|= bIsKeyword
;
1111 if( !rNames
.isEmpty() )
1113 if( cQuote
&& !bIsKeyword
)
1114 rNames
+= OUStringChar( cQuote
);
1116 if( cQuote
&& !bIsKeyword
)
1117 rNames
+= OUStringChar( cQuote
);
1121 if( bContainsKeyword
|| !bGeneric
)
1124 std::string_view pStr
;
1125 switch( rFontItem
.GetFamily() )
1127 case FAMILY_ROMAN
: pStr
= sCSS1_PV_serif
; break;
1128 case FAMILY_SWISS
: pStr
= sCSS1_PV_sans_serif
; break;
1129 case FAMILY_SCRIPT
: pStr
= sCSS1_PV_cursive
; break;
1130 case FAMILY_DECORATIVE
: pStr
= sCSS1_PV_fantasy
; break;
1131 case FAMILY_MODERN
: pStr
= sCSS1_PV_monospace
; break;
1138 if( !rNames
.isEmpty() )
1140 rNames
+= OStringToOUString( pStr
, RTL_TEXTENCODING_ASCII_US
);
1144 bool SwHTMLWriter::HasScriptDependentItems( const SfxItemSet
& rItemSet
,
1145 bool bCheckDropCap
)
1147 static const sal_uInt16 aWhichIds
[] =
1149 RES_CHRATR_FONT
, RES_CHRATR_CJK_FONT
, RES_CHRATR_CTL_FONT
,
1150 RES_CHRATR_FONTSIZE
, RES_CHRATR_CJK_FONTSIZE
, RES_CHRATR_CTL_FONTSIZE
,
1151 RES_CHRATR_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
, RES_CHRATR_CTL_LANGUAGE
,
1152 RES_CHRATR_POSTURE
, RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CTL_POSTURE
,
1153 RES_CHRATR_WEIGHT
, RES_CHRATR_CJK_WEIGHT
, RES_CHRATR_CTL_WEIGHT
,
1157 for( int i
=0; aWhichIds
[i
]; i
+= 3 )
1159 const SfxPoolItem
*pItem
= nullptr, *pItemCJK
= nullptr, *pItemCTL
= nullptr, *pTmp
;
1161 if( SfxItemState::SET
== rItemSet
.GetItemState( aWhichIds
[i
], false,
1167 if( SfxItemState::SET
== rItemSet
.GetItemState( aWhichIds
[i
+1], false,
1173 if( SfxItemState::SET
== rItemSet
.GetItemState( aWhichIds
[i
+2], false,
1180 // If some of the items are set, but not all, we need script dependent
1182 if( nItemCount
> 0 && nItemCount
< 3 )
1185 if( 3 == nItemCount
)
1187 // If all items are set, but some of them have different values,
1188 // we need script dependent styles, too. For font items, we have
1189 // to take care about their special HTML/CSS1 representation.
1190 if( RES_CHRATR_FONT
== aWhichIds
[i
] )
1192 if( !swhtml_css1atr_equalFontItems( *pItem
, *pItemCJK
) ||
1193 !swhtml_css1atr_equalFontItems( *pItem
, *pItemCTL
) ||
1194 !swhtml_css1atr_equalFontItems( *pItemCJK
, *pItemCTL
) )
1199 if( *pItem
!= *pItemCJK
||
1200 *pItem
!= *pItemCTL
||
1201 *pItemCJK
!= *pItemCTL
)
1207 const SwFormatDrop
*pDrop
;
1208 if( bCheckDropCap
&&
1209 (pDrop
= rItemSet
.GetItemIfSet( RES_PARATR_DROP
)) )
1211 const SwCharFormat
*pDCCharFormat
= pDrop
->GetCharFormat();
1214 //sequence of (start, end) property ranges we want to
1217 RES_CHRATR_FONT
, RES_CHRATR_FONT
,
1218 RES_CHRATR_POSTURE
, RES_CHRATR_POSTURE
,
1219 RES_CHRATR_WEIGHT
, RES_CHRATR_WEIGHT
,
1220 RES_CHRATR_CJK_FONT
, RES_CHRATR_CJK_FONT
,
1221 RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CTL_FONT
,
1222 RES_CHRATR_CTL_POSTURE
, RES_CHRATR_CTL_WEIGHT
>
1223 aTstItemSet(*pDCCharFormat
->GetAttrSet().GetPool());
1224 aTstItemSet
.Set( pDCCharFormat
->GetAttrSet() );
1225 return HasScriptDependentItems( aTstItemSet
, false );
1232 static bool OutCSS1Rule( SwHTMLWriter
& rWrt
, const OUString
& rSelector
,
1233 const SfxItemSet
& rItemSet
, bool bHasClass
,
1234 bool bCheckForPseudo
)
1236 bool bScriptDependent
= false;
1237 if( SwHTMLWriter::HasScriptDependentItems( rItemSet
, bHasClass
) )
1239 bScriptDependent
= true;
1240 std::u16string_view
aSelector( rSelector
);
1242 std::u16string_view aPseudo
;
1243 if( bCheckForPseudo
)
1245 size_t nPos
= aSelector
.rfind( ':' );
1246 if( nPos
!= std::u16string_view::npos
)
1248 aPseudo
= aSelector
.substr( nPos
);
1249 aSelector
=aSelector
.substr( 0, nPos
);
1255 // If we are exporting styles for a tag we have to export a tag
1256 // rule for all properties that aren't style dependent and
1257 // some class rule for the additional style dependen properties
1259 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_NO_SCRIPT
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1261 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1264 //sequence of (start, end) property ranges we want to
1266 SfxItemSetFixed
<RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
,
1267 RES_CHRATR_LANGUAGE
, RES_CHRATR_POSTURE
,
1268 RES_CHRATR_WEIGHT
, RES_CHRATR_WEIGHT
,
1269 RES_CHRATR_CJK_FONT
, RES_CHRATR_CTL_WEIGHT
>
1270 aScriptItemSet( *rItemSet
.GetPool() );
1271 aScriptItemSet
.Put( rItemSet
);
1273 OUString aNewSelector
= OUString::Concat(aSelector
) + ".western" + aPseudo
;
1275 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1277 rWrt
.OutCSS1_SfxItemSet( aScriptItemSet
, false );
1280 aNewSelector
= OUString::Concat(aSelector
) + ".cjk" + aPseudo
;
1282 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1284 rWrt
.OutCSS1_SfxItemSet( aScriptItemSet
, false );
1287 aNewSelector
= OUString::Concat(aSelector
) + ".ctl" + aPseudo
;
1289 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1291 rWrt
.OutCSS1_SfxItemSet( aScriptItemSet
, false );
1296 // If there are script dependencies and we are derived from a tag,
1297 // when we have to export a style dependent class for all
1299 OUString aNewSelector
= OUString::Concat(aSelector
) + "-western" + aPseudo
;
1301 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1303 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1306 aNewSelector
= OUString::Concat(aSelector
) + "-cjk" + aPseudo
;
1308 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1310 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1313 aNewSelector
= OUString::Concat(aSelector
) + "-ctl" + aPseudo
;
1315 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1317 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1323 // If there are no script dependencies, when all items are
1324 // exported in one step. For hyperlinks only, a script information
1325 // must be there, because these two chr formats don't support
1326 // script dependencies by now.
1327 SwCSS1OutMode
aMode( rWrt
,
1328 rWrt
.m_nCSS1Script
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1330 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1333 return bScriptDependent
;
1336 static void OutCSS1DropCapRule(
1337 SwHTMLWriter
& rWrt
, const OUString
& rSelector
,
1338 const SwFormatDrop
& rDrop
, bool bHasClass
,
1339 bool bHasScriptDependencies
)
1341 const SwCharFormat
*pDCCharFormat
= rDrop
.GetCharFormat();
1342 if( (bHasScriptDependencies
&& bHasClass
) ||
1343 (pDCCharFormat
&& SwHTMLWriter::HasScriptDependentItems( pDCCharFormat
->GetAttrSet(), false ) ) )
1345 std::u16string_view
aSelector( rSelector
);
1347 std::u16string_view aPseudo
;
1348 size_t nPos
= aSelector
.rfind( ':' );
1349 if( nPos
!= std::u16string_view::npos
)
1351 aPseudo
= aSelector
.substr( nPos
);
1352 aSelector
= aSelector
.substr( 0, nPos
);
1357 // If we are exporting styles for a tag we have to export a tag
1358 // rule for all properties that aren't style dependent and
1359 // some class rule for the additional style dependen properties
1361 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_NO_SCRIPT
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1363 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1366 SfxItemSetFixed
<RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
,
1367 RES_CHRATR_LANGUAGE
, RES_CHRATR_POSTURE
,
1368 RES_CHRATR_WEIGHT
, RES_CHRATR_WEIGHT
,
1369 RES_CHRATR_CJK_FONT
, RES_CHRATR_CTL_WEIGHT
>
1370 aScriptItemSet( rWrt
.m_pDoc
->GetAttrPool() );
1372 aScriptItemSet
.Set( pDCCharFormat
->GetAttrSet() );
1374 OUString aNewSelector
= OUString::Concat(aSelector
) + ".western" + aPseudo
;
1376 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1378 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
, &aScriptItemSet
);
1381 aNewSelector
= OUString::Concat(aSelector
) + ".cjk" + aPseudo
;
1383 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1385 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
, &aScriptItemSet
);
1388 aNewSelector
= OUString::Concat(aSelector
) + ".ctl" + aPseudo
;
1390 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1392 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
, &aScriptItemSet
);
1397 // If there are script dependencies and we are derived from a tag,
1398 // when we have to export a style dependent class for all
1400 OUString aNewSelector
= OUString::Concat(aSelector
) + "-western" + aPseudo
;
1402 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_WESTERN
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1404 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1407 aNewSelector
= OUString::Concat(aSelector
) + "-cjk" + aPseudo
;
1409 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CJK
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1411 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1414 aNewSelector
= OUString::Concat(aSelector
) + "-ctl" + aPseudo
;
1416 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_CTL
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1418 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1424 // If there are no script dependencies, when all items are
1425 // exported in one step. For hyperlinks only, a script information
1426 // must be there, because these two chr formats don't support
1427 // script dependencies by now.
1428 SwCSS1OutMode
aMode( rWrt
,
1429 rWrt
.m_nCSS1Script
|CSS1_OUTMODE_RULE
|CSS1_OUTMODE_DROPCAP
,
1431 OutCSS1_SwFormatDropAttrs( rWrt
, rDrop
);
1435 static SwHTMLWriter
& OutCSS1_SwFormat( SwHTMLWriter
& rWrt
, const SwFormat
& rFormat
,
1436 IDocumentStylePoolAccess
/*SwDoc*/ *pDoc
, SwDoc
*pTemplate
)
1438 bool bCharFormat
= false;
1439 switch( rFormat
.Which() )
1445 case RES_TXTFMTCOLL
:
1446 case RES_CONDTXTFMTCOLL
:
1447 // these template-types can be exported
1455 // determine Selector and the to-be-exported Attr-Set-depth
1457 sal_uInt16 nRefPoolId
= 0;
1458 sal_uInt16 nDeep
= GetCSS1Selector( &rFormat
, aSelector
, nRefPoolId
);
1460 return rWrt
; // not derived from a HTML-template
1462 sal_uInt16 nPoolFormatId
= rFormat
.GetPoolFormatId();
1464 // Determine the to-be-exported Attr-Set. We have to distinguish 3 cases:
1465 // - HTML-Tag templates (nDeep==USHRT_MAX):
1467 // - that are set in the template, but not in the original of the HTML template
1468 // - the Default-Attrs for the Attrs, that are set in the Original of the
1469 // HTML template, but not in the current template.
1470 // - templates directly derived from HTML templates (nDeep==1):
1471 // Export only Attributes of the template Item-Set w/o its parents.
1472 // - templates in-directly derived from HTML templates (nDeep>1):
1473 // Export Attributes of the template Item-Set incl. its Parents,
1474 // but w/o Attributes that are set in the HTML-Tag template.
1476 // create Item-Set with all Attributes from the template
1477 // (all but for nDeep==1)
1478 const SfxItemSet
& rFormatItemSet
= rFormat
.GetAttrSet();
1479 SfxItemSet
aItemSet( *rFormatItemSet
.GetPool(), rFormatItemSet
.GetRanges() );
1480 aItemSet
.Set( rFormatItemSet
); // Was nDeep!=1 that is not working
1481 // for script dependent items but should
1482 // not make a difference for any other
1484 bool bSetDefaults
= true, bClearSame
= true;
1485 const SwFormat
*pRefFormat
= nullptr;
1486 const SwFormat
*pRefFormatScript
= nullptr;
1489 case CSS1_FMT_ISTAG
:
1490 pRefFormat
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pTemplate
== nullptr ? nullptr : &pTemplate
->getIDocumentStylePoolAccess() );
1492 case CSS1_FMT_CMPREF
:
1493 pRefFormat
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pDoc
);
1494 pRefFormatScript
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pTemplate
== nullptr ? nullptr : &pTemplate
->getIDocumentStylePoolAccess() );
1498 pRefFormat
= SwHTMLWriter::GetParentFormat( rFormat
, nDeep
);
1499 pRefFormatScript
= SwHTMLWriter::GetTemplateFormat( nRefPoolId
, pTemplate
== nullptr ? nullptr : &pTemplate
->getIDocumentStylePoolAccess() );
1500 bSetDefaults
= false;
1506 // subtract Item-Set of the Reference template (incl. its Parents)
1507 SwHTMLWriter::SubtractItemSet( aItemSet
, pRefFormat
->GetAttrSet(),
1508 bSetDefaults
, bClearSame
,
1510 ? &pRefFormatScript
->GetAttrSet()
1515 const SvxULSpaceItem
& rULItem
= pRefFormat
->GetULSpace();
1516 rWrt
.m_nDfltTopMargin
= rULItem
.GetUpper();
1517 rWrt
.m_nDfltBottomMargin
= rULItem
.GetLower();
1520 else if( CSS1_FMT_ISTAG
==nDeep
&& !bCharFormat
)
1522 // set Default-distance above and below (for the
1523 // case that there is no reference template)
1524 rWrt
.m_nDfltTopMargin
= 0;
1525 rWrt
.m_nDfltBottomMargin
= HTML_PARSPACE
;
1526 if( USER_FMT
& nPoolFormatId
)
1529 const OUString
& aNm(rFormat
.GetName());
1531 if (aNm
== "DD 1" || aNm
== "DT 1")
1532 rWrt
.m_nDfltBottomMargin
= 0;
1533 else if (aNm
== OOO_STRING_SVTOOLS_HTML_listing
)
1534 rWrt
.m_nDfltBottomMargin
= 0;
1535 else if (aNm
== OOO_STRING_SVTOOLS_HTML_preformtxt
)
1536 rWrt
.m_nDfltBottomMargin
= 0;
1537 else if (aNm
== OOO_STRING_SVTOOLS_HTML_xmp
)
1538 rWrt
.m_nDfltBottomMargin
= 0;
1543 switch( nPoolFormatId
)
1545 case RES_POOLCOLL_HEADLINE1
:
1546 case RES_POOLCOLL_HEADLINE2
:
1547 case RES_POOLCOLL_HEADLINE3
:
1548 case RES_POOLCOLL_HEADLINE4
:
1549 case RES_POOLCOLL_HEADLINE5
:
1550 case RES_POOLCOLL_HEADLINE6
:
1551 rWrt
.m_nDfltTopMargin
= HTML_HEADSPACE
;
1553 case RES_POOLCOLL_SEND_ADDRESS
:
1554 case RES_POOLCOLL_HTML_DT
:
1555 case RES_POOLCOLL_HTML_DD
:
1556 case RES_POOLCOLL_HTML_PRE
:
1557 rWrt
.m_nDfltBottomMargin
= 0;
1563 // if nothing is to be exported ...
1564 if( !aItemSet
.Count() )
1567 // There is no support for script dependent hyperlinks by now.
1568 bool bCheckForPseudo
= false;
1570 (RES_POOLCHR_INET_NORMAL
==nRefPoolId
||
1571 RES_POOLCHR_INET_VISIT
==nRefPoolId
) )
1572 bCheckForPseudo
= true;
1574 // export now the Attributes (incl. selector)
1575 bool bHasScriptDependencies
= false;
1576 if( OutCSS1Rule( rWrt
, aSelector
, aItemSet
, CSS1_FMT_ISTAG
!= nDeep
,
1580 rWrt
.m_aScriptTextStyles
.insert( rFormat
.GetName() );
1583 if( nPoolFormatId
==RES_POOLCOLL_TEXT
)
1584 rWrt
.m_aScriptParaStyles
.insert( pDoc
->GetTextCollFromPool( RES_POOLCOLL_STANDARD
, false )->GetName() );
1585 rWrt
.m_aScriptParaStyles
.insert( rFormat
.GetName() );
1587 bHasScriptDependencies
= true;
1591 if( const SwFormatDrop
*pDrop
= aItemSet
.GetItemIfSet( RES_PARATR_DROP
, false ) )
1593 OUString sOut
= aSelector
+
1594 ":" + OStringToOUString( sCSS1_first_letter
, RTL_TEXTENCODING_ASCII_US
);
1595 OutCSS1DropCapRule( rWrt
, sOut
, *pDrop
, CSS1_FMT_ISTAG
!= nDeep
, bHasScriptDependencies
);
1601 static SwHTMLWriter
& OutCSS1_SwPageDesc( SwHTMLWriter
& rWrt
, const SwPageDesc
& rPageDesc
,
1602 IDocumentStylePoolAccess
/*SwDoc*/ *pDoc
, SwDoc
*pTemplate
,
1603 sal_uInt16 nRefPoolId
, bool bExtRef
,
1606 const SwPageDesc
* pRefPageDesc
= nullptr;
1608 pRefPageDesc
= pDoc
->GetPageDescFromPool( nRefPoolId
, false );
1609 else if( pTemplate
)
1610 pRefPageDesc
= pTemplate
->getIDocumentStylePoolAccess().GetPageDescFromPool( nRefPoolId
, false );
1612 OUString aSelector
= "@" + OStringToOUString( sCSS1_page
, RTL_TEXTENCODING_ASCII_US
);
1616 std::string_view pPseudo
;
1617 switch( rPageDesc
.GetPoolFormatId() )
1619 case RES_POOLPAGE_FIRST
: pPseudo
= sCSS1_first
; break;
1620 case RES_POOLPAGE_LEFT
: pPseudo
= sCSS1_left
; break;
1621 case RES_POOLPAGE_RIGHT
: pPseudo
= sCSS1_right
; break;
1623 if( !pPseudo
.empty() )
1624 aSelector
+= ":" + OStringToOUString( pPseudo
, RTL_TEXTENCODING_ASCII_US
);
1627 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_RULE_ON
|CSS1_OUTMODE_TEMPLATE
,
1630 // Size: If the only difference is the Landscape-Flag,
1631 // only export Portrait or Landscape. Otherwise export size.
1632 bool bRefLandscape
= pRefPageDesc
&& pRefPageDesc
->GetLandscape();
1634 const Size
& rSz
= rPageDesc
.GetMaster().GetFrameSize().GetSize();
1637 aRefSz
= pRefPageDesc
->GetMaster().GetFrameSize().GetSize();
1638 if( bRefLandscape
!= rPageDesc
.GetLandscape() )
1640 tools::Long nTmp
= aRefSz
.Height();
1641 aRefSz
.setHeight( aRefSz
.Width() );
1642 aRefSz
.setWidth( nTmp
);
1646 // TODO: Bad Hack: On the Page-Tabpage there are small rounding errors
1647 // for the page size. Partially because of bug 25535, we stupidly still
1648 // use the Size-Item from Dialog, even if nothing changed.
1649 // Thus: once one visited the Page-Dialog and left it with OK, we get a
1650 // new page size that then gets exported here. To avoid that, we allow
1651 // here small deviations.
1652 if( std::abs( rSz
.Width() - aRefSz
.Width() ) <= 2 &&
1653 std::abs( rSz
.Height() - aRefSz
.Height() ) <= 2 )
1655 if( bRefLandscape
!= rPageDesc
.GetLandscape() )
1657 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_size
,
1658 rPageDesc
.GetLandscape() ? sCSS1_PV_landscape
1659 : sCSS1_PV_portrait
);
1665 AddUnitPropertyValue(sVal
, rSz
.Width(), rWrt
.GetCSS1Unit());
1667 AddUnitPropertyValue(sVal
, rSz
.Height(), rWrt
.GetCSS1Unit());
1668 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_size
, sVal
);
1671 // Export the distance-Attributes as normally
1672 const SwFrameFormat
&rMaster
= rPageDesc
.GetMaster();
1673 SfxItemSetFixed
<RES_LR_SPACE
, RES_UL_SPACE
> aItemSet( *rMaster
.GetAttrSet().GetPool() );
1674 aItemSet
.Set( rMaster
.GetAttrSet() );
1678 SwHTMLWriter::SubtractItemSet( aItemSet
,
1679 pRefPageDesc
->GetMaster().GetAttrSet(),
1683 OutCSS1_SvxULSpace_SvxLRSpace( rWrt
, aItemSet
);
1685 // If for a Pseudo-Selector no Property had been set, we still
1686 // have to export something, so that the corresponding template is
1687 // created on the next import.
1688 if( rWrt
.m_bFirstCSS1Property
&& bPseudo
)
1691 OString
sTmp(OUStringToOString(aSelector
, RTL_TEXTENCODING_UTF8
));
1692 rWrt
.Strm().WriteOString( sTmp
).WriteOString( " {" );
1693 rWrt
.m_bFirstCSS1Property
= false;
1696 if( !rWrt
.m_bFirstCSS1Property
)
1697 rWrt
.Strm().WriteOString( sCSS1_rule_end
);
1702 static SwHTMLWriter
& OutCSS1_SwFootnoteInfo( SwHTMLWriter
& rWrt
, const SwEndNoteInfo
& rInfo
,
1703 SwDoc
*pDoc
, bool bHasNotes
, bool bEndNote
)
1709 aSelector
= OUString::Concat(OOO_STRING_SVTOOLS_HTML_anchor
".") +
1710 ( bEndNote
? std::u16string_view(u
"" OOO_STRING_SVTOOLS_HTML_sdendnote_anc
)
1711 : std::u16string_view(u
"" OOO_STRING_SVTOOLS_HTML_sdfootnote_anc
) );
1712 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_RULE
|CSS1_OUTMODE_TEMPLATE
,
1714 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_size
,
1715 sHTML_FTN_fontheight
);
1716 rWrt
.Strm().WriteOString( sCSS1_rule_end
);
1719 const SwCharFormat
*pSymCharFormat
= rInfo
.GetCharFormat( *pDoc
);
1720 if( pSymCharFormat
)
1722 const SfxItemSet
& rFormatItemSet
= pSymCharFormat
->GetAttrSet();
1723 SfxItemSet
aItemSet( *rFormatItemSet
.GetPool(), rFormatItemSet
.GetRanges() );
1724 aItemSet
.Set( rFormatItemSet
);
1726 // If there are footnotes or endnotes, then all Attributes have to be
1727 // exported, so that Netscape displays the document correctly.
1728 // Otherwise it is sufficient, to export the differences to the
1729 // footnote and endnote template.
1730 if( !bHasNotes
&& rWrt
.m_xTemplate
.is() )
1732 SwFormat
*pRefFormat
= rWrt
.m_xTemplate
->getIDocumentStylePoolAccess().GetCharFormatFromPool(
1733 static_cast< sal_uInt16
>(bEndNote
? RES_POOLCHR_ENDNOTE
: RES_POOLCHR_FOOTNOTE
) );
1735 SwHTMLWriter::SubtractItemSet( aItemSet
, pRefFormat
->GetAttrSet(),
1738 if( aItemSet
.Count() )
1740 aSelector
= OUString::Concat(OOO_STRING_SVTOOLS_HTML_anchor
".") +
1741 ( bEndNote
? std::u16string_view(u
"" OOO_STRING_SVTOOLS_HTML_sdendnote_sym
)
1742 : std::u16string_view(
1743 u
"" OOO_STRING_SVTOOLS_HTML_sdfootnote_sym
));
1744 if( OutCSS1Rule( rWrt
, aSelector
, aItemSet
, true, false ))
1745 rWrt
.m_aScriptTextStyles
.insert( pSymCharFormat
->GetName() );
1752 SwHTMLWriter
& OutCSS1_BodyTagStyleOpt( SwHTMLWriter
& rWrt
, const SfxItemSet
& rItemSet
)
1754 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT_ON
|
1755 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_BODY
, nullptr );
1757 // Only export the attributes of the page template.
1758 // The attributes of the default paragraph template were
1759 // considered already when exporting the paragraph template.
1761 const SfxPoolItem
*pItem
;
1762 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_BACKGROUND
, false,
1765 OUString rEmbeddedGraphicName
;
1766 OutCSS1_SvxBrush( rWrt
, *pItem
, sw::Css1Background::Page
, &rEmbeddedGraphicName
);
1769 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_BOX
, false,
1772 OutCSS1_SvxBox( rWrt
, *pItem
);
1775 if( !rWrt
.m_bFirstCSS1Property
)
1777 // if a Property was exported as part of a Style-Option,
1778 // the Option still needs to be finished
1779 rWrt
.Strm().WriteChar( '\"' );
1785 SwHTMLWriter
& OutCSS1_ParaTagStyleOpt( SwHTMLWriter
& rWrt
, const SfxItemSet
& rItemSet
)
1787 SwCSS1OutMode
aMode( rWrt
, rWrt
.m_nCSS1Script
|CSS1_OUTMODE_STYLE_OPT
|
1788 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_PARA
, nullptr );
1789 rWrt
.OutCSS1_SfxItemSet( rItemSet
, false );
1794 SwHTMLWriter
& OutCSS1_TableBGStyleOpt( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
1796 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT_ON
|
1797 CSS1_OUTMODE_ENCODE
|
1798 CSS1_OUTMODE_TABLEBOX
, nullptr );
1799 OutCSS1_SvxBrush( rWrt
, rHt
, sw::Css1Background::TableRow
, nullptr );
1801 if (!rWrt
.m_bFirstCSS1Property
)
1802 rWrt
.Strm().WriteChar(cCSS1_style_opt_end
);
1807 SwHTMLWriter
& OutCSS1_NumberBulletListStyleOpt( SwHTMLWriter
& rWrt
, const SwNumRule
& rNumRule
,
1810 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT
|
1811 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_PARA
, nullptr );
1813 const SwNumFormat
& rNumFormat
= rNumRule
.Get( nLevel
);
1815 tools::Long nLSpace
= rNumFormat
.GetAbsLSpace();
1816 tools::Long nFirstLineOffset
= rNumFormat
.GetFirstLineOffset();
1817 tools::Long nDfltFirstLineOffset
= HTML_NUMBER_BULLET_INDENT
;
1820 const SwNumFormat
& rPrevNumFormat
= rNumRule
.Get( nLevel
-1 );
1821 nLSpace
-= rPrevNumFormat
.GetAbsLSpace();
1822 nDfltFirstLineOffset
= rPrevNumFormat
.GetFirstLineOffset();
1825 if( rWrt
.IsHTMLMode(HTMLMODE_LSPACE_IN_NUMBER_BULLET
) &&
1826 nLSpace
!= HTML_NUMBER_BULLET_MARGINLEFT
)
1827 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_left
, nLSpace
);
1829 if( rWrt
.IsHTMLMode(HTMLMODE_FRSTLINE_IN_NUMBER_BULLET
) &&
1830 nFirstLineOffset
!= nDfltFirstLineOffset
)
1831 rWrt
.OutCSS1_UnitProperty( sCSS1_P_text_indent
, nFirstLineOffset
);
1833 if( !rWrt
.m_bFirstCSS1Property
)
1834 rWrt
.Strm().WriteChar( '\"' );
1839 void SwHTMLWriter::OutCSS1_FrameFormatOptions( const SwFrameFormat
& rFrameFormat
,
1840 HtmlFrmOpts nFrameOpts
,
1841 const SdrObject
*pSdrObj
,
1842 const SfxItemSet
*pItemSet
)
1844 SwCSS1OutMode
aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON
|
1845 CSS1_OUTMODE_ENCODE
|
1846 CSS1_OUTMODE_FRAME
, nullptr );
1848 const SwFormatHoriOrient
& rHoriOri
= rFrameFormat
.GetHoriOrient();
1849 SvxLRSpaceItem
aLRItem( rFrameFormat
.GetLRSpace() );
1850 SvxULSpaceItem
aULItem( rFrameFormat
.GetULSpace() );
1851 if( nFrameOpts
& HtmlFrmOpts::SAlign
)
1853 const SwFormatAnchor
& rAnchor
= rFrameFormat
.GetAnchor();
1854 switch( rAnchor
.GetAnchorId() )
1856 case RndStdIds::FLY_AT_PARA
:
1857 case RndStdIds::FLY_AT_CHAR
:
1858 if( text::RelOrientation::FRAME
== rHoriOri
.GetRelationOrient() ||
1859 text::RelOrientation::PRINT_AREA
== rHoriOri
.GetRelationOrient() )
1861 if( !(nFrameOpts
& HtmlFrmOpts::Align
) )
1864 std::string_view pStr
= text::HoriOrientation::RIGHT
==rHoriOri
.GetHoriOrient()
1867 OutCSS1_PropertyAscii( sCSS1_P_float
, pStr
);
1873 case RndStdIds::FLY_AT_PAGE
:
1874 case RndStdIds::FLY_AT_FLY
:
1877 OutCSS1_PropertyAscii( sCSS1_P_position
, sCSS1_PV_absolute
);
1879 // For top/left we need to subtract the distance to the frame
1880 // from the position, as in CSS1 it is added to the position.
1881 // This works also for automatically aligned frames, even that
1882 // in this case Writer also adds the distance; because in this
1883 // case the Orient-Attribute contains the correct position.
1886 tools::Long nXPos
=0, nYPos
=0;
1887 bool bOutXPos
= false, bOutYPos
= false;
1888 if( RES_DRAWFRMFMT
== rFrameFormat
.Which() )
1890 OSL_ENSURE( pSdrObj
, "Do not pass a SdrObject. Inefficient" );
1892 pSdrObj
= rFrameFormat
.FindSdrObject();
1893 OSL_ENSURE( pSdrObj
, "Where is the SdrObject" );
1896 Point
aPos( pSdrObj
->GetRelativePos() );
1900 bOutXPos
= bOutYPos
= true;
1904 bOutXPos
= text::RelOrientation::CHAR
!= rHoriOri
.GetRelationOrient();
1905 nXPos
= text::HoriOrientation::NONE
== rHoriOri
.GetHoriOrient()
1906 ? rHoriOri
.GetPos() : 0;
1908 const SwFormatVertOrient
& rVertOri
= rFrameFormat
.GetVertOrient();
1909 bOutYPos
= text::RelOrientation::CHAR
!= rVertOri
.GetRelationOrient();
1910 nYPos
= text::VertOrientation::NONE
== rVertOri
.GetVertOrient()
1911 ? rVertOri
.GetPos() : 0;
1916 if( IsHTMLMode( HTMLMODE_FLY_MARGINS
) )
1918 nYPos
-= aULItem
.GetUpper();
1921 aULItem
.SetUpper( o3tl::narrowing
<sal_uInt16
>(aULItem
.GetUpper() + nYPos
) );
1926 OutCSS1_UnitProperty( sCSS1_P_top
, nYPos
);
1932 if( IsHTMLMode( HTMLMODE_FLY_MARGINS
) )
1934 nXPos
-= aLRItem
.GetLeft();
1937 aLRItem
.SetLeft( o3tl::narrowing
<sal_uInt16
>(aLRItem
.GetLeft() + nXPos
) );
1942 OutCSS1_UnitProperty( sCSS1_P_left
, nXPos
);
1953 if( nFrameOpts
& HtmlFrmOpts::SSize
)
1955 if( RES_DRAWFRMFMT
== rFrameFormat
.Which() )
1957 OSL_ENSURE( pSdrObj
, "Do not pass a SdrObject. Inefficient" );
1959 pSdrObj
= rFrameFormat
.FindSdrObject();
1960 OSL_ENSURE( pSdrObj
, "Where is the SdrObject" );
1963 Size
aTwipSz( pSdrObj
->GetLogicRect().GetSize() );
1964 if( nFrameOpts
& HtmlFrmOpts::SWidth
)
1966 if( nFrameOpts
& HtmlFrmOpts::SPixSize
)
1967 OutCSS1_PixelProperty( sCSS1_P_width
, aTwipSz
.Width() );
1969 OutCSS1_UnitProperty( sCSS1_P_width
, aTwipSz
.Width() );
1971 if( nFrameOpts
& HtmlFrmOpts::SHeight
)
1973 if( nFrameOpts
& HtmlFrmOpts::SPixSize
)
1974 OutCSS1_PixelProperty( sCSS1_P_height
, aTwipSz
.Height() );
1976 OutCSS1_UnitProperty( sCSS1_P_height
, aTwipSz
.Height() );
1982 OSL_ENSURE( HtmlFrmOpts::AbsSize
& nFrameOpts
,
1983 "Export absolute size" );
1984 OSL_ENSURE( HtmlFrmOpts::AnySize
& nFrameOpts
,
1985 "Export every size" );
1986 Css1FrameSize nMode
= Css1FrameSize::NONE
;
1987 if( nFrameOpts
& HtmlFrmOpts::SWidth
)
1988 nMode
|= Css1FrameSize::Width
;
1989 if( nFrameOpts
& HtmlFrmOpts::SHeight
)
1990 nMode
|= Css1FrameSize::MinHeight
|Css1FrameSize::FixHeight
;
1991 if( nFrameOpts
& HtmlFrmOpts::SPixSize
)
1992 nMode
|= Css1FrameSize::Pixel
;
1994 OutCSS1_SwFormatFrameSize( *this, rFrameFormat
.GetFrameSize(), nMode
);
1998 const SfxItemSet
& rItemSet
= rFrameFormat
.GetAttrSet();
2000 if( (nFrameOpts
& HtmlFrmOpts::SSpace
) &&
2001 IsHTMLMode( HTMLMODE_FLY_MARGINS
) )
2003 const SvxLRSpaceItem
*pLRItem
= nullptr;
2004 const SvxULSpaceItem
*pULItem
= nullptr;
2005 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_LR_SPACE
) )
2007 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_UL_SPACE
) )
2009 if( pLRItem
|| pULItem
)
2010 OutCSS1_SvxULSpace_SvxLRSpace( *this, pULItem
, pLRItem
);
2014 if( nFrameOpts
& HtmlFrmOpts::SBorder
)
2016 const SfxPoolItem
* pItem
;
2017 if( nFrameOpts
& HtmlFrmOpts::SNoBorder
)
2018 OutCSS1_SvxBox( *this, rFrameFormat
.GetBox() );
2019 else if( SfxItemState::SET
==rItemSet
.GetItemState( RES_BOX
, true, &pItem
) )
2020 OutCSS1_SvxBox( *this, *pItem
);
2023 // background (if, then the color must be set also)
2024 if( nFrameOpts
& HtmlFrmOpts::SBackground
)
2025 OutCSS1_FrameFormatBackground( rFrameFormat
);
2028 OutCSS1_SfxItemSet( *pItemSet
, false );
2030 if( !m_bFirstCSS1Property
)
2031 Strm().WriteChar( '\"' );
2034 void SwHTMLWriter::OutCSS1_TableFrameFormatOptions( const SwFrameFormat
& rFrameFormat
)
2036 SwCSS1OutMode
aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON
|
2037 CSS1_OUTMODE_ENCODE
|
2038 CSS1_OUTMODE_TABLE
, nullptr );
2040 const SfxPoolItem
*pItem
;
2041 const SfxItemSet
& rItemSet
= rFrameFormat
.GetAttrSet();
2042 if( SfxItemState::SET
==rItemSet
.GetItemState( RES_BACKGROUND
, false, &pItem
) )
2043 OutCSS1_SvxBrush( *this, *pItem
, sw::Css1Background::Table
, nullptr );
2045 if( IsHTMLMode( HTMLMODE_PRINT_EXT
) )
2046 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet
, false );
2048 if( SfxItemState::SET
==rItemSet
.GetItemState( RES_LAYOUT_SPLIT
, false, &pItem
) )
2049 OutCSS1_SwFormatLayoutSplit( *this, *pItem
);
2053 sal_Int16 eTabHoriOri
= rFrameFormat
.GetHoriOrient().GetHoriOrient();
2054 if (eTabHoriOri
== text::HoriOrientation::CENTER
)
2056 // Emit XHTML's center using inline CSS.
2057 OutCSS1_Property(sCSS1_P_margin_left
, "auto", nullptr, sw::Css1Background::Table
);
2058 OutCSS1_Property(sCSS1_P_margin_right
, "auto", nullptr, sw::Css1Background::Table
);
2062 if( !m_bFirstCSS1Property
)
2063 Strm().WriteChar( '\"' );
2066 void SwHTMLWriter::OutCSS1_TableCellBordersAndBG(SwFrameFormat
const& rFrameFormat
, const SvxBrushItem
*pBrushItem
)
2068 SwCSS1OutMode
const aMode( *this,
2069 CSS1_OUTMODE_STYLE_OPT_ON
|CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_TABLEBOX
, nullptr );
2071 OutCSS1_SvxBrush(*this, *pBrushItem
, sw::Css1Background::TableCell
, nullptr);
2072 OutCSS1_SvxBox(*this, rFrameFormat
.GetBox());
2073 if (!m_bFirstCSS1Property
)
2074 Strm().WriteChar(cCSS1_style_opt_end
);
2077 void SwHTMLWriter::OutCSS1_SectionFormatOptions( const SwFrameFormat
& rFrameFormat
, const SwFormatCol
*pCol
)
2079 SwCSS1OutMode
aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON
|
2080 CSS1_OUTMODE_ENCODE
|
2081 CSS1_OUTMODE_SECTION
, nullptr );
2083 const SfxPoolItem
*pItem
;
2084 const SfxItemSet
& rItemSet
= rFrameFormat
.GetAttrSet();
2085 if( SfxItemState::SET
==rItemSet
.GetItemState( RES_BACKGROUND
, false, &pItem
) )
2086 OutCSS1_SvxBrush( *this, *pItem
, sw::Css1Background::Section
, nullptr );
2090 SvxFrameDirection nDir
= GetHTMLDirection(rFrameFormat
.GetAttrSet());
2091 OString sConvertedDirection
= convertDirection(nDir
);
2092 if (!sConvertedDirection
.isEmpty())
2094 OutCSS1_Property(sCSS1_P_dir
, sConvertedDirection
, nullptr,
2095 sw::Css1Background::Section
);
2101 OString
sColumnCount(OString::number(static_cast<sal_Int32
>(pCol
->GetNumCols())));
2102 OutCSS1_PropertyAscii(sCSS1_P_column_count
, sColumnCount
);
2105 if( !m_bFirstCSS1Property
)
2106 Strm().WriteChar( '\"' );
2109 static bool OutCSS1_FrameFormatBrush( SwHTMLWriter
& rWrt
,
2110 const SvxBrushItem
& rBrushItem
)
2112 bool bWritten
= false;
2113 /// output brush of frame format, if its background color is not "no fill"/"auto fill"
2114 /// or it has a background graphic.
2115 if( rBrushItem
.GetColor() != COL_TRANSPARENT
||
2116 !rBrushItem
.GetGraphicLink().isEmpty() ||
2117 0 != rBrushItem
.GetGraphicPos() )
2119 OutCSS1_SvxBrush( rWrt
, rBrushItem
, sw::Css1Background::Fly
, nullptr );
2125 void SwHTMLWriter::OutCSS1_FrameFormatBackground( const SwFrameFormat
& rFrameFormat
)
2127 // If the frame itself has a background, then export.
2128 if( OutCSS1_FrameFormatBrush( *this, *rFrameFormat
.makeBackgroundBrushItem() ) )
2131 // If the frame is not linked to a page, we use the background of the anchor.
2132 const SwFormatAnchor
& rAnchor
= rFrameFormat
.GetAnchor();
2133 RndStdIds eAnchorId
= rAnchor
.GetAnchorId();
2134 const SwNode
*pAnchorNode
= rAnchor
.GetAnchorNode();
2135 if (RndStdIds::FLY_AT_PAGE
!= eAnchorId
&& pAnchorNode
)
2137 if( pAnchorNode
->IsContentNode() )
2139 // If the frame is linked to a content-node,
2140 // we take the background of the content-node, if it has one.
2141 if( OutCSS1_FrameFormatBrush( *this,
2142 pAnchorNode
->GetContentNode()->GetSwAttrSet().GetBackground()) )
2145 // Otherwise we also could be in a table
2146 const SwTableNode
*pTableNd
= pAnchorNode
->FindTableNode();
2149 const SwStartNode
*pBoxSttNd
= pAnchorNode
->FindTableBoxStartNode();
2150 const SwTableBox
*pBox
=
2151 pTableNd
->GetTable().GetTableBox( pBoxSttNd
->GetIndex() );
2153 // If the box has a background, we take it.
2154 if( OutCSS1_FrameFormatBrush( *this,
2155 *pBox
->GetFrameFormat()->makeBackgroundBrushItem() ) )
2158 // Otherwise we use that of the lines
2159 const SwTableLine
*pLine
= pBox
->GetUpper();
2162 if( OutCSS1_FrameFormatBrush( *this,
2163 *pLine
->GetFrameFormat()->makeBackgroundBrushItem() ) )
2165 pBox
= pLine
->GetUpper();
2166 pLine
= pBox
? pBox
->GetUpper() : nullptr;
2169 // If there was none either, we use the background of the table.
2170 if( OutCSS1_FrameFormatBrush( *this,
2171 *pTableNd
->GetTable().GetFrameFormat()->makeBackgroundBrushItem() ) )
2177 // If the anchor is again in a Fly-Frame, use the background of the Fly-Frame.
2178 const SwFrameFormat
*pFrameFormat
= pAnchorNode
->GetFlyFormat();
2181 OutCSS1_FrameFormatBackground( *pFrameFormat
);
2186 // At last there is the background of the page, and as the final rescue
2187 // the value of the Config.
2188 OSL_ENSURE( m_pCurrPageDesc
, "no page template found" );
2189 if( OutCSS1_FrameFormatBrush( *this,
2190 *m_pCurrPageDesc
->GetMaster().makeBackgroundBrushItem() ) )
2193 Color
aColor( COL_WHITE
);
2195 // The background color is normally only used in Browse-Mode.
2196 // We always use it for a HTML document, but for a text document
2197 // only if viewed in Browse-Mode.
2198 if( m_pDoc
->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE
) ||
2199 m_pDoc
->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE
))
2201 SwViewShell
*pVSh
= m_pDoc
->getIDocumentLayoutAccess().GetCurrentViewShell();
2203 COL_TRANSPARENT
!= pVSh
->GetViewOptions()->GetRetoucheColor())
2204 aColor
= pVSh
->GetViewOptions()->GetRetoucheColor();
2207 OutCSS1_PropertyAscii(sCSS1_P_background
, GetCSS1_Color(aColor
));
2210 static SwHTMLWriter
& OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( SwHTMLWriter
& rWrt
,
2211 const SvxUnderlineItem
*pUItem
,
2212 const SvxOverlineItem
*pOItem
,
2213 const SvxCrossedOutItem
*pCOItem
,
2214 const SvxBlinkItem
*pBItem
)
2221 switch( pUItem
->GetLineStyle() )
2223 case LINESTYLE_NONE
:
2226 case LINESTYLE_DONTKNOW
:
2229 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2231 // this also works in HTML does not need to be written as
2232 // a STYLE-Options, and must not be written as Hint
2233 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) || rWrt
.mbReqIF
,
2234 "write underline as Hint?" );
2235 sOut
.append(sCSS1_PV_underline
);
2243 switch( pOItem
->GetLineStyle() )
2245 case LINESTYLE_NONE
:
2248 case LINESTYLE_DONTKNOW
:
2251 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2253 // this also works in HTML does not need to be written as
2254 // a STYLE-Options, and must not be written as Hint
2255 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2256 "write overline as Hint?" );
2257 if (!sOut
.isEmpty())
2259 sOut
.append(sCSS1_PV_overline
);
2267 switch( pCOItem
->GetStrikeout() )
2269 case STRIKEOUT_NONE
:
2272 case STRIKEOUT_DONTKNOW
:
2275 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2277 // this also works in HTML does not need to be written as
2278 // a STYLE-Options, and must not be written as Hint
2279 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) || rWrt
.mbReqIF
,
2280 "write crossedOut as Hint?" );
2281 if (!sOut
.isEmpty())
2283 sOut
.append(sCSS1_PV_line_through
);
2291 if( !pBItem
->GetValue() )
2295 else if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2297 // this also works in HTML does not need to be written as
2298 // a STYLE-Options, and must not be written as Hint
2299 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2300 "write blink as Hint?" );
2301 if (!sOut
.isEmpty())
2303 sOut
.append(sCSS1_PV_blink
);
2307 if (!sOut
.isEmpty())
2308 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_decoration
, sOut
);
2310 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_decoration
, sCSS1_PV_none
);
2315 static SwHTMLWriter
& OutCSS1_SvxCaseMap( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2317 switch( static_cast<const SvxCaseMapItem
&>(rHt
).GetCaseMap() )
2319 case SvxCaseMap::NotMapped
:
2320 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_variant
, sCSS1_PV_normal
);
2322 case SvxCaseMap::SmallCaps
:
2323 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_variant
, sCSS1_PV_small_caps
);
2325 case SvxCaseMap::Uppercase
:
2326 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_transform
, sCSS1_PV_uppercase
);
2328 case SvxCaseMap::Lowercase
:
2329 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_transform
, sCSS1_PV_lowercase
);
2331 case SvxCaseMap::Capitalize
:
2332 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_transform
, sCSS1_PV_capitalize
);
2341 static SwHTMLWriter
& OutCSS1_SvxColor( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2343 // Colors do not need to be exported for Style-Option.
2344 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) &&
2345 !rWrt
.m_bCfgPreferStyles
)
2347 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2348 "write color as Hint?" );
2350 Color
aColor( static_cast<const SvxColorItem
&>(rHt
).GetValue() );
2351 if( COL_AUTO
== aColor
)
2354 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_color
, GetCSS1_Color(aColor
));
2359 static SwHTMLWriter
& OutCSS1_SvxCrossedOut( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2361 // This function only exports Hints!
2362 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2364 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2365 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2366 nullptr, nullptr, static_cast<const SvxCrossedOutItem
*>(&rHt
), nullptr );
2371 static SwHTMLWriter
& OutCSS1_SvxFont( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2373 // No need to export Fonts for the Style-Option.
2374 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2377 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2378 switch( rHt
.Which() )
2380 case RES_CHRATR_CJK_FONT
: nScript
= CSS1_OUTMODE_CJK
; break;
2381 case RES_CHRATR_CTL_FONT
: nScript
= CSS1_OUTMODE_CTL
; break;
2383 if( !rWrt
.IsCSS1Script( nScript
) )
2386 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2387 "write Font as Hint?" );
2390 // MS IE3b1 has problems with single quotes
2391 sal_uInt16 nMode
= rWrt
.m_nCSS1OutMode
& CSS1_OUTMODE_ANY_ON
;
2392 sal_Unicode cQuote
= nMode
== CSS1_OUTMODE_RULE_ON
? '\"' : '\'';
2393 SwHTMLWriter::PrepareFontList( static_cast<const SvxFontItem
&>(rHt
), sOut
, cQuote
,
2396 rWrt
.OutCSS1_Property( sCSS1_P_font_family
, sOut
);
2401 static SwHTMLWriter
& OutCSS1_SvxFontHeight( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2403 // Font-Height need not be exported in the Style-Option.
2404 // For Drop-Caps another Font-Size is exported.
2405 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) ||
2406 rWrt
.IsCSS1Source( CSS1_OUTMODE_DROPCAP
) )
2409 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2410 switch( rHt
.Which() )
2412 case RES_CHRATR_CJK_FONTSIZE
: nScript
= CSS1_OUTMODE_CJK
; break;
2413 case RES_CHRATR_CTL_FONTSIZE
: nScript
= CSS1_OUTMODE_CTL
; break;
2415 if( !rWrt
.IsCSS1Script( nScript
) )
2418 sal_uInt32 nHeight
= static_cast<const SvxFontHeightItem
&>(rHt
).GetHeight();
2419 OString
sHeight(OString::number(nHeight
/20) + sCSS1_UNIT_pt
);
2420 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_font_size
, sHeight
);
2425 static SwHTMLWriter
& OutCSS1_SvxPosture( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2427 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2428 switch( rHt
.Which() )
2430 case RES_CHRATR_CJK_POSTURE
: nScript
= CSS1_OUTMODE_CJK
; break;
2431 case RES_CHRATR_CTL_POSTURE
: nScript
= CSS1_OUTMODE_CTL
; break;
2433 if( !rWrt
.IsCSS1Script( nScript
) )
2436 std::string_view pStr
;
2437 switch( static_cast<const SvxPostureItem
&>(rHt
).GetPosture() )
2439 case ITALIC_NONE
: pStr
= sCSS1_PV_normal
; break;
2440 case ITALIC_OBLIQUE
: pStr
= sCSS1_PV_oblique
; break;
2442 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2444 // this also works in HTML does not need to be written as
2445 // a STYLE-Options, and must not be written as Hint
2446 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2447 "write italic as Hint?" );
2448 pStr
= sCSS1_PV_italic
;
2456 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_style
, pStr
);
2461 static SwHTMLWriter
& OutCSS1_SvxKerning( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2463 sal_Int16 nValue
= static_cast<const SvxKerningItem
&>(rHt
).GetValue();
2474 nValue
= (nValue
+ 1) / 2; // 1/10pt
2475 sOut
.append(OString::number(nValue
/ 10) + "." + OString::number(nValue
% 10) +
2478 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_letter_spacing
, sOut
);
2483 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing
,
2490 static SwHTMLWriter
& OutCSS1_SvxLanguage( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2492 // Only export Language rules
2493 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2496 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2497 switch( rHt
.Which() )
2499 case RES_CHRATR_CJK_LANGUAGE
: nScript
= CSS1_OUTMODE_CJK
; break;
2500 case RES_CHRATR_CTL_LANGUAGE
: nScript
= CSS1_OUTMODE_CTL
; break;
2502 if( !rWrt
.IsCSS1Script( nScript
) )
2505 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2506 "write Language as Hint?" );
2508 LanguageType eLang
= static_cast<const SvxLanguageItem
&>(rHt
).GetLanguage();
2509 if( LANGUAGE_DONTKNOW
== eLang
)
2512 OUString sOut
= LanguageTag::convertToBcp47( eLang
);
2514 rWrt
.OutCSS1_Property( sCSS1_P_so_language
, sOut
);
2519 static SwHTMLWriter
& OutCSS1_SvxUnderline( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2521 // This function only exports Hints!
2522 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2524 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2525 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2526 static_cast<const SvxUnderlineItem
*>(&rHt
), nullptr, nullptr, nullptr );
2531 static SwHTMLWriter
& OutCSS1_SvxOverline( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2533 // This function only exports Hints!
2534 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2536 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2537 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2538 nullptr, static_cast<const SvxOverlineItem
*>(&rHt
), nullptr, nullptr );
2543 static SwHTMLWriter
& OutCSS1_SvxHidden( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2545 if ( static_cast<const SvxCharHiddenItem
&>(rHt
).GetValue() )
2546 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_display
, sCSS1_PV_none
);
2551 static SwHTMLWriter
& OutCSS1_SvxFontWeight( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2553 sal_uInt16 nScript
= CSS1_OUTMODE_WESTERN
;
2554 switch( rHt
.Which() )
2556 case RES_CHRATR_CJK_WEIGHT
: nScript
= CSS1_OUTMODE_CJK
; break;
2557 case RES_CHRATR_CTL_WEIGHT
: nScript
= CSS1_OUTMODE_CTL
; break;
2559 if( !rWrt
.IsCSS1Script( nScript
) )
2562 std::string_view pStr
;
2563 switch( static_cast<const SvxWeightItem
&>(rHt
).GetWeight() )
2565 case WEIGHT_ULTRALIGHT
: pStr
= sCSS1_PV_extra_light
; break;
2566 case WEIGHT_LIGHT
: pStr
= sCSS1_PV_light
; break;
2567 case WEIGHT_SEMILIGHT
: pStr
= sCSS1_PV_demi_light
; break;
2568 case WEIGHT_NORMAL
: pStr
= sCSS1_PV_normal
; break;
2569 case WEIGHT_SEMIBOLD
: pStr
= sCSS1_PV_demi_bold
; break;
2571 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
2573 // this also works in HTML does not need to be written as
2574 // a STYLE-Options, and must not be written as Hint
2575 OSL_ENSURE( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
),
2576 "write bold as Hint?" );
2577 pStr
= sCSS1_PV_bold
;
2580 case WEIGHT_ULTRABOLD
: pStr
= sCSS1_PV_extra_bold
; break;
2582 pStr
= sCSS1_PV_normal
;
2586 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_font_weight
, pStr
);
2591 static SwHTMLWriter
& OutCSS1_SvxBlink( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2593 // This function only exports Hints!
2594 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2596 if( rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2597 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt
,
2598 nullptr, nullptr, nullptr, static_cast<const SvxBlinkItem
*>(&rHt
) );
2603 static SwHTMLWriter
& OutCSS1_SvxLineSpacing( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2605 // Netscape4 has big problems with cell heights if the line spacing is
2606 // changed within a table and the width of the table is not calculated
2607 // automatically (== if there is a WIDTH-Option)
2608 if( rWrt
.m_bOutTable
&& rWrt
.m_bCfgNetscape4
)
2611 const SvxLineSpacingItem
& rLSItem
= static_cast<const SvxLineSpacingItem
&>(rHt
);
2613 sal_uInt16 nHeight
= 0;
2614 sal_uInt16 nPercentHeight
= 0;
2615 SvxLineSpaceRule eLineSpace
= rLSItem
.GetLineSpaceRule();
2616 switch( rLSItem
.GetInterLineSpaceRule() )
2618 case SvxInterLineSpaceRule::Off
:
2619 case SvxInterLineSpaceRule::Fix
:
2621 switch( eLineSpace
)
2623 case SvxLineSpaceRule::Min
:
2624 case SvxLineSpaceRule::Fix
:
2625 nHeight
= rLSItem
.GetLineHeight();
2627 case SvxLineSpaceRule::Auto
:
2628 nPercentHeight
= 100;
2635 case SvxInterLineSpaceRule::Prop
:
2636 nPercentHeight
= rLSItem
.GetPropLineSpace();
2644 rWrt
.OutCSS1_UnitProperty( sCSS1_P_line_height
, static_cast<tools::Long
>(nHeight
) );
2645 else if( nPercentHeight
&&
2646 !(nPercentHeight
< 115 && rWrt
.m_bParaDotLeaders
)) // avoid HTML scrollbars and missing descenders
2648 OString
sHeight(OString::number(nPercentHeight
) + "%");
2649 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_line_height
, sHeight
);
2655 static SwHTMLWriter
& OutCSS1_SvxAdjust( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2657 // Export Alignment in Style-Option only if the Tag does not allow ALIGN=xxx
2658 if( rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) &&
2662 std::string_view pStr
;
2663 switch( static_cast<const SvxAdjustItem
&>(rHt
).GetAdjust() )
2665 case SvxAdjust::Left
: pStr
= sCSS1_PV_left
; break;
2666 case SvxAdjust::Right
: pStr
= sCSS1_PV_right
; break;
2667 case SvxAdjust::Block
: pStr
= sCSS1_PV_justify
; break;
2668 case SvxAdjust::Center
: pStr
= sCSS1_PV_center
; break;
2674 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_text_align
, pStr
);
2679 static SwHTMLWriter
& OutCSS1_SvxFormatSplit( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2681 std::string_view pStr
= static_cast<const SvxFormatSplitItem
&>(rHt
).GetValue()
2684 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside
, pStr
);
2689 static SwHTMLWriter
& OutCSS1_SwFormatLayoutSplit( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2691 std::string_view pStr
= static_cast<const SwFormatLayoutSplit
&>(rHt
).GetValue()
2694 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside
, pStr
);
2699 static SwHTMLWriter
& OutCSS1_SvxWidows( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2701 OString
aStr(OString::number(static_cast<const SvxWidowsItem
&>(rHt
).GetValue()));
2702 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_widows
, aStr
);
2707 static SwHTMLWriter
& OutCSS1_SvxOrphans( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2709 OString
aStr(OString::number(static_cast<const SvxOrphansItem
&>(rHt
).GetValue()));
2710 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_orphans
, aStr
);
2715 static void OutCSS1_SwFormatDropAttrs( SwHTMLWriter
& rHWrt
,
2716 const SwFormatDrop
& rDrop
,
2717 const SfxItemSet
*pCharFormatItemSet
)
2719 // Text flows around on right side
2720 rHWrt
.OutCSS1_PropertyAscii( sCSS1_P_float
, sCSS1_PV_left
);
2722 // number of lines -> use % for Font-Height!
2723 OString
sOut(OString::number(rDrop
.GetLines()*100) + "%");
2724 rHWrt
.OutCSS1_PropertyAscii(sCSS1_P_font_size
, sOut
);
2726 // distance to Text = right margin
2727 sal_uInt16 nDistance
= rDrop
.GetDistance();
2729 rHWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_right
, nDistance
);
2731 const SwCharFormat
*pDCCharFormat
= rDrop
.GetCharFormat();
2732 if( pCharFormatItemSet
)
2733 rHWrt
.OutCSS1_SfxItemSet( *pCharFormatItemSet
);
2734 else if( pDCCharFormat
)
2735 rHWrt
.OutCSS1_SfxItemSet( pDCCharFormat
->GetAttrSet() );
2736 else if( (rHWrt
.m_nCSS1OutMode
& CSS1_OUTMODE_ANY_OFF
) == CSS1_OUTMODE_RULE_OFF
)
2737 rHWrt
.Strm().WriteOString( sCSS1_rule_end
);
2741 static SwHTMLWriter
& OutCSS1_SwFormatDrop( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2743 // never export as an Option of a paragraph, but only as Hints
2744 if( !rWrt
.IsCSS1Source(CSS1_OUTMODE_HINT
) )
2749 SwCSS1OutMode
aMode( rWrt
,
2750 rWrt
.m_nCSS1Script
|CSS1_OUTMODE_SPAN_TAG1_ON
|CSS1_OUTMODE_ENCODE
|
2751 CSS1_OUTMODE_DROPCAP
, nullptr );
2753 OutCSS1_SwFormatDropAttrs( rWrt
, static_cast<const SwFormatDrop
&>(rHt
) );
2754 // A "> is already printed by the calling OutCSS1_HintAsSpanTag.
2758 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
), false );
2764 static SwHTMLWriter
& OutCSS1_SwFormatFrameSize( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
,
2765 Css1FrameSize nMode
)
2767 const SwFormatFrameSize
& rFSItem
= static_cast<const SwFormatFrameSize
&>(rHt
);
2769 if( nMode
& Css1FrameSize::Width
)
2771 sal_uInt8 nPercentWidth
= rFSItem
.GetWidthPercent();
2774 OString
sOut(OString::number(nPercentWidth
) + "%");
2775 rWrt
.OutCSS1_PropertyAscii(sCSS1_P_width
, sOut
);
2777 else if( nMode
& Css1FrameSize::Pixel
)
2779 rWrt
.OutCSS1_PixelProperty( sCSS1_P_width
,
2780 rFSItem
.GetSize().Width() );
2784 rWrt
.OutCSS1_UnitProperty( sCSS1_P_width
,
2785 rFSItem
.GetSize().Width() );
2792 static SwHTMLWriter
& OutCSS1_SvxFirstLineIndent(SwHTMLWriter
& rWrt
, SfxPoolItem
const& rHt
)
2794 const SvxFirstLineIndentItem
& rFirstLine(static_cast<const SvxFirstLineIndentItem
&>(rHt
));
2796 // No Export of a firm attribute is needed if the new values
2797 // match that of the current template
2799 // The LineIndent of the first line might contain the room for numbering
2800 tools::Long nFirstLineIndent
= static_cast<tools::Long
>(rFirstLine
.GetTextFirstLineOffset())
2801 - rWrt
.m_nFirstLineIndent
;
2802 if (rWrt
.m_nDfltFirstLineIndent
!= nFirstLineIndent
)
2804 rWrt
.OutCSS1_UnitProperty(sCSS1_P_text_indent
, nFirstLineIndent
);
2810 static SwHTMLWriter
& OutCSS1_SvxTextLeftMargin(SwHTMLWriter
& rWrt
, SfxPoolItem
const& rHt
)
2812 const SvxTextLeftMarginItem
& rLeftMargin(static_cast<const SvxTextLeftMarginItem
&>(rHt
));
2814 // No Export of a firm attribute is needed if the new values
2815 // match that of the current template
2817 // A left margin can exist because of a list nearby
2818 tools::Long nLeftMargin
= rLeftMargin
.GetTextLeft() - rWrt
.m_nLeftMargin
;
2819 if (rWrt
.m_nDfltLeftMargin
!= nLeftMargin
)
2821 rWrt
.OutCSS1_UnitProperty(sCSS1_P_margin_left
, nLeftMargin
);
2823 // max-width = max-width - margin-left for TOC paragraphs with dot leaders
2824 if (rWrt
.m_bParaDotLeaders
)
2825 rWrt
.OutCSS1_UnitProperty(sCSS1_P_max_width
, tools::Long(DOT_LEADERS_MAX_WIDTH
/2.54*72*20) - nLeftMargin
);
2832 static SwHTMLWriter
& OutCSS1_SvxRightMargin(SwHTMLWriter
& rWrt
, SfxPoolItem
const& rHt
)
2834 const SvxRightMarginItem
& rRightMargin(static_cast<const SvxRightMarginItem
&>(rHt
));
2836 // No Export of a firm attribute is needed if the new values
2837 // match that of the current template
2839 if (rWrt
.m_nDfltRightMargin
!= rRightMargin
.GetRight())
2841 rWrt
.OutCSS1_UnitProperty(sCSS1_P_margin_right
, rRightMargin
.GetRight());
2847 static SwHTMLWriter
& OutCSS1_SvxLRSpace( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2849 const SvxLRSpaceItem
& rLRItem
= static_cast<const SvxLRSpaceItem
&>(rHt
);
2851 // No Export of a firm attribute is needed if the new values
2852 // match that of the current template
2854 // A left margin can exist because of a list nearby
2855 tools::Long nLeftMargin
= rLRItem
.GetTextLeft() - rWrt
.m_nLeftMargin
;
2856 if( rWrt
.m_nDfltLeftMargin
!= nLeftMargin
)
2858 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_left
, nLeftMargin
);
2860 // max-width = max-width - margin-left for TOC paragraphs with dot leaders
2861 if( rWrt
.m_bParaDotLeaders
)
2862 rWrt
.OutCSS1_UnitProperty( sCSS1_P_max_width
, tools::Long(DOT_LEADERS_MAX_WIDTH
/2.54*72*20) - nLeftMargin
);
2866 if( rWrt
.m_nDfltRightMargin
!= rLRItem
.GetRight() )
2868 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_right
, rLRItem
.GetRight() );
2871 // The LineIndent of the first line might contain the room for numbering
2872 tools::Long nFirstLineIndent
= static_cast<tools::Long
>(rLRItem
.GetTextFirstLineOffset()) -
2873 rWrt
.m_nFirstLineIndent
;
2874 if( rWrt
.m_nDfltFirstLineIndent
!= nFirstLineIndent
)
2876 rWrt
.OutCSS1_UnitProperty( sCSS1_P_text_indent
,
2883 static SwHTMLWriter
& OutCSS1_SvxULSpace( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
2885 const SvxULSpaceItem
& rULItem
= static_cast<const SvxULSpaceItem
&>(rHt
);
2887 if( rWrt
.m_nDfltTopMargin
!= rULItem
.GetUpper() )
2889 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_top
,
2890 static_cast<tools::Long
>(rULItem
.GetUpper()) );
2893 if( rWrt
.m_nDfltBottomMargin
!= rULItem
.GetLower() )
2895 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin_bottom
,
2896 static_cast<tools::Long
>(rULItem
.GetLower()) );
2902 static SwHTMLWriter
& OutCSS1_SvxULSpace_SvxLRSpace( SwHTMLWriter
& rWrt
,
2903 const SvxULSpaceItem
*pULItem
,
2904 const SvxLRSpaceItem
*pLRItem
)
2906 if( pLRItem
&& pULItem
&&
2907 pLRItem
->GetLeft() == pLRItem
->GetRight() &&
2908 pLRItem
->GetLeft() == pULItem
->GetUpper() &&
2909 pLRItem
->GetLeft() == pULItem
->GetLower() &&
2910 pLRItem
->GetLeft() != rWrt
.m_nDfltLeftMargin
&&
2911 pLRItem
->GetRight() != rWrt
.m_nDfltRightMargin
&&
2912 pULItem
->GetUpper() != rWrt
.m_nDfltTopMargin
&&
2913 pULItem
->GetLower() != rWrt
.m_nDfltBottomMargin
)
2915 rWrt
.OutCSS1_UnitProperty( sCSS1_P_margin
, pLRItem
->GetLeft() );
2920 OutCSS1_SvxLRSpace( rWrt
, *pLRItem
);
2922 OutCSS1_SvxULSpace( rWrt
, *pULItem
);
2928 static SwHTMLWriter
& OutCSS1_SvxULSpace_SvxLRSpace( SwHTMLWriter
& rWrt
,
2929 const SfxItemSet
& rItemSet
)
2931 const SvxLRSpaceItem
*pLRSpace
= rItemSet
.GetItemIfSet( RES_LR_SPACE
, false/*bDeep*/ );
2932 const SvxULSpaceItem
*pULSpace
= rItemSet
.GetItemIfSet( RES_UL_SPACE
, false/*bDeep*/ );
2934 if( pLRSpace
|| pULSpace
)
2935 OutCSS1_SvxULSpace_SvxLRSpace( rWrt
, pULSpace
, pLRSpace
);
2940 static SwHTMLWriter
& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( SwHTMLWriter
& rWrt
,
2941 const SvxFormatBreakItem
*pBreakItem
,
2942 const SwFormatPageDesc
*pPDescItem
,
2943 const SvxFormatKeepItem
*pKeepItem
)
2945 if( !rWrt
.IsHTMLMode(HTMLMODE_PRINT_EXT
) )
2948 std::string_view pBreakBefore
;
2949 std::string_view pBreakAfter
;
2953 pBreakAfter
= pKeepItem
->GetValue() ? sCSS1_PV_avoid
: sCSS1_PV_auto
;
2957 switch( pBreakItem
->GetBreak() )
2959 case SvxBreak::NONE
:
2960 pBreakBefore
= sCSS1_PV_auto
;
2961 if( pBreakAfter
.empty() )
2962 pBreakAfter
= sCSS1_PV_auto
;
2965 case SvxBreak::PageBefore
:
2966 pBreakBefore
= sCSS1_PV_always
;
2969 case SvxBreak::PageAfter
:
2970 pBreakAfter
= sCSS1_PV_always
;
2979 const SwPageDesc
*pPDesc
= pPDescItem
->GetPageDesc();
2982 switch( pPDesc
->GetPoolFormatId() )
2984 case RES_POOLPAGE_LEFT
: pBreakBefore
= sCSS1_PV_left
; break;
2985 case RES_POOLPAGE_RIGHT
: pBreakBefore
= sCSS1_PV_right
; break;
2986 default: pBreakBefore
= sCSS1_PV_always
; break;
2989 else if( pBreakBefore
.empty() )
2991 pBreakBefore
= sCSS1_PV_auto
;
2995 if (rWrt
.mbSkipHeaderFooter
)
2996 // No page break when writing only a fragment.
2999 if( !pBreakBefore
.empty() )
3000 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_before
,
3002 if( !pBreakAfter
.empty() )
3003 rWrt
.OutCSS1_PropertyAscii( sCSS1_P_page_break_after
,
3009 static SwHTMLWriter
& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( SwHTMLWriter
& rWrt
,
3010 const SfxItemSet
& rItemSet
,
3013 const SvxFormatBreakItem
*pBreakItem
= rItemSet
.GetItemIfSet( RES_BREAK
, bDeep
);
3015 const SwFormatPageDesc
*pPDescItem
= nullptr;
3016 if( !rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) ||
3017 !rWrt
.m_bCSS1IgnoreFirstPageDesc
||
3018 rWrt
.m_pStartNdIdx
->GetIndex() !=
3019 rWrt
.m_pCurrentPam
->GetPoint()->GetNodeIndex() )
3020 pPDescItem
= rItemSet
.GetItemIfSet( RES_PAGEDESC
, bDeep
);
3022 const SvxFormatKeepItem
*pKeepItem
= rItemSet
.GetItemIfSet( RES_KEEP
, bDeep
);
3024 if( pBreakItem
|| pPDescItem
|| pKeepItem
)
3025 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( rWrt
, pBreakItem
,
3026 pPDescItem
, pKeepItem
);
3031 // Wrapper for OutCSS1_SfxItemSet etc.
3032 static SwHTMLWriter
& OutCSS1_SvxBrush( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3034 OutCSS1_SvxBrush( rWrt
, rHt
, sw::Css1Background::Attr
, nullptr );
3038 static SwHTMLWriter
& OutCSS1_SvxBrush( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
,
3039 sw::Css1Background nMode
,
3040 const OUString
* pGraphicName
)
3042 // The Character-Attribute is skipped, if we are about to
3043 // exporting options
3044 if( rHt
.Which() < RES_CHRATR_END
&&
3045 rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
3048 // start getting a few values
3049 // const Brush &rBrush = static_cast<const SvxBrushItem &>(rHt).GetBrush();
3050 const Color
& rColor
= static_cast<const SvxBrushItem
&>(rHt
).GetColor();
3051 OUString aLink
= pGraphicName
? *pGraphicName
3052 : static_cast<const SvxBrushItem
&>(rHt
).GetGraphicLink();
3053 SvxGraphicPosition ePos
= static_cast<const SvxBrushItem
&>(rHt
).GetGraphicPos();
3054 if( sw::Css1Background::Page
== nMode
&& !rWrt
.mbEmbedImages
)
3056 // page style images are exported if not tiled
3057 if( aLink
.isEmpty() || GPOS_TILED
==ePos
)
3062 bool bColor
= false;
3063 /// set <bTransparent> to true, if color is "no fill"/"auto fill"
3064 bool bTransparent
= (rColor
== COL_TRANSPARENT
);
3072 // and now the Graphic
3073 OUString aGraphicInBase64
;
3075 // Embedded Graphic -> export WriteEmbedded
3076 const Graphic
* pGrf
= nullptr;
3077 if( rWrt
.mbEmbedImages
|| aLink
.isEmpty())
3079 pGrf
= static_cast<const SvxBrushItem
&>(rHt
).GetGraphic();
3082 if( !XOutBitmap::GraphicToBase64(*pGrf
, aGraphicInBase64
) )
3084 rWrt
.m_nWarn
= WARN_SWG_POOR_LOAD
;
3089 else if( !pGraphicName
&& rWrt
.m_bCfgCpyLinkedGrfs
)
3091 OUString aGraphicAsLink
= aLink
;
3092 rWrt
.CopyLocalFileToINet( aGraphicAsLink
);
3093 aLink
= aGraphicAsLink
;
3095 // In tables we only export something if there is a Graphic
3096 if( (nMode
== sw::Css1Background::Table
|| nMode
== sw::Css1Background::TableRow
) && !pGrf
&& !aLink
.isEmpty())
3099 // if necessary, add the orientation of the Graphic
3100 std::string_view pRepeat
, pHori
, 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
+= OStringToOUString(sCSS1_PV_transparent
, RTL_TEXTENCODING_ASCII_US
);
3174 OString
sTmp(GetCSS1_Color(aColor
));
3175 sOut
+= OStringToOUString(sTmp
, RTL_TEXTENCODING_ASCII_US
);
3178 if( pGrf
|| !aLink
.isEmpty() )
3185 sOut
+= OStringToOUString(sCSS1_url
, RTL_TEXTENCODING_ASCII_US
) +
3186 "(\'" OOO_STRING_SVTOOLS_HTML_O_data
":" + aGraphicInBase64
+ "\')";
3190 sOut
+= OStringToOUString(sCSS1_url
, RTL_TEXTENCODING_ASCII_US
)+
3191 "(" + URIHelper::simpleNormalizedMakeRelative(rWrt
.GetBaseURL(),
3195 if( !pRepeat
.empty() )
3197 sOut
+= " " + OStringToOUString(pRepeat
, RTL_TEXTENCODING_ASCII_US
);
3200 if( !pHori
.empty() )
3202 sOut
+= " " + OStringToOUString(pHori
, RTL_TEXTENCODING_ASCII_US
);
3204 if( !pVert
.empty() )
3206 sOut
+= " " + OStringToOUString(pVert
, RTL_TEXTENCODING_ASCII_US
);
3209 sOut
+= " " + OStringToOUString(sCSS1_PV_scroll
, RTL_TEXTENCODING_ASCII_US
) + " ";
3213 if( !sOut
.isEmpty() )
3215 rWrt
.OutCSS1_Property(sCSS1_P_background
, std::string_view(), &sOut
,
3222 static void OutCSS1_SvxBorderLine( SwHTMLWriter
& rWrt
,
3223 std::string_view pProperty
,
3224 const SvxBorderLine
*pLine
)
3226 if( !pLine
|| pLine
->isEmpty() )
3228 rWrt
.OutCSS1_PropertyAscii( pProperty
, sCSS1_PV_none
);
3232 sal_Int32 nWidth
= pLine
->GetWidth();
3235 if( nWidth
<= o3tl::convert(1, o3tl::Length::px
, o3tl::Length::twip
) )
3237 // If the width is smaller than one pixel, then export as 1px
3238 // so that Netscape and IE show the line.
3243 nWidth
*= 5; // 1/100pt
3246 sOut
.append(OString::number(nWidth
/ 100) + "." + OString::number((nWidth
/10) % 10) +
3247 OString::number(nWidth
% 10) + sCSS1_UNIT_pt
);
3250 // Line-Style: solid or double
3252 switch (pLine
->GetBorderLineStyle())
3254 case SvxBorderLineStyle::SOLID
:
3255 sOut
.append(sCSS1_PV_solid
);
3257 case SvxBorderLineStyle::DOTTED
:
3258 sOut
.append(sCSS1_PV_dotted
);
3260 case SvxBorderLineStyle::DASHED
:
3261 sOut
.append(sCSS1_PV_dashed
);
3263 case SvxBorderLineStyle::DOUBLE
:
3264 case SvxBorderLineStyle::THINTHICK_SMALLGAP
:
3265 case SvxBorderLineStyle::THINTHICK_MEDIUMGAP
:
3266 case SvxBorderLineStyle::THINTHICK_LARGEGAP
:
3267 case SvxBorderLineStyle::THICKTHIN_SMALLGAP
:
3268 case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
:
3269 case SvxBorderLineStyle::THICKTHIN_LARGEGAP
:
3270 sOut
.append(sCSS1_PV_double
);
3272 case SvxBorderLineStyle::EMBOSSED
:
3273 sOut
.append(sCSS1_PV_ridge
);
3275 case SvxBorderLineStyle::ENGRAVED
:
3276 sOut
.append(sCSS1_PV_groove
);
3278 case SvxBorderLineStyle::INSET
:
3279 sOut
.append(sCSS1_PV_inset
);
3281 case SvxBorderLineStyle::OUTSET
:
3282 sOut
.append(sCSS1_PV_outset
);
3285 sOut
.append(sCSS1_PV_none
);
3289 // and also the color
3290 sOut
.append(GetCSS1_Color(pLine
->GetColor()));
3292 rWrt
.OutCSS1_PropertyAscii(pProperty
, sOut
);
3295 SwHTMLWriter
& OutCSS1_SvxBox( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3297 // Avoid interference between character and paragraph attributes
3298 if( rHt
.Which() < RES_CHRATR_END
&&
3299 rWrt
.IsCSS1Source( CSS1_OUTMODE_PARA
) )
3302 if( rHt
.Which() == RES_CHRATR_BOX
)
3306 // Inline-block to make the line height changing correspond to the character border
3307 rWrt
.OutCSS1_PropertyAscii(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
,
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
);
3606 if( m_bFirstCSS1Property
)
3609 // if a Property was exported as part of a Style-Option,
3610 // the Option still needs to be finished
3612 switch( m_nCSS1OutMode
& CSS1_OUTMODE_ANY_OFF
)
3614 case CSS1_OUTMODE_SPAN_TAG_OFF
:
3615 sOut
.append(sCSS1_span_tag_end
);
3618 case CSS1_OUTMODE_STYLE_OPT_OFF
:
3619 sOut
.append(cCSS1_style_opt_end
);
3622 case CSS1_OUTMODE_RULE_OFF
:
3623 sOut
.append(sCSS1_rule_end
);
3626 if (!sOut
.isEmpty())
3627 Strm().WriteOString( sOut
);
3630 SwHTMLWriter
& OutCSS1_HintSpanTag( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3632 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_SPAN_TAG
|
3633 CSS1_OUTMODE_ENCODE
|CSS1_OUTMODE_HINT
, nullptr );
3635 Out( aCSS1AttrFnTab
, rHt
, rWrt
);
3637 if( !rWrt
.m_bFirstCSS1Property
&& rWrt
.m_bTagOn
)
3638 rWrt
.Strm().WriteOString( sCSS1_span_tag_end
);
3643 SwHTMLWriter
& OutCSS1_HintStyleOpt( SwHTMLWriter
& rWrt
, const SfxPoolItem
& rHt
)
3645 SwCSS1OutMode
aMode( rWrt
, CSS1_OUTMODE_STYLE_OPT_ON
|
3646 CSS1_OUTMODE_ENCODE
|
3647 CSS1_OUTMODE_HINT
, nullptr );
3649 Out( aCSS1AttrFnTab
, rHt
, rWrt
);
3651 if( !rWrt
.m_bFirstCSS1Property
)
3652 rWrt
.Strm().WriteChar( '\"' );
3657 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */