build fix
[LibreOffice.git] / sw / source / filter / html / css1atr.cxx
blob40b7a98429e4e79fdbdceadebe025cc04953d70b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "hintids.hxx"
21 #include <comphelper/string.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/wrkwin.hxx>
24 #include <svl/whiter.hxx>
25 #include <editeng/boxitem.hxx>
26 #include <editeng/ulspitem.hxx>
27 #include <editeng/udlnitem.hxx>
28 #include <editeng/crossedoutitem.hxx>
29 #include <editeng/blinkitem.hxx>
30 #include <editeng/cmapitem.hxx>
31 #include <editeng/colritem.hxx>
32 #include <editeng/fontitem.hxx>
33 #include <editeng/fhgtitem.hxx>
34 #include <editeng/postitem.hxx>
35 #include <editeng/kernitem.hxx>
36 #include <editeng/wghtitem.hxx>
37 #include <editeng/lspcitem.hxx>
38 #include <editeng/adjustitem.hxx>
39 #include <editeng/lrspitem.hxx>
40 #include <editeng/brushitem.hxx>
41 #include <editeng/formatbreakitem.hxx>
42 #include <editeng/keepitem.hxx>
43 #include <editeng/widwitem.hxx>
44 #include <editeng/spltitem.hxx>
45 #include <editeng/orphitem.hxx>
46 #include <editeng/charhiddenitem.hxx>
47 #include <svx/xoutbmp.hxx>
48 #include <svx/svdobj.hxx>
49 #include <editeng/langitem.hxx>
50 #include <editeng/frmdiritem.hxx>
51 #include <svtools/htmlout.hxx>
52 #include <svtools/htmlkywd.hxx>
53 #include <sfx2/htmlmode.hxx>
54 #include <svl/urihelper.hxx>
55 #include <tools/urlobj.hxx>
56 #include <unotools/charclass.hxx>
57 #include <i18nlangtag/languagetag.hxx>
58 #include <charfmt.hxx>
59 #include <fmtclds.hxx>
60 #include <fmtcol.hxx>
61 #include <fmtfsize.hxx>
62 #include <fmtornt.hxx>
63 #include <fmtpdsc.hxx>
64 #include <fmtlsplt.hxx>
65 #include <pagedesc.hxx>
66 #include <fmtanchr.hxx>
67 #include <docary.hxx>
68 #include <pam.hxx>
69 #include <viewsh.hxx>
70 #include <viewopt.hxx>
71 #include <swtable.hxx>
72 // OTES
73 #include <ftninfo.hxx>
74 #include <ftnidx.hxx>
75 #include <txtftn.hxx>
76 #include <fmtftn.hxx>
77 // FOOTNOTES
78 #include "doc.hxx"
79 #include <IDocumentSettingAccess.hxx>
80 #include <IDocumentLayoutAccess.hxx>
81 #include "swerror.h"
82 #include "charatr.hxx"
83 #include "paratr.hxx"
84 #include "frmatr.hxx"
85 #include "poolfmt.hxx"
86 #include "fltini.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>
95 #include <rtl/strbuf.hxx>
97 using namespace css;
98 using editeng::SvxBorderLine;
100 #define HTML_HEADSPACE (12*20)
102 #define CSS1_BACKGROUND_ATTR 1
103 #define CSS1_BACKGROUND_PAGE 2
104 #define CSS1_BACKGROUND_TABLE 3
105 #define CSS1_BACKGROUND_FLY 4
106 #define CSS1_BACKGROUND_SECTION 5
108 #define CSS1_FRMSIZE_WIDTH 0x01
109 #define CSS1_FRMSIZE_VARHEIGHT 0x02
110 #define CSS1_FRMSIZE_MINHEIGHT 0x04
111 #define CSS1_FRMSIZE_FIXHEIGHT 0x08
112 #define CSS1_FRMSIZE_ANYHEIGHT 0x0e
113 #define CSS1_FRMSIZE_PIXEL 0x10
115 #define DOT_LEADERS_MAX_WIDTH 18
117 extern SwAttrFnTab aCSS1AttrFnTab;
119 static Writer& OutCSS1_SwFormat( Writer& rWrt, const SwFormat& rFormat,
120 IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate );
121 static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rFormat,
122 IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate,
123 sal_uInt16 nRefPoolId, bool bExtRef,
124 bool bPseudo=true );
125 static Writer& OutCSS1_SwFootnoteInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
126 SwDoc *pDoc, bool bHasNotes, bool bEndNote );
127 static void OutCSS1_SwFormatDropAttrs( SwHTMLWriter& rHWrt,
128 const SwFormatDrop& rDrop,
129 const SfxItemSet *pCharFormatItemSet=nullptr );
130 static Writer& OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( Writer& rWrt,
131 const SvxUnderlineItem *pUItem,
132 const SvxOverlineItem *pOItem,
133 const SvxCrossedOutItem *pCOItem,
134 const SvxBlinkItem *pBItem );
135 static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt );
136 static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt );
137 static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt );
138 static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt );
139 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
140 const SvxULSpaceItem *pULSpace,
141 const SvxLRSpaceItem *pLRSpace );
142 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
143 const SfxItemSet& rItemSet,
144 bool bDeep );
145 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
146 sal_uInt16 nMode,
147 const OUString *pGraphicName );
148 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt );
149 static Writer& OutCSS1_SwFormatFrameSize( Writer& rWrt, const SfxPoolItem& rHt,
150 sal_uInt16 nMode );
151 static Writer& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( Writer& rWrt,
152 const SfxItemSet& rItemSet,
153 bool bDeep );
154 static Writer& OutCSS1_SwFormatLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt );
156 namespace
159 const sal_Char* sCSS1_rule_end = " }";
160 const sal_Char* sCSS1_span_tag_end = "\">";
161 const sal_Char cCSS1_style_opt_end = '\"';
163 const sal_Char* sHTML_FTN_fontheight = "57%";
165 OString lclConvToHex(sal_uInt16 nHex)
167 sal_Char aNToABuf[] = "00";
169 // set pointer to end of buffer
170 sal_Char *pStr = aNToABuf + (sizeof(aNToABuf)-1);
171 for( sal_uInt8 n = 0; n < 2; ++n )
173 *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
174 if( *pStr > '9' )
175 *pStr += 39;
176 nHex >>= 4;
179 return OString(aNToABuf, 2);
182 OString lclGetCSS1Color(const Color& rColor)
184 return "#" + lclConvToHex(rColor.GetRed()) + lclConvToHex(rColor.GetGreen()) + lclConvToHex(rColor.GetBlue());
189 class SwCSS1OutMode
191 SwHTMLWriter& rWrt;
192 sal_uInt16 nOldMode;
194 public:
196 SwCSS1OutMode( SwHTMLWriter& rHWrt, sal_uInt16 nMode,
197 const OUString *pSelector ) :
198 rWrt( rHWrt ),
199 nOldMode( rHWrt.m_nCSS1OutMode )
201 rWrt.m_nCSS1OutMode = nMode;
202 rWrt.m_bFirstCSS1Property = true;
203 if( pSelector )
204 rWrt.m_aCSS1Selector = *pSelector;
207 ~SwCSS1OutMode()
209 rWrt.m_nCSS1OutMode = nOldMode;
213 void SwHTMLWriter::OutCSS1_Property( const sal_Char *pProp,
214 const sal_Char *pVal,
215 const OUString *pSVal )
217 OStringBuffer sOut;
219 if( m_bFirstCSS1Rule && (m_nCSS1OutMode & CSS1_OUTMODE_RULE_ON)!=0 )
221 m_bFirstCSS1Rule = false;
222 OutNewLine();
223 sOut.append("<" OOO_STRING_SVTOOLS_HTML_style " "
224 OOO_STRING_SVTOOLS_HTML_O_type "=\"text/css\">");
225 // Optional CSS2 code for dot leaders (dotted line between the Table of Contents titles and page numbers):
226 // (More information: http://www.w3.org/Style/Examples/007/leaders.en.html)
228 // p.leaders {
229 // /* FIXME:
230 // (1) dots line up vertically only in the paragraphs with the same alignation/level
231 // (2) max-width = 18 cm instead of 80em; possible improvement with the new CSS3 calc() */
232 // max-width: 18cm; /* note: need to overwrite max-width with max-width - border-left_of_the_actual_paragraph */
233 // padding: 0;
234 // overflow-x: hidden;
235 // line-height: 120%; /* note: avoid HTML scrollbars and missing descenders of the letters */
236 // }
237 // p.leaders:after {
238 // float: left;
239 // width: 0;
240 // white-space: nowrap;
241 // content: ". . . . . . . . . . . . . . . . . . ...";
242 // }
243 // p.leaders span:first-child {
244 // padding-right: 0.33em;
245 // background: white;
246 // }
247 // p.leaders span + span {
248 // float: right;
249 // padding-left: 0.33em;
250 // background: white;
251 // position: relative;
252 // z-index: 1
253 // }
255 if (m_bCfgPrintLayout) {
256 sOut.append(
257 "p." sCSS2_P_CLASS_leaders "{max-width:" + OString::number(DOT_LEADERS_MAX_WIDTH) +
258 "cm;padding:0;overflow-x:hidden;line-height:120%}"
259 "p." sCSS2_P_CLASS_leaders ":after{float:left;width:0;white-space:nowrap;content:\"");
260 for (int i = 0; i < 100; i++ )
261 sOut.append(". ");
262 sOut.append(
263 "\"}p." sCSS2_P_CLASS_leaders " span:first-child{padding-right:0.33em;background:white}"
264 "p." sCSS2_P_CLASS_leaders " span+span{float:right;padding-left:0.33em;"
265 "background:white;position:relative;z-index:1}");
267 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
269 IncIndentLevel();
272 if( m_bFirstCSS1Property )
274 switch( m_nCSS1OutMode & CSS1_OUTMODE_ANY_ON )
276 case CSS1_OUTMODE_SPAN_TAG_ON:
277 case CSS1_OUTMODE_SPAN_TAG1_ON:
278 if( m_bTagOn )
280 sOut.append("<" OOO_STRING_SVTOOLS_HTML_span
281 " " OOO_STRING_SVTOOLS_HTML_O_style "=\"");
283 else
285 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, false );
286 return;
288 break;
290 case CSS1_OUTMODE_RULE_ON:
292 OutNewLine();
293 sOut.append(OUStringToOString(m_aCSS1Selector, m_eDestEnc) + " { ");
295 break;
297 case CSS1_OUTMODE_STYLE_OPT_ON:
298 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_style "=\"");
299 break;
301 m_bFirstCSS1Property = false;
303 else
305 sOut.append("; ");
308 sOut.append(OString(pProp) + ": ");
309 if( m_nCSS1OutMode & CSS1_OUTMODE_ENCODE )
311 // for STYLE-Option encode string
312 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
313 if( pVal )
314 HTMLOutFuncs::Out_String( Strm(), OUString::createFromAscii(pVal),
315 m_eDestEnc, &m_aNonConvertableCharacters );
316 else if( pSVal )
317 HTMLOutFuncs::Out_String( Strm(), *pSVal, m_eDestEnc, &m_aNonConvertableCharacters );
319 else
321 // for STYLE-Tag print string directly
322 if( pVal )
323 sOut.append(pVal);
324 else if( pSVal )
325 sOut.append(OUStringToOString(*pSVal, m_eDestEnc));
328 if (!sOut.isEmpty())
329 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
332 static void AddUnitPropertyValue(OStringBuffer &rOut, long nVal,
333 FieldUnit eUnit)
335 if( nVal < 0 )
337 // special-case sign symbol
338 nVal = -nVal;
339 rOut.append('-');
342 // the recalculated unit results from (x * nMul)/(nDiv*nFac*10)
343 long nMul = 1000;
344 long nDiv = 1;
345 long nFac = 100;
346 const sal_Char *pUnit;
347 switch( eUnit )
349 case FUNIT_100TH_MM:
350 OSL_ENSURE( FUNIT_MM == eUnit, "Measuring unit not supported" );
351 SAL_FALLTHROUGH;
352 case FUNIT_MM:
353 // 0.01mm = 0.57twip
354 nMul = 25400; // 25.4 * 1000
355 nDiv = 1440; // 72 * 20;
356 nFac = 100;
357 pUnit = sCSS1_UNIT_mm;
358 break;
360 case FUNIT_M:
361 case FUNIT_KM:
362 OSL_ENSURE( FUNIT_CM == eUnit, "Measuring unit not supported" );
363 SAL_FALLTHROUGH;
364 case FUNIT_CM:
365 // 0.01cm = 5.7twip (not exact, but the UI is also not exact)
366 nMul = 2540; // 2.54 * 1000
367 nDiv = 1440; // 72 * 20;
368 nFac = 100;
369 pUnit = sCSS1_UNIT_cm;
370 break;
372 case FUNIT_TWIP:
373 OSL_ENSURE( FUNIT_POINT == eUnit, "Measuring unit not supported" );
374 SAL_FALLTHROUGH;
375 case FUNIT_POINT:
376 // 0.1pt = 2.0twip (not exact, but the UI is also not exact)
377 nMul = 100;
378 nDiv = 20;
379 nFac = 10;
380 pUnit = sCSS1_UNIT_pt;
381 break;
383 case FUNIT_PICA:
384 // 0.01pc = 2.40twip (not exact, but the UI is also not exact)
385 nMul = 1000;
386 nDiv = 240; // 12 * 20;
387 nFac = 100;
388 pUnit = sCSS1_UNIT_pc;
389 break;
391 case FUNIT_NONE:
392 case FUNIT_FOOT:
393 case FUNIT_MILE:
394 case FUNIT_CUSTOM:
395 case FUNIT_PERCENT:
396 case FUNIT_INCH:
397 default:
398 OSL_ENSURE( FUNIT_INCH == eUnit, "Measuring unit not supported" );
399 // 0.01in = 14.4twip (not exact, but the UI is also not exact)
400 nMul = 1000;
401 nDiv = 1440; // 72 * 20;
402 nFac = 100;
403 pUnit = sCSS1_UNIT_inch;
404 break;
407 long nLongVal = 0;
408 bool bOutLongVal = true;
409 if( nVal > LONG_MAX / nMul )
411 sal_Int64 nBigVal( nVal );
412 nBigVal *= nMul;
413 nBigVal /= nDiv;
414 nBigVal += 5;
415 nBigVal /= 10;
417 if( nBigVal <= LONG_MAX )
419 // a long is sufficient
420 nLongVal = (long)nBigVal;
422 else
424 rOut.append(nBigVal / (sal_Int64)nFac);
425 if( (nBigVal % (sal_Int64)nFac) != 0 )
427 rOut.append('.');
428 while( nFac > 1 && (nBigVal % (sal_Int64)nFac) != 0 )
430 nFac /= 10;
431 rOut.append((nBigVal / (sal_Int64)nFac) % (sal_Int64)10);
434 bOutLongVal = false;
437 else
439 nLongVal = nVal * nMul;
440 nLongVal /= nDiv;
441 nLongVal += 5;
442 nLongVal /= 10;
445 if( bOutLongVal )
447 rOut.append(OString::number(nLongVal/nFac));
448 if( (nLongVal % nFac) != 0 )
450 rOut.append('.');
451 while( nFac > 1 && (nLongVal % nFac) != 0 )
453 nFac /= 10;
454 rOut.append(OString::number((nLongVal / nFac) % 10));
459 rOut.append(pUnit);
462 void SwHTMLWriter::OutCSS1_UnitProperty( const sal_Char *pProp, long nVal )
464 OStringBuffer sOut;
465 AddUnitPropertyValue(sOut, nVal, m_eCSS1Unit);
466 OutCSS1_PropertyAscii(pProp, sOut.makeStringAndClear());
469 void SwHTMLWriter::OutCSS1_PixelProperty( const sal_Char *pProp, long nVal,
470 bool bVert )
472 OString sOut(OString::number(ToPixel(nVal,bVert)) + sCSS1_UNIT_px);
473 OutCSS1_PropertyAscii(pProp, sOut);
476 void SwHTMLWriter::OutCSS1_SfxItemSet( const SfxItemSet& rItemSet,
477 bool bDeep )
479 // print ItemSet, including all attributes
480 Out_SfxItemSet( aCSS1AttrFnTab, *this, rItemSet, bDeep );
482 // some Attributes require special treatment
483 const SfxPoolItem *pItem = nullptr;
485 // Underline, Overline, CrossedOut and Blink form together a CSS1-Property
486 // (doesn't work of course for Hints)
487 if( !IsCSS1Source(CSS1_OUTMODE_HINT) )
489 const SvxUnderlineItem *pUnderlineItem = nullptr;
490 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_UNDERLINE, bDeep, &pItem ))
491 pUnderlineItem = static_cast<const SvxUnderlineItem *>(pItem);
493 const SvxOverlineItem *pOverlineItem = nullptr;
494 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_OVERLINE, bDeep, &pItem ))
495 pOverlineItem = static_cast<const SvxOverlineItem *>(pItem);
497 const SvxCrossedOutItem *pCrossedOutItem = nullptr;
498 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_CROSSEDOUT, bDeep, &pItem ))
499 pCrossedOutItem = static_cast<const SvxCrossedOutItem *>(pItem);
501 const SvxBlinkItem *pBlinkItem = nullptr;
502 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_BLINK, bDeep, &pItem ))
503 pBlinkItem = static_cast<const SvxBlinkItem *>(pItem);
505 if( pUnderlineItem || pOverlineItem || pCrossedOutItem || pBlinkItem )
506 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( *this, pUnderlineItem,
507 pOverlineItem,
508 pCrossedOutItem,
509 pBlinkItem );
511 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet, bDeep );
514 if( !m_bFirstCSS1Property )
516 // if a Property was exported as part of a Style-Option,
517 // the Option still needs to be finished
518 OStringBuffer sOut;
519 switch( m_nCSS1OutMode & CSS1_OUTMODE_ANY_OFF )
521 case CSS1_OUTMODE_SPAN_TAG_OFF:
522 sOut.append(sCSS1_span_tag_end);
523 break;
525 case CSS1_OUTMODE_STYLE_OPT_OFF:
526 sOut.append(cCSS1_style_opt_end);
527 break;
529 case CSS1_OUTMODE_RULE_OFF:
530 sOut.append(sCSS1_rule_end);
531 break;
533 if (!sOut.isEmpty())
534 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
538 void SwHTMLWriter::OutStyleSheet( const SwPageDesc& rPageDesc )
540 m_bFirstCSS1Rule = true;
542 // Feature: PrintExt
543 if( IsHTMLMode(HTMLMODE_PRINT_EXT) )
545 const SwPageDesc *pFirstPageDesc = nullptr;
546 sal_uInt16 nFirstRefPoolId = RES_POOLPAGE_HTML;
547 m_bCSS1IgnoreFirstPageDesc = true;
549 // First we try to guess how the document is constructed.
550 // Allowed are only the templates: HTML, 1st page, left page, and right page.
551 // A first page is only exported, if it matches the template "1st page".
552 // Left and right pages are only exported, if their templates are linked.
553 // If other templates are used, only very simple cases are exported.
554 const SwPageDesc *pPageDesc = &rPageDesc;
555 const SwPageDesc *pFollow = rPageDesc.GetFollow();
556 if( RES_POOLPAGE_FIRST == pPageDesc->GetPoolFormatId() &&
557 pFollow != pPageDesc &&
558 !IsPoolUserFormat( pFollow->GetPoolFormatId() ) )
560 // the document has a first page
561 pFirstPageDesc = pPageDesc;
562 pPageDesc = pFollow;
563 pFollow = pPageDesc->GetFollow();
566 IDocumentStylePoolAccess* pStylePoolAccess = &getIDocumentStylePoolAccess();
567 if( pPageDesc == pFollow )
569 // The document is one-sided; no matter what page, we do not create a 2-sided doc.
570 // The attribute is exported relative to the HTML page template.
571 OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, m_pTemplate,
572 RES_POOLPAGE_HTML, true, false );
573 nFirstRefPoolId = pFollow->GetPoolFormatId();
575 else if( (RES_POOLPAGE_LEFT == pPageDesc->GetPoolFormatId() &&
576 RES_POOLPAGE_RIGHT == pFollow->GetPoolFormatId()) ||
577 (RES_POOLPAGE_RIGHT == pPageDesc->GetPoolFormatId() &&
578 RES_POOLPAGE_LEFT == pFollow->GetPoolFormatId()) )
580 // the document is double-sided
581 OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, m_pTemplate,
582 RES_POOLPAGE_HTML, true );
583 OutCSS1_SwPageDesc( *this, *pFollow, pStylePoolAccess, m_pTemplate,
584 RES_POOLPAGE_HTML, true );
585 nFirstRefPoolId = RES_POOLPAGE_RIGHT;
586 m_bCSS1IgnoreFirstPageDesc = false;
588 // other cases we miss
590 if( pFirstPageDesc )
591 OutCSS1_SwPageDesc( *this, *pFirstPageDesc, pStylePoolAccess, m_pTemplate,
592 nFirstRefPoolId, false );
595 // The text body style has to be exported always (if it is changed compared
596 // to the template), because it is used as reference for any style
597 // that maps to <P>, and that's especially the standard style
598 getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_TEXT, false );
600 // the Default-TextStyle is not also exported !!
601 // 0-Style is the Default; is never exported !!
602 const size_t nTextFormats = pDoc->GetTextFormatColls()->size();
603 for( size_t i = 1; i < nTextFormats; ++i )
605 const SwTextFormatColl* pColl = (*pDoc->GetTextFormatColls())[i];
606 sal_uInt16 nPoolId = pColl->GetPoolFormatId();
607 if( nPoolId == RES_POOLCOLL_TEXT || pDoc->IsUsed( *pColl ) )
608 OutCSS1_SwFormat( *this, *pColl, &pDoc->getIDocumentStylePoolAccess(), m_pTemplate );
611 // the Default-TextStyle is not also exported !!
612 const size_t nCharFormats = pDoc->GetCharFormats()->size();
613 for( size_t i = 1; i < nCharFormats; ++i )
615 const SwCharFormat *pCFormat = (*pDoc->GetCharFormats())[i];
616 sal_uInt16 nPoolId = pCFormat->GetPoolFormatId();
617 if( nPoolId == RES_POOLCHR_INET_NORMAL ||
618 nPoolId == RES_POOLCHR_INET_VISIT ||
619 pDoc->IsUsed( *pCFormat ) )
620 OutCSS1_SwFormat( *this, *pCFormat, &pDoc->getIDocumentStylePoolAccess(), m_pTemplate );
623 bool bHasEndNotes {false};
624 bool bHasFootNotes {false};
625 const SwFootnoteIdxs& rIdxs = pDoc->GetFootnoteIdxs();
626 for( auto pIdx : rIdxs )
628 if( pIdx->GetFootnote().IsEndNote() )
630 bHasEndNotes = true;
631 if (bHasFootNotes)
632 break;
634 else
636 bHasFootNotes = true;
637 if (bHasEndNotes)
638 break;
641 OutCSS1_SwFootnoteInfo( *this, pDoc->GetFootnoteInfo(), pDoc, bHasFootNotes, false );
642 OutCSS1_SwFootnoteInfo( *this, pDoc->GetEndNoteInfo(), pDoc, bHasEndNotes, true );
644 if( !m_bFirstCSS1Rule )
646 DecIndentLevel();
648 OutNewLine();
649 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_style, false );
651 else
653 m_bFirstCSS1Rule = false;
656 m_nDfltTopMargin = 0;
657 m_nDfltBottomMargin = 0;
660 // if pPseudo is set, Styles-Sheets will be exported;
661 // otherwise we only search for Token and Class for a Format
662 sal_uInt16 SwHTMLWriter::GetCSS1Selector( const SwFormat *pFormat, OString& rToken,
663 OUString& rClass, sal_uInt16& rRefPoolId,
664 OUString *pPseudo )
666 sal_uInt16 nDeep = 0;
667 rToken.clear();
668 rClass.clear();
669 rRefPoolId = 0;
670 if( pPseudo )
671 pPseudo->clear();
673 bool bChrFormat = RES_CHRFMT==pFormat->Which();
675 // search formats above for the nearest standard or HTML-Tag template
676 const SwFormat *pPFormat = pFormat;
677 while( pPFormat && !pPFormat->IsDefault() )
679 bool bStop = false;
680 sal_uInt16 nPoolId = pPFormat->GetPoolFormatId();
681 if( USER_FMT & nPoolId )
683 // user templates
684 const OUString aNm(pPFormat->GetName());
686 if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_blockquote)
688 rRefPoolId = RES_POOLCOLL_HTML_BLOCKQUOTE;
689 rToken = OString(OOO_STRING_SVTOOLS_HTML_blockquote);
691 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_citiation)
693 rRefPoolId = RES_POOLCHR_HTML_CITIATION;
694 rToken = OString(OOO_STRING_SVTOOLS_HTML_citiation);
696 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_code)
698 rRefPoolId = RES_POOLCHR_HTML_CODE;
699 rToken = OString(OOO_STRING_SVTOOLS_HTML_code);
701 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_definstance)
703 rRefPoolId = RES_POOLCHR_HTML_DEFINSTANCE;
704 rToken = OString(OOO_STRING_SVTOOLS_HTML_definstance);
706 else if (!bChrFormat && (aNm == OOO_STRING_SVTOOLS_HTML_dd ||
707 aNm == OOO_STRING_SVTOOLS_HTML_dt))
709 sal_uInt16 nDefListLvl = GetDefListLvl(aNm, nPoolId);
710 // Export the templates DD 1/DT 1,
711 // but none of their derived templates,
712 // also not DD 2/DT 2 etc.
713 if (nDefListLvl)
715 if (pPseudo && (nDeep || (nDefListLvl & 0x0fff) > 1))
717 bStop = true;
719 else if (nDefListLvl & HTML_DLCOLL_DD)
721 rRefPoolId = RES_POOLCOLL_HTML_DD;
722 rToken = OString(OOO_STRING_SVTOOLS_HTML_dd);
724 else
726 rRefPoolId = RES_POOLCOLL_HTML_DT;
727 rToken = OString(OOO_STRING_SVTOOLS_HTML_dt);
731 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_emphasis)
733 rRefPoolId = RES_POOLCHR_HTML_EMPHASIS;
734 rToken = OString(OOO_STRING_SVTOOLS_HTML_emphasis);
736 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_horzrule)
738 // do not export HR !
739 bStop = (nDeep==0);
741 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_keyboard)
743 rRefPoolId = RES_POOLCHR_HTML_KEYBOARD;
744 rToken = OString(OOO_STRING_SVTOOLS_HTML_keyboard);
746 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_listing)
748 // Export Listings as PRE or PRE-derived template
749 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt);
750 rRefPoolId = RES_POOLCOLL_HTML_PRE;
751 nDeep = CSS1_FMT_CMPREF;
753 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_preformtxt)
755 rRefPoolId = RES_POOLCOLL_HTML_PRE;
756 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt);
758 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_sample)
760 rRefPoolId = RES_POOLCHR_HTML_SAMPLE;
761 rToken = OString(OOO_STRING_SVTOOLS_HTML_sample);
763 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_strong)
765 rRefPoolId = RES_POOLCHR_HTML_STRONG;
766 rToken = OString(OOO_STRING_SVTOOLS_HTML_strong);
768 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_teletype)
770 rRefPoolId = RES_POOLCHR_HTML_TELETYPE;
771 rToken = OString(OOO_STRING_SVTOOLS_HTML_teletype);
773 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_variable)
775 rRefPoolId = RES_POOLCHR_HTML_VARIABLE;
776 rToken = OString(OOO_STRING_SVTOOLS_HTML_variable);
778 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_xmp)
780 // export XMP as PRE (but not the template as Style)
781 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt);
782 rRefPoolId = RES_POOLCOLL_HTML_PRE;
783 nDeep = CSS1_FMT_CMPREF;
786 // if a PoolId is set, the Name of the template is that of the related Token
787 OSL_ENSURE( (rRefPoolId != 0) == (!rToken.isEmpty()),
788 "Token missing" );
790 else
792 // Pool templates
793 switch( nPoolId )
795 // paragraph templates
796 case RES_POOLCOLL_HEADLINE_BASE:
797 case RES_POOLCOLL_STANDARD:
798 // do not export this template
799 bStop = (nDeep==0);
800 break;
801 case RES_POOLCOLL_TEXT:
802 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak);
803 break;
804 case RES_POOLCOLL_HEADLINE1:
805 rToken = OString(OOO_STRING_SVTOOLS_HTML_head1);
806 break;
807 case RES_POOLCOLL_HEADLINE2:
808 rToken = OString(OOO_STRING_SVTOOLS_HTML_head2);
809 break;
810 case RES_POOLCOLL_HEADLINE3:
811 rToken = OString(OOO_STRING_SVTOOLS_HTML_head3);
812 break;
813 case RES_POOLCOLL_HEADLINE4:
814 rToken = OString(OOO_STRING_SVTOOLS_HTML_head4);
815 break;
816 case RES_POOLCOLL_HEADLINE5:
817 rToken = OString(OOO_STRING_SVTOOLS_HTML_head5);
818 break;
819 case RES_POOLCOLL_HEADLINE6:
820 rToken = OString(OOO_STRING_SVTOOLS_HTML_head6);
821 break;
822 case RES_POOLCOLL_SENDADRESS:
823 rToken = OString(OOO_STRING_SVTOOLS_HTML_address);
824 break;
825 case RES_POOLCOLL_HTML_BLOCKQUOTE:
826 rToken = OString(OOO_STRING_SVTOOLS_HTML_blockquote);
827 break;
828 case RES_POOLCOLL_HTML_PRE:
829 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt);
830 break;
832 case RES_POOLCOLL_HTML_DD:
833 rToken = OString(OOO_STRING_SVTOOLS_HTML_dd);
834 break;
835 case RES_POOLCOLL_HTML_DT:
836 rToken = OString(OOO_STRING_SVTOOLS_HTML_dt);
837 break;
839 case RES_POOLCOLL_TABLE:
840 if( pPseudo )
842 rToken = OOO_STRING_SVTOOLS_HTML_tabledata " "
843 OOO_STRING_SVTOOLS_HTML_parabreak;
845 else
846 rToken = OOO_STRING_SVTOOLS_HTML_parabreak;
847 break;
848 case RES_POOLCOLL_TABLE_HDLN:
849 if( pPseudo )
851 rToken = OOO_STRING_SVTOOLS_HTML_tableheader " "
852 OOO_STRING_SVTOOLS_HTML_parabreak;
854 else
855 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak);
856 break;
857 case RES_POOLCOLL_HTML_HR:
858 // do not export HR !
859 bStop = (nDeep==0);
860 break;
861 case RES_POOLCOLL_FOOTNOTE:
862 if( !nDeep )
864 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak);
865 rClass = OOO_STRING_SVTOOLS_HTML_sdfootnote;
866 rRefPoolId = RES_POOLCOLL_TEXT;
867 nDeep = CSS1_FMT_CMPREF;
869 break;
870 case RES_POOLCOLL_ENDNOTE:
871 if( !nDeep )
873 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak);
874 rClass = OOO_STRING_SVTOOLS_HTML_sdendnote;
875 rRefPoolId = RES_POOLCOLL_TEXT;
876 nDeep = CSS1_FMT_CMPREF;
878 break;
880 // character templates
881 case RES_POOLCHR_HTML_EMPHASIS:
882 rToken = OString(OOO_STRING_SVTOOLS_HTML_emphasis);
883 break;
884 case RES_POOLCHR_HTML_CITIATION:
885 rToken = OString(OOO_STRING_SVTOOLS_HTML_citiation);
886 break;
887 case RES_POOLCHR_HTML_STRONG:
888 rToken = OString(OOO_STRING_SVTOOLS_HTML_strong);
889 break;
890 case RES_POOLCHR_HTML_CODE:
891 rToken = OString(OOO_STRING_SVTOOLS_HTML_code);
892 break;
893 case RES_POOLCHR_HTML_SAMPLE:
894 rToken = OString(OOO_STRING_SVTOOLS_HTML_sample);
895 break;
896 case RES_POOLCHR_HTML_KEYBOARD:
897 rToken = OString(OOO_STRING_SVTOOLS_HTML_keyboard);
898 break;
899 case RES_POOLCHR_HTML_VARIABLE:
900 rToken = OString(OOO_STRING_SVTOOLS_HTML_variable);
901 break;
902 case RES_POOLCHR_HTML_DEFINSTANCE:
903 rToken = OString(OOO_STRING_SVTOOLS_HTML_definstance);
904 break;
905 case RES_POOLCHR_HTML_TELETYPE:
906 rToken = OString(OOO_STRING_SVTOOLS_HTML_teletype);
907 break;
909 case RES_POOLCHR_INET_NORMAL:
910 if( pPseudo )
912 rToken = OString(OOO_STRING_SVTOOLS_HTML_anchor);
913 *pPseudo = OStringToOUString( sCSS1_link, RTL_TEXTENCODING_ASCII_US );
915 break;
916 case RES_POOLCHR_INET_VISIT:
917 if( pPseudo )
919 rToken = OString(OOO_STRING_SVTOOLS_HTML_anchor);
920 *pPseudo = OStringToOUString( sCSS1_visited, RTL_TEXTENCODING_ASCII_US );
922 break;
925 // if a token is set, PoolId contains the related template
926 if( !rToken.isEmpty() && !rRefPoolId )
927 rRefPoolId = nPoolId;
930 if( !rToken.isEmpty() || bStop )
932 // stop if a HTML-Tag template was found
933 break;
935 else
937 // continue otherwise
938 nDeep++;
939 pPFormat = pPFormat->DerivedFrom();
943 if( !rToken.isEmpty() )
945 // this is a HTML-Tag template
946 if( !nDeep )
947 nDeep = CSS1_FMT_ISTAG;
949 else
951 // this is not a HTML-Tag template nor derived from one
952 nDeep = 0;
954 if( nDeep > 0 && nDeep < CSS1_FMT_SPECIAL )
956 // If the template is derived from a HTML template,
957 // we export it as <TOKEN>.<CLASS>, otherwise as .<CLASS>.
958 // <CLASS> is the name of the template after removing all characters
959 // before and including the first '.'
960 rClass = pFormat->GetName();
961 sal_Int32 nPos = rClass.indexOf( '.' );
962 if( nPos >= 0 && rClass.getLength() > nPos+1 )
964 rClass = rClass.replaceAt( 0, nPos+1, "" );
967 rClass = GetAppCharClass().lowercase( rClass );
968 rClass = rClass.replaceAll( ".", "-" );
969 rClass = rClass.replaceAll( " ", "-" );
970 rClass = rClass.replaceAll( "_", "-" );
973 return nDeep;
976 static sal_uInt16 GetCSS1Selector( const SwFormat *pFormat, OUString& rSelector,
977 sal_uInt16& rRefPoolId )
979 OString aToken;
980 OUString aClass;
981 OUString aPseudo;
983 sal_uInt16 nDeep = SwHTMLWriter::GetCSS1Selector( pFormat, aToken, aClass,
984 rRefPoolId, &aPseudo );
985 if( nDeep )
987 if( !aToken.isEmpty() )
988 rSelector = OStringToOUString(aToken, RTL_TEXTENCODING_ASCII_US);
989 else
990 rSelector.clear();
992 if( !aClass.isEmpty() )
993 rSelector += "." + aClass;
994 if( !aPseudo.isEmpty() )
995 rSelector += ":" + aPseudo;
998 return nDeep;
1001 const SwFormat *SwHTMLWriter::GetTemplateFormat( sal_uInt16 nPoolFormatId,
1002 IDocumentStylePoolAccess* pTemplate /*SwDoc *pTemplate*/)
1004 const SwFormat *pRefFormat = nullptr;
1006 if( pTemplate )
1008 OSL_ENSURE( !(USER_FMT & nPoolFormatId),
1009 "No user templates found" );
1010 if( POOLGRP_NOCOLLID & nPoolFormatId )
1011 pRefFormat = pTemplate->GetCharFormatFromPool( nPoolFormatId );
1012 else
1013 pRefFormat = pTemplate->GetTextCollFromPool( nPoolFormatId, false );
1016 return pRefFormat;
1019 const SwFormat *SwHTMLWriter::GetParentFormat( const SwFormat& rFormat, sal_uInt16 nDeep )
1021 OSL_ENSURE( nDeep != USHRT_MAX, "Called GetParent for HTML-template!" );
1022 const SwFormat *pRefFormat = nullptr;
1024 if( nDeep > 0 )
1026 // get the pointer for the HTML-Tag template, from which the template is derived
1027 pRefFormat = &rFormat;
1028 for( sal_uInt16 i=nDeep; i>0; i-- )
1029 pRefFormat = pRefFormat->DerivedFrom();
1031 if( pRefFormat && pRefFormat->IsDefault() )
1032 pRefFormat = nullptr;
1035 return pRefFormat;
1038 bool swhtml_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 )
1040 return static_cast<const SvxFontItem &>(r1).GetFamilyName() ==
1041 static_cast<const SvxFontItem &>(r2).GetFamilyName() &&
1042 static_cast<const SvxFontItem &>(r1).GetFamily() ==
1043 static_cast<const SvxFontItem &>(r2).GetFamily();
1046 void SwHTMLWriter::SubtractItemSet( SfxItemSet& rItemSet,
1047 const SfxItemSet& rRefItemSet,
1048 bool bSetDefaults,
1049 bool bClearSame,
1050 const SfxItemSet *pRefScriptItemSet )
1052 OSL_ENSURE( bSetDefaults || bClearSame,
1053 "SwHTMLWriter::SubtractItemSet: No action for this Flag" );
1054 SfxItemSet aRefItemSet( *rRefItemSet.GetPool(), rRefItemSet.GetRanges() );
1055 aRefItemSet.Set( rRefItemSet );
1057 // compare with the Attr-Set of the template
1058 SfxWhichIter aIter( rItemSet );
1059 sal_uInt16 nWhich = aIter.FirstWhich();
1060 while( nWhich )
1062 const SfxPoolItem *pRefItem, *pItem;
1063 bool bItemSet = ( SfxItemState::SET ==
1064 rItemSet.GetItemState( nWhich, false, &pItem) );
1065 bool bRefItemSet;
1067 if( pRefScriptItemSet )
1069 switch( nWhich )
1071 case RES_CHRATR_FONT:
1072 case RES_CHRATR_FONTSIZE:
1073 case RES_CHRATR_LANGUAGE:
1074 case RES_CHRATR_POSTURE:
1075 case RES_CHRATR_WEIGHT:
1076 case RES_CHRATR_CJK_FONT:
1077 case RES_CHRATR_CJK_FONTSIZE:
1078 case RES_CHRATR_CJK_LANGUAGE:
1079 case RES_CHRATR_CJK_POSTURE:
1080 case RES_CHRATR_CJK_WEIGHT:
1081 case RES_CHRATR_CTL_FONT:
1082 case RES_CHRATR_CTL_FONTSIZE:
1083 case RES_CHRATR_CTL_LANGUAGE:
1084 case RES_CHRATR_CTL_POSTURE:
1085 case RES_CHRATR_CTL_WEIGHT:
1086 bRefItemSet = ( SfxItemState::SET ==
1087 pRefScriptItemSet->GetItemState( nWhich, true, &pRefItem) );
1088 break;
1089 default:
1090 bRefItemSet = ( SfxItemState::SET ==
1091 aRefItemSet.GetItemState( nWhich, false, &pRefItem) );
1092 break;
1095 else
1097 bRefItemSet = ( SfxItemState::SET ==
1098 aRefItemSet.GetItemState( nWhich, false, &pRefItem) );
1101 if( bItemSet )
1103 if( (bClearSame || pRefScriptItemSet) && bRefItemSet &&
1104 ( *pItem == *pRefItem ||
1105 ((RES_CHRATR_FONT == nWhich ||
1106 RES_CHRATR_CJK_FONT == nWhich ||
1107 RES_CHRATR_CTL_FONT == nWhich) &&
1108 swhtml_css1atr_equalFontItems( *pItem, *pRefItem )) ) )
1110 // the Attribute is in both templates wit the same value
1111 // and does not need to be exported
1112 rItemSet.ClearItem( nWhich );
1115 else
1117 if( (bSetDefaults || pRefScriptItemSet) && bRefItemSet )
1119 // the Attribute exists only in the reference; the default
1120 // might have to be exported
1121 rItemSet.Put( rItemSet.GetPool()->GetDefaultItem(nWhich) );
1125 nWhich = aIter.NextWhich();
1129 void SwHTMLWriter::PrepareFontList( const SvxFontItem& rFontItem,
1130 OUString& rNames,
1131 sal_Unicode cQuote, bool bGeneric )
1133 rNames = aEmptyOUStr;
1134 const OUString& rName = rFontItem.GetFamilyName();
1135 bool bContainsKeyword = false;
1136 if( !rName.isEmpty() )
1138 sal_Int32 nStrPos = 0;
1139 while( nStrPos != -1 )
1141 OUString aName = rName.getToken( 0, ';', nStrPos );
1142 aName = comphelper::string::strip(aName, ' ');
1143 if( aName.isEmpty() )
1144 continue;
1146 bool bIsKeyword = false;
1147 switch( aName[0] )
1149 case 'c':
1150 case 'C':
1151 bIsKeyword = aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_cursive );
1152 break;
1154 case 'f':
1155 case 'F':
1156 bIsKeyword = aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_fantasy );
1157 break;
1159 case 'm':
1160 case 'M':
1161 bIsKeyword = aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_monospace );
1162 break;
1164 case 's':
1165 case 'S':
1166 bIsKeyword =
1167 aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_serif ) ||
1168 aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_sans_serif );
1169 break;
1172 bContainsKeyword |= bIsKeyword;
1174 if( !rNames.isEmpty() )
1175 rNames += ", ";
1176 if( cQuote && !bIsKeyword )
1177 rNames += OUStringLiteral1( cQuote );
1178 rNames += aName;
1179 if( cQuote && !bIsKeyword )
1180 rNames += OUStringLiteral1( cQuote );
1184 if( !bContainsKeyword && bGeneric )
1186 const sal_Char *pStr = nullptr;
1187 switch( rFontItem.GetFamily() )
1189 case FAMILY_ROMAN: pStr = sCSS1_PV_serif; break;
1190 case FAMILY_SWISS: pStr = sCSS1_PV_sans_serif; break;
1191 case FAMILY_SCRIPT: pStr = sCSS1_PV_cursive; break;
1192 case FAMILY_DECORATIVE: pStr = sCSS1_PV_fantasy; break;
1193 case FAMILY_MODERN: pStr = sCSS1_PV_monospace; break;
1194 default:
1198 if( pStr )
1200 if( !rNames.isEmpty() )
1201 rNames += ", ";
1202 rNames += OStringToOUString( pStr, RTL_TEXTENCODING_ASCII_US );
1207 bool SwHTMLWriter::HasScriptDependentItems( const SfxItemSet& rItemSet,
1208 bool bCheckDropCap )
1210 static const sal_uInt16 aWhichIds[] =
1212 RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT,
1213 RES_CHRATR_FONTSIZE, RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CTL_FONTSIZE,
1214 RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
1215 RES_CHRATR_POSTURE, RES_CHRATR_CJK_POSTURE, RES_CHRATR_CTL_POSTURE,
1216 RES_CHRATR_WEIGHT, RES_CHRATR_CJK_WEIGHT, RES_CHRATR_CTL_WEIGHT,
1217 0, 0, 0
1220 for( int i=0; aWhichIds[i]; i += 3 )
1222 const SfxPoolItem *pItem = nullptr, *pItemCJK = nullptr, *pItemCTL = nullptr, *pTmp;
1223 int nItemCount = 0;
1224 if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i], false,
1225 &pTmp ) )
1227 pItem = pTmp;
1228 nItemCount++;
1230 if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i+1], false,
1231 &pTmp ) )
1233 pItemCJK = pTmp;
1234 nItemCount++;
1236 if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i+2], false,
1237 &pTmp ) )
1239 pItemCTL = pTmp;
1240 nItemCount++;
1243 // If some of the items are set, but not all, we need script dependent
1244 // styles
1245 if( nItemCount > 0 && nItemCount < 3 )
1246 return true;
1248 if( 3 == nItemCount )
1250 // If all items are set, but some of them have different values,
1251 // we need script dependent styles, too. For font items, we have
1252 // to take care about their special HTML/CSS1 representation.
1253 if( RES_CHRATR_FONT == aWhichIds[i] )
1255 if( !swhtml_css1atr_equalFontItems( *pItem, *pItemCJK ) ||
1256 !swhtml_css1atr_equalFontItems( *pItem, *pItemCTL ) ||
1257 !swhtml_css1atr_equalFontItems( *pItemCJK, *pItemCTL ) )
1258 return true;
1260 else
1262 if( !( *pItem == *pItemCJK ) ||
1263 !( *pItem == *pItemCTL ) ||
1264 !( *pItemCJK == *pItemCTL ) )
1265 return true;
1270 const SfxPoolItem *pItem;
1271 if( bCheckDropCap &&
1272 SfxItemState::SET == rItemSet.GetItemState( RES_PARATR_DROP, true,
1273 &pItem ) )
1275 const SwFormatDrop *pDrop = static_cast<const SwFormatDrop *>(pItem);
1276 const SwCharFormat *pDCCharFormat = pDrop->GetCharFormat();
1277 if( pDCCharFormat )
1279 //sequence of (start, end) property ranges we want to
1280 //query
1281 SfxItemSet aTstItemSet( *pDCCharFormat->GetAttrSet().GetPool(),
1282 RES_CHRATR_FONT, RES_CHRATR_FONT,
1283 RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
1284 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
1285 RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
1286 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT,
1287 RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT,
1288 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT,
1289 0 );
1290 aTstItemSet.Set( pDCCharFormat->GetAttrSet() );
1291 return HasScriptDependentItems( aTstItemSet, false );
1295 return false;
1298 static bool OutCSS1Rule( SwHTMLWriter& rHTMLWrt, const OUString& rSelector,
1299 const SfxItemSet& rItemSet, bool bHasClass,
1300 bool bCheckForPseudo )
1302 bool bScriptDependent = false;
1303 if( SwHTMLWriter::HasScriptDependentItems( rItemSet, bHasClass ) )
1305 bScriptDependent = true;
1306 OUString aSelector( rSelector );
1308 OUString aPseudo;
1309 if( bCheckForPseudo )
1311 sal_Int32 nPos = aSelector.lastIndexOf( ':' );
1312 if( nPos >= 0 )
1314 aPseudo = aSelector.copy( nPos );
1315 aSelector =aSelector.copy( 0, nPos );
1319 if( !bHasClass )
1321 // If we are exporting styles for a tag we have to export a tag
1322 // rule for all properties that aren't style dependent and
1323 // some class rule for the additional style dependen properties
1325 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1326 &rSelector );
1327 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false );
1330 //sequence of (start, end) property ranges we want to
1331 //query
1332 SfxItemSet aScriptItemSet( *rItemSet.GetPool(),
1333 RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
1334 RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
1335 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
1336 RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
1337 0 );
1338 aScriptItemSet.Put( rItemSet );
1340 OUString aNewSelector( aSelector );
1341 aNewSelector += ".western" + aPseudo;
1343 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1344 &aNewSelector );
1345 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, false );
1348 aNewSelector = aSelector + ".cjk" + aPseudo;
1350 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1351 &aNewSelector );
1352 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, false );
1355 aNewSelector = aSelector + ".ctl" + aPseudo;
1357 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1358 &aNewSelector );
1359 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, false );
1362 else
1364 // If there are script dependencies and we are derived from a tag,
1365 // when we have to export a style dependent class for all
1366 // scripts
1367 OUString aNewSelector( aSelector );
1368 aNewSelector += "-western" + aPseudo;
1370 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1371 &aNewSelector );
1372 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false );
1375 aNewSelector = aSelector + "-cjk" + aPseudo;
1377 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1378 &aNewSelector );
1379 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false );
1382 aNewSelector = aSelector + "-ctl" + aPseudo;
1384 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1385 &aNewSelector );
1386 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false );
1390 else
1392 // If there are no script dependencies, when all items are
1393 // exported in one step. For hyperlinks only, a script information
1394 // must be there, because these two chr formats don't support
1395 // script dependencies by now.
1396 SwCSS1OutMode aMode( rHTMLWrt,
1397 rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1398 &rSelector );
1399 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false );
1402 return bScriptDependent;
1405 static void OutCSS1DropCapRule(
1406 SwHTMLWriter& rHTMLWrt, const OUString& rSelector,
1407 const SwFormatDrop& rDrop, bool bHasClass,
1408 bool bHasScriptDependencies )
1410 const SwCharFormat *pDCCharFormat = rDrop.GetCharFormat();
1411 if( (bHasScriptDependencies && bHasClass) ||
1412 (pDCCharFormat && SwHTMLWriter::HasScriptDependentItems( pDCCharFormat->GetAttrSet(), false ) ) )
1414 OUString aSelector( rSelector );
1416 OUString aPseudo;
1417 sal_Int32 nPos = aSelector.lastIndexOf( ':' );
1418 if( nPos >= 0 )
1420 aPseudo = aSelector.copy( nPos );
1421 aSelector = aSelector.copy( 0, nPos );
1424 if( !bHasClass )
1426 // If we are exporting styles for a tag we have to export a tag
1427 // rule for all properties that aren't style dependent and
1428 // some class rule for the additional style dependen properties
1430 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1431 &rSelector );
1432 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop );
1435 SfxItemSet aScriptItemSet( rHTMLWrt.pDoc->GetAttrPool(),
1436 RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
1437 RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
1438 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
1439 RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
1440 0 );
1441 if( pDCCharFormat )
1442 aScriptItemSet.Set( pDCCharFormat->GetAttrSet() );
1444 OUString aNewSelector( aSelector );
1445 aNewSelector += ".western" + aPseudo;
1447 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1448 &aNewSelector );
1449 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet );
1452 aNewSelector = aSelector + ".cjk" + aPseudo;
1454 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1455 &aNewSelector );
1456 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet );
1459 aNewSelector = aSelector + ".ctl" + aPseudo;
1461 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1462 &aNewSelector );
1463 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet );
1466 else
1468 // If there are script dependencies and we are derived from a tag,
1469 // when we have to export a style dependent class for all
1470 // scripts
1471 OUString aNewSelector( aSelector );
1472 aNewSelector += "-western" + aPseudo;
1474 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1475 &aNewSelector );
1476 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop );
1479 aNewSelector = aSelector + "-cjk" + aPseudo;
1481 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1482 &aNewSelector );
1483 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop );
1486 aNewSelector = aSelector + "-ctl" + aPseudo;
1488 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1489 &aNewSelector );
1490 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop );
1494 else
1496 // If there are no script dependencies, when all items are
1497 // exported in one step. For hyperlinks only, a script information
1498 // must be there, because these two chr formats don't support
1499 // script dependencies by now.
1500 SwCSS1OutMode aMode( rHTMLWrt,
1501 rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1502 &rSelector );
1503 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop );
1507 static Writer& OutCSS1_SwFormat( Writer& rWrt, const SwFormat& rFormat,
1508 IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate )
1510 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1512 bool bCharFormat = false;
1513 switch( rFormat.Which() )
1515 case RES_CHRFMT:
1516 bCharFormat = true;
1517 break;
1519 case RES_TXTFMTCOLL:
1520 case RES_CONDTXTFMTCOLL:
1521 // these template-types can be exported
1522 break;
1524 default:
1525 // but not these
1526 return rWrt;
1529 // determine Selector and the to-be-exported Attr-Set-depth
1530 OUString aSelector;
1531 sal_uInt16 nRefPoolId = 0;
1532 sal_uInt16 nDeep = GetCSS1Selector( &rFormat, aSelector, nRefPoolId );
1533 if( !nDeep )
1534 return rWrt; // not derived from a HTML-template
1536 sal_uInt16 nPoolFormatId = rFormat.GetPoolFormatId();
1538 // Determine the to-be-exported Attr-Set. We have to distinguish 3 cases:
1539 // - HTML-Tag templates (nDeep==USHRT_MAX):
1540 // Export Attrs...
1541 // - that are set in the template, but not in the original of the HTML template
1542 // - the Default-Attrs for the Attrs, that are set in the Original of the
1543 // HTML template, but not in the current template.
1544 // - templates directly derived from HTML templates (nDeep==1):
1545 // Export only Attributes of the template Item-Set w/o its parents.
1546 // - templates in-directly derived from HTML templates (nDeep>1):
1547 // Export Attributes of the template Item-Set incl. its Parents,
1548 // but w/o Attributes that are set in the HTML-Tag template.
1550 // create Item-Set with all Attributes from the template
1551 // (all but for nDeep==1)
1552 const SfxItemSet& rFormatItemSet = rFormat.GetAttrSet();
1553 SfxItemSet aItemSet( *rFormatItemSet.GetPool(), rFormatItemSet.GetRanges() );
1554 aItemSet.Set( rFormatItemSet ); // Was nDeep!=1 that is not working
1555 // for script dependent items buts should
1556 // not make a difference for any other
1558 bool bSetDefaults = true, bClearSame = true;
1559 const SwFormat *pRefFormat = nullptr;
1560 const SwFormat *pRefFormatScript = nullptr;
1561 switch( nDeep )
1563 case CSS1_FMT_ISTAG:
1564 pRefFormat = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pTemplate == nullptr ? nullptr : &pTemplate->getIDocumentStylePoolAccess() );
1565 break;
1566 case CSS1_FMT_CMPREF:
1567 pRefFormat = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pDoc );
1568 pRefFormatScript = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pTemplate == nullptr ? nullptr : &pTemplate->getIDocumentStylePoolAccess() );
1569 bClearSame = false;
1570 break;
1571 default:
1572 pRefFormat = SwHTMLWriter::GetParentFormat( rFormat, nDeep );
1573 pRefFormatScript = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pTemplate == nullptr ? nullptr : &pTemplate->getIDocumentStylePoolAccess() );
1574 bSetDefaults = false;
1575 break;
1578 if( pRefFormat )
1580 // subtract Item-Set of the Reference template (incl. its Parents)
1581 SwHTMLWriter::SubtractItemSet( aItemSet, pRefFormat->GetAttrSet(),
1582 bSetDefaults, bClearSame,
1583 pRefFormatScript
1584 ? &pRefFormatScript->GetAttrSet()
1585 : nullptr );
1587 if( !bCharFormat )
1589 const SvxULSpaceItem& rULItem = pRefFormat->GetULSpace();
1590 rHTMLWrt.m_nDfltTopMargin = rULItem.GetUpper();
1591 rHTMLWrt.m_nDfltBottomMargin = rULItem.GetLower();
1594 else if( CSS1_FMT_ISTAG==nDeep && !bCharFormat )
1596 // set Default-distance above and below (for the
1597 // case that there is no reference template)
1598 rHTMLWrt.m_nDfltTopMargin = 0;
1599 rHTMLWrt.m_nDfltBottomMargin = HTML_PARSPACE;
1600 if( USER_FMT & nPoolFormatId )
1602 // user templates
1603 const OUString& aNm(rFormat.GetName());
1605 if (aNm == "DD 1" || aNm == "DT 1")
1606 rHTMLWrt.m_nDfltBottomMargin = 0;
1607 else if (aNm == OOO_STRING_SVTOOLS_HTML_listing)
1608 rHTMLWrt.m_nDfltBottomMargin = 0;
1609 else if (aNm == OOO_STRING_SVTOOLS_HTML_preformtxt)
1610 rHTMLWrt.m_nDfltBottomMargin = 0;
1611 else if (aNm == OOO_STRING_SVTOOLS_HTML_xmp)
1612 rHTMLWrt.m_nDfltBottomMargin = 0;
1614 else
1616 // Pool templates
1617 switch( nPoolFormatId )
1619 case RES_POOLCOLL_HEADLINE1:
1620 case RES_POOLCOLL_HEADLINE2:
1621 case RES_POOLCOLL_HEADLINE3:
1622 case RES_POOLCOLL_HEADLINE4:
1623 case RES_POOLCOLL_HEADLINE5:
1624 case RES_POOLCOLL_HEADLINE6:
1625 rHTMLWrt.m_nDfltTopMargin = HTML_HEADSPACE;
1626 break;
1627 case RES_POOLCOLL_SENDADRESS:
1628 case RES_POOLCOLL_HTML_DT:
1629 case RES_POOLCOLL_HTML_DD:
1630 case RES_POOLCOLL_HTML_PRE:
1631 rHTMLWrt.m_nDfltBottomMargin = 0;
1632 break;
1637 // if nothing is to be exported ...
1638 if( !aItemSet.Count() )
1639 return rWrt;
1641 // There is no support for script dependent hyperlinks by now.
1642 bool bCheckForPseudo = false;
1643 if( bCharFormat &&
1644 (RES_POOLCHR_INET_NORMAL==nRefPoolId ||
1645 RES_POOLCHR_INET_VISIT==nRefPoolId) )
1646 bCheckForPseudo = true;
1648 // export now the Attributes (incl. Selektor)
1649 bool bHasScriptDependencies = false;
1650 if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, CSS1_FMT_ISTAG != nDeep,
1651 bCheckForPseudo ) )
1653 if( bCharFormat )
1654 rHTMLWrt.m_aScriptTextStyles.insert( rFormat.GetName() );
1655 else
1657 if( nPoolFormatId==RES_POOLCOLL_TEXT )
1658 rHTMLWrt.m_aScriptParaStyles.insert( pDoc->GetTextCollFromPool( RES_POOLCOLL_STANDARD, false )->GetName() );
1659 rHTMLWrt.m_aScriptParaStyles.insert( rFormat.GetName() );
1661 bHasScriptDependencies = true;
1664 if( nPoolFormatId==RES_POOLCOLL_TEXT && !rHTMLWrt.m_bFirstCSS1Property )
1665 rHTMLWrt.m_bPoolCollTextModified = true;
1667 // export Drop-Caps
1668 const SfxPoolItem *pItem;
1669 if( SfxItemState::SET==aItemSet.GetItemState( RES_PARATR_DROP, false, &pItem ))
1671 OUString sOut( aSelector );
1672 sOut += ":" + OStringToOUString( sCSS1_first_letter, RTL_TEXTENCODING_ASCII_US );
1673 const SwFormatDrop *pDrop = static_cast<const SwFormatDrop *>(pItem);
1674 OutCSS1DropCapRule( rHTMLWrt, sOut, *pDrop, CSS1_FMT_ISTAG != nDeep, bHasScriptDependencies );
1677 return rWrt;
1680 static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rPageDesc,
1681 IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate,
1682 sal_uInt16 nRefPoolId, bool bExtRef,
1683 bool bPseudo )
1685 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1687 const SwPageDesc* pRefPageDesc = nullptr;
1688 if( !bExtRef )
1689 pRefPageDesc = pDoc->GetPageDescFromPool( nRefPoolId, false );
1690 else if( pTemplate )
1691 pRefPageDesc = pTemplate->getIDocumentStylePoolAccess().GetPageDescFromPool( nRefPoolId, false );
1693 OUString aSelector = "@" + OStringToOUString( sCSS1_page, RTL_TEXTENCODING_ASCII_US );
1695 if( bPseudo )
1697 const sal_Char *pPseudo = nullptr;
1698 switch( rPageDesc.GetPoolFormatId() )
1700 case RES_POOLPAGE_FIRST: pPseudo = sCSS1_first; break;
1701 case RES_POOLPAGE_LEFT: pPseudo = sCSS1_left; break;
1702 case RES_POOLPAGE_RIGHT: pPseudo = sCSS1_right; break;
1704 if( pPseudo )
1705 aSelector += ":" + OStringToOUString( pPseudo, RTL_TEXTENCODING_ASCII_US );
1708 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE_ON|CSS1_OUTMODE_TEMPLATE,
1709 &aSelector );
1711 // Size: If the only difference is the Landscape-Flag,
1712 // only export Portrait oder Landscape. Otherwise export size.
1713 bool bRefLandscape = pRefPageDesc && pRefPageDesc->GetLandscape();
1714 Size aRefSz;
1715 const Size& rSz = rPageDesc.GetMaster().GetFrameSize().GetSize();
1716 if( pRefPageDesc )
1718 aRefSz = pRefPageDesc->GetMaster().GetFrameSize().GetSize();
1719 if( bRefLandscape != rPageDesc.GetLandscape() )
1721 long nTmp = aRefSz.Height();
1722 aRefSz.Height() = aRefSz.Width();
1723 aRefSz.Width() = nTmp;
1727 // TODO: Bad Hack: On the Page-Tabpage there are small rounding errors
1728 // for the page size. Partially because of bug 25535, we stupidly still
1729 // use the Size-Item from Dialog, even if nothing changed.
1730 // Thus: once one visited the Page-Dialog and left it with OK, we get a
1731 // new page size that then gets exported here. To avoid that, we allow
1732 // here small deviations.
1733 if( std::abs( rSz.Width() - aRefSz.Width() ) <= 2 &&
1734 std::abs( rSz.Height() - aRefSz.Height() ) <= 2 )
1736 if( bRefLandscape != rPageDesc.GetLandscape() )
1738 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size,
1739 rPageDesc.GetLandscape() ? sCSS1_PV_landscape
1740 : sCSS1_PV_portrait );
1743 else
1745 OStringBuffer sVal;
1746 AddUnitPropertyValue(sVal, rSz.Width(), rHTMLWrt.GetCSS1Unit());
1747 sVal.append(' ');
1748 AddUnitPropertyValue(sVal, rSz.Height(), rHTMLWrt.GetCSS1Unit());
1749 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_size, sVal.makeStringAndClear());
1752 // Export the distance-Attributes as normally
1753 const SwFrameFormat &rMaster = rPageDesc.GetMaster();
1754 SfxItemSet aItemSet( *rMaster.GetAttrSet().GetPool(),
1755 RES_LR_SPACE, RES_UL_SPACE );
1756 aItemSet.Set( rMaster.GetAttrSet() );
1758 if( pRefPageDesc )
1760 SwHTMLWriter::SubtractItemSet( aItemSet,
1761 pRefPageDesc->GetMaster().GetAttrSet(),
1762 true );
1765 OutCSS1_SvxULSpace_SvxLRSpace( rWrt, aItemSet, false );
1767 // If for a Pseudo-Selector no Property had been set, we still
1768 // have to export something, so that the corresponding template is
1769 // created on the next import.
1770 if( rHTMLWrt.m_bFirstCSS1Property && bPseudo )
1772 rHTMLWrt.OutNewLine();
1773 OString sTmp(OUStringToOString(aSelector, rHTMLWrt.m_eDestEnc));
1774 rWrt.Strm().WriteCharPtr( sTmp.getStr() ).WriteCharPtr( " {" );
1775 rHTMLWrt.m_bFirstCSS1Property = false;
1778 if( !rHTMLWrt.m_bFirstCSS1Property )
1779 rWrt.Strm().WriteCharPtr( sCSS1_rule_end );
1781 return rWrt;
1784 static Writer& OutCSS1_SwFootnoteInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
1785 SwDoc *pDoc, bool bHasNotes, bool bEndNote )
1787 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1789 OUString aSelector;
1791 if( bHasNotes )
1793 aSelector = OOO_STRING_SVTOOLS_HTML_anchor "." +
1794 ( bEndNote ? OUString(OOO_STRING_SVTOOLS_HTML_sdendnote_anc)
1795 : OUString(OOO_STRING_SVTOOLS_HTML_sdfootnote_anc) );
1796 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1797 &aSelector );
1798 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size,
1799 sHTML_FTN_fontheight );
1800 rHTMLWrt.Strm().WriteCharPtr( sCSS1_rule_end );
1803 const SwCharFormat *pSymCharFormat = rInfo.GetCharFormat( *pDoc );
1804 if( pSymCharFormat )
1806 const SfxItemSet& rFormatItemSet = pSymCharFormat->GetAttrSet();
1807 SfxItemSet aItemSet( *rFormatItemSet.GetPool(), rFormatItemSet.GetRanges() );
1808 aItemSet.Set( rFormatItemSet );
1810 // If there are footnotes or endnotes, then all Attributes have to be
1811 // exported, so that Netscape displays the document correctly.
1812 // Otherwise it is sufficient, to export the differences to the
1813 // footnote and endnote template.
1814 if( !bHasNotes && rHTMLWrt.m_pTemplate )
1816 SwFormat *pRefFormat = rHTMLWrt.m_pTemplate->getIDocumentStylePoolAccess().GetCharFormatFromPool(
1817 static_cast< sal_uInt16 >(bEndNote ? RES_POOLCHR_ENDNOTE : RES_POOLCHR_FOOTNOTE) );
1818 if( pRefFormat )
1819 SwHTMLWriter::SubtractItemSet( aItemSet, pRefFormat->GetAttrSet(),
1820 true );
1822 if( aItemSet.Count() )
1824 aSelector = OOO_STRING_SVTOOLS_HTML_anchor "." +
1825 ( bEndNote ? OUString(OOO_STRING_SVTOOLS_HTML_sdendnote_sym)
1826 : OUString(OOO_STRING_SVTOOLS_HTML_sdfootnote_sym));
1827 if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, true, false ))
1828 rHTMLWrt.m_aScriptTextStyles.insert( pSymCharFormat->GetName() );
1832 return rWrt;
1835 Writer& OutCSS1_BodyTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet,
1836 const OUString& rEmbeddedGraphicName )
1838 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1840 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
1841 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_BODY, nullptr );
1843 // Only export the attributes of the page template.
1844 // The attributes of the default paragraph template were
1845 // considered already when exporting the paragraph template.
1847 const SfxPoolItem *pItem;
1848 if( SfxItemState::SET == rItemSet.GetItemState( RES_BACKGROUND, false,
1849 &pItem ) )
1851 OutCSS1_SvxBrush( rWrt, *pItem, CSS1_BACKGROUND_PAGE, &rEmbeddedGraphicName );
1854 if( SfxItemState::SET == rItemSet.GetItemState( RES_BOX, false,
1855 &pItem ))
1857 OutCSS1_SvxBox( rWrt, *pItem );
1860 if( !rHTMLWrt.m_bFirstCSS1Property )
1862 // if a Property was exported as part of a Style-Option,
1863 // the Option still needs to be finished
1864 rWrt.Strm().WriteChar( '\"' );
1867 return rWrt;
1870 Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet )
1872 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1874 SwCSS1OutMode aMode( rHTMLWrt, rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_STYLE_OPT |
1875 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA, nullptr );
1876 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false );
1878 return rWrt;
1881 Writer& OutCSS1_HintSpanTag( Writer& rWrt, const SfxPoolItem& rHt )
1883 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1885 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_SPAN_TAG |
1886 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_HINT, nullptr );
1888 Out( aCSS1AttrFnTab, rHt, rWrt );
1890 if( !rHTMLWrt.m_bFirstCSS1Property && rHTMLWrt.m_bTagOn )
1891 rWrt.Strm().WriteCharPtr( sCSS1_span_tag_end );
1893 return rWrt;
1896 Writer& OutCSS1_HintStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
1898 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1900 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
1901 CSS1_OUTMODE_ENCODE|
1902 CSS1_OUTMODE_HINT, nullptr );
1904 Out( aCSS1AttrFnTab, rHt, rWrt );
1906 if( !rHTMLWrt.m_bFirstCSS1Property )
1907 rWrt.Strm().WriteChar( '\"' );
1909 return rWrt;
1912 // Wrapper for Table background
1913 Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
1915 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1917 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
1918 CSS1_OUTMODE_ENCODE|
1919 CSS1_OUTMODE_TABLEBOX, nullptr );
1920 OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_TABLE, nullptr );
1922 if( !rHTMLWrt.m_bFirstCSS1Property )
1923 rWrt.Strm().WriteChar( '\"' );
1925 return rWrt;
1928 Writer& OutCSS1_NumBulListStyleOpt( Writer& rWrt, const SwNumRule& rNumRule,
1929 sal_uInt8 nLevel )
1931 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1933 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT |
1934 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA, nullptr );
1936 const SwNumFormat& rNumFormat = rNumRule.Get( nLevel );
1938 long nLSpace = rNumFormat.GetAbsLSpace();
1939 long nFirstLineOffset = rNumFormat.GetFirstLineOffset();
1940 long nDfltFirstLineOffset = HTML_NUMBUL_INDENT;
1941 if( nLevel > 0 )
1943 const SwNumFormat& rPrevNumFormat = rNumRule.Get( nLevel-1 );
1944 nLSpace -= rPrevNumFormat.GetAbsLSpace();
1945 nDfltFirstLineOffset = rPrevNumFormat.GetFirstLineOffset();
1948 if( rHTMLWrt.IsHTMLMode(HTMLMODE_LSPACE_IN_NUMBUL) &&
1949 nLSpace != HTML_NUMBUL_MARGINLEFT )
1950 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLSpace );
1952 if( rHTMLWrt.IsHTMLMode(HTMLMODE_FRSTLINE_IN_NUMBUL) &&
1953 nFirstLineOffset != nDfltFirstLineOffset )
1954 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent, nFirstLineOffset );
1956 if( !rHTMLWrt.m_bFirstCSS1Property )
1957 rWrt.Strm().WriteChar( '\"' );
1959 return rWrt;
1962 void SwHTMLWriter::OutCSS1_FrameFormatOptions( const SwFrameFormat& rFrameFormat,
1963 sal_uInt32 nFrameOpts,
1964 const SdrObject *pSdrObj,
1965 const SfxItemSet *pItemSet )
1967 SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
1968 CSS1_OUTMODE_ENCODE|
1969 CSS1_OUTMODE_FRAME, nullptr );
1971 const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient();
1972 SvxLRSpaceItem aLRItem( rFrameFormat.GetLRSpace() );
1973 SvxULSpaceItem aULItem( rFrameFormat.GetULSpace() );
1974 if( nFrameOpts & HTML_FRMOPT_S_ALIGN )
1976 const SwFormatAnchor& rAnchor = rFrameFormat.GetAnchor();
1977 switch( rAnchor.GetAnchorId() )
1979 case FLY_AT_PARA:
1980 case FLY_AT_CHAR:
1981 if( text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
1982 text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
1984 if( !(nFrameOpts & HTML_FRMOPT_ALIGN) )
1986 // float
1987 const sal_Char *pStr = text::HoriOrientation::RIGHT==rHoriOri.GetHoriOrient()
1988 ? sCSS1_PV_right
1989 : sCSS1_PV_left;
1990 OutCSS1_PropertyAscii( sCSS1_P_float, pStr );
1992 break;
1994 SAL_FALLTHROUGH;
1996 case FLY_AT_PAGE:
1997 case FLY_AT_FLY:
1999 // position
2000 OutCSS1_PropertyAscii( sCSS1_P_position, sCSS1_PV_absolute );
2002 // For top/left we need to subtract the distance to the frame
2003 // from the position, as in CSS1 it is added to the position.
2004 // This works also for automatically aligned frames, even that
2005 // in this case Writer also adds the distance; because in this
2006 // case the Orient-Attribute contains the correct position.
2008 // top
2009 long nXPos=0, nYPos=0;
2010 bool bOutXPos = false, bOutYPos = false;
2011 if( RES_DRAWFRMFMT == rFrameFormat.Which() )
2013 OSL_ENSURE( pSdrObj, "Do not pass a SdrObject. Inefficient" );
2014 if( !pSdrObj )
2015 pSdrObj = rFrameFormat.FindSdrObject();
2016 OSL_ENSURE( pSdrObj, "Where is the SdrObject" );
2017 if( pSdrObj )
2019 Point aPos( pSdrObj->GetRelativePos() );
2020 nXPos = aPos.A();
2021 nYPos = aPos.B();
2023 bOutXPos = bOutYPos = true;
2025 else
2027 bOutXPos = text::RelOrientation::CHAR != rHoriOri.GetRelationOrient();
2028 nXPos = text::HoriOrientation::NONE == rHoriOri.GetHoriOrient()
2029 ? rHoriOri.GetPos() : 0;
2031 const SwFormatVertOrient& rVertOri = rFrameFormat.GetVertOrient();
2032 bOutYPos = text::RelOrientation::CHAR != rVertOri.GetRelationOrient();
2033 nYPos = text::VertOrientation::NONE == rVertOri.GetVertOrient()
2034 ? rVertOri.GetPos() : 0;
2037 if( bOutYPos )
2039 if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
2041 nYPos -= aULItem.GetUpper();
2042 if( nYPos < 0 )
2044 aULItem.SetUpper( (sal_uInt16)(aULItem.GetUpper() + nYPos) );
2045 nYPos = 0;
2049 OutCSS1_UnitProperty( sCSS1_P_top, nYPos );
2052 if( bOutXPos )
2054 // left
2055 if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
2057 nXPos -= aLRItem.GetLeft();
2058 if( nXPos < 0 )
2060 aLRItem.SetLeft( (sal_uInt16)(aLRItem.GetLeft() + nXPos) );
2061 nXPos = 0;
2065 OutCSS1_UnitProperty( sCSS1_P_left, nXPos );
2068 break;
2070 default:
2075 // width/height
2076 if( nFrameOpts & HTML_FRMOPT_S_SIZE )
2078 if( RES_DRAWFRMFMT == rFrameFormat.Which() )
2080 OSL_ENSURE( pSdrObj, "Do not pass a SdrObject. Inefficient" );
2081 if( !pSdrObj )
2082 pSdrObj = rFrameFormat.FindSdrObject();
2083 OSL_ENSURE( pSdrObj, "Where is the SdrObject" );
2084 if( pSdrObj )
2086 Size aTwipSz( pSdrObj->GetLogicRect().GetSize() );
2087 if( nFrameOpts & HTML_FRMOPT_S_WIDTH )
2089 if( nFrameOpts & HTML_FRMOPT_S_PIXSIZE )
2090 OutCSS1_PixelProperty( sCSS1_P_width, aTwipSz.Width(),
2091 false );
2092 else
2093 OutCSS1_UnitProperty( sCSS1_P_width, aTwipSz.Width() );
2095 if( nFrameOpts & HTML_FRMOPT_S_HEIGHT )
2097 if( nFrameOpts & HTML_FRMOPT_S_PIXSIZE )
2098 OutCSS1_PixelProperty( sCSS1_P_height, aTwipSz.Height(),
2099 true );
2100 else
2101 OutCSS1_UnitProperty( sCSS1_P_height, aTwipSz.Height() );
2105 else
2107 OSL_ENSURE( HTML_FRMOPT_ABSSIZE & nFrameOpts,
2108 "Export absolute size" );
2109 OSL_ENSURE( HTML_FRMOPT_ANYSIZE & nFrameOpts,
2110 "Export every size" );
2111 sal_uInt16 nMode = 0;
2112 if( nFrameOpts & HTML_FRMOPT_S_WIDTH )
2113 nMode |= CSS1_FRMSIZE_WIDTH;
2114 if( nFrameOpts & HTML_FRMOPT_S_HEIGHT )
2115 nMode |= (CSS1_FRMSIZE_MINHEIGHT|CSS1_FRMSIZE_FIXHEIGHT);
2116 if( nFrameOpts & HTML_FRMOPT_S_PIXSIZE )
2117 nMode |= CSS1_FRMSIZE_PIXEL;
2119 OutCSS1_SwFormatFrameSize( *this, rFrameFormat.GetFrameSize(), nMode );
2123 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
2124 // margin-*
2125 if( (nFrameOpts & HTML_FRMOPT_S_SPACE) &&
2126 IsHTMLMode( HTMLMODE_FLY_MARGINS) )
2128 const SvxLRSpaceItem *pLRItem = nullptr;
2129 const SvxULSpaceItem *pULItem = nullptr;
2130 if( SfxItemState::SET == rItemSet.GetItemState( RES_LR_SPACE ) )
2131 pLRItem = &aLRItem;
2132 if( SfxItemState::SET == rItemSet.GetItemState( RES_UL_SPACE ) )
2133 pULItem = &aULItem;
2134 if( pLRItem || pULItem )
2135 OutCSS1_SvxULSpace_SvxLRSpace( *this, pULItem, pLRItem );
2138 // border
2139 if( nFrameOpts & HTML_FRMOPT_S_BORDER )
2141 const SfxPoolItem* pItem;
2142 if( nFrameOpts & HTML_FRMOPT_S_NOBORDER )
2143 OutCSS1_SvxBox( *this, rFrameFormat.GetBox() );
2144 else if( SfxItemState::SET==rItemSet.GetItemState( RES_BOX, true, &pItem ) )
2145 OutCSS1_SvxBox( *this, *pItem );
2148 // background (if, then the color must be set also)
2149 if( nFrameOpts & HTML_FRMOPT_S_BACKGROUND )
2150 OutCSS1_FrameFormatBackground( rFrameFormat );
2152 if( pItemSet )
2153 OutCSS1_SfxItemSet( *pItemSet, false );
2155 if( !m_bFirstCSS1Property )
2156 Strm().WriteChar( '\"' );
2159 void SwHTMLWriter::OutCSS1_TableFrameFormatOptions( const SwFrameFormat& rFrameFormat )
2161 SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
2162 CSS1_OUTMODE_ENCODE|
2163 CSS1_OUTMODE_TABLE, nullptr );
2165 const SfxPoolItem *pItem;
2166 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
2167 if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
2168 OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_TABLE, nullptr );
2170 if( IsHTMLMode( HTMLMODE_PRINT_EXT ) )
2171 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet, false );
2173 if( SfxItemState::SET==rItemSet.GetItemState( RES_LAYOUT_SPLIT, false, &pItem ) )
2174 OutCSS1_SwFormatLayoutSplit( *this, *pItem );
2176 if( !m_bFirstCSS1Property )
2177 Strm().WriteChar( '\"' );
2180 void SwHTMLWriter::OutCSS1_TableCellBorderHack(SwFrameFormat const& rFrameFormat)
2182 SwCSS1OutMode const aMode( *this,
2183 CSS1_OUTMODE_STYLE_OPT_ON|CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_TABLEBOX, nullptr );
2184 OutCSS1_SvxBox(*this, rFrameFormat.GetBox());
2185 if (!m_bFirstCSS1Property)
2187 this->Strm().WriteChar( cCSS1_style_opt_end );
2191 void SwHTMLWriter::OutCSS1_SectionFormatOptions( const SwFrameFormat& rFrameFormat, const SwFormatCol *pCol )
2193 SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
2194 CSS1_OUTMODE_ENCODE|
2195 CSS1_OUTMODE_SECTION, nullptr );
2197 const SfxPoolItem *pItem;
2198 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
2199 if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
2200 OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_SECTION, nullptr );
2202 if (pCol)
2204 OString sColumnCount(OString::number(static_cast<sal_Int32>(pCol->GetNumCols())));
2205 OutCSS1_PropertyAscii(sCSS1_P_column_count, sColumnCount);
2208 if( !m_bFirstCSS1Property )
2209 Strm().WriteChar( '\"' );
2212 static bool OutCSS1_FrameFormatBrush( SwHTMLWriter& rWrt,
2213 const SvxBrushItem& rBrushItem )
2215 bool bWritten = false;
2216 /// output brush of frame format, if its background color is not "no fill"/"auto fill"
2217 /// or it has a background graphic.
2218 if( rBrushItem.GetColor() != COL_TRANSPARENT ||
2219 !rBrushItem.GetGraphicLink().isEmpty() ||
2220 0 != rBrushItem.GetGraphicPos() )
2222 OutCSS1_SvxBrush( rWrt, rBrushItem, CSS1_BACKGROUND_FLY, nullptr );
2223 bWritten = true;
2225 return bWritten;
2228 void SwHTMLWriter::OutCSS1_FrameFormatBackground( const SwFrameFormat& rFrameFormat )
2230 // If the frame itself has a background, then export.
2231 if( OutCSS1_FrameFormatBrush( *this, rFrameFormat.makeBackgroundBrushItem() ) )
2232 return;
2234 // If the frame is not linked to a page, we use the background of the anchor.
2235 const SwFormatAnchor& rAnchor = rFrameFormat.GetAnchor();
2236 RndStdIds eAnchorId = rAnchor.GetAnchorId();
2237 const SwPosition *pAnchorPos = rAnchor.GetContentAnchor();
2238 if (FLY_AT_PAGE != eAnchorId && pAnchorPos)
2240 const SwNode& rNode = pAnchorPos->nNode.GetNode();
2241 if( rNode.IsContentNode() )
2243 // If the frame is linked to a content-node,
2244 // we take the background of the content-node, if it has one.
2245 if( OutCSS1_FrameFormatBrush( *this,
2246 rNode.GetContentNode()->GetSwAttrSet().GetBackground()) )
2247 return;
2249 // Otherwise we also could be in a table
2250 const SwTableNode *pTableNd = rNode.FindTableNode();
2251 if( pTableNd )
2253 const SwStartNode *pBoxSttNd = rNode.FindTableBoxStartNode();
2254 const SwTableBox *pBox =
2255 pTableNd->GetTable().GetTableBox( pBoxSttNd->GetIndex() );
2257 // If the box has a background, we take it.
2258 if( OutCSS1_FrameFormatBrush( *this,
2259 pBox->GetFrameFormat()->makeBackgroundBrushItem() ) )
2260 return;
2262 // Otherwise we use that of the lines
2263 const SwTableLine *pLine = pBox->GetUpper();
2264 while( pLine )
2266 if( OutCSS1_FrameFormatBrush( *this,
2267 pLine->GetFrameFormat()->makeBackgroundBrushItem() ) )
2268 return;
2269 pBox = pLine->GetUpper();
2270 pLine = pBox ? pBox->GetUpper() : nullptr;
2273 // If there was none either, we use the background of the table.
2274 if( OutCSS1_FrameFormatBrush( *this,
2275 pTableNd->GetTable().GetFrameFormat()->makeBackgroundBrushItem() ) )
2276 return;
2281 // If the anchor is again in a Fly-Frame, use the background of the Fly-Frame.
2282 const SwFrameFormat *pFrameFormat = rNode.GetFlyFormat();
2283 if( pFrameFormat )
2285 OutCSS1_FrameFormatBackground( *pFrameFormat );
2286 return;
2290 // At last there is the background of the page, and as the final rescue
2291 // the value of the Config.
2292 OSL_ENSURE( m_pCurrPageDesc, "no page template found" );
2293 if( !OutCSS1_FrameFormatBrush( *this,
2294 m_pCurrPageDesc->GetMaster().makeBackgroundBrushItem() ) )
2296 Color aColor( COL_WHITE );
2298 // The background color is normally only used in Browse-Mode.
2299 // We always use it for a HTML document, but for a text document
2300 // only if viewed in Browse-Mode.
2301 if( pDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) ||
2302 pDoc->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE))
2304 SwViewShell *pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2305 if ( pVSh &&
2306 COL_TRANSPARENT != pVSh->GetViewOptions()->GetRetoucheColor().GetColor())
2307 aColor = pVSh->GetViewOptions()->GetRetoucheColor().GetColor();
2310 OutCSS1_PropertyAscii(sCSS1_P_background, lclGetCSS1Color(aColor));
2314 static Writer& OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( Writer& rWrt,
2315 const SvxUnderlineItem *pUItem,
2316 const SvxOverlineItem *pOItem,
2317 const SvxCrossedOutItem *pCOItem,
2318 const SvxBlinkItem *pBItem )
2320 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2321 bool bNone = false;
2323 const sal_Char *pUStr = nullptr;
2324 if( pUItem )
2326 switch( pUItem->GetLineStyle() )
2328 case LINESTYLE_NONE:
2329 bNone = true;
2330 break;
2331 case LINESTYLE_DONTKNOW:
2332 break;
2333 default:
2334 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2336 // this also works in HTML does not need to be written as
2337 // a STYLE-Options, and must not be written as Hint
2338 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2339 "write underline as Hint?" );
2340 pUStr = sCSS1_PV_underline;
2342 break;
2346 const sal_Char *pOStr = nullptr;
2347 if( pOItem )
2349 switch( pOItem->GetLineStyle() )
2351 case LINESTYLE_NONE:
2352 bNone = true;
2353 break;
2354 case LINESTYLE_DONTKNOW:
2355 break;
2356 default:
2357 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2359 // this also works in HTML does not need to be written as
2360 // a STYLE-Options, and must not be written as Hint
2361 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2362 "write overline as Hint?" );
2363 pOStr = sCSS1_PV_overline;
2365 break;
2369 const sal_Char *pCOStr = nullptr;
2370 if( pCOItem )
2372 switch( pCOItem->GetStrikeout() )
2374 case STRIKEOUT_NONE:
2375 bNone = true;
2376 break;
2377 case STRIKEOUT_DONTKNOW:
2378 break;
2379 default:
2380 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2382 // this also works in HTML does not need to be written as
2383 // a STYLE-Options, and must not be written as Hint
2384 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2385 "write crossedOut as Hint?" );
2386 pCOStr = sCSS1_PV_line_through;
2388 break;
2392 const sal_Char *pBStr = nullptr;
2393 if( pBItem )
2395 if( !pBItem->GetValue() )
2397 bNone = true;
2399 else if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2401 // this also works in HTML does not need to be written as
2402 // a STYLE-Options, and must not be written as Hint
2403 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2404 "write blink as Hint?" );
2405 pBStr = sCSS1_PV_blink;
2409 OStringBuffer sOut;
2410 if( pUStr )
2411 sOut.append(pUStr);
2413 if( pOStr )
2415 if (!sOut.isEmpty())
2416 sOut.append(' ');
2417 sOut.append(pOStr);
2420 if( pCOStr )
2422 if (!sOut.isEmpty())
2423 sOut.append(' ');
2424 sOut.append(pCOStr);
2427 if( pBStr )
2429 if (!sOut.isEmpty())
2430 sOut.append(' ');
2431 sOut.append(pBStr);
2434 if (!sOut.isEmpty())
2435 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sOut.makeStringAndClear() );
2436 else if( bNone )
2437 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sCSS1_PV_none );
2439 return rWrt;
2442 static Writer& OutCSS1_SvxCaseMap( Writer& rWrt, const SfxPoolItem& rHt )
2444 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2446 switch( static_cast<const SvxCaseMapItem&>(rHt).GetCaseMap() )
2448 case SVX_CASEMAP_NOT_MAPPED:
2449 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, sCSS1_PV_normal );
2450 break;
2451 case SVX_CASEMAP_KAPITAELCHEN:
2452 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, sCSS1_PV_small_caps );
2453 break;
2454 case SVX_CASEMAP_VERSALIEN:
2455 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_uppercase );
2456 break;
2457 case SVX_CASEMAP_GEMEINE:
2458 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_lowercase );
2459 break;
2460 case SVX_CASEMAP_TITEL:
2461 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_capitalize );
2462 break;
2463 default:
2467 return rWrt;
2470 static Writer& OutCSS1_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
2472 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2474 // Colors do not need to be exported for Style-Option.
2475 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
2476 !rHTMLWrt.m_bCfgPreferStyles )
2477 return rWrt;
2478 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2479 "write color as Hint?" );
2481 Color aColor( static_cast<const SvxColorItem&>(rHt).GetValue() );
2482 if( COL_AUTO == aColor.GetColor() )
2483 aColor.SetColor( COL_BLACK );
2485 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_color, lclGetCSS1Color(aColor));
2487 return rWrt;
2490 static Writer& OutCSS1_SvxCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
2492 // This function only exports Hints!
2493 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2495 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2496 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt,
2497 nullptr, nullptr, static_cast<const SvxCrossedOutItem *>(&rHt), nullptr );
2499 return rWrt;
2502 static Writer& OutCSS1_SvxFont( Writer& rWrt, const SfxPoolItem& rHt )
2504 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2506 // No need to export Fonts for the Style-Option.
2507 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2508 return rWrt;
2510 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2511 switch( rHt.Which() )
2513 case RES_CHRATR_CJK_FONT: nScript = CSS1_OUTMODE_CJK; break;
2514 case RES_CHRATR_CTL_FONT: nScript = CSS1_OUTMODE_CTL; break;
2516 if( !rHTMLWrt.IsCSS1Script( nScript ) )
2517 return rWrt;
2519 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2520 "write Font as Hint?" );
2522 OUString sOut;
2523 // MS IE3b1 has problems with single quotes
2524 sal_uInt16 nMode = rHTMLWrt.m_nCSS1OutMode & CSS1_OUTMODE_ANY_ON;
2525 sal_Unicode cQuote = nMode == CSS1_OUTMODE_RULE_ON ? '\"' : '\'';
2526 SwHTMLWriter::PrepareFontList( static_cast<const SvxFontItem&>(rHt), sOut, cQuote,
2527 true );
2529 rHTMLWrt.OutCSS1_Property( sCSS1_P_font_family, sOut );
2531 return rWrt;
2534 static Writer& OutCSS1_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt )
2536 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2538 // Font-Height need not be exported in the Style-Option.
2539 // For Drop-Caps another Font-Size is exported.
2540 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
2541 rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_DROPCAP ) )
2542 return rWrt;
2544 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2545 switch( rHt.Which() )
2547 case RES_CHRATR_CJK_FONTSIZE: nScript = CSS1_OUTMODE_CJK; break;
2548 case RES_CHRATR_CTL_FONTSIZE: nScript = CSS1_OUTMODE_CTL; break;
2550 if( !rHTMLWrt.IsCSS1Script( nScript ) )
2551 return rWrt;
2553 sal_uInt32 nHeight = static_cast<const SvxFontHeightItem&>(rHt).GetHeight();
2554 OString sHeight(OString::number(nHeight/20) + OString(sCSS1_UNIT_pt));
2555 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_font_size, sHeight);
2557 return rWrt;
2560 static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt )
2562 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2564 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2565 switch( rHt.Which() )
2567 case RES_CHRATR_CJK_POSTURE: nScript = CSS1_OUTMODE_CJK; break;
2568 case RES_CHRATR_CTL_POSTURE: nScript = CSS1_OUTMODE_CTL; break;
2570 if( !rHTMLWrt.IsCSS1Script( nScript ) )
2571 return rWrt;
2573 const sal_Char *pStr = nullptr;
2574 switch( static_cast<const SvxPostureItem&>(rHt).GetPosture() )
2576 case ITALIC_NONE: pStr = sCSS1_PV_normal; break;
2577 case ITALIC_OBLIQUE: pStr = sCSS1_PV_oblique; break;
2578 case ITALIC_NORMAL:
2579 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2581 // this also works in HTML does not need to be written as
2582 // a STYLE-Options, and must not be written as Hint
2583 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2584 "write italic as Hint?" );
2585 pStr = sCSS1_PV_italic;
2587 break;
2588 default:
2592 if( pStr )
2593 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_style, pStr );
2595 return rWrt;
2598 static Writer& OutCSS1_SvxKerning( Writer& rWrt, const SfxPoolItem& rHt )
2600 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2602 sal_Int16 nValue = static_cast<const SvxKerningItem&>(rHt).GetValue();
2603 if( nValue )
2605 OStringBuffer sOut;
2606 if( nValue < 0 )
2608 sOut.append('-');
2609 nValue = -nValue;
2612 // Width as n.n pt
2613 nValue = (nValue + 1) / 2; // 1/10pt
2614 sOut.append(OString::number(nValue / 10) + "." + OString::number(nValue % 10) +
2615 OString(sCSS1_UNIT_pt));
2617 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_letter_spacing,
2618 sOut.makeStringAndClear());
2620 else
2622 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing,
2623 sCSS1_PV_normal );
2626 return rWrt;
2629 static Writer& OutCSS1_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt )
2631 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2633 // Only export Language rules
2634 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2635 return rWrt;
2637 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2638 switch( rHt.Which() )
2640 case RES_CHRATR_CJK_LANGUAGE: nScript = CSS1_OUTMODE_CJK; break;
2641 case RES_CHRATR_CTL_LANGUAGE: nScript = CSS1_OUTMODE_CTL; break;
2643 if( !rHTMLWrt.IsCSS1Script( nScript ) )
2644 return rWrt;
2646 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2647 "write Language as Hint?" );
2649 LanguageType eLang = static_cast<const SvxLanguageItem &>(rHt).GetLanguage();
2650 if( LANGUAGE_DONTKNOW == eLang )
2651 return rWrt;
2653 OUString sOut = LanguageTag::convertToBcp47( eLang );
2655 rHTMLWrt.OutCSS1_Property( sCSS1_P_so_language, sOut );
2657 return rWrt;
2660 static Writer& OutCSS1_SvxUnderline( Writer& rWrt, const SfxPoolItem& rHt )
2662 // This function only exports Hints!
2663 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2665 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2666 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt,
2667 static_cast<const SvxUnderlineItem *>(&rHt), nullptr, nullptr, nullptr );
2669 return rWrt;
2672 static Writer& OutCSS1_SvxOverline( Writer& rWrt, const SfxPoolItem& rHt )
2674 // This function only exports Hints!
2675 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2677 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2678 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt,
2679 nullptr, static_cast<const SvxOverlineItem *>(&rHt), nullptr, nullptr );
2681 return rWrt;
2684 static Writer& OutCSS1_SvxHidden( Writer& rWrt, const SfxPoolItem& rHt )
2686 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2688 if ( static_cast<const SvxCharHiddenItem&>(rHt).GetValue() )
2689 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_display, sCSS1_PV_none );
2691 return rWrt;
2694 static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt )
2696 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2698 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2699 switch( rHt.Which() )
2701 case RES_CHRATR_CJK_WEIGHT: nScript = CSS1_OUTMODE_CJK; break;
2702 case RES_CHRATR_CTL_WEIGHT: nScript = CSS1_OUTMODE_CTL; break;
2704 if( !rHTMLWrt.IsCSS1Script( nScript ) )
2705 return rWrt;
2707 const sal_Char *pStr = nullptr;
2708 switch( static_cast<const SvxWeightItem&>(rHt).GetWeight() )
2710 case WEIGHT_ULTRALIGHT: pStr = sCSS1_PV_extra_light; break;
2711 case WEIGHT_LIGHT: pStr = sCSS1_PV_light; break;
2712 case WEIGHT_SEMILIGHT: pStr = sCSS1_PV_demi_light; break;
2713 case WEIGHT_NORMAL: pStr = sCSS1_PV_normal; break;
2714 case WEIGHT_SEMIBOLD: pStr = sCSS1_PV_demi_bold; break;
2715 case WEIGHT_BOLD:
2716 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2718 // this also works in HTML does not need to be written as
2719 // a STYLE-Options, and must not be written as Hint
2720 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2721 "write bold as Hint?" );
2722 pStr = sCSS1_PV_bold;
2724 break;
2725 case WEIGHT_ULTRABOLD: pStr = sCSS1_PV_extra_bold; break;
2726 default:
2727 pStr = sCSS1_PV_normal;
2730 if( pStr )
2731 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_weight, pStr );
2733 return rWrt;
2736 static Writer& OutCSS1_SvxBlink( Writer& rWrt, const SfxPoolItem& rHt )
2738 // This function only exports Hints!
2739 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly.
2741 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2742 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt,
2743 nullptr, nullptr, nullptr, static_cast<const SvxBlinkItem *>(&rHt) );
2745 return rWrt;
2748 static Writer& OutCSS1_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt )
2750 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2752 // Netscape4 has big problems with cell heights if the line spacing is
2753 // changed within a table and the width of the table is not calculated
2754 // automatically (== if there is a WIDTH-Option)
2755 if( rHTMLWrt.m_bOutTable && rHTMLWrt.m_bCfgNetscape4 )
2756 return rWrt;
2758 const SvxLineSpacingItem& rLSItem = static_cast<const SvxLineSpacingItem&>(rHt);
2760 sal_uInt16 nHeight = 0;
2761 sal_uInt16 nPrcHeight = 0;
2762 SvxLineSpaceRule eLineSpace = rLSItem.GetLineSpaceRule();
2763 switch( rLSItem.GetInterLineSpaceRule() )
2765 case SvxInterLineSpaceRule::Off:
2766 case SvxInterLineSpaceRule::Fix:
2768 switch( eLineSpace )
2770 case SvxLineSpaceRule::Min:
2771 case SvxLineSpaceRule::Fix:
2772 nHeight = rLSItem.GetLineHeight();
2773 break;
2774 case SvxLineSpaceRule::Auto:
2775 nPrcHeight = 100;
2776 break;
2777 default:
2781 break;
2782 case SvxInterLineSpaceRule::Prop:
2783 nPrcHeight = rLSItem.GetPropLineSpace();
2784 break;
2786 default:
2790 if( nHeight )
2791 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_line_height, (long)nHeight );
2792 else if( nPrcHeight &&
2793 !(nPrcHeight < 115 && rHTMLWrt.m_bParaDotLeaders )) // avoid HTML scrollbars and missing descenders
2795 OString sHeight(OString::number(nPrcHeight) + "%");
2796 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_line_height, sHeight);
2799 return rWrt;
2802 static Writer& OutCSS1_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt )
2804 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2806 // Export Alignment in Style-Option only if the Tag does not allow ALIGN=xxx
2807 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
2808 !rHTMLWrt.m_bNoAlign)
2809 return rWrt;
2811 const sal_Char* pStr = nullptr;
2812 switch( static_cast<const SvxAdjustItem&>(rHt).GetAdjust() )
2814 case SVX_ADJUST_LEFT: pStr = sCSS1_PV_left; break;
2815 case SVX_ADJUST_RIGHT: pStr = sCSS1_PV_right; break;
2816 case SVX_ADJUST_BLOCK: pStr = sCSS1_PV_justify; break;
2817 case SVX_ADJUST_CENTER: pStr = sCSS1_PV_center; break;
2818 default:
2822 if( pStr )
2823 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_align, pStr );
2825 return rWrt;
2828 static Writer& OutCSS1_SvxFormatSplit( Writer& rWrt, const SfxPoolItem& rHt )
2830 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2832 const sal_Char *pStr = static_cast<const SvxFormatSplitItem&>(rHt).GetValue()
2833 ? sCSS1_PV_auto
2834 : sCSS1_PV_avoid;
2835 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );
2837 return rWrt;
2840 static Writer& OutCSS1_SwFormatLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt )
2842 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2844 const sal_Char *pStr = static_cast<const SwFormatLayoutSplit&>(rHt).GetValue()
2845 ? sCSS1_PV_auto
2846 : sCSS1_PV_avoid;
2847 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );
2849 return rWrt;
2852 static Writer& OutCSS1_SvxWidows( Writer& rWrt, const SfxPoolItem& rHt )
2854 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2856 OString aStr(OString::number(static_cast<const SvxWidowsItem&>(rHt).GetValue()));
2857 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_widows, aStr );
2859 return rWrt;
2862 static Writer& OutCSS1_SvxOrphans( Writer& rWrt, const SfxPoolItem& rHt )
2864 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2866 OString aStr(OString::number(static_cast<const SvxOrphansItem&>(rHt).GetValue()));
2867 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_orphans, aStr );
2869 return rWrt;
2872 static void OutCSS1_SwFormatDropAttrs( SwHTMLWriter& rHWrt,
2873 const SwFormatDrop& rDrop,
2874 const SfxItemSet *pCharFormatItemSet )
2876 // Text flows around on right side
2877 rHWrt.OutCSS1_PropertyAscii( sCSS1_P_float, sCSS1_PV_left );
2879 // number of lines -> use % for Font-Height!
2880 OString sOut(OString::number(rDrop.GetLines()*100) + "%");
2881 rHWrt.OutCSS1_PropertyAscii(sCSS1_P_font_size, sOut);
2883 // distance to Text = right margin
2884 sal_uInt16 nDistance = rDrop.GetDistance();
2885 if( nDistance > 0 )
2886 rHWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right, nDistance );
2888 const SwCharFormat *pDCCharFormat = rDrop.GetCharFormat();
2889 if( pCharFormatItemSet )
2890 rHWrt.OutCSS1_SfxItemSet( *pCharFormatItemSet );
2891 else if( pDCCharFormat )
2892 rHWrt.OutCSS1_SfxItemSet( pDCCharFormat->GetAttrSet() );
2893 else if( (rHWrt.m_nCSS1OutMode & CSS1_OUTMODE_ANY_OFF) == CSS1_OUTMODE_RULE_OFF )
2894 rHWrt.Strm().WriteCharPtr( sCSS1_rule_end );
2898 static Writer& OutCSS1_SwFormatDrop( Writer& rWrt, const SfxPoolItem& rHt )
2900 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2902 // never export as an Option of a paragraph, but only as Hints
2903 if( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) )
2904 return rWrt;
2906 if( rHTMLWrt.m_bTagOn )
2908 SwCSS1OutMode aMode( rHTMLWrt,
2909 rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_SPAN_TAG1_ON|CSS1_OUTMODE_ENCODE|
2910 CSS1_OUTMODE_DROPCAP, nullptr );
2912 OutCSS1_SwFormatDropAttrs( rHTMLWrt, static_cast<const SwFormatDrop&>(rHt) );
2913 // A "> is already printed by the calling OutCSS1_HintAsSpanTag.
2915 else
2917 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, false );
2920 return rWrt;
2923 static Writer& OutCSS1_SwFormatFrameSize( Writer& rWrt, const SfxPoolItem& rHt,
2924 sal_uInt16 nMode )
2926 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2928 const SwFormatFrameSize& rFSItem = static_cast<const SwFormatFrameSize&>(rHt);
2930 if( nMode & CSS1_FRMSIZE_WIDTH )
2932 sal_uInt8 nPrcWidth = rFSItem.GetWidthPercent();
2933 if( nPrcWidth )
2935 OString sOut(OString::number(nPrcWidth) + "%");
2936 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_width, sOut);
2938 else if( nMode & CSS1_FRMSIZE_PIXEL )
2940 rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_width,
2941 rFSItem.GetSize().Width(), false );
2943 else
2945 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_width,
2946 rFSItem.GetSize().Width() );
2950 if( nMode & CSS1_FRMSIZE_ANYHEIGHT )
2952 bool bOutHeight = false;
2953 switch( rFSItem.GetHeightSizeType() )
2955 case ATT_FIX_SIZE:
2956 bOutHeight = (nMode & CSS1_FRMSIZE_FIXHEIGHT) != 0;
2957 break;
2958 case ATT_MIN_SIZE:
2959 bOutHeight = (nMode & CSS1_FRMSIZE_MINHEIGHT) != 0;
2960 break;
2961 case ATT_VAR_SIZE:
2962 bOutHeight = (nMode & CSS1_FRMSIZE_VARHEIGHT) != 0;
2963 break;
2964 default:
2965 OSL_ENSURE( bOutHeight, "Hoehe wird nicht exportiert" );
2966 break;
2969 if( bOutHeight )
2971 sal_uInt8 nPrcHeight = rFSItem.GetHeightPercent();
2972 if( nPrcHeight )
2974 OString sOut(OString::number(nPrcHeight) + "%");
2975 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_height, sOut);
2977 else if( nMode & CSS1_FRMSIZE_PIXEL )
2979 rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_height,
2980 rFSItem.GetSize().Height(),
2981 true );
2983 else
2985 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_height,
2986 rFSItem.GetSize().Height() );
2991 return rWrt;
2994 static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt )
2996 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
2998 const SvxLRSpaceItem& rLRItem = static_cast<const SvxLRSpaceItem&>(rHt);
3000 // No Export of a firm attribute is needed if the new values
3001 // match that of the current template
3003 // A left margin can exist because of a list nearby
3004 long nLeftMargin = (long)rLRItem.GetTextLeft() - rHTMLWrt.m_nLeftMargin;
3005 if( rHTMLWrt.m_nDfltLeftMargin != nLeftMargin )
3007 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLeftMargin );
3009 // max-width = max-width - margin-left for TOC paragraphs with dot leaders
3010 if( rHTMLWrt.m_bParaDotLeaders )
3011 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_max_width, (long)(DOT_LEADERS_MAX_WIDTH/2.54*72*20) - nLeftMargin );
3015 if( rHTMLWrt.m_nDfltRightMargin != rLRItem.GetRight() )
3017 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right,
3018 (long)rLRItem.GetRight() );
3021 // The LineIndent of the first line might contain the room for numbering
3022 long nFirstLineIndent = (long)rLRItem.GetTextFirstLineOfst() -
3023 rHTMLWrt.m_nFirstLineIndent;
3024 if( rHTMLWrt.m_nDfltFirstLineIndent != nFirstLineIndent )
3026 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent,
3027 nFirstLineIndent );
3030 return rWrt;
3033 static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt )
3035 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
3037 const SvxULSpaceItem& rULItem = static_cast<const SvxULSpaceItem&>(rHt);
3039 if( rHTMLWrt.m_nDfltTopMargin != rULItem.GetUpper() )
3041 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_top,
3042 (long)rULItem.GetUpper() );
3045 if( rHTMLWrt.m_nDfltBottomMargin != rULItem.GetLower() )
3047 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_bottom,
3048 (long)rULItem.GetLower() );
3051 return rWrt;
3054 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
3055 const SvxULSpaceItem *pULItem,
3056 const SvxLRSpaceItem *pLRItem )
3058 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
3060 if( pLRItem && pULItem &&
3061 pLRItem->GetLeft() == pLRItem->GetRight() &&
3062 pLRItem->GetLeft() == pULItem->GetUpper() &&
3063 pLRItem->GetLeft() == pULItem->GetLower() &&
3064 pLRItem->GetLeft() != rHTMLWrt.m_nDfltLeftMargin &&
3065 pLRItem->GetRight() != rHTMLWrt.m_nDfltRightMargin &&
3066 pULItem->GetUpper() != rHTMLWrt.m_nDfltTopMargin &&
3067 pULItem->GetLower() != rHTMLWrt.m_nDfltBottomMargin )
3069 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin, (long)pLRItem->GetLeft() );
3071 else
3073 if( pLRItem )
3074 OutCSS1_SvxLRSpace( rWrt, *pLRItem );
3075 if( pULItem )
3076 OutCSS1_SvxULSpace( rWrt, *pULItem );
3079 return rWrt;
3082 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
3083 const SfxItemSet& rItemSet,
3084 bool bDeep )
3086 const SvxULSpaceItem *pULSpace = nullptr;
3087 const SvxLRSpaceItem *pLRSpace = nullptr;
3088 const SfxPoolItem *pItem;
3089 if( SfxItemState::SET == rItemSet.GetItemState( RES_LR_SPACE, bDeep, &pItem ) )
3090 pLRSpace = static_cast<const SvxLRSpaceItem *>(pItem);
3092 if( SfxItemState::SET == rItemSet.GetItemState( RES_UL_SPACE, bDeep, &pItem ) )
3093 pULSpace = static_cast<const SvxULSpaceItem *>(pItem);
3095 if( pLRSpace || pULSpace )
3096 OutCSS1_SvxULSpace_SvxLRSpace( rWrt, pULSpace, pLRSpace );
3098 return rWrt;
3101 static Writer& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( Writer& rWrt,
3102 const SvxFormatBreakItem *pBreakItem,
3103 const SwFormatPageDesc *pPDescItem,
3104 const SvxFormatKeepItem *pKeepItem )
3106 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
3108 if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PRINT_EXT) )
3109 return rWrt;
3111 const sal_Char *pBreakBefore = nullptr;
3112 const sal_Char *pBreakAfter = nullptr;
3114 if( pKeepItem )
3116 pBreakAfter = pKeepItem->GetValue() ? sCSS1_PV_avoid : sCSS1_PV_auto;
3118 if( pBreakItem )
3120 switch( pBreakItem->GetBreak() )
3122 case SvxBreak::NONE:
3123 pBreakBefore = sCSS1_PV_auto;
3124 if( !pBreakAfter )
3125 pBreakAfter = sCSS1_PV_auto;
3126 break;
3128 case SvxBreak::PageBefore:
3129 pBreakBefore = sCSS1_PV_always;
3130 break;
3132 case SvxBreak::PageAfter:
3133 pBreakAfter= sCSS1_PV_always;
3134 break;
3136 default:
3140 if( pPDescItem )
3142 const SwPageDesc *pPDesc = pPDescItem->GetPageDesc();
3143 if( pPDesc )
3145 switch( pPDesc->GetPoolFormatId() )
3147 case RES_POOLPAGE_LEFT: pBreakBefore = sCSS1_PV_left; break;
3148 case RES_POOLPAGE_RIGHT: pBreakBefore = sCSS1_PV_right; break;
3149 default: pBreakBefore = sCSS1_PV_always; break;
3152 else if( !pBreakBefore )
3154 pBreakBefore = sCSS1_PV_auto;
3158 if( pBreakBefore )
3159 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_before,
3160 pBreakBefore );
3161 if( pBreakAfter )
3162 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_after,
3163 pBreakAfter );
3165 return rWrt;
3168 static Writer& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( Writer& rWrt,
3169 const SfxItemSet& rItemSet,
3170 bool bDeep )
3172 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
3173 const SfxPoolItem *pItem;
3174 const SvxFormatBreakItem *pBreakItem = nullptr;
3175 if( SfxItemState::SET==rItemSet.GetItemState( RES_BREAK, bDeep, &pItem ))
3176 pBreakItem = static_cast<const SvxFormatBreakItem *>(pItem);
3178 const SwFormatPageDesc *pPDescItem = nullptr;
3179 if( ( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
3180 !rHTMLWrt.m_bCSS1IgnoreFirstPageDesc ||
3181 rHTMLWrt.m_pStartNdIdx->GetIndex() !=
3182 rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex() ) &&
3183 SfxItemState::SET==rItemSet.GetItemState( RES_PAGEDESC, bDeep, &pItem ))
3184 pPDescItem = static_cast<const SwFormatPageDesc*>(pItem);
3186 const SvxFormatKeepItem *pKeepItem = nullptr;
3187 if( SfxItemState::SET==rItemSet.GetItemState( RES_KEEP, bDeep, &pItem ))
3188 pKeepItem = static_cast<const SvxFormatKeepItem *>(pItem);
3190 if( pBreakItem || pPDescItem || pKeepItem )
3191 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( rWrt, pBreakItem,
3192 pPDescItem, pKeepItem );
3194 return rWrt;
3197 // Wrapper for OutCSS1_SfxItemSet etc.
3198 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt )
3200 OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_ATTR, nullptr );
3201 return rWrt;
3204 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
3205 sal_uInt16 nMode,
3206 const OUString* pGraphicName)
3208 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
3210 // The Character-Attribute is skipped, if we are about to
3211 // exporting options
3212 if( rHt.Which() < RES_CHRATR_END &&
3213 rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
3214 return rWrt;
3216 // start getting a few values
3217 // const Brush &rBrush = static_cast<const SvxBrushItem &>(rHt).GetBrush();
3218 const Color & rColor = static_cast<const SvxBrushItem &>(rHt).GetColor();
3219 OUString aLink = pGraphicName ? *pGraphicName
3220 : static_cast<const SvxBrushItem &>(rHt).GetGraphicLink();
3221 SvxGraphicPosition ePos = static_cast<const SvxBrushItem &>(rHt).GetGraphicPos();
3222 if( CSS1_BACKGROUND_PAGE==nMode && !rHTMLWrt.mbEmbedImages )
3224 // page style images are exported if not tiled
3225 if( aLink.isEmpty() || GPOS_TILED==ePos )
3226 return rWrt;
3229 // get the color
3230 bool bColor = false;
3231 /// set <bTransparent> to true, if color is "no fill"/"auto fill"
3232 bool bTransparent = (rColor.GetColor() == COL_TRANSPARENT);
3233 Color aColor;
3234 if( !bTransparent )
3236 aColor = rColor;
3237 bColor = true;
3240 // and now the Graphic
3241 OUString aGraphicInBase64;
3242 OUString aGraphicAsLink;
3244 // Embedded Grafic -> export WriteEmbedded
3245 const Graphic* pGrf = nullptr;
3246 if( rHTMLWrt.mbEmbedImages || aLink.isEmpty())
3248 pGrf = static_cast<const SvxBrushItem &>(rHt).GetGraphic();
3249 if( pGrf )
3251 if( !XOutBitmap::GraphicToBase64(*pGrf, aGraphicInBase64) )
3253 rHTMLWrt.m_nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
3256 aLink.clear();
3258 else if( !pGraphicName && rHTMLWrt.m_bCfgCpyLinkedGrfs )
3260 aGraphicAsLink = aLink;
3261 rWrt.CopyLocalFileToINet( aGraphicAsLink );
3262 aLink = aGraphicAsLink;
3264 // In tables we only export something if there is a Graphic
3265 if( CSS1_BACKGROUND_TABLE==nMode && !pGrf && !aLink.isEmpty())
3266 return rWrt;
3268 // if necessary, add the orientation of the Graphic
3269 const sal_Char *pRepeat = nullptr, *pHori = nullptr, *pVert = nullptr;
3270 if( pGrf || !aLink.isEmpty() )
3272 if( GPOS_TILED==ePos )
3274 pRepeat = sCSS1_PV_repeat;
3276 else
3278 switch( ePos )
3280 case GPOS_LT:
3281 case GPOS_MT:
3282 case GPOS_RT:
3283 pHori = sCSS1_PV_top;
3284 break;
3286 case GPOS_LM:
3287 case GPOS_MM:
3288 case GPOS_RM:
3289 pHori = sCSS1_PV_middle;
3290 break;
3292 case GPOS_LB:
3293 case GPOS_MB:
3294 case GPOS_RB:
3295 pHori = sCSS1_PV_bottom;
3296 break;
3298 default:
3302 switch( ePos )
3304 case GPOS_LT:
3305 case GPOS_LM:
3306 case GPOS_LB:
3307 pVert = sCSS1_PV_left;
3308 break;
3310 case GPOS_MT:
3311 case GPOS_MM:
3312 case GPOS_MB:
3313 pVert = sCSS1_PV_center;
3314 break;
3316 case GPOS_RT:
3317 case GPOS_RM:
3318 case GPOS_RB:
3319 pVert = sCSS1_PV_right;
3320 break;
3322 default:
3326 if( pHori || pVert )
3327 pRepeat = sCSS1_PV_no_repeat;
3331 // now build the string
3332 OUString sOut;
3333 if( !pGrf && aLink.isEmpty() && !bColor )
3335 // no color and no Link, but a transparent Brush
3336 if( bTransparent && CSS1_BACKGROUND_FLY != nMode )
3337 sOut += OStringToOUString(sCSS1_PV_transparent, RTL_TEXTENCODING_ASCII_US);
3339 else
3341 if( bColor )
3343 OString sTmp(lclGetCSS1Color(aColor));
3344 sOut += OStringToOUString(sTmp, RTL_TEXTENCODING_ASCII_US);
3347 if( pGrf || !aLink.isEmpty() )
3349 if( bColor )
3350 sOut += " ";
3352 if(pGrf)
3354 sOut += OStringToOUString(sCSS1_url, RTL_TEXTENCODING_ASCII_US) +
3355 "(\'" OOO_STRING_SVTOOLS_HTML_O_data ":" + aGraphicInBase64 + "\')";
3357 else
3359 sOut += OStringToOUString(sCSS1_url, RTL_TEXTENCODING_ASCII_US)+
3360 "(" + URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(),
3361 aLink) + ")";
3364 if( pRepeat )
3366 sOut += " " + OStringToOUString(pRepeat, RTL_TEXTENCODING_ASCII_US);
3369 if( pHori )
3371 sOut += " " + OStringToOUString(pHori, RTL_TEXTENCODING_ASCII_US);
3373 if( pVert )
3375 sOut += " " + OStringToOUString(pVert, RTL_TEXTENCODING_ASCII_US);
3378 sOut += " " + OStringToOUString(sCSS1_PV_scroll, RTL_TEXTENCODING_ASCII_US) + " ";
3382 if( !sOut.isEmpty() )
3383 rHTMLWrt.OutCSS1_Property( sCSS1_P_background, sOut );
3385 return rWrt;
3388 static void OutCSS1_SvxBorderLine( SwHTMLWriter& rHTMLWrt,
3389 const sal_Char *pProperty,
3390 const SvxBorderLine *pLine )
3392 if( !pLine || pLine->isEmpty() )
3394 rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sCSS1_PV_none );
3395 return;
3398 sal_Int32 nWidth = pLine->GetWidth();
3400 OStringBuffer sOut;
3401 if( Application::GetDefaultDevice() &&
3402 nWidth <= Application::GetDefaultDevice()->PixelToLogic(
3403 Size( 1, 1 ), MapMode( MapUnit::MapTwip) ).Width() )
3405 // If the width is smaller than one pixel, then export as 1px
3406 // so that Netscape and IE show the line.
3407 sOut.append("1px");
3409 else
3411 nWidth *= 5; // 1/100pt
3413 // width in n.nn pt
3414 sOut.append(OString::number(nWidth / 100) + "." + OString::number((nWidth/10) % 10) +
3415 OString::number(nWidth % 10) + OString(sCSS1_UNIT_pt));
3418 // Line-Style: solid or double
3419 sOut.append(' ');
3420 switch (pLine->GetBorderLineStyle())
3422 case table::BorderLineStyle::SOLID:
3423 sOut.append(sCSS1_PV_solid);
3424 break;
3425 case table::BorderLineStyle::DOTTED:
3426 sOut.append(sCSS1_PV_dotted);
3427 break;
3428 case table::BorderLineStyle::DASHED:
3429 sOut.append(sCSS1_PV_dashed);
3430 break;
3431 case table::BorderLineStyle::DOUBLE:
3432 case table::BorderLineStyle::THINTHICK_SMALLGAP:
3433 case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
3434 case table::BorderLineStyle::THINTHICK_LARGEGAP:
3435 case table::BorderLineStyle::THICKTHIN_SMALLGAP:
3436 case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
3437 case table::BorderLineStyle::THICKTHIN_LARGEGAP:
3438 sOut.append(sCSS1_PV_double);
3439 break;
3440 case table::BorderLineStyle::EMBOSSED:
3441 sOut.append(sCSS1_PV_ridge);
3442 break;
3443 case table::BorderLineStyle::ENGRAVED:
3444 sOut.append(sCSS1_PV_groove);
3445 break;
3446 case table::BorderLineStyle::INSET:
3447 sOut.append(sCSS1_PV_inset);
3448 break;
3449 case table::BorderLineStyle::OUTSET:
3450 sOut.append(sCSS1_PV_outset);
3451 break;
3452 default:
3453 sOut.append(sCSS1_PV_none);
3455 sOut.append(' ');
3457 // and also the color
3458 sOut.append(lclGetCSS1Color(pLine->GetColor()));
3460 rHTMLWrt.OutCSS1_PropertyAscii(pProperty, sOut.makeStringAndClear());
3463 Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt )
3465 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
3467 // Avoid interference between character and paragraph attributes
3468 if( rHt.Which() < RES_CHRATR_END &&
3469 rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
3470 return rWrt;
3472 if( rHt.Which() == RES_CHRATR_BOX )
3474 if( rHTMLWrt.m_bTagOn )
3476 // Inline-block to make the line height changing correspond to the character border
3477 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_display, "inline-block");
3479 else
3481 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, false );
3482 return rWrt;
3486 const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(rHt);
3487 const SvxBorderLine *pTop = rBoxItem.GetTop();
3488 const SvxBorderLine *pBottom = rBoxItem.GetBottom();
3489 const SvxBorderLine *pLeft = rBoxItem.GetLeft();
3490 const SvxBorderLine *pRight = rBoxItem.GetRight();
3492 if( (pTop && pBottom && pLeft && pRight &&
3493 *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) ||
3494 (!pTop && !pBottom && !pLeft && !pRight) )
3496 // all Lines are set and equal, or all Lines are not set
3497 // => border : ...
3498 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border, pTop );
3500 else
3502 // otherwise export all Lines separately
3503 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_top, pTop );
3504 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_bottom, pBottom );
3505 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_left, pLeft );
3506 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_right, pRight );
3509 long nTopDist = pTop ? rBoxItem.GetDistance( SvxBoxItemLine::TOP ) : 0;
3510 long nBottomDist = pBottom ? rBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) : 0;
3511 long nLeftDist = pLeft ? rBoxItem.GetDistance( SvxBoxItemLine::LEFT ) : 0;
3512 long nRightDist = pRight ? rBoxItem.GetDistance( SvxBoxItemLine::RIGHT ) : 0;
3514 if( nTopDist == nBottomDist && nLeftDist == nRightDist )
3516 OStringBuffer sVal;
3517 AddUnitPropertyValue(sVal, nTopDist, rHTMLWrt.GetCSS1Unit());
3518 if( nTopDist != nLeftDist )
3520 sVal.append(' ');
3521 AddUnitPropertyValue(sVal, nLeftDist, rHTMLWrt.GetCSS1Unit());
3523 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_padding, sVal.makeStringAndClear());
3525 else
3527 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_top, nTopDist );
3528 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_bottom, nBottomDist );
3529 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_left, nLeftDist );
3530 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_right, nRightDist );
3533 return rWrt;
3536 static Writer& OutCSS1_SvxFrameDirection( Writer& rWrt, const SfxPoolItem& rHt )
3538 SwHTMLWriter& rHTMLWrt = static_cast< SwHTMLWriter& >( rWrt );
3540 // Language will be exported rules only
3541 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_TEMPLATE ) )
3542 return rWrt;
3544 sal_uInt16 nDir =
3545 static_cast< const SvxFrameDirectionItem& >( rHt ).GetValue();
3546 const sal_Char* pStr = nullptr;
3547 switch( nDir )
3549 case FRMDIR_HORI_LEFT_TOP:
3550 case FRMDIR_VERT_TOP_LEFT:
3551 pStr = sCSS1_PV_ltr;
3552 break;
3553 case FRMDIR_HORI_RIGHT_TOP:
3554 case FRMDIR_VERT_TOP_RIGHT:
3555 pStr = sCSS1_PV_rtl;
3556 break;
3557 case FRMDIR_ENVIRONMENT:
3558 pStr = sCSS1_PV_inherit;
3559 break;
3562 if( pStr )
3563 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_direction, pStr );
3565 return rWrt;
3569 * Place here the table for the HTML-Function-Pointer to the
3570 * Export-Functions.
3571 * They are local structures, only needed within the HTML-DLL.
3574 SwAttrFnTab aCSS1AttrFnTab = {
3575 /* RES_CHRATR_CASEMAP */ OutCSS1_SvxCaseMap,
3576 /* RES_CHRATR_CHARSETCOLOR */ nullptr,
3577 /* RES_CHRATR_COLOR */ OutCSS1_SvxColor,
3578 /* RES_CHRATR_CONTOUR */ nullptr,
3579 /* RES_CHRATR_CROSSEDOUT */ OutCSS1_SvxCrossedOut,
3580 /* RES_CHRATR_ESCAPEMENT */ nullptr,
3581 /* RES_CHRATR_FONT */ OutCSS1_SvxFont,
3582 /* RES_CHRATR_FONTSIZE */ OutCSS1_SvxFontHeight,
3583 /* RES_CHRATR_KERNING */ OutCSS1_SvxKerning,
3584 /* RES_CHRATR_LANGUAGE */ OutCSS1_SvxLanguage,
3585 /* RES_CHRATR_POSTURE */ OutCSS1_SvxPosture,
3586 /* RES_CHRATR_PROPORTIONALFONTSIZE*/nullptr,
3587 /* RES_CHRATR_SHADOWED */ nullptr,
3588 /* RES_CHRATR_UNDERLINE */ OutCSS1_SvxUnderline,
3589 /* RES_CHRATR_WEIGHT */ OutCSS1_SvxFontWeight,
3590 /* RES_CHRATR_WORDLINEMODE */ nullptr,
3591 /* RES_CHRATR_AUTOKERN */ nullptr,
3592 /* RES_CHRATR_BLINK */ OutCSS1_SvxBlink,
3593 /* RES_CHRATR_NOHYPHEN */ nullptr, // Neu: nicht trennen
3594 /* RES_CHRATR_NOLINEBREAK */ nullptr, // Neu: nicht umbrechen
3595 /* RES_CHRATR_BACKGROUND */ OutCSS1_SvxBrush, // Neu: Zeichenhintergrund
3596 /* RES_CHRATR_CJK_FONT */ OutCSS1_SvxFont,
3597 /* RES_CHRATR_CJK_FONTSIZE */ OutCSS1_SvxFontHeight,
3598 /* RES_CHRATR_CJK_LANGUAGE */ OutCSS1_SvxLanguage,
3599 /* RES_CHRATR_CJK_POSTURE */ OutCSS1_SvxPosture,
3600 /* RES_CHRATR_CJK_WEIGHT */ OutCSS1_SvxFontWeight,
3601 /* RES_CHRATR_CTL_FONT */ OutCSS1_SvxFont,
3602 /* RES_CHRATR_CTL_FONTSIZE */ OutCSS1_SvxFontHeight,
3603 /* RES_CHRATR_CTL_LANGUAGE */ OutCSS1_SvxLanguage,
3604 /* RES_CHRATR_CTL_POSTURE */ OutCSS1_SvxPosture,
3605 /* RES_CHRATR_CTL_WEIGHT */ OutCSS1_SvxFontWeight,
3606 /* RES_CHRATR_ROTATE */ nullptr,
3607 /* RES_CHRATR_EMPHASIS_MARK */ nullptr,
3608 /* RES_CHRATR_TWO_LINES */ nullptr,
3609 /* RES_CHRATR_SCALEW */ nullptr,
3610 /* RES_CHRATR_RELIEF */ nullptr,
3611 /* RES_CHRATR_HIDDEN */ OutCSS1_SvxHidden,
3612 /* RES_CHRATR_OVERLINE */ OutCSS1_SvxOverline,
3613 /* RES_CHRATR_RSID */ nullptr,
3614 /* RES_CHRATR_BOX */ OutCSS1_SvxBox,
3615 /* RES_CHRATR_SHADOW */ nullptr,
3616 /* RES_CHRATR_HIGHLIGHT */ nullptr,
3617 /* RES_CHRATR_GRABBAG */ nullptr,
3618 /* RES_CHRATR_BIDIRTL */ nullptr,
3619 /* RES_CHRATR_IDCTHINT */ nullptr,
3621 /* RES_TXTATR_REFMARK */ nullptr,
3622 /* RES_TXTATR_TOXMARK */ nullptr,
3623 /* RES_TXTATR_META */ nullptr,
3624 /* RES_TXTATR_METAFIELD */ nullptr,
3625 /* RES_TXTATR_AUTOFMT */ nullptr,
3626 /* RES_TXTATR_INETFMT */ nullptr,
3627 /* RES_TXTATR_CHARFMT */ nullptr,
3628 /* RES_TXTATR_CJK_RUBY */ nullptr,
3629 /* RES_TXTATR_UNKNOWN_CONTAINER */ nullptr,
3630 /* RES_TXTATR_INPUTFIELD */ nullptr,
3632 /* RES_TXTATR_FIELD */ nullptr,
3633 /* RES_TXTATR_FLYCNT */ nullptr,
3634 /* RES_TXTATR_FTN */ nullptr,
3635 /* RES_TXTATR_ANNOTATION */ nullptr,
3636 /* RES_TXTATR_DUMMY3 */ nullptr,
3637 /* RES_TXTATR_DUMMY1 */ nullptr, // Dummy:
3638 /* RES_TXTATR_DUMMY2 */ nullptr, // Dummy:
3640 /* RES_PARATR_LINESPACING */ OutCSS1_SvxLineSpacing,
3641 /* RES_PARATR_ADJUST */ OutCSS1_SvxAdjust,
3642 /* RES_PARATR_SPLIT */ OutCSS1_SvxFormatSplit,
3643 /* RES_PARATR_ORPHANS */ OutCSS1_SvxOrphans,
3644 /* RES_PARATR_WIDOWS */ OutCSS1_SvxWidows,
3645 /* RES_PARATR_TABSTOP */ nullptr,
3646 /* RES_PARATR_HYPHENZONE*/ nullptr,
3647 /* RES_PARATR_DROP */ OutCSS1_SwFormatDrop,
3648 /* RES_PARATR_REGISTER */ nullptr, // neu: Registerhaltigkeit
3649 /* RES_PARATR_NUMRULE */ nullptr,
3650 /* RES_PARATR_SCRIPTSPACE */ nullptr,
3651 /* RES_PARATR_HANGINGPUNCTUATION */ nullptr,
3652 /* RES_PARATR_FORBIDDEN_RULES */ nullptr, // new
3653 /* RES_PARATR_VERTALIGN */ nullptr, // new
3654 /* RES_PARATR_SNAPTOGRID*/ nullptr, // new
3655 /* RES_PARATR_CONNECT_TO_BORDER */ nullptr, // new
3656 /* RES_PARATR_OUTLINELEVEL */ nullptr, // new since cws outlinelevel
3657 /* RES_PARATR_RSID */ nullptr, // new
3658 /* RES_PARATR_GRABBAG */ nullptr,
3660 /* RES_PARATR_LIST_ID */ nullptr, // new
3661 /* RES_PARATR_LIST_LEVEL */ nullptr, // new
3662 /* RES_PARATR_LIST_ISRESTART */ nullptr, // new
3663 /* RES_PARATR_LIST_RESTARTVALUE */ nullptr, // new
3664 /* RES_PARATR_LIST_ISCOUNTED */ nullptr, // new
3666 /* RES_FILL_ORDER */ nullptr,
3667 /* RES_FRM_SIZE */ nullptr,
3668 /* RES_PAPER_BIN */ nullptr,
3669 /* RES_LR_SPACE */ OutCSS1_SvxLRSpace,
3670 /* RES_UL_SPACE */ OutCSS1_SvxULSpace,
3671 /* RES_PAGEDESC */ nullptr,
3672 /* RES_BREAK */ nullptr,
3673 /* RES_CNTNT */ nullptr,
3674 /* RES_HEADER */ nullptr,
3675 /* RES_FOOTER */ nullptr,
3676 /* RES_PRINT */ nullptr,
3677 /* RES_OPAQUE */ nullptr,
3678 /* RES_PROTECT */ nullptr,
3679 /* RES_SURROUND */ nullptr,
3680 /* RES_VERT_ORIENT */ nullptr,
3681 /* RES_HORI_ORIENT */ nullptr,
3682 /* RES_ANCHOR */ nullptr,
3683 /* RES_BACKGROUND */ OutCSS1_SvxBrush,
3684 /* RES_BOX */ OutCSS1_SvxBox,
3685 /* RES_SHADOW */ nullptr,
3686 /* RES_FRMMACRO */ nullptr,
3687 /* RES_COL */ nullptr,
3688 /* RES_KEEP */ nullptr,
3689 /* RES_URL */ nullptr,
3690 /* RES_EDIT_IN_READONLY */ nullptr,
3691 /* RES_LAYOUT_SPLIT */ nullptr,
3692 /* RES_CHAIN */ nullptr,
3693 /* RES_TEXTGRID */ nullptr,
3694 /* RES_LINENUMBER */ nullptr,
3695 /* RES_FTN_AT_TXTEND */ nullptr,
3696 /* RES_END_AT_TXTEND */ nullptr,
3697 /* RES_COLUMNBALANCE */ nullptr,
3698 /* RES_FRAMEDIR */ OutCSS1_SvxFrameDirection,
3699 /* RES_HEADER_FOOTER_EAT_SPACING */ nullptr,
3700 /* RES_ROW_SPLIT */ nullptr,
3701 /* RES_FOLLOW_TEXT_FLOW */ nullptr,
3702 /* RES_COLLAPSING_BORDERS */ nullptr,
3703 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ nullptr,
3704 /* RES_AUTO_STYLE */ nullptr,
3705 /* RES_FRMATR_STYLE_NAME */ nullptr,
3706 /* RES_FRMATR_CONDITIONAL_STYLE_NAME */ nullptr,
3707 /* RES_FRMATR_GRABBAG */ nullptr,
3708 /* RES_TEXT_VERT_ADJUST */ nullptr,
3710 /* RES_GRFATR_MIRRORGRF */ nullptr,
3711 /* RES_GRFATR_CROPGRF */ nullptr,
3712 /* RES_GRFATR_ROTATION */ nullptr,
3713 /* RES_GRFATR_LUMINANCE */ nullptr,
3714 /* RES_GRFATR_CONTRAST */ nullptr,
3715 /* RES_GRFATR_CHANNELR */ nullptr,
3716 /* RES_GRFATR_CHANNELG */ nullptr,
3717 /* RES_GRFATR_CHANNELB */ nullptr,
3718 /* RES_GRFATR_GAMMA */ nullptr,
3719 /* RES_GRFATR_INVERT */ nullptr,
3720 /* RES_GRFATR_TRANSPARENCY */ nullptr,
3721 /* RES_GRFATR_DRWAMODE */ nullptr,
3722 /* RES_GRFATR_DUMMY1 */ nullptr,
3723 /* RES_GRFATR_DUMMY2 */ nullptr,
3724 /* RES_GRFATR_DUMMY3 */ nullptr,
3725 /* RES_GRFATR_DUMMY4 */ nullptr,
3726 /* RES_GRFATR_DUMMY5 */ nullptr,
3728 /* RES_BOXATR_FORMAT */ nullptr,
3729 /* RES_BOXATR_FORMULA */ nullptr,
3730 /* RES_BOXATR_VALUE */ nullptr
3733 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */