1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <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 // NOTES 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" 91 92 #include <IDocumentStylePoolAccess.hxx> 93 #include <numrule.hxx> 94 #include <o3tl/typed_flags_set.hxx> 95 96 #include <rtl/strbuf.hxx> 97 98 using namespace css; 99 using editeng::SvxBorderLine; 100 101 #define HTML_HEADSPACE (12*20) 102 103 enum class Css1Background { 104 Attr = 1, 105 Page = 2, 106 Table = 3, 107 Fly = 4, 108 Section = 5 109 }; 110 111 enum class Css1FrameSize { 112 NONE = 0x00, 113 Width = 0x01, 114 MinHeight = 0x02, 115 FixHeight = 0x04, 116 AnyHeight = 0x06, 117 Pixel = 0x10, 118 }; 119 namespace o3tl { 120 template<> struct typed_flags<Css1FrameSize> : is_typed_flags<Css1FrameSize, 0x17> {}; 121 } 122 123 #define DOT_LEADERS_MAX_WIDTH 18 124 125 static Writer& OutCSS1_SwFormat( Writer& rWrt, const SwFormat& rFormat, 126 IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate ); 127 static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rFormat, 128 IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate, 129 sal_uInt16 nRefPoolId, bool bExtRef, 130 bool bPseudo=true ); 131 static Writer& OutCSS1_SwFootnoteInfo( Writer& rWrt, const SwEndNoteInfo& rInfo, 132 SwDoc *pDoc, bool bHasNotes, bool bEndNote ); 133 static void OutCSS1_SwFormatDropAttrs( SwHTMLWriter& rHWrt, 134 const SwFormatDrop& rDrop, 135 const SfxItemSet *pCharFormatItemSet=nullptr ); 136 static Writer& OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( Writer& rWrt, 137 const SvxUnderlineItem *pUItem, 138 const SvxOverlineItem *pOItem, 139 const SvxCrossedOutItem *pCOItem, 140 const SvxBlinkItem *pBItem ); 141 static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt ); 142 static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt ); 143 static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt ); 144 static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt ); 145 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt, 146 const SvxULSpaceItem *pULSpace, 147 const SvxLRSpaceItem *pLRSpace ); 148 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt, 149 const SfxItemSet& rItemSet ); 150 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt, 151 Css1Background nMode, 152 const OUString *pGraphicName ); 153 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt ); 154 static Writer& OutCSS1_SwFormatFrameSize( Writer& rWrt, const SfxPoolItem& rHt, 155 Css1FrameSize nMode ); 156 static Writer& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( Writer& rWrt, 157 const SfxItemSet& rItemSet, 158 bool bDeep ); 159 static Writer& OutCSS1_SwFormatLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt ); 160 161 namespace 162 { 163 164 const sal_Char sCSS1_rule_end[] = " }"; 165 const sal_Char sCSS1_span_tag_end[] = "\">"; 166 const sal_Char cCSS1_style_opt_end = '\"'; 167 168 const sal_Char* const sHTML_FTN_fontheight = "57%"; 169 170 OString lclConvToHex(sal_uInt16 nHex) 171 { 172 sal_Char aNToABuf[] = "00"; 173 174 // set pointer to end of buffer 175 sal_Char *pStr = aNToABuf + (sizeof(aNToABuf)-1); 176 for( sal_uInt8 n = 0; n < 2; ++n ) 177 { 178 *(--pStr) = static_cast<sal_Char>(nHex & 0xf ) + 48; 179 if( *pStr > '9' ) 180 *pStr += 39; 181 nHex >>= 4; 182 } 183 184 return OString(aNToABuf, 2); 185 } 186 187 /// Determines if rProperty has to be suppressed due to ReqIF mode. 188 bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty) 189 { 190 if (!bReqIF) 191 return false; 192 193 // Only allow these two keys, nothing else in ReqIF mode. 194 if (rProperty == sCSS1_P_text_decoration) 195 return false; 196 197 if (rProperty == sCSS1_P_color) 198 return false; 199 200 return true; 201 } 202 } 203 204 OString GetCSS1_Color(const Color& rColor) 205 { 206 return "#" + lclConvToHex(rColor.GetRed()) + lclConvToHex(rColor.GetGreen()) + lclConvToHex(rColor.GetBlue()); 207 } 208 209 class SwCSS1OutMode 210 { 211 SwHTMLWriter& rWrt; 212 sal_uInt16 const nOldMode; 213 214 public: 215 216 SwCSS1OutMode( SwHTMLWriter& rHWrt, sal_uInt16 nMode, 217 const OUString *pSelector ) : 218 rWrt( rHWrt ), 219 nOldMode( rHWrt.m_nCSS1OutMode ) 220 { 221 rWrt.m_nCSS1OutMode = nMode; 222 rWrt.m_bFirstCSS1Property = true; 223 if( pSelector ) 224 rWrt.m_aCSS1Selector = *pSelector; 225 } 226 227 ~SwCSS1OutMode() 228 { 229 rWrt.m_nCSS1OutMode = nOldMode; 230 } 231 }; 232 233 void SwHTMLWriter::OutCSS1_Property( const sal_Char *pProp, 234 const sal_Char *pVal, 235 const OUString *pSVal ) 236 { 237 if (IgnorePropertyForReqIF(mbReqIF, pProp)) 238 return; 239 240 OStringBuffer sOut; 241 242 if( m_bFirstCSS1Rule && (m_nCSS1OutMode & CSS1_OUTMODE_RULE_ON)!=0 ) 243 { 244 m_bFirstCSS1Rule = false; 245 OutNewLine(); 246 sOut.append("<" + GetNamespace() + OOO_STRING_SVTOOLS_HTML_style " " 247 OOO_STRING_SVTOOLS_HTML_O_type "=\"text/css\">"); 248 // Optional CSS2 code for dot leaders (dotted line between the Table of Contents titles and page numbers): 249 // (More information: http://www.w3.org/Style/Examples/007/leaders.en.html) 250 // 251 // p.leaders { 252 // /* FIXME: 253 // (1) dots line up vertically only in the paragraphs with the same alignment/level 254 // (2) max-width = 18 cm instead of 80em; possible improvement with the new CSS3 calc() */ 255 // max-width: 18cm; /* note: need to overwrite max-width with max-width - border-left_of_the_actual_paragraph */ 256 // padding: 0; 257 // overflow-x: hidden; 258 // line-height: 120%; /* note: avoid HTML scrollbars and missing descenders of the letters */ 259 // } 260 // p.leaders:after { 261 // float: left; 262 // width: 0; 263 // white-space: nowrap; 264 // content: ". . . . . . . . . . . . . . . . . . ..."; 265 // } 266 // p.leaders span:first-child { 267 // padding-right: 0.33em; 268 // background: white; 269 // } 270 // p.leaders span + span { 271 // float: right; 272 // padding-left: 0.33em; 273 // background: white; 274 // position: relative; 275 // z-index: 1 276 // } 277 278 if (m_bCfgPrintLayout) { 279 sOut.append( 280 "p." sCSS2_P_CLASS_leaders "{max-width:" + OString::number(DOT_LEADERS_MAX_WIDTH) + 281 "cm;padding:0;overflow-x:hidden;line-height:120%}" 282 "p." sCSS2_P_CLASS_leaders ":after{float:left;width:0;white-space:nowrap;content:\""); 283 for (int i = 0; i < 100; i++ ) 284 sOut.append(". "); 285 sOut.append( 286 "\"}p." sCSS2_P_CLASS_leaders " span:first-child{padding-right:0.33em;background:white}" 287 "p." sCSS2_P_CLASS_leaders " span+span{float:right;padding-left:0.33em;" 288 "background:white;position:relative;z-index:1}"); 289 } 290 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); 291 292 IncIndentLevel(); 293 } 294 295 if( m_bFirstCSS1Property ) 296 { 297 switch( m_nCSS1OutMode & CSS1_OUTMODE_ANY_ON ) 298 { 299 case CSS1_OUTMODE_SPAN_TAG_ON: 300 case CSS1_OUTMODE_SPAN_TAG1_ON: 301 if( m_bTagOn ) 302 { 303 sOut.append("<" + GetNamespace() + OOO_STRING_SVTOOLS_HTML_span 304 " " OOO_STRING_SVTOOLS_HTML_O_style "=\""); 305 } 306 else 307 { 308 HTMLOutFuncs::Out_AsciiTag( Strm(), GetNamespace() + OOO_STRING_SVTOOLS_HTML_span, false ); 309 return; 310 } 311 break; 312 313 case CSS1_OUTMODE_RULE_ON: 314 { 315 OutNewLine(); 316 sOut.append(OUStringToOString(m_aCSS1Selector, m_eDestEnc) + " { "); 317 } 318 break; 319 320 case CSS1_OUTMODE_STYLE_OPT_ON: 321 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_style "=\""); 322 break; 323 } 324 m_bFirstCSS1Property = false; 325 } 326 else 327 { 328 sOut.append("; "); 329 } 330 331 sOut.append(OString(pProp) + ": "); 332 if( m_nCSS1OutMode & CSS1_OUTMODE_ENCODE ) 333 { 334 // for STYLE-Option encode string 335 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); 336 if( pVal ) 337 HTMLOutFuncs::Out_String( Strm(), OUString::createFromAscii(pVal), 338 m_eDestEnc, &m_aNonConvertableCharacters ); 339 else if( pSVal ) 340 HTMLOutFuncs::Out_String( Strm(), *pSVal, m_eDestEnc, &m_aNonConvertableCharacters ); 341 } 342 else 343 { 344 // for STYLE-Tag print string directly 345 if( pVal ) 346 sOut.append(pVal); 347 else if( pSVal ) 348 sOut.append(OUStringToOString(*pSVal, m_eDestEnc)); 349 } 350 351 if (!sOut.isEmpty()) 352 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); 353 } 354 355 static void AddUnitPropertyValue(OStringBuffer &rOut, long nVal, 356 FieldUnit eUnit) 357 { 358 if( nVal < 0 ) 359 { 360 // special-case sign symbol 361 nVal = -nVal; 362 rOut.append('-'); 363 } 364 365 // the recalculated unit results from (x * nMul)/(nDiv*nFac*10) 366 long nMul = 1000; 367 long nDiv = 1; 368 long nFac = 100; 369 const sal_Char *pUnit; 370 switch( eUnit ) 371 { 372 case FieldUnit::MM_100TH: 373 OSL_ENSURE( FieldUnit::MM == eUnit, "Measuring unit not supported" ); 374 [[fallthrough]]; 375 case FieldUnit::MM: 376 // 0.01mm = 0.57twip 377 nMul = 25400; // 25.4 * 1000 378 nDiv = 1440; // 72 * 20; 379 nFac = 100; 380 pUnit = sCSS1_UNIT_mm; 381 break; 382 383 case FieldUnit::M: 384 case FieldUnit::KM: 385 OSL_ENSURE( FieldUnit::CM == eUnit, "Measuring unit not supported" ); 386 [[fallthrough]]; 387 case FieldUnit::CM: 388 // 0.01cm = 5.7twip (not exact, but the UI is also not exact) 389 nMul = 2540; // 2.54 * 1000 390 nDiv = 1440; // 72 * 20; 391 nFac = 100; 392 pUnit = sCSS1_UNIT_cm; 393 break; 394 395 case FieldUnit::TWIP: 396 OSL_ENSURE( FieldUnit::POINT == eUnit, "Measuring unit not supported" ); 397 [[fallthrough]]; 398 case FieldUnit::POINT: 399 // 0.1pt = 2.0twip (not exact, but the UI is also not exact) 400 nMul = 100; 401 nDiv = 20; 402 nFac = 10; 403 pUnit = sCSS1_UNIT_pt; 404 break; 405 406 case FieldUnit::PICA: 407 // 0.01pc = 2.40twip (not exact, but the UI is also not exact) 408 nMul = 1000; 409 nDiv = 240; // 12 * 20; 410 nFac = 100; 411 pUnit = sCSS1_UNIT_pc; 412 break; 413 414 case FieldUnit::NONE: 415 case FieldUnit::FOOT: 416 case FieldUnit::MILE: 417 case FieldUnit::CUSTOM: 418 case FieldUnit::PERCENT: 419 case FieldUnit::INCH: 420 default: 421 OSL_ENSURE( FieldUnit::INCH == eUnit, "Measuring unit not supported" ); 422 // 0.01in = 14.4twip (not exact, but the UI is also not exact) 423 nMul = 1000; 424 nDiv = 1440; // 72 * 20; 425 nFac = 100; 426 pUnit = sCSS1_UNIT_inch; 427 break; 428 } 429 430 long nLongVal = 0; 431 bool bOutLongVal = true; 432 if( nVal > LONG_MAX / nMul ) 433 { 434 sal_Int64 nBigVal( nVal ); 435 nBigVal *= nMul; 436 nBigVal /= nDiv; 437 nBigVal += 5; 438 nBigVal /= 10; 439 440 if( nBigVal <= LONG_MAX ) 441 { 442 // a long is sufficient 443 nLongVal = static_cast<long>(nBigVal); 444 } 445 else 446 { 447 rOut.append(nBigVal / static_cast<sal_Int64>(nFac)); 448 if( (nBigVal % static_cast<sal_Int64>(nFac)) != 0 ) 449 { 450 rOut.append('.'); 451 while( nFac > 1 && (nBigVal % static_cast<sal_Int64>(nFac)) != 0 ) 452 { 453 nFac /= 10; 454 rOut.append((nBigVal / static_cast<sal_Int64>(nFac)) % sal_Int64(10)); 455 } 456 } 457 bOutLongVal = false; 458 } 459 } 460 else 461 { 462 nLongVal = nVal * nMul; 463 nLongVal /= nDiv; 464 nLongVal += 5; 465 nLongVal /= 10; 466 } 467 468 if( bOutLongVal ) 469 { 470 rOut.append(OString::number(nLongVal/nFac)); 471 if( (nLongVal % nFac) != 0 ) 472 { 473 rOut.append('.'); 474 while( nFac > 1 && (nLongVal % nFac) != 0 ) 475 { 476 nFac /= 10; 477 rOut.append(OString::number((nLongVal / nFac) % 10)); 478 } 479 } 480 } 481 482 rOut.append(pUnit); 483 } 484 485 void SwHTMLWriter::OutCSS1_UnitProperty( const sal_Char *pProp, long nVal ) 486 { 487 OStringBuffer sOut; 488 AddUnitPropertyValue(sOut, nVal, m_eCSS1Unit); 489 OutCSS1_PropertyAscii(pProp, sOut.makeStringAndClear()); 490 } 491 492 void SwHTMLWriter::OutCSS1_PixelProperty( const sal_Char *pProp, long nVal, 493 bool bVert ) 494 { 495 OString sOut(OString::number(ToPixel(nVal,bVert)) + sCSS1_UNIT_px); 496 OutCSS1_PropertyAscii(pProp, sOut); 497 } 498 499 void SwHTMLWriter::OutStyleSheet( const SwPageDesc& rPageDesc ) 500 { 501 m_bFirstCSS1Rule = true; 502 503 // Feature: PrintExt 504 if( IsHTMLMode(HTMLMODE_PRINT_EXT) ) 505 { 506 const SwPageDesc *pFirstPageDesc = nullptr; 507 sal_uInt16 nFirstRefPoolId = RES_POOLPAGE_HTML; 508 m_bCSS1IgnoreFirstPageDesc = true; 509 510 // First we try to guess how the document is constructed. 511 // Allowed are only the templates: HTML, 1st page, left page, and right page. 512 // A first page is only exported, if it matches the template "1st page". 513 // Left and right pages are only exported, if their templates are linked. 514 // If other templates are used, only very simple cases are exported. 515 const SwPageDesc *pPageDesc = &rPageDesc; 516 const SwPageDesc *pFollow = rPageDesc.GetFollow(); 517 if( RES_POOLPAGE_FIRST == pPageDesc->GetPoolFormatId() && 518 pFollow != pPageDesc && 519 !IsPoolUserFormat( pFollow->GetPoolFormatId() ) ) 520 { 521 // the document has a first page 522 pFirstPageDesc = pPageDesc; 523 pPageDesc = pFollow; 524 pFollow = pPageDesc->GetFollow(); 525 } 526 527 IDocumentStylePoolAccess* pStylePoolAccess = &getIDocumentStylePoolAccess(); 528 if( pPageDesc == pFollow ) 529 { 530 // The document is one-sided; no matter what page, we do not create a 2-sided doc. 531 // The attribute is exported relative to the HTML page template. 532 OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, m_xTemplate.get(), 533 RES_POOLPAGE_HTML, true, false ); 534 nFirstRefPoolId = pFollow->GetPoolFormatId(); 535 } 536 else if( (RES_POOLPAGE_LEFT == pPageDesc->GetPoolFormatId() && 537 RES_POOLPAGE_RIGHT == pFollow->GetPoolFormatId()) || 538 (RES_POOLPAGE_RIGHT == pPageDesc->GetPoolFormatId() && 539 RES_POOLPAGE_LEFT == pFollow->GetPoolFormatId()) ) 540 { 541 // the document is double-sided 542 OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, m_xTemplate.get(), 543 RES_POOLPAGE_HTML, true ); 544 OutCSS1_SwPageDesc( *this, *pFollow, pStylePoolAccess, m_xTemplate.get(), 545 RES_POOLPAGE_HTML, true ); 546 nFirstRefPoolId = RES_POOLPAGE_RIGHT; 547 m_bCSS1IgnoreFirstPageDesc = false; 548 } 549 // other cases we miss 550 551 if( pFirstPageDesc ) 552 OutCSS1_SwPageDesc( *this, *pFirstPageDesc, pStylePoolAccess, m_xTemplate.get(), 553 nFirstRefPoolId, false ); 554 } 555 556 // The text body style has to be exported always (if it is changed compared 557 // to the template), because it is used as reference for any style 558 // that maps to <P>, and that's especially the standard style 559 getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_TEXT, false ); 560 561 // the Default-TextStyle is not also exported !! 562 // 0-Style is the Default; is never exported !! 563 const size_t nTextFormats = m_pDoc->GetTextFormatColls()->size(); 564 for( size_t i = 1; i < nTextFormats; ++i ) 565 { 566 const SwTextFormatColl* pColl = (*m_pDoc->GetTextFormatColls())[i]; 567 sal_uInt16 nPoolId = pColl->GetPoolFormatId(); 568 if( nPoolId == RES_POOLCOLL_TEXT || m_pDoc->IsUsed( *pColl ) ) 569 OutCSS1_SwFormat( *this, *pColl, &m_pDoc->getIDocumentStylePoolAccess(), m_xTemplate.get() ); 570 } 571 572 // the Default-TextStyle is not also exported !! 573 const size_t nCharFormats = m_pDoc->GetCharFormats()->size(); 574 for( size_t i = 1; i < nCharFormats; ++i ) 575 { 576 const SwCharFormat *pCFormat = (*m_pDoc->GetCharFormats())[i]; 577 sal_uInt16 nPoolId = pCFormat->GetPoolFormatId(); 578 if( nPoolId == RES_POOLCHR_INET_NORMAL || 579 nPoolId == RES_POOLCHR_INET_VISIT || 580 m_pDoc->IsUsed( *pCFormat ) ) 581 OutCSS1_SwFormat( *this, *pCFormat, &m_pDoc->getIDocumentStylePoolAccess(), m_xTemplate.get() ); 582 } 583 584 bool bHasEndNotes {false}; 585 bool bHasFootNotes {false}; 586 const SwFootnoteIdxs& rIdxs = m_pDoc->GetFootnoteIdxs(); 587 for( auto pIdx : rIdxs ) 588 { 589 if( pIdx->GetFootnote().IsEndNote() ) 590 { 591 bHasEndNotes = true; 592 if (bHasFootNotes) 593 break; 594 } 595 else 596 { 597 bHasFootNotes = true; 598 if (bHasEndNotes) 599 break; 600 } 601 } 602 OutCSS1_SwFootnoteInfo( *this, m_pDoc->GetFootnoteInfo(), m_pDoc, bHasFootNotes, false ); 603 OutCSS1_SwFootnoteInfo( *this, m_pDoc->GetEndNoteInfo(), m_pDoc, bHasEndNotes, true ); 604 605 if( !m_bFirstCSS1Rule ) 606 { 607 DecIndentLevel(); 608 609 OutNewLine(); 610 HTMLOutFuncs::Out_AsciiTag( Strm(), GetNamespace() + OOO_STRING_SVTOOLS_HTML_style, false ); 611 } 612 else 613 { 614 m_bFirstCSS1Rule = false; 615 } 616 617 m_nDfltTopMargin = 0; 618 m_nDfltBottomMargin = 0; 619 } 620 621 // if pPseudo is set, Styles-Sheets will be exported; 622 // otherwise we only search for Token and Class for a Format 623 sal_uInt16 SwHTMLWriter::GetCSS1Selector( const SwFormat *pFormat, OString& rToken, 624 OUString& rClass, sal_uInt16& rRefPoolId, 625 OUString *pPseudo ) 626 { 627 sal_uInt16 nDeep = 0; 628 rToken.clear(); 629 rClass.clear(); 630 rRefPoolId = 0; 631 if( pPseudo ) 632 pPseudo->clear(); 633 634 bool bChrFormat = RES_CHRFMT==pFormat->Which(); 635 636 // search formats above for the nearest standard or HTML-Tag template 637 const SwFormat *pPFormat = pFormat; 638 while( pPFormat && !pPFormat->IsDefault() ) 639 { 640 bool bStop = false; 641 sal_uInt16 nPoolId = pPFormat->GetPoolFormatId(); 642 if( USER_FMT & nPoolId ) 643 { 644 // user templates 645 const OUString& aNm(pPFormat->GetName()); 646 647 if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_blockquote) 648 { 649 rRefPoolId = RES_POOLCOLL_HTML_BLOCKQUOTE; 650 rToken = OString(OOO_STRING_SVTOOLS_HTML_blockquote); 651 } 652 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_citiation) 653 { 654 rRefPoolId = RES_POOLCHR_HTML_CITIATION; 655 rToken = OString(OOO_STRING_SVTOOLS_HTML_citiation); 656 } 657 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_code) 658 { 659 rRefPoolId = RES_POOLCHR_HTML_CODE; 660 rToken = OString(OOO_STRING_SVTOOLS_HTML_code); 661 } 662 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_definstance) 663 { 664 rRefPoolId = RES_POOLCHR_HTML_DEFINSTANCE; 665 rToken = OString(OOO_STRING_SVTOOLS_HTML_definstance); 666 } 667 else if (!bChrFormat && (aNm == OOO_STRING_SVTOOLS_HTML_dd || 668 aNm == OOO_STRING_SVTOOLS_HTML_dt)) 669 { 670 sal_uInt16 nDefListLvl = GetDefListLvl(aNm, nPoolId); 671 // Export the templates DD 1/DT 1, 672 // but none of their derived templates, 673 // also not DD 2/DT 2 etc. 674 if (nDefListLvl) 675 { 676 if (pPseudo && (nDeep || (nDefListLvl & 0x0fff) > 1)) 677 { 678 bStop = true; 679 } 680 else if (nDefListLvl & HTML_DLCOLL_DD) 681 { 682 rRefPoolId = RES_POOLCOLL_HTML_DD; 683 rToken = OString(OOO_STRING_SVTOOLS_HTML_dd); 684 } 685 else 686 { 687 rRefPoolId = RES_POOLCOLL_HTML_DT; 688 rToken = OString(OOO_STRING_SVTOOLS_HTML_dt); 689 } 690 } 691 } 692 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_emphasis) 693 { 694 rRefPoolId = RES_POOLCHR_HTML_EMPHASIS; 695 rToken = OString(OOO_STRING_SVTOOLS_HTML_emphasis); 696 } 697 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_horzrule) 698 { 699 // do not export HR ! 700 bStop = (nDeep==0); 701 } 702 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_keyboard) 703 { 704 rRefPoolId = RES_POOLCHR_HTML_KEYBOARD; 705 rToken = OString(OOO_STRING_SVTOOLS_HTML_keyboard); 706 } 707 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_listing) 708 { 709 // Export Listings as PRE or PRE-derived template 710 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt); 711 rRefPoolId = RES_POOLCOLL_HTML_PRE; 712 nDeep = CSS1_FMT_CMPREF; 713 } 714 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_preformtxt) 715 { 716 rRefPoolId = RES_POOLCOLL_HTML_PRE; 717 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt); 718 } 719 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_sample) 720 { 721 rRefPoolId = RES_POOLCHR_HTML_SAMPLE; 722 rToken = OString(OOO_STRING_SVTOOLS_HTML_sample); 723 } 724 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_strong) 725 { 726 rRefPoolId = RES_POOLCHR_HTML_STRONG; 727 rToken = OString(OOO_STRING_SVTOOLS_HTML_strong); 728 } 729 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_teletype) 730 { 731 rRefPoolId = RES_POOLCHR_HTML_TELETYPE; 732 rToken = OString(OOO_STRING_SVTOOLS_HTML_teletype); 733 } 734 else if (bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_variable) 735 { 736 rRefPoolId = RES_POOLCHR_HTML_VARIABLE; 737 rToken = OString(OOO_STRING_SVTOOLS_HTML_variable); 738 } 739 else if (!bChrFormat && aNm == OOO_STRING_SVTOOLS_HTML_xmp) 740 { 741 // export XMP as PRE (but not the template as Style) 742 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt); 743 rRefPoolId = RES_POOLCOLL_HTML_PRE; 744 nDeep = CSS1_FMT_CMPREF; 745 } 746 747 // if a PoolId is set, the Name of the template is that of the related Token 748 OSL_ENSURE( (rRefPoolId != 0) == (!rToken.isEmpty()), 749 "Token missing" ); 750 } 751 else 752 { 753 // Pool templates 754 switch( nPoolId ) 755 { 756 // paragraph templates 757 case RES_POOLCOLL_HEADLINE_BASE: 758 case RES_POOLCOLL_STANDARD: 759 // do not export this template 760 bStop = (nDeep==0); 761 break; 762 case RES_POOLCOLL_TEXT: 763 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak); 764 break; 765 case RES_POOLCOLL_HEADLINE1: 766 rToken = OString(OOO_STRING_SVTOOLS_HTML_head1); 767 break; 768 case RES_POOLCOLL_HEADLINE2: 769 rToken = OString(OOO_STRING_SVTOOLS_HTML_head2); 770 break; 771 case RES_POOLCOLL_HEADLINE3: 772 rToken = OString(OOO_STRING_SVTOOLS_HTML_head3); 773 break; 774 case RES_POOLCOLL_HEADLINE4: 775 rToken = OString(OOO_STRING_SVTOOLS_HTML_head4); 776 break; 777 case RES_POOLCOLL_HEADLINE5: 778 rToken = OString(OOO_STRING_SVTOOLS_HTML_head5); 779 break; 780 case RES_POOLCOLL_HEADLINE6: 781 rToken = OString(OOO_STRING_SVTOOLS_HTML_head6); 782 break; 783 case RES_POOLCOLL_SENDADRESS: 784 rToken = OString(OOO_STRING_SVTOOLS_HTML_address); 785 break; 786 case RES_POOLCOLL_HTML_BLOCKQUOTE: 787 rToken = OString(OOO_STRING_SVTOOLS_HTML_blockquote); 788 break; 789 case RES_POOLCOLL_HTML_PRE: 790 rToken = OString(OOO_STRING_SVTOOLS_HTML_preformtxt); 791 break; 792 793 case RES_POOLCOLL_HTML_DD: 794 rToken = OString(OOO_STRING_SVTOOLS_HTML_dd); 795 break; 796 case RES_POOLCOLL_HTML_DT: 797 rToken = OString(OOO_STRING_SVTOOLS_HTML_dt); 798 break; 799 800 case RES_POOLCOLL_TABLE: 801 if( pPseudo ) 802 { 803 rToken = OOO_STRING_SVTOOLS_HTML_tabledata " " 804 OOO_STRING_SVTOOLS_HTML_parabreak; 805 } 806 else 807 rToken = OOO_STRING_SVTOOLS_HTML_parabreak; 808 break; 809 case RES_POOLCOLL_TABLE_HDLN: 810 if( pPseudo ) 811 { 812 rToken = OOO_STRING_SVTOOLS_HTML_tableheader " " 813 OOO_STRING_SVTOOLS_HTML_parabreak; 814 } 815 else 816 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak); 817 break; 818 case RES_POOLCOLL_HTML_HR: 819 // do not export HR ! 820 bStop = (nDeep==0); 821 break; 822 case RES_POOLCOLL_FOOTNOTE: 823 if( !nDeep ) 824 { 825 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak); 826 rClass = OOO_STRING_SVTOOLS_HTML_sdfootnote; 827 rRefPoolId = RES_POOLCOLL_TEXT; 828 nDeep = CSS1_FMT_CMPREF; 829 } 830 break; 831 case RES_POOLCOLL_ENDNOTE: 832 if( !nDeep ) 833 { 834 rToken = OString(OOO_STRING_SVTOOLS_HTML_parabreak); 835 rClass = OOO_STRING_SVTOOLS_HTML_sdendnote; 836 rRefPoolId = RES_POOLCOLL_TEXT; 837 nDeep = CSS1_FMT_CMPREF; 838 } 839 break; 840 841 // character templates 842 case RES_POOLCHR_HTML_EMPHASIS: 843 rToken = OString(OOO_STRING_SVTOOLS_HTML_emphasis); 844 break; 845 case RES_POOLCHR_HTML_CITIATION: 846 rToken = OString(OOO_STRING_SVTOOLS_HTML_citiation); 847 break; 848 case RES_POOLCHR_HTML_STRONG: 849 rToken = OString(OOO_STRING_SVTOOLS_HTML_strong); 850 break; 851 case RES_POOLCHR_HTML_CODE: 852 rToken = OString(OOO_STRING_SVTOOLS_HTML_code); 853 break; 854 case RES_POOLCHR_HTML_SAMPLE: 855 rToken = OString(OOO_STRING_SVTOOLS_HTML_sample); 856 break; 857 case RES_POOLCHR_HTML_KEYBOARD: 858 rToken = OString(OOO_STRING_SVTOOLS_HTML_keyboard); 859 break; 860 case RES_POOLCHR_HTML_VARIABLE: 861 rToken = OString(OOO_STRING_SVTOOLS_HTML_variable); 862 break; 863 case RES_POOLCHR_HTML_DEFINSTANCE: 864 rToken = OString(OOO_STRING_SVTOOLS_HTML_definstance); 865 break; 866 case RES_POOLCHR_HTML_TELETYPE: 867 rToken = OString(OOO_STRING_SVTOOLS_HTML_teletype); 868 break; 869 870 case RES_POOLCHR_INET_NORMAL: 871 if( pPseudo ) 872 { 873 rToken = OString(OOO_STRING_SVTOOLS_HTML_anchor); 874 *pPseudo = OStringToOUString( sCSS1_link, RTL_TEXTENCODING_ASCII_US ); 875 } 876 break; 877 case RES_POOLCHR_INET_VISIT: 878 if( pPseudo ) 879 { 880 rToken = OString(OOO_STRING_SVTOOLS_HTML_anchor); 881 *pPseudo = OStringToOUString( sCSS1_visited, RTL_TEXTENCODING_ASCII_US ); 882 } 883 break; 884 } 885 886 // if a token is set, PoolId contains the related template 887 if( !rToken.isEmpty() && !rRefPoolId ) 888 rRefPoolId = nPoolId; 889 } 890 891 if( !rToken.isEmpty() || bStop ) 892 { 893 // stop if a HTML-Tag template was found 894 break; 895 } 896 else 897 { 898 // continue otherwise 899 nDeep++; 900 pPFormat = pPFormat->DerivedFrom(); 901 } 902 } 903 904 if( !rToken.isEmpty() ) 905 { 906 // this is a HTML-Tag template 907 if( !nDeep ) 908 nDeep = CSS1_FMT_ISTAG; 909 } 910 else 911 { 912 // this is not a HTML-Tag template nor derived from one 913 nDeep = 0; 914 } 915 if( nDeep > 0 && nDeep < CSS1_FMT_SPECIAL ) 916 { 917 // If the template is derived from a HTML template, 918 // we export it as <TOKEN>.<CLASS>, otherwise as .<CLASS>. 919 // <CLASS> is the name of the template after removing all characters 920 // before and including the first '.' 921 rClass = pFormat->GetName(); 922 sal_Int32 nPos = rClass.indexOf( '.' ); 923 if( nPos >= 0 && rClass.getLength() > nPos+1 ) 924 { 925 rClass = rClass.replaceAt( 0, nPos+1, "" ); 926 } 927 928 rClass = GetAppCharClass().lowercase( rClass ); 929 rClass = rClass.replaceAll( ".", "-" ); 930 rClass = rClass.replaceAll( " ", "-" ); 931 rClass = rClass.replaceAll( "_", "-" ); 932 } 933 934 return nDeep; 935 } 936 937 static sal_uInt16 GetCSS1Selector( const SwFormat *pFormat, OUString& rSelector, 938 sal_uInt16& rRefPoolId ) 939 { 940 OString aToken; 941 OUString aClass; 942 OUString aPseudo; 943 944 sal_uInt16 nDeep = SwHTMLWriter::GetCSS1Selector( pFormat, aToken, aClass, 945 rRefPoolId, &aPseudo ); 946 if( nDeep ) 947 { 948 if( !aToken.isEmpty() ) 949 rSelector = OStringToOUString(aToken, RTL_TEXTENCODING_ASCII_US); 950 else 951 rSelector.clear(); 952 953 if( !aClass.isEmpty() ) 954 rSelector += "." + aClass; 955 if( !aPseudo.isEmpty() ) 956 rSelector += ":" + aPseudo; 957 } 958 959 return nDeep; 960 } 961 962 const SwFormat *SwHTMLWriter::GetTemplateFormat( sal_uInt16 nPoolFormatId, 963 IDocumentStylePoolAccess* pTemplate /*SwDoc *pTemplate*/) 964 { 965 const SwFormat *pRefFormat = nullptr; 966 967 if( pTemplate ) 968 { 969 OSL_ENSURE( !(USER_FMT & nPoolFormatId), 970 "No user templates found" ); 971 if( POOLGRP_NOCOLLID & nPoolFormatId ) 972 pRefFormat = pTemplate->GetCharFormatFromPool( nPoolFormatId ); 973 else 974 pRefFormat = pTemplate->GetTextCollFromPool( nPoolFormatId, false ); 975 } 976 977 return pRefFormat; 978 } 979 980 const SwFormat *SwHTMLWriter::GetParentFormat( const SwFormat& rFormat, sal_uInt16 nDeep ) 981 { 982 OSL_ENSURE( nDeep != USHRT_MAX, "Called GetParent for HTML-template!" ); 983 const SwFormat *pRefFormat = nullptr; 984 985 if( nDeep > 0 ) 986 { 987 // get the pointer for the HTML-Tag template, from which the template is derived 988 pRefFormat = &rFormat; 989 for( sal_uInt16 i=nDeep; i>0; i-- ) 990 pRefFormat = pRefFormat->DerivedFrom(); 991 992 if( pRefFormat && pRefFormat->IsDefault() ) 993 pRefFormat = nullptr; 994 } 995 996 return pRefFormat; 997 } 998 999 bool swhtml_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 ) 1000 { 1001 return static_cast<const SvxFontItem &>(r1).GetFamilyName() == 1002 static_cast<const SvxFontItem &>(r2).GetFamilyName() && 1003 static_cast<const SvxFontItem &>(r1).GetFamily() == 1004 static_cast<const SvxFontItem &>(r2).GetFamily(); 1005 } 1006 1007 void SwHTMLWriter::SubtractItemSet( SfxItemSet& rItemSet, 1008 const SfxItemSet& rRefItemSet, 1009 bool bSetDefaults, 1010 bool bClearSame, 1011 const SfxItemSet *pRefScriptItemSet ) 1012 { 1013 OSL_ENSURE( bSetDefaults || bClearSame, 1014 "SwHTMLWriter::SubtractItemSet: No action for this Flag" ); 1015 SfxItemSet aRefItemSet( *rRefItemSet.GetPool(), rRefItemSet.GetRanges() ); 1016 aRefItemSet.Set( rRefItemSet ); 1017 1018 // compare with the Attr-Set of the template 1019 SfxWhichIter aIter( rItemSet ); 1020 sal_uInt16 nWhich = aIter.FirstWhich(); 1021 while( nWhich ) 1022 { 1023 const SfxPoolItem *pRefItem, *pItem; 1024 bool bItemSet = ( SfxItemState::SET == 1025 rItemSet.GetItemState( nWhich, false, &pItem) ); 1026 bool bRefItemSet; 1027 1028 if( pRefScriptItemSet ) 1029 { 1030 switch( nWhich ) 1031 { 1032 case RES_CHRATR_FONT: 1033 case RES_CHRATR_FONTSIZE: 1034 case RES_CHRATR_LANGUAGE: 1035 case RES_CHRATR_POSTURE: 1036 case RES_CHRATR_WEIGHT: 1037 case RES_CHRATR_CJK_FONT: 1038 case RES_CHRATR_CJK_FONTSIZE: 1039 case RES_CHRATR_CJK_LANGUAGE: 1040 case RES_CHRATR_CJK_POSTURE: 1041 case RES_CHRATR_CJK_WEIGHT: 1042 case RES_CHRATR_CTL_FONT: 1043 case RES_CHRATR_CTL_FONTSIZE: 1044 case RES_CHRATR_CTL_LANGUAGE: 1045 case RES_CHRATR_CTL_POSTURE: 1046 case RES_CHRATR_CTL_WEIGHT: 1047 bRefItemSet = ( SfxItemState::SET == 1048 pRefScriptItemSet->GetItemState( nWhich, true, &pRefItem) ); 1049 break; 1050 default: 1051 bRefItemSet = ( SfxItemState::SET == 1052 aRefItemSet.GetItemState( nWhich, false, &pRefItem) ); 1053 break; 1054 } 1055 } 1056 else 1057 { 1058 bRefItemSet = ( SfxItemState::SET == 1059 aRefItemSet.GetItemState( nWhich, false, &pRefItem) ); 1060 } 1061 1062 if( bItemSet ) 1063 { 1064 if( (bClearSame || pRefScriptItemSet) && bRefItemSet && 1065 ( *pItem == *pRefItem || 1066 ((RES_CHRATR_FONT == nWhich || 1067 RES_CHRATR_CJK_FONT == nWhich || 1068 RES_CHRATR_CTL_FONT == nWhich) && 1069 swhtml_css1atr_equalFontItems( *pItem, *pRefItem )) ) ) 1070 { 1071 // the Attribute is in both templates with the same value 1072 // and does not need to be exported 1073 rItemSet.ClearItem( nWhich ); 1074 } 1075 } 1076 else 1077 { 1078 if( (bSetDefaults || pRefScriptItemSet) && bRefItemSet ) 1079 { 1080 // the Attribute exists only in the reference; the default 1081 // might have to be exported 1082 rItemSet.Put( rItemSet.GetPool()->GetDefaultItem(nWhich) ); 1083 } 1084 } 1085 1086 nWhich = aIter.NextWhich(); 1087 } 1088 } 1089 1090 void SwHTMLWriter::PrepareFontList( const SvxFontItem& rFontItem, 1091 OUString& rNames, 1092 sal_Unicode cQuote, bool bGeneric ) 1093 { 1094 rNames.clear(); 1095 const OUString& rName = rFontItem.GetFamilyName(); 1096 bool bContainsKeyword = false; 1097 if( !rName.isEmpty() ) 1098 { 1099 sal_Int32 nStrPos = 0; 1100 while( nStrPos != -1 ) 1101 { 1102 OUString aName = rName.getToken( 0, ';', nStrPos ); 1103 aName = comphelper::string::strip(aName, ' '); 1104 if( aName.isEmpty() ) 1105 continue; 1106 1107 bool bIsKeyword = false; 1108 switch( aName[0] ) 1109 { 1110 case 'c': 1111 case 'C': 1112 bIsKeyword = aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_cursive ); 1113 break; 1114 1115 case 'f': 1116 case 'F': 1117 bIsKeyword = aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_fantasy ); 1118 break; 1119 1120 case 'm': 1121 case 'M': 1122 bIsKeyword = aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_monospace ); 1123 break; 1124 1125 case 's': 1126 case 'S': 1127 bIsKeyword = 1128 aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_serif ) || 1129 aName.equalsIgnoreAsciiCaseAscii( sCSS1_PV_sans_serif ); 1130 break; 1131 } 1132 1133 bContainsKeyword |= bIsKeyword; 1134 1135 if( !rNames.isEmpty() ) 1136 rNames += ", "; 1137 if( cQuote && !bIsKeyword ) 1138 rNames += OUStringLiteral1( cQuote ); 1139 rNames += aName; 1140 if( cQuote && !bIsKeyword ) 1141 rNames += OUStringLiteral1( cQuote ); 1142 } 1143 } 1144 1145 if( !bContainsKeyword && bGeneric ) 1146 { 1147 const sal_Char *pStr = nullptr; 1148 switch( rFontItem.GetFamily() ) 1149 { 1150 case FAMILY_ROMAN: pStr = sCSS1_PV_serif; break; 1151 case FAMILY_SWISS: pStr = sCSS1_PV_sans_serif; break; 1152 case FAMILY_SCRIPT: pStr = sCSS1_PV_cursive; break; 1153 case FAMILY_DECORATIVE: pStr = sCSS1_PV_fantasy; break; 1154 case FAMILY_MODERN: pStr = sCSS1_PV_monospace; break; 1155 default: 1156 ; 1157 } 1158 1159 if( pStr ) 1160 { 1161 if( !rNames.isEmpty() ) 1162 rNames += ", "; 1163 rNames += OStringToOUString( pStr, RTL_TEXTENCODING_ASCII_US ); 1164 } 1165 } 1166 } 1167 1168 bool SwHTMLWriter::HasScriptDependentItems( const SfxItemSet& rItemSet, 1169 bool bCheckDropCap ) 1170 { 1171 static const sal_uInt16 aWhichIds[] = 1172 { 1173 RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT, 1174 RES_CHRATR_FONTSIZE, RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CTL_FONTSIZE, 1175 RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE, 1176 RES_CHRATR_POSTURE, RES_CHRATR_CJK_POSTURE, RES_CHRATR_CTL_POSTURE, 1177 RES_CHRATR_WEIGHT, RES_CHRATR_CJK_WEIGHT, RES_CHRATR_CTL_WEIGHT, 1178 0, 0, 0 1179 }; 1180 1181 for( int i=0; aWhichIds[i]; i += 3 ) 1182 { 1183 const SfxPoolItem *pItem = nullptr, *pItemCJK = nullptr, *pItemCTL = nullptr, *pTmp; 1184 int nItemCount = 0; 1185 if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i], false, 1186 &pTmp ) ) 1187 { 1188 pItem = pTmp; 1189 nItemCount++; 1190 } 1191 if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i+1], false, 1192 &pTmp ) ) 1193 { 1194 pItemCJK = pTmp; 1195 nItemCount++; 1196 } 1197 if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i+2], false, 1198 &pTmp ) ) 1199 { 1200 pItemCTL = pTmp; 1201 nItemCount++; 1202 } 1203 1204 // If some of the items are set, but not all, we need script dependent 1205 // styles 1206 if( nItemCount > 0 && nItemCount < 3 ) 1207 return true; 1208 1209 if( 3 == nItemCount ) 1210 { 1211 // If all items are set, but some of them have different values, 1212 // we need script dependent styles, too. For font items, we have 1213 // to take care about their special HTML/CSS1 representation. 1214 if( RES_CHRATR_FONT == aWhichIds[i] ) 1215 { 1216 if( !swhtml_css1atr_equalFontItems( *pItem, *pItemCJK ) || 1217 !swhtml_css1atr_equalFontItems( *pItem, *pItemCTL ) || 1218 !swhtml_css1atr_equalFontItems( *pItemCJK, *pItemCTL ) ) 1219 return true; 1220 } 1221 else 1222 { 1223 if( *pItem != *pItemCJK || 1224 *pItem != *pItemCTL || 1225 *pItemCJK != *pItemCTL ) 1226 return true; 1227 } 1228 } 1229 } 1230 1231 const SfxPoolItem *pItem; 1232 if( bCheckDropCap && 1233 SfxItemState::SET == rItemSet.GetItemState( RES_PARATR_DROP, true, 1234 &pItem ) ) 1235 { 1236 const SwFormatDrop *pDrop = static_cast<const SwFormatDrop *>(pItem); 1237 const SwCharFormat *pDCCharFormat = pDrop->GetCharFormat(); 1238 if( pDCCharFormat ) 1239 { 1240 //sequence of (start, end) property ranges we want to 1241 //query 1242 SfxItemSet aTstItemSet( 1243 *pDCCharFormat->GetAttrSet().GetPool(), 1244 svl::Items< 1245 RES_CHRATR_FONT, RES_CHRATR_FONT, 1246 RES_CHRATR_POSTURE, RES_CHRATR_POSTURE, 1247 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT, 1248 RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT, 1249 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CTL_FONT, 1250 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT>{}); 1251 aTstItemSet.Set( pDCCharFormat->GetAttrSet() ); 1252 return HasScriptDependentItems( aTstItemSet, false ); 1253 } 1254 } 1255 1256 return false; 1257 } 1258 1259 static bool OutCSS1Rule( SwHTMLWriter& rHTMLWrt, const OUString& rSelector, 1260 const SfxItemSet& rItemSet, bool bHasClass, 1261 bool bCheckForPseudo ) 1262 { 1263 bool bScriptDependent = false; 1264 if( SwHTMLWriter::HasScriptDependentItems( rItemSet, bHasClass ) ) 1265 { 1266 bScriptDependent = true; 1267 OUString aSelector( rSelector ); 1268 1269 OUString aPseudo; 1270 if( bCheckForPseudo ) 1271 { 1272 sal_Int32 nPos = aSelector.lastIndexOf( ':' ); 1273 if( nPos >= 0 ) 1274 { 1275 aPseudo = aSelector.copy( nPos ); 1276 aSelector =aSelector.copy( 0, nPos ); 1277 } 1278 } 1279 1280 if( !bHasClass ) 1281 { 1282 // If we are exporting styles for a tag we have to export a tag 1283 // rule for all properties that aren't style dependent and 1284 // some class rule for the additional style dependen properties 1285 { 1286 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1287 &rSelector ); 1288 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false ); 1289 } 1290 1291 //sequence of (start, end) property ranges we want to 1292 //query 1293 SfxItemSet aScriptItemSet( *rItemSet.GetPool(), 1294 svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONTSIZE, 1295 RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE, 1296 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT, 1297 RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT>{} ); 1298 aScriptItemSet.Put( rItemSet ); 1299 1300 OUString aNewSelector( aSelector ); 1301 aNewSelector += ".western" + aPseudo; 1302 { 1303 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1304 &aNewSelector ); 1305 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, false ); 1306 } 1307 1308 aNewSelector = aSelector + ".cjk" + aPseudo; 1309 { 1310 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1311 &aNewSelector ); 1312 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, false ); 1313 } 1314 1315 aNewSelector = aSelector + ".ctl" + aPseudo; 1316 { 1317 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1318 &aNewSelector ); 1319 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, false ); 1320 } 1321 } 1322 else 1323 { 1324 // If there are script dependencies and we are derived from a tag, 1325 // when we have to export a style dependent class for all 1326 // scripts 1327 OUString aNewSelector( aSelector ); 1328 aNewSelector += "-western" + aPseudo; 1329 { 1330 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1331 &aNewSelector ); 1332 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false ); 1333 } 1334 1335 aNewSelector = aSelector + "-cjk" + aPseudo; 1336 { 1337 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1338 &aNewSelector ); 1339 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false ); 1340 } 1341 1342 aNewSelector = aSelector + "-ctl" + aPseudo; 1343 { 1344 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1345 &aNewSelector ); 1346 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false ); 1347 } 1348 } 1349 } 1350 else 1351 { 1352 // If there are no script dependencies, when all items are 1353 // exported in one step. For hyperlinks only, a script information 1354 // must be there, because these two chr formats don't support 1355 // script dependencies by now. 1356 SwCSS1OutMode aMode( rHTMLWrt, 1357 rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1358 &rSelector ); 1359 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false ); 1360 } 1361 1362 return bScriptDependent; 1363 } 1364 1365 static void OutCSS1DropCapRule( 1366 SwHTMLWriter& rHTMLWrt, const OUString& rSelector, 1367 const SwFormatDrop& rDrop, bool bHasClass, 1368 bool bHasScriptDependencies ) 1369 { 1370 const SwCharFormat *pDCCharFormat = rDrop.GetCharFormat(); 1371 if( (bHasScriptDependencies && bHasClass) || 1372 (pDCCharFormat && SwHTMLWriter::HasScriptDependentItems( pDCCharFormat->GetAttrSet(), false ) ) ) 1373 { 1374 OUString aSelector( rSelector ); 1375 1376 OUString aPseudo; 1377 sal_Int32 nPos = aSelector.lastIndexOf( ':' ); 1378 if( nPos >= 0 ) 1379 { 1380 aPseudo = aSelector.copy( nPos ); 1381 aSelector = aSelector.copy( 0, nPos ); 1382 } 1383 1384 if( !bHasClass ) 1385 { 1386 // If we are exporting styles for a tag we have to export a tag 1387 // rule for all properties that aren't style dependent and 1388 // some class rule for the additional style dependen properties 1389 { 1390 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1391 &rSelector ); 1392 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop ); 1393 } 1394 1395 SfxItemSet aScriptItemSet( rHTMLWrt.m_pDoc->GetAttrPool(), 1396 svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONTSIZE, 1397 RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE, 1398 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT, 1399 RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT>{} ); 1400 if( pDCCharFormat ) 1401 aScriptItemSet.Set( pDCCharFormat->GetAttrSet() ); 1402 1403 OUString aNewSelector( aSelector ); 1404 aNewSelector += ".western" + aPseudo; 1405 { 1406 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1407 &aNewSelector ); 1408 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet ); 1409 } 1410 1411 aNewSelector = aSelector + ".cjk" + aPseudo; 1412 { 1413 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1414 &aNewSelector ); 1415 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet ); 1416 } 1417 1418 aNewSelector = aSelector + ".ctl" + aPseudo; 1419 { 1420 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1421 &aNewSelector ); 1422 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet ); 1423 } 1424 } 1425 else 1426 { 1427 // If there are script dependencies and we are derived from a tag, 1428 // when we have to export a style dependent class for all 1429 // scripts 1430 OUString aNewSelector( aSelector ); 1431 aNewSelector += "-western" + aPseudo; 1432 { 1433 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1434 &aNewSelector ); 1435 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop ); 1436 } 1437 1438 aNewSelector = aSelector + "-cjk" + aPseudo; 1439 { 1440 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1441 &aNewSelector ); 1442 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop ); 1443 } 1444 1445 aNewSelector = aSelector + "-ctl" + aPseudo; 1446 { 1447 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1448 &aNewSelector ); 1449 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop ); 1450 } 1451 } 1452 } 1453 else 1454 { 1455 // If there are no script dependencies, when all items are 1456 // exported in one step. For hyperlinks only, a script information 1457 // must be there, because these two chr formats don't support 1458 // script dependencies by now. 1459 SwCSS1OutMode aMode( rHTMLWrt, 1460 rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP, 1461 &rSelector ); 1462 OutCSS1_SwFormatDropAttrs( rHTMLWrt, rDrop ); 1463 } 1464 } 1465 1466 static Writer& OutCSS1_SwFormat( Writer& rWrt, const SwFormat& rFormat, 1467 IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate ) 1468 { 1469 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 1470 1471 bool bCharFormat = false; 1472 switch( rFormat.Which() ) 1473 { 1474 case RES_CHRFMT: 1475 bCharFormat = true; 1476 break; 1477 1478 case RES_TXTFMTCOLL: 1479 case RES_CONDTXTFMTCOLL: 1480 // these template-types can be exported 1481 break; 1482 1483 default: 1484 // but not these 1485 return rWrt; 1486 } 1487 1488 // determine Selector and the to-be-exported Attr-Set-depth 1489 OUString aSelector; 1490 sal_uInt16 nRefPoolId = 0; 1491 sal_uInt16 nDeep = GetCSS1Selector( &rFormat, aSelector, nRefPoolId ); 1492 if( !nDeep ) 1493 return rWrt; // not derived from a HTML-template 1494 1495 sal_uInt16 nPoolFormatId = rFormat.GetPoolFormatId(); 1496 1497 // Determine the to-be-exported Attr-Set. We have to distinguish 3 cases: 1498 // - HTML-Tag templates (nDeep==USHRT_MAX): 1499 // Export Attrs... 1500 // - that are set in the template, but not in the original of the HTML template 1501 // - the Default-Attrs for the Attrs, that are set in the Original of the 1502 // HTML template, but not in the current template. 1503 // - templates directly derived from HTML templates (nDeep==1): 1504 // Export only Attributes of the template Item-Set w/o its parents. 1505 // - templates in-directly derived from HTML templates (nDeep>1): 1506 // Export Attributes of the template Item-Set incl. its Parents, 1507 // but w/o Attributes that are set in the HTML-Tag template. 1508 1509 // create Item-Set with all Attributes from the template 1510 // (all but for nDeep==1) 1511 const SfxItemSet& rFormatItemSet = rFormat.GetAttrSet(); 1512 SfxItemSet aItemSet( *rFormatItemSet.GetPool(), rFormatItemSet.GetRanges() ); 1513 aItemSet.Set( rFormatItemSet ); // Was nDeep!=1 that is not working 1514 // for script dependent items buts should 1515 // not make a difference for any other 1516 1517 bool bSetDefaults = true, bClearSame = true; 1518 const SwFormat *pRefFormat = nullptr; 1519 const SwFormat *pRefFormatScript = nullptr; 1520 switch( nDeep ) 1521 { 1522 case CSS1_FMT_ISTAG: 1523 pRefFormat = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pTemplate == nullptr ? nullptr : &pTemplate->getIDocumentStylePoolAccess() ); 1524 break; 1525 case CSS1_FMT_CMPREF: 1526 pRefFormat = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pDoc ); 1527 pRefFormatScript = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pTemplate == nullptr ? nullptr : &pTemplate->getIDocumentStylePoolAccess() ); 1528 bClearSame = false; 1529 break; 1530 default: 1531 pRefFormat = SwHTMLWriter::GetParentFormat( rFormat, nDeep ); 1532 pRefFormatScript = SwHTMLWriter::GetTemplateFormat( nRefPoolId, pTemplate == nullptr ? nullptr : &pTemplate->getIDocumentStylePoolAccess() ); 1533 bSetDefaults = false; 1534 break; 1535 } 1536 1537 if( pRefFormat ) 1538 { 1539 // subtract Item-Set of the Reference template (incl. its Parents) 1540 SwHTMLWriter::SubtractItemSet( aItemSet, pRefFormat->GetAttrSet(), 1541 bSetDefaults, bClearSame, 1542 pRefFormatScript 1543 ? &pRefFormatScript->GetAttrSet() 1544 : nullptr ); 1545 1546 if( !bCharFormat ) 1547 { 1548 const SvxULSpaceItem& rULItem = pRefFormat->GetULSpace(); 1549 rHTMLWrt.m_nDfltTopMargin = rULItem.GetUpper(); 1550 rHTMLWrt.m_nDfltBottomMargin = rULItem.GetLower(); 1551 } 1552 } 1553 else if( CSS1_FMT_ISTAG==nDeep && !bCharFormat ) 1554 { 1555 // set Default-distance above and below (for the 1556 // case that there is no reference template) 1557 rHTMLWrt.m_nDfltTopMargin = 0; 1558 rHTMLWrt.m_nDfltBottomMargin = HTML_PARSPACE; 1559 if( USER_FMT & nPoolFormatId ) 1560 { 1561 // user templates 1562 const OUString& aNm(rFormat.GetName()); 1563 1564 if (aNm == "DD 1" || aNm == "DT 1") 1565 rHTMLWrt.m_nDfltBottomMargin = 0; 1566 else if (aNm == OOO_STRING_SVTOOLS_HTML_listing) 1567 rHTMLWrt.m_nDfltBottomMargin = 0; 1568 else if (aNm == OOO_STRING_SVTOOLS_HTML_preformtxt) 1569 rHTMLWrt.m_nDfltBottomMargin = 0; 1570 else if (aNm == OOO_STRING_SVTOOLS_HTML_xmp) 1571 rHTMLWrt.m_nDfltBottomMargin = 0; 1572 } 1573 else 1574 { 1575 // Pool templates 1576 switch( nPoolFormatId ) 1577 { 1578 case RES_POOLCOLL_HEADLINE1: 1579 case RES_POOLCOLL_HEADLINE2: 1580 case RES_POOLCOLL_HEADLINE3: 1581 case RES_POOLCOLL_HEADLINE4: 1582 case RES_POOLCOLL_HEADLINE5: 1583 case RES_POOLCOLL_HEADLINE6: 1584 rHTMLWrt.m_nDfltTopMargin = HTML_HEADSPACE; 1585 break; 1586 case RES_POOLCOLL_SENDADRESS: 1587 case RES_POOLCOLL_HTML_DT: 1588 case RES_POOLCOLL_HTML_DD: 1589 case RES_POOLCOLL_HTML_PRE: 1590 rHTMLWrt.m_nDfltBottomMargin = 0; 1591 break; 1592 } 1593 } 1594 } 1595 1596 // if nothing is to be exported ... 1597 if( !aItemSet.Count() ) 1598 return rWrt; 1599 1600 // There is no support for script dependent hyperlinks by now. 1601 bool bCheckForPseudo = false; 1602 if( bCharFormat && 1603 (RES_POOLCHR_INET_NORMAL==nRefPoolId || 1604 RES_POOLCHR_INET_VISIT==nRefPoolId) ) 1605 bCheckForPseudo = true; 1606 1607 // export now the Attributes (incl. selector) 1608 bool bHasScriptDependencies = false; 1609 if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, CSS1_FMT_ISTAG != nDeep, 1610 bCheckForPseudo ) ) 1611 { 1612 if( bCharFormat ) 1613 rHTMLWrt.m_aScriptTextStyles.insert( rFormat.GetName() ); 1614 else 1615 { 1616 if( nPoolFormatId==RES_POOLCOLL_TEXT ) 1617 rHTMLWrt.m_aScriptParaStyles.insert( pDoc->GetTextCollFromPool( RES_POOLCOLL_STANDARD, false )->GetName() ); 1618 rHTMLWrt.m_aScriptParaStyles.insert( rFormat.GetName() ); 1619 } 1620 bHasScriptDependencies = true; 1621 } 1622 1623 // export Drop-Caps 1624 const SfxPoolItem *pItem; 1625 if( SfxItemState::SET==aItemSet.GetItemState( RES_PARATR_DROP, false, &pItem )) 1626 { 1627 OUString sOut( aSelector ); 1628 sOut += ":" + OStringToOUString( sCSS1_first_letter, RTL_TEXTENCODING_ASCII_US ); 1629 const SwFormatDrop *pDrop = static_cast<const SwFormatDrop *>(pItem); 1630 OutCSS1DropCapRule( rHTMLWrt, sOut, *pDrop, CSS1_FMT_ISTAG != nDeep, bHasScriptDependencies ); 1631 } 1632 1633 return rWrt; 1634 } 1635 1636 static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rPageDesc, 1637 IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate, 1638 sal_uInt16 nRefPoolId, bool bExtRef, 1639 bool bPseudo ) 1640 { 1641 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 1642 1643 const SwPageDesc* pRefPageDesc = nullptr; 1644 if( !bExtRef ) 1645 pRefPageDesc = pDoc->GetPageDescFromPool( nRefPoolId, false ); 1646 else if( pTemplate ) 1647 pRefPageDesc = pTemplate->getIDocumentStylePoolAccess().GetPageDescFromPool( nRefPoolId, false ); 1648 1649 OUString aSelector = "@" + OStringToOUString( sCSS1_page, RTL_TEXTENCODING_ASCII_US ); 1650 1651 if( bPseudo ) 1652 { 1653 const sal_Char *pPseudo = nullptr; 1654 switch( rPageDesc.GetPoolFormatId() ) 1655 { 1656 case RES_POOLPAGE_FIRST: pPseudo = sCSS1_first; break; 1657 case RES_POOLPAGE_LEFT: pPseudo = sCSS1_left; break; 1658 case RES_POOLPAGE_RIGHT: pPseudo = sCSS1_right; break; 1659 } 1660 if( pPseudo ) 1661 aSelector += ":" + OStringToOUString( pPseudo, RTL_TEXTENCODING_ASCII_US ); 1662 } 1663 1664 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE_ON|CSS1_OUTMODE_TEMPLATE, 1665 &aSelector ); 1666 1667 // Size: If the only difference is the Landscape-Flag, 1668 // only export Portrait or Landscape. Otherwise export size. 1669 bool bRefLandscape = pRefPageDesc && pRefPageDesc->GetLandscape(); 1670 Size aRefSz; 1671 const Size& rSz = rPageDesc.GetMaster().GetFrameSize().GetSize(); 1672 if( pRefPageDesc ) 1673 { 1674 aRefSz = pRefPageDesc->GetMaster().GetFrameSize().GetSize(); 1675 if( bRefLandscape != rPageDesc.GetLandscape() ) 1676 { 1677 long nTmp = aRefSz.Height(); 1678 aRefSz.setHeight( aRefSz.Width() ); 1679 aRefSz.setWidth( nTmp ); 1680 } 1681 } 1682 1683 // TODO: Bad Hack: On the Page-Tabpage there are small rounding errors 1684 // for the page size. Partially because of bug 25535, we stupidly still 1685 // use the Size-Item from Dialog, even if nothing changed. 1686 // Thus: once one visited the Page-Dialog and left it with OK, we get a 1687 // new page size that then gets exported here. To avoid that, we allow 1688 // here small deviations. 1689 if( std::abs( rSz.Width() - aRefSz.Width() ) <= 2 && 1690 std::abs( rSz.Height() - aRefSz.Height() ) <= 2 ) 1691 { 1692 if( bRefLandscape != rPageDesc.GetLandscape() ) 1693 { 1694 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size, 1695 rPageDesc.GetLandscape() ? sCSS1_PV_landscape 1696 : sCSS1_PV_portrait ); 1697 } 1698 } 1699 else 1700 { 1701 OStringBuffer sVal; 1702 AddUnitPropertyValue(sVal, rSz.Width(), rHTMLWrt.GetCSS1Unit()); 1703 sVal.append(' '); 1704 AddUnitPropertyValue(sVal, rSz.Height(), rHTMLWrt.GetCSS1Unit()); 1705 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_size, sVal.makeStringAndClear()); 1706 } 1707 1708 // Export the distance-Attributes as normally 1709 const SwFrameFormat &rMaster = rPageDesc.GetMaster(); 1710 SfxItemSet aItemSet( *rMaster.GetAttrSet().GetPool(), 1711 svl::Items<RES_LR_SPACE, RES_UL_SPACE>{} ); 1712 aItemSet.Set( rMaster.GetAttrSet() ); 1713 1714 if( pRefPageDesc ) 1715 { 1716 SwHTMLWriter::SubtractItemSet( aItemSet, 1717 pRefPageDesc->GetMaster().GetAttrSet(), 1718 true ); 1719 } 1720 1721 OutCSS1_SvxULSpace_SvxLRSpace( rWrt, aItemSet ); 1722 1723 // If for a Pseudo-Selector no Property had been set, we still 1724 // have to export something, so that the corresponding template is 1725 // created on the next import. 1726 if( rHTMLWrt.m_bFirstCSS1Property && bPseudo ) 1727 { 1728 rHTMLWrt.OutNewLine(); 1729 OString sTmp(OUStringToOString(aSelector, rHTMLWrt.m_eDestEnc)); 1730 rWrt.Strm().WriteCharPtr( sTmp.getStr() ).WriteCharPtr( " {" ); 1731 rHTMLWrt.m_bFirstCSS1Property = false; 1732 } 1733 1734 if( !rHTMLWrt.m_bFirstCSS1Property ) 1735 rWrt.Strm().WriteCharPtr( sCSS1_rule_end ); 1736 1737 return rWrt; 1738 } 1739 1740 static Writer& OutCSS1_SwFootnoteInfo( Writer& rWrt, const SwEndNoteInfo& rInfo, 1741 SwDoc *pDoc, bool bHasNotes, bool bEndNote ) 1742 { 1743 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 1744 1745 OUString aSelector; 1746 1747 if( bHasNotes ) 1748 { 1749 aSelector = OOO_STRING_SVTOOLS_HTML_anchor "." + 1750 ( bEndNote ? OUString(OOO_STRING_SVTOOLS_HTML_sdendnote_anc) 1751 : OUString(OOO_STRING_SVTOOLS_HTML_sdfootnote_anc) ); 1752 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE, 1753 &aSelector ); 1754 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size, 1755 sHTML_FTN_fontheight ); 1756 rHTMLWrt.Strm().WriteCharPtr( sCSS1_rule_end ); 1757 } 1758 1759 const SwCharFormat *pSymCharFormat = rInfo.GetCharFormat( *pDoc ); 1760 if( pSymCharFormat ) 1761 { 1762 const SfxItemSet& rFormatItemSet = pSymCharFormat->GetAttrSet(); 1763 SfxItemSet aItemSet( *rFormatItemSet.GetPool(), rFormatItemSet.GetRanges() ); 1764 aItemSet.Set( rFormatItemSet ); 1765 1766 // If there are footnotes or endnotes, then all Attributes have to be 1767 // exported, so that Netscape displays the document correctly. 1768 // Otherwise it is sufficient, to export the differences to the 1769 // footnote and endnote template. 1770 if( !bHasNotes && rHTMLWrt.m_xTemplate.is() ) 1771 { 1772 SwFormat *pRefFormat = rHTMLWrt.m_xTemplate->getIDocumentStylePoolAccess().GetCharFormatFromPool( 1773 static_cast< sal_uInt16 >(bEndNote ? RES_POOLCHR_ENDNOTE : RES_POOLCHR_FOOTNOTE) ); 1774 if( pRefFormat ) 1775 SwHTMLWriter::SubtractItemSet( aItemSet, pRefFormat->GetAttrSet(), 1776 true ); 1777 } 1778 if( aItemSet.Count() ) 1779 { 1780 aSelector = OOO_STRING_SVTOOLS_HTML_anchor "." + 1781 ( bEndNote ? OUString(OOO_STRING_SVTOOLS_HTML_sdendnote_sym) 1782 : OUString(OOO_STRING_SVTOOLS_HTML_sdfootnote_sym)); 1783 if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, true, false )) 1784 rHTMLWrt.m_aScriptTextStyles.insert( pSymCharFormat->GetName() ); 1785 } 1786 } 1787 1788 return rWrt; 1789 } 1790 1791 Writer& OutCSS1_BodyTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet ) 1792 { 1793 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 1794 1795 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON | 1796 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_BODY, nullptr ); 1797 1798 // Only export the attributes of the page template. 1799 // The attributes of the default paragraph template were 1800 // considered already when exporting the paragraph template. 1801 1802 const SfxPoolItem *pItem; 1803 if( SfxItemState::SET == rItemSet.GetItemState( RES_BACKGROUND, false, 1804 &pItem ) ) 1805 { 1806 OUString rEmbeddedGraphicName; 1807 OutCSS1_SvxBrush( rWrt, *pItem, Css1Background::Page, &rEmbeddedGraphicName ); 1808 } 1809 1810 if( SfxItemState::SET == rItemSet.GetItemState( RES_BOX, false, 1811 &pItem )) 1812 { 1813 OutCSS1_SvxBox( rWrt, *pItem ); 1814 } 1815 1816 if( !rHTMLWrt.m_bFirstCSS1Property ) 1817 { 1818 // if a Property was exported as part of a Style-Option, 1819 // the Option still needs to be finished 1820 rWrt.Strm().WriteChar( '\"' ); 1821 } 1822 1823 return rWrt; 1824 } 1825 1826 Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet ) 1827 { 1828 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 1829 1830 SwCSS1OutMode aMode( rHTMLWrt, rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_STYLE_OPT | 1831 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA, nullptr ); 1832 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, false ); 1833 1834 return rWrt; 1835 } 1836 1837 // Wrapper for Table background 1838 Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt ) 1839 { 1840 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 1841 1842 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON | 1843 CSS1_OUTMODE_ENCODE| 1844 CSS1_OUTMODE_TABLEBOX, nullptr ); 1845 OutCSS1_SvxBrush( rWrt, rHt, Css1Background::Table, nullptr ); 1846 1847 if( !rHTMLWrt.m_bFirstCSS1Property ) 1848 rWrt.Strm().WriteChar( '\"' ); 1849 1850 return rWrt; 1851 } 1852 1853 Writer& OutCSS1_NumBulListStyleOpt( Writer& rWrt, const SwNumRule& rNumRule, 1854 sal_uInt8 nLevel ) 1855 { 1856 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 1857 1858 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT | 1859 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA, nullptr ); 1860 1861 const SwNumFormat& rNumFormat = rNumRule.Get( nLevel ); 1862 1863 long nLSpace = rNumFormat.GetAbsLSpace(); 1864 long nFirstLineOffset = rNumFormat.GetFirstLineOffset(); 1865 long nDfltFirstLineOffset = HTML_NUMBUL_INDENT; 1866 if( nLevel > 0 ) 1867 { 1868 const SwNumFormat& rPrevNumFormat = rNumRule.Get( nLevel-1 ); 1869 nLSpace -= rPrevNumFormat.GetAbsLSpace(); 1870 nDfltFirstLineOffset = rPrevNumFormat.GetFirstLineOffset(); 1871 } 1872 1873 if( rHTMLWrt.IsHTMLMode(HTMLMODE_LSPACE_IN_NUMBUL) && 1874 nLSpace != HTML_NUMBUL_MARGINLEFT ) 1875 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLSpace ); 1876 1877 if( rHTMLWrt.IsHTMLMode(HTMLMODE_FRSTLINE_IN_NUMBUL) && 1878 nFirstLineOffset != nDfltFirstLineOffset ) 1879 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent, nFirstLineOffset ); 1880 1881 if( !rHTMLWrt.m_bFirstCSS1Property ) 1882 rWrt.Strm().WriteChar( '\"' ); 1883 1884 return rWrt; 1885 } 1886 1887 void SwHTMLWriter::OutCSS1_FrameFormatOptions( const SwFrameFormat& rFrameFormat, 1888 HtmlFrmOpts nFrameOpts, 1889 const SdrObject *pSdrObj, 1890 const SfxItemSet *pItemSet ) 1891 { 1892 SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON | 1893 CSS1_OUTMODE_ENCODE| 1894 CSS1_OUTMODE_FRAME, nullptr ); 1895 1896 const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient(); 1897 SvxLRSpaceItem aLRItem( rFrameFormat.GetLRSpace() ); 1898 SvxULSpaceItem aULItem( rFrameFormat.GetULSpace() ); 1899 if( nFrameOpts & HtmlFrmOpts::SAlign ) 1900 { 1901 const SwFormatAnchor& rAnchor = rFrameFormat.GetAnchor(); 1902 switch( rAnchor.GetAnchorId() ) 1903 { 1904 case RndStdIds::FLY_AT_PARA: 1905 case RndStdIds::FLY_AT_CHAR: 1906 if( text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() || 1907 text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() ) 1908 { 1909 if( !(nFrameOpts & HtmlFrmOpts::Align) ) 1910 { 1911 // float 1912 const sal_Char *pStr = text::HoriOrientation::RIGHT==rHoriOri.GetHoriOrient() 1913 ? sCSS1_PV_right 1914 : sCSS1_PV_left; 1915 OutCSS1_PropertyAscii( sCSS1_P_float, pStr ); 1916 } 1917 break; 1918 } 1919 [[fallthrough]]; 1920 1921 case RndStdIds::FLY_AT_PAGE: 1922 case RndStdIds::FLY_AT_FLY: 1923 { 1924 // position 1925 OutCSS1_PropertyAscii( sCSS1_P_position, sCSS1_PV_absolute ); 1926 1927 // For top/left we need to subtract the distance to the frame 1928 // from the position, as in CSS1 it is added to the position. 1929 // This works also for automatically aligned frames, even that 1930 // in this case Writer also adds the distance; because in this 1931 // case the Orient-Attribute contains the correct position. 1932 1933 // top 1934 long nXPos=0, nYPos=0; 1935 bool bOutXPos = false, bOutYPos = false; 1936 if( RES_DRAWFRMFMT == rFrameFormat.Which() ) 1937 { 1938 OSL_ENSURE( pSdrObj, "Do not pass a SdrObject. Inefficient" ); 1939 if( !pSdrObj ) 1940 pSdrObj = rFrameFormat.FindSdrObject(); 1941 OSL_ENSURE( pSdrObj, "Where is the SdrObject" ); 1942 if( pSdrObj ) 1943 { 1944 Point aPos( pSdrObj->GetRelativePos() ); 1945 nXPos = aPos.X(); 1946 nYPos = aPos.Y(); 1947 } 1948 bOutXPos = bOutYPos = true; 1949 } 1950 else 1951 { 1952 bOutXPos = text::RelOrientation::CHAR != rHoriOri.GetRelationOrient(); 1953 nXPos = text::HoriOrientation::NONE == rHoriOri.GetHoriOrient() 1954 ? rHoriOri.GetPos() : 0; 1955 1956 const SwFormatVertOrient& rVertOri = rFrameFormat.GetVertOrient(); 1957 bOutYPos = text::RelOrientation::CHAR != rVertOri.GetRelationOrient(); 1958 nYPos = text::VertOrientation::NONE == rVertOri.GetVertOrient() 1959 ? rVertOri.GetPos() : 0; 1960 } 1961 1962 if( bOutYPos ) 1963 { 1964 if( IsHTMLMode( HTMLMODE_FLY_MARGINS) ) 1965 { 1966 nYPos -= aULItem.GetUpper(); 1967 if( nYPos < 0 ) 1968 { 1969 aULItem.SetUpper( static_cast<sal_uInt16>(aULItem.GetUpper() + nYPos) ); 1970 nYPos = 0; 1971 } 1972 } 1973 1974 OutCSS1_UnitProperty( sCSS1_P_top, nYPos ); 1975 } 1976 1977 if( bOutXPos ) 1978 { 1979 // left 1980 if( IsHTMLMode( HTMLMODE_FLY_MARGINS) ) 1981 { 1982 nXPos -= aLRItem.GetLeft(); 1983 if( nXPos < 0 ) 1984 { 1985 aLRItem.SetLeft( static_cast<sal_uInt16>(aLRItem.GetLeft() + nXPos) ); 1986 nXPos = 0; 1987 } 1988 } 1989 1990 OutCSS1_UnitProperty( sCSS1_P_left, nXPos ); 1991 } 1992 } 1993 break; 1994 1995 default: 1996 ; 1997 } 1998 } 1999 2000 // width/height 2001 if( nFrameOpts & HtmlFrmOpts::SSize ) 2002 { 2003 if( RES_DRAWFRMFMT == rFrameFormat.Which() ) 2004 { 2005 OSL_ENSURE( pSdrObj, "Do not pass a SdrObject. Inefficient" ); 2006 if( !pSdrObj ) 2007 pSdrObj = rFrameFormat.FindSdrObject(); 2008 OSL_ENSURE( pSdrObj, "Where is the SdrObject" ); 2009 if( pSdrObj ) 2010 { 2011 Size aTwipSz( pSdrObj->GetLogicRect().GetSize() ); 2012 if( nFrameOpts & HtmlFrmOpts::SWidth ) 2013 { 2014 if( nFrameOpts & HtmlFrmOpts::SPixSize ) 2015 OutCSS1_PixelProperty( sCSS1_P_width, aTwipSz.Width(), 2016 false ); 2017 else 2018 OutCSS1_UnitProperty( sCSS1_P_width, aTwipSz.Width() ); 2019 } 2020 if( nFrameOpts & HtmlFrmOpts::SHeight ) 2021 { 2022 if( nFrameOpts & HtmlFrmOpts::SPixSize ) 2023 OutCSS1_PixelProperty( sCSS1_P_height, aTwipSz.Height(), 2024 true ); 2025 else 2026 OutCSS1_UnitProperty( sCSS1_P_height, aTwipSz.Height() ); 2027 } 2028 } 2029 } 2030 else 2031 { 2032 OSL_ENSURE( HtmlFrmOpts::AbsSize & nFrameOpts, 2033 "Export absolute size" ); 2034 OSL_ENSURE( HtmlFrmOpts::AnySize & nFrameOpts, 2035 "Export every size" ); 2036 Css1FrameSize nMode = Css1FrameSize::NONE; 2037 if( nFrameOpts & HtmlFrmOpts::SWidth ) 2038 nMode |= Css1FrameSize::Width; 2039 if( nFrameOpts & HtmlFrmOpts::SHeight ) 2040 nMode |= Css1FrameSize::MinHeight|Css1FrameSize::FixHeight; 2041 if( nFrameOpts & HtmlFrmOpts::SPixSize ) 2042 nMode |= Css1FrameSize::Pixel; 2043 2044 OutCSS1_SwFormatFrameSize( *this, rFrameFormat.GetFrameSize(), nMode ); 2045 } 2046 } 2047 2048 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet(); 2049 // margin-* 2050 if( (nFrameOpts & HtmlFrmOpts::SSpace) && 2051 IsHTMLMode( HTMLMODE_FLY_MARGINS) ) 2052 { 2053 const SvxLRSpaceItem *pLRItem = nullptr; 2054 const SvxULSpaceItem *pULItem = nullptr; 2055 if( SfxItemState::SET == rItemSet.GetItemState( RES_LR_SPACE ) ) 2056 pLRItem = &aLRItem; 2057 if( SfxItemState::SET == rItemSet.GetItemState( RES_UL_SPACE ) ) 2058 pULItem = &aULItem; 2059 if( pLRItem || pULItem ) 2060 OutCSS1_SvxULSpace_SvxLRSpace( *this, pULItem, pLRItem ); 2061 } 2062 2063 // border 2064 if( nFrameOpts & HtmlFrmOpts::SBorder ) 2065 { 2066 const SfxPoolItem* pItem; 2067 if( nFrameOpts & HtmlFrmOpts::SNoBorder ) 2068 OutCSS1_SvxBox( *this, rFrameFormat.GetBox() ); 2069 else if( SfxItemState::SET==rItemSet.GetItemState( RES_BOX, true, &pItem ) ) 2070 OutCSS1_SvxBox( *this, *pItem ); 2071 } 2072 2073 // background (if, then the color must be set also) 2074 if( nFrameOpts & HtmlFrmOpts::SBackground ) 2075 OutCSS1_FrameFormatBackground( rFrameFormat ); 2076 2077 if( pItemSet ) 2078 OutCSS1_SfxItemSet( *pItemSet, false ); 2079 2080 if( !m_bFirstCSS1Property ) 2081 Strm().WriteChar( '\"' ); 2082 } 2083 2084 void SwHTMLWriter::OutCSS1_TableFrameFormatOptions( const SwFrameFormat& rFrameFormat ) 2085 { 2086 SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON | 2087 CSS1_OUTMODE_ENCODE| 2088 CSS1_OUTMODE_TABLE, nullptr ); 2089 2090 const SfxPoolItem *pItem; 2091 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet(); 2092 if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) ) 2093 OutCSS1_SvxBrush( *this, *pItem, Css1Background::Table, nullptr ); 2094 2095 if( IsHTMLMode( HTMLMODE_PRINT_EXT ) ) 2096 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet, false ); 2097 2098 if( SfxItemState::SET==rItemSet.GetItemState( RES_LAYOUT_SPLIT, false, &pItem ) ) 2099 OutCSS1_SwFormatLayoutSplit( *this, *pItem ); 2100 2101 if( !m_bFirstCSS1Property ) 2102 Strm().WriteChar( '\"' ); 2103 } 2104 2105 void SwHTMLWriter::OutCSS1_TableCellBorderHack(SwFrameFormat const& rFrameFormat) 2106 { 2107 SwCSS1OutMode const aMode( *this, 2108 CSS1_OUTMODE_STYLE_OPT_ON|CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_TABLEBOX, nullptr ); 2109 OutCSS1_SvxBox(*this, rFrameFormat.GetBox()); 2110 if (!m_bFirstCSS1Property) 2111 { 2112 Strm().WriteChar( cCSS1_style_opt_end ); 2113 } 2114 } 2115 2116 void SwHTMLWriter::OutCSS1_SectionFormatOptions( const SwFrameFormat& rFrameFormat, const SwFormatCol *pCol ) 2117 { 2118 SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON | 2119 CSS1_OUTMODE_ENCODE| 2120 CSS1_OUTMODE_SECTION, nullptr ); 2121 2122 const SfxPoolItem *pItem; 2123 const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet(); 2124 if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) ) 2125 OutCSS1_SvxBrush( *this, *pItem, Css1Background::Section, nullptr ); 2126 2127 if (pCol) 2128 { 2129 OString sColumnCount(OString::number(static_cast<sal_Int32>(pCol->GetNumCols()))); 2130 OutCSS1_PropertyAscii(sCSS1_P_column_count, sColumnCount); 2131 } 2132 2133 if( !m_bFirstCSS1Property ) 2134 Strm().WriteChar( '\"' ); 2135 } 2136 2137 static bool OutCSS1_FrameFormatBrush( SwHTMLWriter& rWrt, 2138 const SvxBrushItem& rBrushItem ) 2139 { 2140 bool bWritten = false; 2141 /// output brush of frame format, if its background color is not "no fill"/"auto fill" 2142 /// or it has a background graphic. 2143 if( rBrushItem.GetColor() != COL_TRANSPARENT || 2144 !rBrushItem.GetGraphicLink().isEmpty() || 2145 0 != rBrushItem.GetGraphicPos() ) 2146 { 2147 OutCSS1_SvxBrush( rWrt, rBrushItem, Css1Background::Fly, nullptr ); 2148 bWritten = true; 2149 } 2150 return bWritten; 2151 } 2152 2153 void SwHTMLWriter::OutCSS1_FrameFormatBackground( const SwFrameFormat& rFrameFormat ) 2154 { 2155 // If the frame itself has a background, then export. 2156 if( OutCSS1_FrameFormatBrush( *this, rFrameFormat.makeBackgroundBrushItem() ) ) 2157 return; 2158 2159 // If the frame is not linked to a page, we use the background of the anchor. 2160 const SwFormatAnchor& rAnchor = rFrameFormat.GetAnchor(); 2161 RndStdIds eAnchorId = rAnchor.GetAnchorId(); 2162 const SwPosition *pAnchorPos = rAnchor.GetContentAnchor(); 2163 if (RndStdIds::FLY_AT_PAGE != eAnchorId && pAnchorPos) 2164 { 2165 const SwNode& rNode = pAnchorPos->nNode.GetNode(); 2166 if( rNode.IsContentNode() ) 2167 { 2168 // If the frame is linked to a content-node, 2169 // we take the background of the content-node, if it has one. 2170 if( OutCSS1_FrameFormatBrush( *this, 2171 rNode.GetContentNode()->GetSwAttrSet().GetBackground()) ) 2172 return; 2173 2174 // Otherwise we also could be in a table 2175 const SwTableNode *pTableNd = rNode.FindTableNode(); 2176 if( pTableNd ) 2177 { 2178 const SwStartNode *pBoxSttNd = rNode.FindTableBoxStartNode(); 2179 const SwTableBox *pBox = 2180 pTableNd->GetTable().GetTableBox( pBoxSttNd->GetIndex() ); 2181 2182 // If the box has a background, we take it. 2183 if( OutCSS1_FrameFormatBrush( *this, 2184 pBox->GetFrameFormat()->makeBackgroundBrushItem() ) ) 2185 return; 2186 2187 // Otherwise we use that of the lines 2188 const SwTableLine *pLine = pBox->GetUpper(); 2189 while( pLine ) 2190 { 2191 if( OutCSS1_FrameFormatBrush( *this, 2192 pLine->GetFrameFormat()->makeBackgroundBrushItem() ) ) 2193 return; 2194 pBox = pLine->GetUpper(); 2195 pLine = pBox ? pBox->GetUpper() : nullptr; 2196 } 2197 2198 // If there was none either, we use the background of the table. 2199 if( OutCSS1_FrameFormatBrush( *this, 2200 pTableNd->GetTable().GetFrameFormat()->makeBackgroundBrushItem() ) ) 2201 return; 2202 } 2203 2204 } 2205 2206 // If the anchor is again in a Fly-Frame, use the background of the Fly-Frame. 2207 const SwFrameFormat *pFrameFormat = rNode.GetFlyFormat(); 2208 if( pFrameFormat ) 2209 { 2210 OutCSS1_FrameFormatBackground( *pFrameFormat ); 2211 return; 2212 } 2213 } 2214 2215 // At last there is the background of the page, and as the final rescue 2216 // the value of the Config. 2217 OSL_ENSURE( m_pCurrPageDesc, "no page template found" ); 2218 if( !OutCSS1_FrameFormatBrush( *this, 2219 m_pCurrPageDesc->GetMaster().makeBackgroundBrushItem() ) ) 2220 { 2221 Color aColor( COL_WHITE ); 2222 2223 // The background color is normally only used in Browse-Mode. 2224 // We always use it for a HTML document, but for a text document 2225 // only if viewed in Browse-Mode. 2226 if( m_pDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) || 2227 m_pDoc->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE)) 2228 { 2229 SwViewShell *pVSh = m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(); 2230 if ( pVSh && 2231 COL_TRANSPARENT != pVSh->GetViewOptions()->GetRetoucheColor()) 2232 aColor = pVSh->GetViewOptions()->GetRetoucheColor(); 2233 } 2234 2235 OutCSS1_PropertyAscii(sCSS1_P_background, GetCSS1_Color(aColor)); 2236 } 2237 } 2238 2239 static Writer& OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( Writer& rWrt, 2240 const SvxUnderlineItem *pUItem, 2241 const SvxOverlineItem *pOItem, 2242 const SvxCrossedOutItem *pCOItem, 2243 const SvxBlinkItem *pBItem ) 2244 { 2245 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2246 bool bNone = false; 2247 2248 const sal_Char *pUStr = nullptr; 2249 if( pUItem ) 2250 { 2251 switch( pUItem->GetLineStyle() ) 2252 { 2253 case LINESTYLE_NONE: 2254 bNone = true; 2255 break; 2256 case LINESTYLE_DONTKNOW: 2257 break; 2258 default: 2259 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2260 { 2261 // this also works in HTML does not need to be written as 2262 // a STYLE-Options, and must not be written as Hint 2263 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) || rHTMLWrt.mbReqIF, 2264 "write underline as Hint?" ); 2265 pUStr = sCSS1_PV_underline; 2266 } 2267 break; 2268 } 2269 } 2270 2271 const sal_Char *pOStr = nullptr; 2272 if( pOItem ) 2273 { 2274 switch( pOItem->GetLineStyle() ) 2275 { 2276 case LINESTYLE_NONE: 2277 bNone = true; 2278 break; 2279 case LINESTYLE_DONTKNOW: 2280 break; 2281 default: 2282 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2283 { 2284 // this also works in HTML does not need to be written as 2285 // a STYLE-Options, and must not be written as Hint 2286 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), 2287 "write overline as Hint?" ); 2288 pOStr = sCSS1_PV_overline; 2289 } 2290 break; 2291 } 2292 } 2293 2294 const sal_Char *pCOStr = nullptr; 2295 if( pCOItem ) 2296 { 2297 switch( pCOItem->GetStrikeout() ) 2298 { 2299 case STRIKEOUT_NONE: 2300 bNone = true; 2301 break; 2302 case STRIKEOUT_DONTKNOW: 2303 break; 2304 default: 2305 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2306 { 2307 // this also works in HTML does not need to be written as 2308 // a STYLE-Options, and must not be written as Hint 2309 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) || rHTMLWrt.mbReqIF, 2310 "write crossedOut as Hint?" ); 2311 pCOStr = sCSS1_PV_line_through; 2312 } 2313 break; 2314 } 2315 } 2316 2317 const sal_Char *pBStr = nullptr; 2318 if( pBItem ) 2319 { 2320 if( !pBItem->GetValue() ) 2321 { 2322 bNone = true; 2323 } 2324 else if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2325 { 2326 // this also works in HTML does not need to be written as 2327 // a STYLE-Options, and must not be written as Hint 2328 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), 2329 "write blink as Hint?" ); 2330 pBStr = sCSS1_PV_blink; 2331 } 2332 } 2333 2334 OStringBuffer sOut; 2335 if( pUStr ) 2336 sOut.append(pUStr); 2337 2338 if( pOStr ) 2339 { 2340 if (!sOut.isEmpty()) 2341 sOut.append(' '); 2342 sOut.append(pOStr); 2343 } 2344 2345 if( pCOStr ) 2346 { 2347 if (!sOut.isEmpty()) 2348 sOut.append(' '); 2349 sOut.append(pCOStr); 2350 } 2351 2352 if( pBStr ) 2353 { 2354 if (!sOut.isEmpty()) 2355 sOut.append(' '); 2356 sOut.append(pBStr); 2357 } 2358 2359 if (!sOut.isEmpty()) 2360 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sOut.makeStringAndClear() ); 2361 else if( bNone ) 2362 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sCSS1_PV_none ); 2363 2364 return rWrt; 2365 } 2366 2367 static Writer& OutCSS1_SvxCaseMap( Writer& rWrt, const SfxPoolItem& rHt ) 2368 { 2369 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2370 2371 switch( static_cast<const SvxCaseMapItem&>(rHt).GetCaseMap() ) 2372 { 2373 case SvxCaseMap::NotMapped: 2374 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, sCSS1_PV_normal ); 2375 break; 2376 case SvxCaseMap::SmallCaps: 2377 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, sCSS1_PV_small_caps ); 2378 break; 2379 case SvxCaseMap::Uppercase: 2380 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_uppercase ); 2381 break; 2382 case SvxCaseMap::Lowercase: 2383 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_lowercase ); 2384 break; 2385 case SvxCaseMap::Capitalize: 2386 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_transform, sCSS1_PV_capitalize ); 2387 break; 2388 default: 2389 ; 2390 } 2391 2392 return rWrt; 2393 } 2394 2395 static Writer& OutCSS1_SvxColor( Writer& rWrt, const SfxPoolItem& rHt ) 2396 { 2397 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2398 2399 // Colors do not need to be exported for Style-Option. 2400 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) && 2401 !rHTMLWrt.m_bCfgPreferStyles ) 2402 return rWrt; 2403 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), 2404 "write color as Hint?" ); 2405 2406 Color aColor( static_cast<const SvxColorItem&>(rHt).GetValue() ); 2407 if( COL_AUTO == aColor ) 2408 aColor = COL_BLACK; 2409 2410 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_color, GetCSS1_Color(aColor)); 2411 2412 return rWrt; 2413 } 2414 2415 static Writer& OutCSS1_SvxCrossedOut( Writer& rWrt, const SfxPoolItem& rHt ) 2416 { 2417 // This function only exports Hints! 2418 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly. 2419 2420 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) ) 2421 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt, 2422 nullptr, nullptr, static_cast<const SvxCrossedOutItem *>(&rHt), nullptr ); 2423 2424 return rWrt; 2425 } 2426 2427 static Writer& OutCSS1_SvxFont( Writer& rWrt, const SfxPoolItem& rHt ) 2428 { 2429 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2430 2431 // No need to export Fonts for the Style-Option. 2432 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2433 return rWrt; 2434 2435 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN; 2436 switch( rHt.Which() ) 2437 { 2438 case RES_CHRATR_CJK_FONT: nScript = CSS1_OUTMODE_CJK; break; 2439 case RES_CHRATR_CTL_FONT: nScript = CSS1_OUTMODE_CTL; break; 2440 } 2441 if( !rHTMLWrt.IsCSS1Script( nScript ) ) 2442 return rWrt; 2443 2444 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), 2445 "write Font as Hint?" ); 2446 2447 OUString sOut; 2448 // MS IE3b1 has problems with single quotes 2449 sal_uInt16 nMode = rHTMLWrt.m_nCSS1OutMode & CSS1_OUTMODE_ANY_ON; 2450 sal_Unicode cQuote = nMode == CSS1_OUTMODE_RULE_ON ? '\"' : '\''; 2451 SwHTMLWriter::PrepareFontList( static_cast<const SvxFontItem&>(rHt), sOut, cQuote, 2452 true ); 2453 2454 rHTMLWrt.OutCSS1_Property( sCSS1_P_font_family, sOut ); 2455 2456 return rWrt; 2457 } 2458 2459 static Writer& OutCSS1_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt ) 2460 { 2461 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2462 2463 // Font-Height need not be exported in the Style-Option. 2464 // For Drop-Caps another Font-Size is exported. 2465 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) || 2466 rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_DROPCAP ) ) 2467 return rWrt; 2468 2469 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN; 2470 switch( rHt.Which() ) 2471 { 2472 case RES_CHRATR_CJK_FONTSIZE: nScript = CSS1_OUTMODE_CJK; break; 2473 case RES_CHRATR_CTL_FONTSIZE: nScript = CSS1_OUTMODE_CTL; break; 2474 } 2475 if( !rHTMLWrt.IsCSS1Script( nScript ) ) 2476 return rWrt; 2477 2478 sal_uInt32 nHeight = static_cast<const SvxFontHeightItem&>(rHt).GetHeight(); 2479 OString sHeight(OString::number(nHeight/20) + OString(sCSS1_UNIT_pt)); 2480 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_font_size, sHeight); 2481 2482 return rWrt; 2483 } 2484 2485 static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt ) 2486 { 2487 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2488 2489 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN; 2490 switch( rHt.Which() ) 2491 { 2492 case RES_CHRATR_CJK_POSTURE: nScript = CSS1_OUTMODE_CJK; break; 2493 case RES_CHRATR_CTL_POSTURE: nScript = CSS1_OUTMODE_CTL; break; 2494 } 2495 if( !rHTMLWrt.IsCSS1Script( nScript ) ) 2496 return rWrt; 2497 2498 const sal_Char *pStr = nullptr; 2499 switch( static_cast<const SvxPostureItem&>(rHt).GetPosture() ) 2500 { 2501 case ITALIC_NONE: pStr = sCSS1_PV_normal; break; 2502 case ITALIC_OBLIQUE: pStr = sCSS1_PV_oblique; break; 2503 case ITALIC_NORMAL: 2504 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2505 { 2506 // this also works in HTML does not need to be written as 2507 // a STYLE-Options, and must not be written as Hint 2508 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), 2509 "write italic as Hint?" ); 2510 pStr = sCSS1_PV_italic; 2511 } 2512 break; 2513 default: 2514 ; 2515 } 2516 2517 if( pStr ) 2518 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_style, pStr ); 2519 2520 return rWrt; 2521 } 2522 2523 static Writer& OutCSS1_SvxKerning( Writer& rWrt, const SfxPoolItem& rHt ) 2524 { 2525 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2526 2527 sal_Int16 nValue = static_cast<const SvxKerningItem&>(rHt).GetValue(); 2528 if( nValue ) 2529 { 2530 OStringBuffer sOut; 2531 if( nValue < 0 ) 2532 { 2533 sOut.append('-'); 2534 nValue = -nValue; 2535 } 2536 2537 // Width as n.n pt 2538 nValue = (nValue + 1) / 2; // 1/10pt 2539 sOut.append(OString::number(nValue / 10) + "." + OString::number(nValue % 10) + 2540 OString(sCSS1_UNIT_pt)); 2541 2542 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_letter_spacing, 2543 sOut.makeStringAndClear()); 2544 } 2545 else 2546 { 2547 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing, 2548 sCSS1_PV_normal ); 2549 } 2550 2551 return rWrt; 2552 } 2553 2554 static Writer& OutCSS1_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt ) 2555 { 2556 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2557 2558 // Only export Language rules 2559 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2560 return rWrt; 2561 2562 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN; 2563 switch( rHt.Which() ) 2564 { 2565 case RES_CHRATR_CJK_LANGUAGE: nScript = CSS1_OUTMODE_CJK; break; 2566 case RES_CHRATR_CTL_LANGUAGE: nScript = CSS1_OUTMODE_CTL; break; 2567 } 2568 if( !rHTMLWrt.IsCSS1Script( nScript ) ) 2569 return rWrt; 2570 2571 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), 2572 "write Language as Hint?" ); 2573 2574 LanguageType eLang = static_cast<const SvxLanguageItem &>(rHt).GetLanguage(); 2575 if( LANGUAGE_DONTKNOW == eLang ) 2576 return rWrt; 2577 2578 OUString sOut = LanguageTag::convertToBcp47( eLang ); 2579 2580 rHTMLWrt.OutCSS1_Property( sCSS1_P_so_language, sOut ); 2581 2582 return rWrt; 2583 } 2584 2585 static Writer& OutCSS1_SvxUnderline( Writer& rWrt, const SfxPoolItem& rHt ) 2586 { 2587 // This function only exports Hints! 2588 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly. 2589 2590 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) ) 2591 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt, 2592 static_cast<const SvxUnderlineItem *>(&rHt), nullptr, nullptr, nullptr ); 2593 2594 return rWrt; 2595 } 2596 2597 static Writer& OutCSS1_SvxOverline( Writer& rWrt, const SfxPoolItem& rHt ) 2598 { 2599 // This function only exports Hints! 2600 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly. 2601 2602 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) ) 2603 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt, 2604 nullptr, static_cast<const SvxOverlineItem *>(&rHt), nullptr, nullptr ); 2605 2606 return rWrt; 2607 } 2608 2609 static Writer& OutCSS1_SvxHidden( Writer& rWrt, const SfxPoolItem& rHt ) 2610 { 2611 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2612 2613 if ( static_cast<const SvxCharHiddenItem&>(rHt).GetValue() ) 2614 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_display, sCSS1_PV_none ); 2615 2616 return rWrt; 2617 } 2618 2619 static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt ) 2620 { 2621 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2622 2623 sal_uInt16 nScript = CSS1_OUTMODE_WESTERN; 2624 switch( rHt.Which() ) 2625 { 2626 case RES_CHRATR_CJK_WEIGHT: nScript = CSS1_OUTMODE_CJK; break; 2627 case RES_CHRATR_CTL_WEIGHT: nScript = CSS1_OUTMODE_CTL; break; 2628 } 2629 if( !rHTMLWrt.IsCSS1Script( nScript ) ) 2630 return rWrt; 2631 2632 const sal_Char *pStr = nullptr; 2633 switch( static_cast<const SvxWeightItem&>(rHt).GetWeight() ) 2634 { 2635 case WEIGHT_ULTRALIGHT: pStr = sCSS1_PV_extra_light; break; 2636 case WEIGHT_LIGHT: pStr = sCSS1_PV_light; break; 2637 case WEIGHT_SEMILIGHT: pStr = sCSS1_PV_demi_light; break; 2638 case WEIGHT_NORMAL: pStr = sCSS1_PV_normal; break; 2639 case WEIGHT_SEMIBOLD: pStr = sCSS1_PV_demi_bold; break; 2640 case WEIGHT_BOLD: 2641 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 2642 { 2643 // this also works in HTML does not need to be written as 2644 // a STYLE-Options, and must not be written as Hint 2645 OSL_ENSURE( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT), 2646 "write bold as Hint?" ); 2647 pStr = sCSS1_PV_bold; 2648 } 2649 break; 2650 case WEIGHT_ULTRABOLD: pStr = sCSS1_PV_extra_bold; break; 2651 default: 2652 pStr = sCSS1_PV_normal; 2653 } 2654 2655 if( pStr ) 2656 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_weight, pStr ); 2657 2658 return rWrt; 2659 } 2660 2661 static Writer& OutCSS1_SvxBlink( Writer& rWrt, const SfxPoolItem& rHt ) 2662 { 2663 // This function only exports Hints! 2664 // Otherwise OutCSS1_SvxTextLn_SvxCrOut_SvxBlink() is called directly. 2665 2666 if( static_cast<SwHTMLWriter&>(rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) ) 2667 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( rWrt, 2668 nullptr, nullptr, nullptr, static_cast<const SvxBlinkItem *>(&rHt) ); 2669 2670 return rWrt; 2671 } 2672 2673 static Writer& OutCSS1_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt ) 2674 { 2675 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2676 2677 // Netscape4 has big problems with cell heights if the line spacing is 2678 // changed within a table and the width of the table is not calculated 2679 // automatically (== if there is a WIDTH-Option) 2680 if( rHTMLWrt.m_bOutTable && rHTMLWrt.m_bCfgNetscape4 ) 2681 return rWrt; 2682 2683 const SvxLineSpacingItem& rLSItem = static_cast<const SvxLineSpacingItem&>(rHt); 2684 2685 sal_uInt16 nHeight = 0; 2686 sal_uInt16 nPrcHeight = 0; 2687 SvxLineSpaceRule eLineSpace = rLSItem.GetLineSpaceRule(); 2688 switch( rLSItem.GetInterLineSpaceRule() ) 2689 { 2690 case SvxInterLineSpaceRule::Off: 2691 case SvxInterLineSpaceRule::Fix: 2692 { 2693 switch( eLineSpace ) 2694 { 2695 case SvxLineSpaceRule::Min: 2696 case SvxLineSpaceRule::Fix: 2697 nHeight = rLSItem.GetLineHeight(); 2698 break; 2699 case SvxLineSpaceRule::Auto: 2700 nPrcHeight = 100; 2701 break; 2702 default: 2703 ; 2704 } 2705 } 2706 break; 2707 case SvxInterLineSpaceRule::Prop: 2708 nPrcHeight = rLSItem.GetPropLineSpace(); 2709 break; 2710 2711 default: 2712 ; 2713 } 2714 2715 if( nHeight ) 2716 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_line_height, static_cast<long>(nHeight) ); 2717 else if( nPrcHeight && 2718 !(nPrcHeight < 115 && rHTMLWrt.m_bParaDotLeaders )) // avoid HTML scrollbars and missing descenders 2719 { 2720 OString sHeight(OString::number(nPrcHeight) + "%"); 2721 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_line_height, sHeight); 2722 } 2723 2724 return rWrt; 2725 } 2726 2727 static Writer& OutCSS1_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt ) 2728 { 2729 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2730 2731 // Export Alignment in Style-Option only if the Tag does not allow ALIGN=xxx 2732 if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) && 2733 !rHTMLWrt.m_bNoAlign) 2734 return rWrt; 2735 2736 const sal_Char* pStr = nullptr; 2737 switch( static_cast<const SvxAdjustItem&>(rHt).GetAdjust() ) 2738 { 2739 case SvxAdjust::Left: pStr = sCSS1_PV_left; break; 2740 case SvxAdjust::Right: pStr = sCSS1_PV_right; break; 2741 case SvxAdjust::Block: pStr = sCSS1_PV_justify; break; 2742 case SvxAdjust::Center: pStr = sCSS1_PV_center; break; 2743 default: 2744 ; 2745 } 2746 2747 if( pStr ) 2748 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_align, pStr ); 2749 2750 return rWrt; 2751 } 2752 2753 static Writer& OutCSS1_SvxFormatSplit( Writer& rWrt, const SfxPoolItem& rHt ) 2754 { 2755 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2756 2757 const sal_Char *pStr = static_cast<const SvxFormatSplitItem&>(rHt).GetValue() 2758 ? sCSS1_PV_auto 2759 : sCSS1_PV_avoid; 2760 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr ); 2761 2762 return rWrt; 2763 } 2764 2765 static Writer& OutCSS1_SwFormatLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt ) 2766 { 2767 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2768 2769 const sal_Char *pStr = static_cast<const SwFormatLayoutSplit&>(rHt).GetValue() 2770 ? sCSS1_PV_auto 2771 : sCSS1_PV_avoid; 2772 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr ); 2773 2774 return rWrt; 2775 } 2776 2777 static Writer& OutCSS1_SvxWidows( Writer& rWrt, const SfxPoolItem& rHt ) 2778 { 2779 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2780 2781 OString aStr(OString::number(static_cast<const SvxWidowsItem&>(rHt).GetValue())); 2782 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_widows, aStr ); 2783 2784 return rWrt; 2785 } 2786 2787 static Writer& OutCSS1_SvxOrphans( Writer& rWrt, const SfxPoolItem& rHt ) 2788 { 2789 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2790 2791 OString aStr(OString::number(static_cast<const SvxOrphansItem&>(rHt).GetValue())); 2792 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_orphans, aStr ); 2793 2794 return rWrt; 2795 } 2796 2797 static void OutCSS1_SwFormatDropAttrs( SwHTMLWriter& rHWrt, 2798 const SwFormatDrop& rDrop, 2799 const SfxItemSet *pCharFormatItemSet ) 2800 { 2801 // Text flows around on right side 2802 rHWrt.OutCSS1_PropertyAscii( sCSS1_P_float, sCSS1_PV_left ); 2803 2804 // number of lines -> use % for Font-Height! 2805 OString sOut(OString::number(rDrop.GetLines()*100) + "%"); 2806 rHWrt.OutCSS1_PropertyAscii(sCSS1_P_font_size, sOut); 2807 2808 // distance to Text = right margin 2809 sal_uInt16 nDistance = rDrop.GetDistance(); 2810 if( nDistance > 0 ) 2811 rHWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right, nDistance ); 2812 2813 const SwCharFormat *pDCCharFormat = rDrop.GetCharFormat(); 2814 if( pCharFormatItemSet ) 2815 rHWrt.OutCSS1_SfxItemSet( *pCharFormatItemSet ); 2816 else if( pDCCharFormat ) 2817 rHWrt.OutCSS1_SfxItemSet( pDCCharFormat->GetAttrSet() ); 2818 else if( (rHWrt.m_nCSS1OutMode & CSS1_OUTMODE_ANY_OFF) == CSS1_OUTMODE_RULE_OFF ) 2819 rHWrt.Strm().WriteCharPtr( sCSS1_rule_end ); 2820 2821 } 2822 2823 static Writer& OutCSS1_SwFormatDrop( Writer& rWrt, const SfxPoolItem& rHt ) 2824 { 2825 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2826 2827 // never export as an Option of a paragraph, but only as Hints 2828 if( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) ) 2829 return rWrt; 2830 2831 if( rHTMLWrt.m_bTagOn ) 2832 { 2833 SwCSS1OutMode aMode( rHTMLWrt, 2834 rHTMLWrt.m_nCSS1Script|CSS1_OUTMODE_SPAN_TAG1_ON|CSS1_OUTMODE_ENCODE| 2835 CSS1_OUTMODE_DROPCAP, nullptr ); 2836 2837 OutCSS1_SwFormatDropAttrs( rHTMLWrt, static_cast<const SwFormatDrop&>(rHt) ); 2838 // A "> is already printed by the calling OutCSS1_HintAsSpanTag. 2839 } 2840 else 2841 { 2842 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span, false ); 2843 } 2844 2845 return rWrt; 2846 } 2847 2848 static Writer& OutCSS1_SwFormatFrameSize( Writer& rWrt, const SfxPoolItem& rHt, 2849 Css1FrameSize nMode ) 2850 { 2851 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2852 2853 const SwFormatFrameSize& rFSItem = static_cast<const SwFormatFrameSize&>(rHt); 2854 2855 if( nMode & Css1FrameSize::Width ) 2856 { 2857 sal_uInt8 nPrcWidth = rFSItem.GetWidthPercent(); 2858 if( nPrcWidth ) 2859 { 2860 OString sOut(OString::number(nPrcWidth) + "%"); 2861 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_width, sOut); 2862 } 2863 else if( nMode & Css1FrameSize::Pixel ) 2864 { 2865 rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_width, 2866 rFSItem.GetSize().Width(), false ); 2867 } 2868 else 2869 { 2870 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_width, 2871 rFSItem.GetSize().Width() ); 2872 } 2873 } 2874 2875 if( nMode & Css1FrameSize::AnyHeight ) 2876 { 2877 bool bOutHeight = false; 2878 switch( rFSItem.GetHeightSizeType() ) 2879 { 2880 case ATT_FIX_SIZE: 2881 bOutHeight = bool(nMode & Css1FrameSize::FixHeight); 2882 break; 2883 case ATT_MIN_SIZE: 2884 bOutHeight = bool(nMode & Css1FrameSize::MinHeight); 2885 break; 2886 default: 2887 OSL_ENSURE( bOutHeight, "Height will not be exported" ); 2888 break; 2889 } 2890 2891 if( bOutHeight ) 2892 { 2893 sal_uInt8 nPrcHeight = rFSItem.GetHeightPercent(); 2894 if( nPrcHeight ) 2895 { 2896 OString sOut(OString::number(nPrcHeight) + "%"); 2897 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_height, sOut); 2898 } 2899 else if( nMode & Css1FrameSize::Pixel ) 2900 { 2901 rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_height, 2902 rFSItem.GetSize().Height(), 2903 true ); 2904 } 2905 else 2906 { 2907 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_height, 2908 rFSItem.GetSize().Height() ); 2909 } 2910 } 2911 } 2912 2913 return rWrt; 2914 } 2915 2916 static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt ) 2917 { 2918 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2919 2920 const SvxLRSpaceItem& rLRItem = static_cast<const SvxLRSpaceItem&>(rHt); 2921 2922 // No Export of a firm attribute is needed if the new values 2923 // match that of the current template 2924 2925 // A left margin can exist because of a list nearby 2926 long nLeftMargin = rLRItem.GetTextLeft() - rHTMLWrt.m_nLeftMargin; 2927 if( rHTMLWrt.m_nDfltLeftMargin != nLeftMargin ) 2928 { 2929 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLeftMargin ); 2930 2931 // max-width = max-width - margin-left for TOC paragraphs with dot leaders 2932 if( rHTMLWrt.m_bParaDotLeaders ) 2933 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_max_width, long(DOT_LEADERS_MAX_WIDTH/2.54*72*20) - nLeftMargin ); 2934 2935 } 2936 2937 if( rHTMLWrt.m_nDfltRightMargin != rLRItem.GetRight() ) 2938 { 2939 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right, rLRItem.GetRight() ); 2940 } 2941 2942 // The LineIndent of the first line might contain the room for numbering 2943 long nFirstLineIndent = static_cast<long>(rLRItem.GetTextFirstLineOfst()) - 2944 rHTMLWrt.m_nFirstLineIndent; 2945 if( rHTMLWrt.m_nDfltFirstLineIndent != nFirstLineIndent ) 2946 { 2947 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent, 2948 nFirstLineIndent ); 2949 } 2950 2951 return rWrt; 2952 } 2953 2954 static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt ) 2955 { 2956 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2957 2958 const SvxULSpaceItem& rULItem = static_cast<const SvxULSpaceItem&>(rHt); 2959 2960 if( rHTMLWrt.m_nDfltTopMargin != rULItem.GetUpper() ) 2961 { 2962 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_top, 2963 static_cast<long>(rULItem.GetUpper()) ); 2964 } 2965 2966 if( rHTMLWrt.m_nDfltBottomMargin != rULItem.GetLower() ) 2967 { 2968 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_bottom, 2969 static_cast<long>(rULItem.GetLower()) ); 2970 } 2971 2972 return rWrt; 2973 } 2974 2975 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt, 2976 const SvxULSpaceItem *pULItem, 2977 const SvxLRSpaceItem *pLRItem ) 2978 { 2979 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 2980 2981 if( pLRItem && pULItem && 2982 pLRItem->GetLeft() == pLRItem->GetRight() && 2983 pLRItem->GetLeft() == pULItem->GetUpper() && 2984 pLRItem->GetLeft() == pULItem->GetLower() && 2985 pLRItem->GetLeft() != rHTMLWrt.m_nDfltLeftMargin && 2986 pLRItem->GetRight() != rHTMLWrt.m_nDfltRightMargin && 2987 pULItem->GetUpper() != rHTMLWrt.m_nDfltTopMargin && 2988 pULItem->GetLower() != rHTMLWrt.m_nDfltBottomMargin ) 2989 { 2990 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin, pLRItem->GetLeft() ); 2991 } 2992 else 2993 { 2994 if( pLRItem ) 2995 OutCSS1_SvxLRSpace( rWrt, *pLRItem ); 2996 if( pULItem ) 2997 OutCSS1_SvxULSpace( rWrt, *pULItem ); 2998 } 2999 3000 return rWrt; 3001 } 3002 3003 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt, 3004 const SfxItemSet& rItemSet ) 3005 { 3006 const SvxULSpaceItem *pULSpace = nullptr; 3007 const SvxLRSpaceItem *pLRSpace = nullptr; 3008 const SfxPoolItem *pItem; 3009 if( SfxItemState::SET == rItemSet.GetItemState( RES_LR_SPACE, false/*bDeep*/, &pItem ) ) 3010 pLRSpace = static_cast<const SvxLRSpaceItem *>(pItem); 3011 3012 if( SfxItemState::SET == rItemSet.GetItemState( RES_UL_SPACE, false/*bDeep*/, &pItem ) ) 3013 pULSpace = static_cast<const SvxULSpaceItem *>(pItem); 3014 3015 if( pLRSpace || pULSpace ) 3016 OutCSS1_SvxULSpace_SvxLRSpace( rWrt, pULSpace, pLRSpace ); 3017 3018 return rWrt; 3019 } 3020 3021 static Writer& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( Writer& rWrt, 3022 const SvxFormatBreakItem *pBreakItem, 3023 const SwFormatPageDesc *pPDescItem, 3024 const SvxFormatKeepItem *pKeepItem ) 3025 { 3026 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 3027 3028 if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PRINT_EXT) ) 3029 return rWrt; 3030 3031 const sal_Char *pBreakBefore = nullptr; 3032 const sal_Char *pBreakAfter = nullptr; 3033 3034 if( pKeepItem ) 3035 { 3036 pBreakAfter = pKeepItem->GetValue() ? sCSS1_PV_avoid : sCSS1_PV_auto; 3037 } 3038 if( pBreakItem ) 3039 { 3040 switch( pBreakItem->GetBreak() ) 3041 { 3042 case SvxBreak::NONE: 3043 pBreakBefore = sCSS1_PV_auto; 3044 if( !pBreakAfter ) 3045 pBreakAfter = sCSS1_PV_auto; 3046 break; 3047 3048 case SvxBreak::PageBefore: 3049 pBreakBefore = sCSS1_PV_always; 3050 break; 3051 3052 case SvxBreak::PageAfter: 3053 pBreakAfter= sCSS1_PV_always; 3054 break; 3055 3056 default: 3057 ; 3058 } 3059 } 3060 if( pPDescItem ) 3061 { 3062 const SwPageDesc *pPDesc = pPDescItem->GetPageDesc(); 3063 if( pPDesc ) 3064 { 3065 switch( pPDesc->GetPoolFormatId() ) 3066 { 3067 case RES_POOLPAGE_LEFT: pBreakBefore = sCSS1_PV_left; break; 3068 case RES_POOLPAGE_RIGHT: pBreakBefore = sCSS1_PV_right; break; 3069 default: pBreakBefore = sCSS1_PV_always; break; 3070 } 3071 } 3072 else if( !pBreakBefore ) 3073 { 3074 pBreakBefore = sCSS1_PV_auto; 3075 } 3076 } 3077 3078 if (rHTMLWrt.mbSkipHeaderFooter) 3079 // No page break when writing only a fragment. 3080 return rWrt; 3081 3082 if( pBreakBefore ) 3083 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_before, 3084 pBreakBefore ); 3085 if( pBreakAfter ) 3086 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_after, 3087 pBreakAfter ); 3088 3089 return rWrt; 3090 } 3091 3092 static Writer& OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( Writer& rWrt, 3093 const SfxItemSet& rItemSet, 3094 bool bDeep ) 3095 { 3096 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 3097 const SfxPoolItem *pItem; 3098 const SvxFormatBreakItem *pBreakItem = nullptr; 3099 if( SfxItemState::SET==rItemSet.GetItemState( RES_BREAK, bDeep, &pItem )) 3100 pBreakItem = static_cast<const SvxFormatBreakItem *>(pItem); 3101 3102 const SwFormatPageDesc *pPDescItem = nullptr; 3103 if( ( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) || 3104 !rHTMLWrt.m_bCSS1IgnoreFirstPageDesc || 3105 rHTMLWrt.m_pStartNdIdx->GetIndex() != 3106 rHTMLWrt.m_pCurrentPam->GetPoint()->nNode.GetIndex() ) && 3107 SfxItemState::SET==rItemSet.GetItemState( RES_PAGEDESC, bDeep, &pItem )) 3108 pPDescItem = static_cast<const SwFormatPageDesc*>(pItem); 3109 3110 const SvxFormatKeepItem *pKeepItem = nullptr; 3111 if( SfxItemState::SET==rItemSet.GetItemState( RES_KEEP, bDeep, &pItem )) 3112 pKeepItem = static_cast<const SvxFormatKeepItem *>(pItem); 3113 3114 if( pBreakItem || pPDescItem || pKeepItem ) 3115 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( rWrt, pBreakItem, 3116 pPDescItem, pKeepItem ); 3117 3118 return rWrt; 3119 } 3120 3121 // Wrapper for OutCSS1_SfxItemSet etc. 3122 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt ) 3123 { 3124 OutCSS1_SvxBrush( rWrt, rHt, Css1Background::Attr, nullptr ); 3125 return rWrt; 3126 } 3127 3128 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt, 3129 Css1Background nMode, 3130 const OUString* pGraphicName) 3131 { 3132 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 3133 3134 // The Character-Attribute is skipped, if we are about to 3135 // exporting options 3136 if( rHt.Which() < RES_CHRATR_END && 3137 rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 3138 return rWrt; 3139 3140 // start getting a few values 3141 // const Brush &rBrush = static_cast<const SvxBrushItem &>(rHt).GetBrush(); 3142 const Color & rColor = static_cast<const SvxBrushItem &>(rHt).GetColor(); 3143 OUString aLink = pGraphicName ? *pGraphicName 3144 : static_cast<const SvxBrushItem &>(rHt).GetGraphicLink(); 3145 SvxGraphicPosition ePos = static_cast<const SvxBrushItem &>(rHt).GetGraphicPos(); 3146 if( Css1Background::Page == nMode && !rHTMLWrt.mbEmbedImages ) 3147 { 3148 // page style images are exported if not tiled 3149 if( aLink.isEmpty() || GPOS_TILED==ePos ) 3150 return rWrt; 3151 } 3152 3153 // get the color 3154 bool bColor = false; 3155 /// set <bTransparent> to true, if color is "no fill"/"auto fill" 3156 bool bTransparent = (rColor == COL_TRANSPARENT); 3157 Color aColor; 3158 if( !bTransparent ) 3159 { 3160 aColor = rColor; 3161 bColor = true; 3162 } 3163 3164 // and now the Graphic 3165 OUString aGraphicInBase64; 3166 OUString aGraphicAsLink; 3167 3168 // Embedded Graphic -> export WriteEmbedded 3169 const Graphic* pGrf = nullptr; 3170 if( rHTMLWrt.mbEmbedImages || aLink.isEmpty()) 3171 { 3172 pGrf = static_cast<const SvxBrushItem &>(rHt).GetGraphic(); 3173 if( pGrf ) 3174 { 3175 if( !XOutBitmap::GraphicToBase64(*pGrf, aGraphicInBase64) ) 3176 { 3177 rHTMLWrt.m_nWarn = WARN_SWG_POOR_LOAD; 3178 } 3179 } 3180 aLink.clear(); 3181 } 3182 else if( !pGraphicName && rHTMLWrt.m_bCfgCpyLinkedGrfs ) 3183 { 3184 aGraphicAsLink = aLink; 3185 rWrt.CopyLocalFileToINet( aGraphicAsLink ); 3186 aLink = aGraphicAsLink; 3187 } 3188 // In tables we only export something if there is a Graphic 3189 if( Css1Background::Table==nMode && !pGrf && !aLink.isEmpty()) 3190 return rWrt; 3191 3192 // if necessary, add the orientation of the Graphic 3193 const sal_Char *pRepeat = nullptr, *pHori = nullptr, *pVert = nullptr; 3194 if( pGrf || !aLink.isEmpty() ) 3195 { 3196 if( GPOS_TILED==ePos ) 3197 { 3198 pRepeat = sCSS1_PV_repeat; 3199 } 3200 else 3201 { 3202 switch( ePos ) 3203 { 3204 case GPOS_LT: 3205 case GPOS_MT: 3206 case GPOS_RT: 3207 pHori = sCSS1_PV_top; 3208 break; 3209 3210 case GPOS_LM: 3211 case GPOS_MM: 3212 case GPOS_RM: 3213 pHori = sCSS1_PV_middle; 3214 break; 3215 3216 case GPOS_LB: 3217 case GPOS_MB: 3218 case GPOS_RB: 3219 pHori = sCSS1_PV_bottom; 3220 break; 3221 3222 default: 3223 ; 3224 } 3225 3226 switch( ePos ) 3227 { 3228 case GPOS_LT: 3229 case GPOS_LM: 3230 case GPOS_LB: 3231 pVert = sCSS1_PV_left; 3232 break; 3233 3234 case GPOS_MT: 3235 case GPOS_MM: 3236 case GPOS_MB: 3237 pVert = sCSS1_PV_center; 3238 break; 3239 3240 case GPOS_RT: 3241 case GPOS_RM: 3242 case GPOS_RB: 3243 pVert = sCSS1_PV_right; 3244 break; 3245 3246 default: 3247 ; 3248 } 3249 3250 if( pHori || pVert ) 3251 pRepeat = sCSS1_PV_no_repeat; 3252 } 3253 } 3254 3255 // now build the string 3256 OUString sOut; 3257 if( !pGrf && aLink.isEmpty() && !bColor ) 3258 { 3259 // no color and no Link, but a transparent Brush 3260 if( bTransparent && Css1Background::Fly != nMode ) 3261 sOut += OStringToOUString(sCSS1_PV_transparent, RTL_TEXTENCODING_ASCII_US); 3262 } 3263 else 3264 { 3265 if( bColor ) 3266 { 3267 OString sTmp(GetCSS1_Color(aColor)); 3268 sOut += OStringToOUString(sTmp, RTL_TEXTENCODING_ASCII_US); 3269 } 3270 3271 if( pGrf || !aLink.isEmpty() ) 3272 { 3273 if( bColor ) 3274 sOut += " "; 3275 3276 if(pGrf) 3277 { 3278 sOut += OStringToOUString(sCSS1_url, RTL_TEXTENCODING_ASCII_US) + 3279 "(\'" OOO_STRING_SVTOOLS_HTML_O_data ":" + aGraphicInBase64 + "\')"; 3280 } 3281 else 3282 { 3283 sOut += OStringToOUString(sCSS1_url, RTL_TEXTENCODING_ASCII_US)+ 3284 "(" + URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), 3285 aLink) + ")"; 3286 } 3287 3288 if( pRepeat ) 3289 { 3290 sOut += " " + OStringToOUString(pRepeat, RTL_TEXTENCODING_ASCII_US); 3291 } 3292 3293 if( pHori ) 3294 { 3295 sOut += " " + OStringToOUString(pHori, RTL_TEXTENCODING_ASCII_US); 3296 } 3297 if( pVert ) 3298 { 3299 sOut += " " + OStringToOUString(pVert, RTL_TEXTENCODING_ASCII_US); 3300 } 3301 3302 sOut += " " + OStringToOUString(sCSS1_PV_scroll, RTL_TEXTENCODING_ASCII_US) + " "; 3303 } 3304 } 3305 3306 if( !sOut.isEmpty() ) 3307 rHTMLWrt.OutCSS1_Property( sCSS1_P_background, sOut ); 3308 3309 return rWrt; 3310 } 3311 3312 static void OutCSS1_SvxBorderLine( SwHTMLWriter& rHTMLWrt, 3313 const sal_Char *pProperty, 3314 const SvxBorderLine *pLine ) 3315 { 3316 if( !pLine || pLine->isEmpty() ) 3317 { 3318 rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sCSS1_PV_none ); 3319 return; 3320 } 3321 3322 sal_Int32 nWidth = pLine->GetWidth(); 3323 3324 OStringBuffer sOut; 3325 if( Application::GetDefaultDevice() && 3326 nWidth <= Application::GetDefaultDevice()->PixelToLogic( 3327 Size( 1, 1 ), MapMode( MapUnit::MapTwip) ).Width() ) 3328 { 3329 // If the width is smaller than one pixel, then export as 1px 3330 // so that Netscape and IE show the line. 3331 sOut.append("1px"); 3332 } 3333 else 3334 { 3335 nWidth *= 5; // 1/100pt 3336 3337 // width in n.nn pt 3338 sOut.append(OString::number(nWidth / 100) + "." + OString::number((nWidth/10) % 10) + 3339 OString::number(nWidth % 10) + OString(sCSS1_UNIT_pt)); 3340 } 3341 3342 // Line-Style: solid or double 3343 sOut.append(' '); 3344 switch (pLine->GetBorderLineStyle()) 3345 { 3346 case SvxBorderLineStyle::SOLID: 3347 sOut.append(sCSS1_PV_solid); 3348 break; 3349 case SvxBorderLineStyle::DOTTED: 3350 sOut.append(sCSS1_PV_dotted); 3351 break; 3352 case SvxBorderLineStyle::DASHED: 3353 sOut.append(sCSS1_PV_dashed); 3354 break; 3355 case SvxBorderLineStyle::DOUBLE: 3356 case SvxBorderLineStyle::THINTHICK_SMALLGAP: 3357 case SvxBorderLineStyle::THINTHICK_MEDIUMGAP: 3358 case SvxBorderLineStyle::THINTHICK_LARGEGAP: 3359 case SvxBorderLineStyle::THICKTHIN_SMALLGAP: 3360 case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP: 3361 case SvxBorderLineStyle::THICKTHIN_LARGEGAP: 3362 sOut.append(sCSS1_PV_double); 3363 break; 3364 case SvxBorderLineStyle::EMBOSSED: 3365 sOut.append(sCSS1_PV_ridge); 3366 break; 3367 case SvxBorderLineStyle::ENGRAVED: 3368 sOut.append(sCSS1_PV_groove); 3369 break; 3370 case SvxBorderLineStyle::INSET: 3371 sOut.append(sCSS1_PV_inset); 3372 break; 3373 case SvxBorderLineStyle::OUTSET: 3374 sOut.append(sCSS1_PV_outset); 3375 break; 3376 default: 3377 sOut.append(sCSS1_PV_none); 3378 } 3379 sOut.append(' '); 3380 3381 // and also the color 3382 sOut.append(GetCSS1_Color(pLine->GetColor())); 3383 3384 rHTMLWrt.OutCSS1_PropertyAscii(pProperty, sOut.makeStringAndClear()); 3385 } 3386 3387 Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt ) 3388 { 3389 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 3390 3391 // Avoid interference between character and paragraph attributes 3392 if( rHt.Which() < RES_CHRATR_END && 3393 rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ) 3394 return rWrt; 3395 3396 if( rHt.Which() == RES_CHRATR_BOX ) 3397 { 3398 if( rHTMLWrt.m_bTagOn ) 3399 { 3400 // Inline-block to make the line height changing correspond to the character border 3401 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_display, "inline-block"); 3402 } 3403 else 3404 { 3405 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span, false ); 3406 return rWrt; 3407 } 3408 } 3409 3410 const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(rHt); 3411 const SvxBorderLine *pTop = rBoxItem.GetTop(); 3412 const SvxBorderLine *pBottom = rBoxItem.GetBottom(); 3413 const SvxBorderLine *pLeft = rBoxItem.GetLeft(); 3414 const SvxBorderLine *pRight = rBoxItem.GetRight(); 3415 3416 if( (pTop && pBottom && pLeft && pRight && 3417 *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) || 3418 (!pTop && !pBottom && !pLeft && !pRight) ) 3419 { 3420 // all Lines are set and equal, or all Lines are not set 3421 // => border : ... 3422 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border, pTop ); 3423 } 3424 else 3425 { 3426 // otherwise export all Lines separately 3427 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_top, pTop ); 3428 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_bottom, pBottom ); 3429 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_left, pLeft ); 3430 OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_right, pRight ); 3431 } 3432 3433 long nTopDist = pTop ? rBoxItem.GetDistance( SvxBoxItemLine::TOP ) : 0; 3434 long nBottomDist = pBottom ? rBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) : 0; 3435 long nLeftDist = pLeft ? rBoxItem.GetDistance( SvxBoxItemLine::LEFT ) : 0; 3436 long nRightDist = pRight ? rBoxItem.GetDistance( SvxBoxItemLine::RIGHT ) : 0; 3437 3438 if( nTopDist == nBottomDist && nLeftDist == nRightDist ) 3439 { 3440 OStringBuffer sVal; 3441 AddUnitPropertyValue(sVal, nTopDist, rHTMLWrt.GetCSS1Unit()); 3442 if( nTopDist != nLeftDist ) 3443 { 3444 sVal.append(' '); 3445 AddUnitPropertyValue(sVal, nLeftDist, rHTMLWrt.GetCSS1Unit()); 3446 } 3447 rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_padding, sVal.makeStringAndClear()); 3448 } 3449 else 3450 { 3451 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_top, nTopDist ); 3452 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_bottom, nBottomDist ); 3453 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_left, nLeftDist ); 3454 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_right, nRightDist ); 3455 } 3456 3457 return rWrt; 3458 } 3459 3460 static Writer& OutCSS1_SvxFrameDirection( Writer& rWrt, const SfxPoolItem& rHt ) 3461 { 3462 SwHTMLWriter& rHTMLWrt = static_cast< SwHTMLWriter& >( rWrt ); 3463 3464 // Language will be exported rules only 3465 if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_TEMPLATE ) ) 3466 return rWrt; 3467 3468 SvxFrameDirection nDir = 3469 static_cast< const SvxFrameDirectionItem& >( rHt ).GetValue(); 3470 const sal_Char* pStr = nullptr; 3471 switch( nDir ) 3472 { 3473 case SvxFrameDirection::Horizontal_LR_TB: 3474 case SvxFrameDirection::Vertical_LR_TB: 3475 pStr = sCSS1_PV_ltr; 3476 break; 3477 case SvxFrameDirection::Horizontal_RL_TB: 3478 case SvxFrameDirection::Vertical_RL_TB: 3479 pStr = sCSS1_PV_rtl; 3480 break; 3481 case SvxFrameDirection::Environment: 3482 pStr = sCSS1_PV_inherit; 3483 break; 3484 default: break; 3485 } 3486 3487 if( pStr ) 3488 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_direction, pStr ); 3489 3490 return rWrt; 3491 } 3492 3493 /* 3494 * Place here the table for the HTML-Function-Pointer to the 3495 * Export-Functions. 3496 * They are local structures, only needed within the HTML-DLL. 3497 */ 3498 3499 static SwAttrFnTab const aCSS1AttrFnTab = { 3500 /* RES_CHRATR_CASEMAP */ OutCSS1_SvxCaseMap, 3501 /* RES_CHRATR_CHARSETCOLOR */ nullptr, 3502 /* RES_CHRATR_COLOR */ OutCSS1_SvxColor, 3503 /* RES_CHRATR_CONTOUR */ nullptr, 3504 /* RES_CHRATR_CROSSEDOUT */ OutCSS1_SvxCrossedOut, 3505 /* RES_CHRATR_ESCAPEMENT */ nullptr, 3506 /* RES_CHRATR_FONT */ OutCSS1_SvxFont, 3507 /* RES_CHRATR_FONTSIZE */ OutCSS1_SvxFontHeight, 3508 /* RES_CHRATR_KERNING */ OutCSS1_SvxKerning, 3509 /* RES_CHRATR_LANGUAGE */ OutCSS1_SvxLanguage, 3510 /* RES_CHRATR_POSTURE */ OutCSS1_SvxPosture, 3511 /* RES_CHRATR_UNUSED1*/ nullptr, 3512 /* RES_CHRATR_SHADOWED */ nullptr, 3513 /* RES_CHRATR_UNDERLINE */ OutCSS1_SvxUnderline, 3514 /* RES_CHRATR_WEIGHT */ OutCSS1_SvxFontWeight, 3515 /* RES_CHRATR_WORDLINEMODE */ nullptr, 3516 /* RES_CHRATR_AUTOKERN */ nullptr, 3517 /* RES_CHRATR_BLINK */ OutCSS1_SvxBlink, 3518 /* RES_CHRATR_NOHYPHEN */ nullptr, // new: don't separate 3519 /* RES_CHRATR_UNUSED2 */ nullptr, 3520 /* RES_CHRATR_BACKGROUND */ OutCSS1_SvxBrush, // new: character background 3521 /* RES_CHRATR_CJK_FONT */ OutCSS1_SvxFont, 3522 /* RES_CHRATR_CJK_FONTSIZE */ OutCSS1_SvxFontHeight, 3523 /* RES_CHRATR_CJK_LANGUAGE */ OutCSS1_SvxLanguage, 3524 /* RES_CHRATR_CJK_POSTURE */ OutCSS1_SvxPosture, 3525 /* RES_CHRATR_CJK_WEIGHT */ OutCSS1_SvxFontWeight, 3526 /* RES_CHRATR_CTL_FONT */ OutCSS1_SvxFont, 3527 /* RES_CHRATR_CTL_FONTSIZE */ OutCSS1_SvxFontHeight, 3528 /* RES_CHRATR_CTL_LANGUAGE */ OutCSS1_SvxLanguage, 3529 /* RES_CHRATR_CTL_POSTURE */ OutCSS1_SvxPosture, 3530 /* RES_CHRATR_CTL_WEIGHT */ OutCSS1_SvxFontWeight, 3531 /* RES_CHRATR_ROTATE */ nullptr, 3532 /* RES_CHRATR_EMPHASIS_MARK */ nullptr, 3533 /* RES_CHRATR_TWO_LINES */ nullptr, 3534 /* RES_CHRATR_SCALEW */ nullptr, 3535 /* RES_CHRATR_RELIEF */ nullptr, 3536 /* RES_CHRATR_HIDDEN */ OutCSS1_SvxHidden, 3537 /* RES_CHRATR_OVERLINE */ OutCSS1_SvxOverline, 3538 /* RES_CHRATR_RSID */ nullptr, 3539 /* RES_CHRATR_BOX */ OutCSS1_SvxBox, 3540 /* RES_CHRATR_SHADOW */ nullptr, 3541 /* RES_CHRATR_HIGHLIGHT */ nullptr, 3542 /* RES_CHRATR_GRABBAG */ nullptr, 3543 /* RES_CHRATR_BIDIRTL */ nullptr, 3544 /* RES_CHRATR_IDCTHINT */ nullptr, 3545 3546 /* RES_TXTATR_REFMARK */ nullptr, 3547 /* RES_TXTATR_TOXMARK */ nullptr, 3548 /* RES_TXTATR_META */ nullptr, 3549 /* RES_TXTATR_METAFIELD */ nullptr, 3550 /* RES_TXTATR_AUTOFMT */ nullptr, 3551 /* RES_TXTATR_INETFMT */ nullptr, 3552 /* RES_TXTATR_CHARFMT */ nullptr, 3553 /* RES_TXTATR_CJK_RUBY */ nullptr, 3554 /* RES_TXTATR_UNKNOWN_CONTAINER */ nullptr, 3555 /* RES_TXTATR_INPUTFIELD */ nullptr, 3556 3557 /* RES_TXTATR_FIELD */ nullptr, 3558 /* RES_TXTATR_FLYCNT */ nullptr, 3559 /* RES_TXTATR_FTN */ nullptr, 3560 /* RES_TXTATR_ANNOTATION */ nullptr, 3561 /* RES_TXTATR_DUMMY3 */ nullptr, 3562 /* RES_TXTATR_DUMMY1 */ nullptr, // Dummy: 3563 /* RES_TXTATR_DUMMY2 */ nullptr, // Dummy: 3564 3565 /* RES_PARATR_LINESPACING */ OutCSS1_SvxLineSpacing, 3566 /* RES_PARATR_ADJUST */ OutCSS1_SvxAdjust, 3567 /* RES_PARATR_SPLIT */ OutCSS1_SvxFormatSplit, 3568 /* RES_PARATR_ORPHANS */ OutCSS1_SvxOrphans, 3569 /* RES_PARATR_WIDOWS */ OutCSS1_SvxWidows, 3570 /* RES_PARATR_TABSTOP */ nullptr, 3571 /* RES_PARATR_HYPHENZONE*/ nullptr, 3572 /* RES_PARATR_DROP */ OutCSS1_SwFormatDrop, 3573 /* RES_PARATR_REGISTER */ nullptr, // new: register-true 3574 /* RES_PARATR_NUMRULE */ nullptr, 3575 /* RES_PARATR_SCRIPTSPACE */ nullptr, 3576 /* RES_PARATR_HANGINGPUNCTUATION */ nullptr, 3577 /* RES_PARATR_FORBIDDEN_RULES */ nullptr, // new 3578 /* RES_PARATR_VERTALIGN */ nullptr, // new 3579 /* RES_PARATR_SNAPTOGRID*/ nullptr, // new 3580 /* RES_PARATR_CONNECT_TO_BORDER */ nullptr, // new 3581 /* RES_PARATR_OUTLINELEVEL */ nullptr, // new since cws outlinelevel 3582 /* RES_PARATR_RSID */ nullptr, // new 3583 /* RES_PARATR_GRABBAG */ nullptr, 3584 3585 /* RES_PARATR_LIST_ID */ nullptr, // new 3586 /* RES_PARATR_LIST_LEVEL */ nullptr, // new 3587 /* RES_PARATR_LIST_ISRESTART */ nullptr, // new 3588 /* RES_PARATR_LIST_RESTARTVALUE */ nullptr, // new 3589 /* RES_PARATR_LIST_ISCOUNTED */ nullptr, // new 3590 3591 /* RES_FILL_ORDER */ nullptr, 3592 /* RES_FRM_SIZE */ nullptr, 3593 /* RES_PAPER_BIN */ nullptr, 3594 /* RES_LR_SPACE */ OutCSS1_SvxLRSpace, 3595 /* RES_UL_SPACE */ OutCSS1_SvxULSpace, 3596 /* RES_PAGEDESC */ nullptr, 3597 /* RES_BREAK */ nullptr, 3598 /* RES_CNTNT */ nullptr, 3599 /* RES_HEADER */ nullptr, 3600 /* RES_FOOTER */ nullptr, 3601 /* RES_PRINT */ nullptr, 3602 /* RES_OPAQUE */ nullptr, 3603 /* RES_PROTECT */ nullptr, 3604 /* RES_SURROUND */ nullptr, 3605 /* RES_VERT_ORIENT */ nullptr, 3606 /* RES_HORI_ORIENT */ nullptr, 3607 /* RES_ANCHOR */ nullptr, 3608 /* RES_BACKGROUND */ OutCSS1_SvxBrush, 3609 /* RES_BOX */ OutCSS1_SvxBox, 3610 /* RES_SHADOW */ nullptr, 3611 /* RES_FRMMACRO */ nullptr, 3612 /* RES_COL */ nullptr, 3613 /* RES_KEEP */ nullptr, 3614 /* RES_URL */ nullptr, 3615 /* RES_EDIT_IN_READONLY */ nullptr, 3616 /* RES_LAYOUT_SPLIT */ nullptr, 3617 /* RES_CHAIN */ nullptr, 3618 /* RES_TEXTGRID */ nullptr, 3619 /* RES_LINENUMBER */ nullptr, 3620 /* RES_FTN_AT_TXTEND */ nullptr, 3621 /* RES_END_AT_TXTEND */ nullptr, 3622 /* RES_COLUMNBALANCE */ nullptr, 3623 /* RES_FRAMEDIR */ OutCSS1_SvxFrameDirection, 3624 /* RES_HEADER_FOOTER_EAT_SPACING */ nullptr, 3625 /* RES_ROW_SPLIT */ nullptr, 3626 /* RES_FOLLOW_TEXT_FLOW */ nullptr, 3627 /* RES_COLLAPSING_BORDERS */ nullptr, 3628 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ nullptr, 3629 /* RES_AUTO_STYLE */ nullptr, 3630 /* RES_FRMATR_STYLE_NAME */ nullptr, 3631 /* RES_FRMATR_CONDITIONAL_STYLE_NAME */ nullptr, 3632 /* RES_FRMATR_GRABBAG */ nullptr, 3633 /* RES_TEXT_VERT_ADJUST */ nullptr, 3634 3635 /* RES_GRFATR_MIRRORGRF */ nullptr, 3636 /* RES_GRFATR_CROPGRF */ nullptr, 3637 /* RES_GRFATR_ROTATION */ nullptr, 3638 /* RES_GRFATR_LUMINANCE */ nullptr, 3639 /* RES_GRFATR_CONTRAST */ nullptr, 3640 /* RES_GRFATR_CHANNELR */ nullptr, 3641 /* RES_GRFATR_CHANNELG */ nullptr, 3642 /* RES_GRFATR_CHANNELB */ nullptr, 3643 /* RES_GRFATR_GAMMA */ nullptr, 3644 /* RES_GRFATR_INVERT */ nullptr, 3645 /* RES_GRFATR_TRANSPARENCY */ nullptr, 3646 /* RES_GRFATR_DRWAMODE */ nullptr, 3647 /* RES_GRFATR_DUMMY1 */ nullptr, 3648 /* RES_GRFATR_DUMMY2 */ nullptr, 3649 /* RES_GRFATR_DUMMY3 */ nullptr, 3650 /* RES_GRFATR_DUMMY4 */ nullptr, 3651 /* RES_GRFATR_DUMMY5 */ nullptr, 3652 3653 /* RES_BOXATR_FORMAT */ nullptr, 3654 /* RES_BOXATR_FORMULA */ nullptr, 3655 /* RES_BOXATR_VALUE */ nullptr 3656 }; 3657 3658 void SwHTMLWriter::OutCSS1_SfxItemSet( const SfxItemSet& rItemSet, 3659 bool bDeep ) 3660 { 3661 // print ItemSet, including all attributes 3662 Out_SfxItemSet( aCSS1AttrFnTab, *this, rItemSet, bDeep ); 3663 3664 // some Attributes require special treatment 3665 const SfxPoolItem *pItem = nullptr; 3666 3667 // Underline, Overline, CrossedOut and Blink form together a CSS1-Property 3668 // (doesn't work of course for Hints) 3669 if( !IsCSS1Source(CSS1_OUTMODE_HINT) ) 3670 { 3671 const SvxUnderlineItem *pUnderlineItem = nullptr; 3672 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_UNDERLINE, bDeep, &pItem )) 3673 pUnderlineItem = static_cast<const SvxUnderlineItem *>(pItem); 3674 3675 const SvxOverlineItem *pOverlineItem = nullptr; 3676 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_OVERLINE, bDeep, &pItem )) 3677 pOverlineItem = static_cast<const SvxOverlineItem *>(pItem); 3678 3679 const SvxCrossedOutItem *pCrossedOutItem = nullptr; 3680 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_CROSSEDOUT, bDeep, &pItem )) 3681 pCrossedOutItem = static_cast<const SvxCrossedOutItem *>(pItem); 3682 3683 const SvxBlinkItem *pBlinkItem = nullptr; 3684 if( SfxItemState::SET==rItemSet.GetItemState( RES_CHRATR_BLINK, bDeep, &pItem )) 3685 pBlinkItem = static_cast<const SvxBlinkItem *>(pItem); 3686 3687 if( pUnderlineItem || pOverlineItem || pCrossedOutItem || pBlinkItem ) 3688 OutCSS1_SvxTextLn_SvxCrOut_SvxBlink( *this, pUnderlineItem, 3689 pOverlineItem, 3690 pCrossedOutItem, 3691 pBlinkItem ); 3692 3693 OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet, bDeep ); 3694 } 3695 3696 if( !m_bFirstCSS1Property ) 3697 { 3698 // if a Property was exported as part of a Style-Option, 3699 // the Option still needs to be finished 3700 OStringBuffer sOut; 3701 switch( m_nCSS1OutMode & CSS1_OUTMODE_ANY_OFF ) 3702 { 3703 case CSS1_OUTMODE_SPAN_TAG_OFF: 3704 sOut.append(sCSS1_span_tag_end); 3705 break; 3706 3707 case CSS1_OUTMODE_STYLE_OPT_OFF: 3708 sOut.append(cCSS1_style_opt_end); 3709 break; 3710 3711 case CSS1_OUTMODE_RULE_OFF: 3712 sOut.append(sCSS1_rule_end); 3713 break; 3714 } 3715 if (!sOut.isEmpty()) 3716 Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); 3717 } 3718 } 3719 3720 Writer& OutCSS1_HintSpanTag( Writer& rWrt, const SfxPoolItem& rHt ) 3721 { 3722 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 3723 3724 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_SPAN_TAG | 3725 CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_HINT, nullptr ); 3726 3727 Out( aCSS1AttrFnTab, rHt, rWrt ); 3728 3729 if( !rHTMLWrt.m_bFirstCSS1Property && rHTMLWrt.m_bTagOn ) 3730 rWrt.Strm().WriteCharPtr( sCSS1_span_tag_end ); 3731 3732 return rWrt; 3733 } 3734 3735 Writer& OutCSS1_HintStyleOpt( Writer& rWrt, const SfxPoolItem& rHt ) 3736 { 3737 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); 3738 3739 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON | 3740 CSS1_OUTMODE_ENCODE| 3741 CSS1_OUTMODE_HINT, nullptr ); 3742 3743 Out( aCSS1AttrFnTab, rHt, rWrt ); 3744 3745 if( !rHTMLWrt.m_bFirstCSS1Property ) 3746 rWrt.Strm().WriteChar( '\"' ); 3747 3748 return rWrt; 3749 } 3750 3751 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 3752
