Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / filter / html / htmlfldw.cxx
blob04f5dad8dbdcdb4114d39b683ed1badba3e53209
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/i18n/XBreakIterator.hpp>
21 #include <comphelper/string.hxx>
22 #include <comphelper/xmlencode.hxx>
23 #include <svtools/htmlkywd.hxx>
24 #include <svtools/htmlout.hxx>
25 #include <osl/diagnose.h>
26 #include <o3tl/string_view.hxx>
27 #include <fmtfld.hxx>
28 #include <doc.hxx>
29 #include <docsh.hxx>
30 #include <view.hxx>
31 #include <wrtsh.hxx>
32 #include <breakit.hxx>
33 #include <ndtxt.hxx>
34 #include <txtfld.hxx>
35 #include <fldbas.hxx>
36 #include <docufld.hxx>
37 #include <flddat.hxx>
38 #include <viewopt.hxx>
39 #include "htmlfld.hxx"
40 #include "wrthtml.hxx"
41 #include <rtl/strbuf.hxx>
42 #include "css1atr.hxx"
43 #include "css1kywd.hxx"
45 using namespace nsSwDocInfoSubType;
47 const char *SwHTMLWriter::GetNumFormat( sal_uInt16 nFormat )
49 const char *pFormatStr = nullptr;
51 switch( static_cast<SvxNumType>(nFormat) )
53 case SVX_NUM_CHARS_UPPER_LETTER: pFormatStr = OOO_STRING_SW_HTML_FF_uletter; break;
54 case SVX_NUM_CHARS_LOWER_LETTER: pFormatStr = OOO_STRING_SW_HTML_FF_lletter; break;
55 case SVX_NUM_ROMAN_UPPER: pFormatStr = OOO_STRING_SW_HTML_FF_uroman; break;
56 case SVX_NUM_ROMAN_LOWER: pFormatStr = OOO_STRING_SW_HTML_FF_lroman; break;
57 case SVX_NUM_ARABIC: pFormatStr = OOO_STRING_SW_HTML_FF_arabic; break;
58 case SVX_NUM_NUMBER_NONE: pFormatStr = OOO_STRING_SW_HTML_FF_none; break;
59 case SVX_NUM_CHAR_SPECIAL: pFormatStr = OOO_STRING_SW_HTML_FF_char; break;
60 case SVX_NUM_PAGEDESC: pFormatStr = OOO_STRING_SW_HTML_FF_page; break;
61 case SVX_NUM_CHARS_UPPER_LETTER_N: pFormatStr = OOO_STRING_SW_HTML_FF_ulettern; break;
62 case SVX_NUM_CHARS_LOWER_LETTER_N: pFormatStr = OOO_STRING_SW_HTML_FF_llettern; break;
63 default:
67 return pFormatStr;
70 static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, const SwField* pField,
71 const SwTextNode& rTextNd, sal_Int32 nFieldPos )
73 const SwFieldType* pFieldTyp = pField->GetTyp();
74 SwFieldIds nField = pFieldTyp->Which();
75 sal_uLong nFormat = pField->GetFormat();
77 const char *pTypeStr=nullptr, // TYPE
78 *pSubStr=nullptr, // SUBTYPE
79 *pFormatStr=nullptr; // FORMAT (SW)
80 OUString aValue; // VALUE (SW)
81 bool bNumFormat=false; // SDNUM (Number-Formatter-Format)
82 bool bNumValue=false; // SDVAL (Number-Formatter-Value)
83 double dNumValue = 0.0; // SDVAL (Number-Formatter-Value)
84 bool bFixed=false; // SDFIXED
85 OUString aName; // NAME (CUSTOM)
87 switch( nField )
89 case SwFieldIds::ExtUser:
90 pTypeStr = OOO_STRING_SW_HTML_FT_sender;
91 switch( static_cast<SwExtUserSubType>(pField->GetSubType()) )
93 case EU_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_company; break;
94 case EU_FIRSTNAME: pSubStr = OOO_STRING_SW_HTML_FS_firstname; break;
95 case EU_NAME: pSubStr = OOO_STRING_SW_HTML_FS_name; break;
96 case EU_SHORTCUT: pSubStr = OOO_STRING_SW_HTML_FS_shortcut; break;
97 case EU_STREET: pSubStr = OOO_STRING_SW_HTML_FS_street; break;
98 case EU_COUNTRY: pSubStr = OOO_STRING_SW_HTML_FS_country; break;
99 case EU_ZIP: pSubStr = OOO_STRING_SW_HTML_FS_zip; break;
100 case EU_CITY: pSubStr = OOO_STRING_SW_HTML_FS_city; break;
101 case EU_TITLE: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
102 case EU_POSITION: pSubStr = OOO_STRING_SW_HTML_FS_position; break;
103 case EU_PHONE_PRIVATE: pSubStr = OOO_STRING_SW_HTML_FS_pphone; break;
104 case EU_PHONE_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_cphone; break;
105 case EU_FAX: pSubStr = OOO_STRING_SW_HTML_FS_fax; break;
106 case EU_EMAIL: pSubStr = OOO_STRING_SW_HTML_FS_email; break;
107 case EU_STATE: pSubStr = OOO_STRING_SW_HTML_FS_state; break;
108 default:
111 OSL_ENSURE( pSubStr, "unknown sub type for SwExtUserField" );
112 bFixed = static_cast<const SwExtUserField*>(pField)->IsFixed();
113 break;
115 case SwFieldIds::Author:
116 pTypeStr = OOO_STRING_SW_HTML_FT_author;
117 switch( static_cast<SwAuthorFormat>(nFormat) & 0xff)
119 case AF_NAME: pFormatStr = OOO_STRING_SW_HTML_FF_name; break;
120 case AF_SHORTCUT: pFormatStr = OOO_STRING_SW_HTML_FF_shortcut; break;
122 OSL_ENSURE( pFormatStr, "unknown format for SwAuthorField" );
123 bFixed = static_cast<const SwAuthorField*>(pField)->IsFixed();
124 break;
126 case SwFieldIds::DateTime:
127 pTypeStr = OOO_STRING_SW_HTML_FT_datetime;
128 bNumFormat = true;
129 if( static_cast<const SwDateTimeField*>(pField)->IsFixed() )
131 bNumValue = true;
132 dNumValue = static_cast<const SwDateTimeField*>(pField)->GetValue();
134 break;
136 case SwFieldIds::PageNumber:
138 pTypeStr = OOO_STRING_SW_HTML_FT_page;
139 SwPageNumSubType eSubType = static_cast<SwPageNumSubType>(pField->GetSubType());
140 switch( eSubType )
142 case PG_RANDOM: pSubStr = OOO_STRING_SW_HTML_FS_random; break;
143 case PG_NEXT: pSubStr = OOO_STRING_SW_HTML_FS_next; break;
144 case PG_PREV: pSubStr = OOO_STRING_SW_HTML_FS_prev; break;
146 OSL_ENSURE( pSubStr, "unknown sub type for SwPageNumberField" );
147 pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFormat) );
149 if( static_cast<SvxNumType>(nFormat)==SVX_NUM_CHAR_SPECIAL )
151 aValue = static_cast<const SwPageNumberField *>(pField)->GetUserString();
153 else
155 const OUString& rValue = pField->GetPar2();
156 short nValue = static_cast<short>(rValue.toInt32());
157 if( (eSubType == PG_NEXT && nValue!=1) ||
158 (eSubType == PG_PREV && nValue!=-1) ||
159 (eSubType == PG_RANDOM && nValue!=0) )
161 aValue = rValue;
165 break;
166 case SwFieldIds::DocInfo:
168 sal_uInt16 nSubType = pField->GetSubType();
169 pTypeStr = OOO_STRING_SW_HTML_FT_docinfo;
170 sal_uInt16 nExtSubType = nSubType & 0x0f00;
171 nSubType &= 0x00ff;
173 switch( nSubType )
175 case DI_TITLE: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
176 case DI_SUBJECT: pSubStr = OOO_STRING_SW_HTML_FS_theme; break;
177 case DI_KEYS: pSubStr = OOO_STRING_SW_HTML_FS_keys; break;
178 case DI_COMMENT: pSubStr = OOO_STRING_SW_HTML_FS_comment; break;
179 case DI_CREATE: pSubStr = OOO_STRING_SW_HTML_FS_create; break;
180 case DI_CHANGE: pSubStr = OOO_STRING_SW_HTML_FS_change; break;
181 case DI_CUSTOM: pSubStr = OOO_STRING_SW_HTML_FS_custom; break;
182 default: pTypeStr = nullptr; break;
185 if( DI_CUSTOM == nSubType ) {
186 aName = static_cast<const SwDocInfoField*>(pField)->GetName();
189 if( DI_CREATE == nSubType || DI_CHANGE == nSubType )
191 switch( nExtSubType )
193 case DI_SUB_AUTHOR:
194 pFormatStr = OOO_STRING_SW_HTML_FF_author;
195 break;
196 case DI_SUB_TIME:
197 pFormatStr = OOO_STRING_SW_HTML_FF_time;
198 bNumFormat = true;
199 break;
200 case DI_SUB_DATE:
201 pFormatStr = OOO_STRING_SW_HTML_FF_date;
202 bNumFormat = true;
203 break;
206 bFixed = static_cast<const SwDocInfoField*>(pField)->IsFixed();
207 if( bNumFormat )
209 if( bFixed )
211 // For a fixed field output the num value too.
212 // Fixed fields without number format shouldn't
213 // exist. See below for OSL_ENSURE().
214 dNumValue = static_cast<const SwDocInfoField*>(pField)->GetValue();
215 bNumValue = true;
217 else if( !nFormat )
219 // Non-fixed fields may not have a number format, when
220 // they come from a 4.0-document.
221 bNumFormat = false;
225 break;
227 case SwFieldIds::DocStat:
229 pTypeStr = OOO_STRING_SW_HTML_FT_docstat;
230 sal_uInt16 nSubType = pField->GetSubType();
231 switch( nSubType )
233 case DS_PAGE: pSubStr = OOO_STRING_SW_HTML_FS_page; break;
234 case DS_PARA: pSubStr = OOO_STRING_SW_HTML_FS_para; break;
235 case DS_WORD: pSubStr = OOO_STRING_SW_HTML_FS_word; break;
236 case DS_CHAR: pSubStr = OOO_STRING_SW_HTML_FS_char; break;
237 case DS_TBL: pSubStr = OOO_STRING_SW_HTML_FS_tbl; break;
238 case DS_GRF: pSubStr = OOO_STRING_SW_HTML_FS_grf; break;
239 case DS_OLE: pSubStr = OOO_STRING_SW_HTML_FS_ole; break;
240 default: pTypeStr = nullptr; break;
242 pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFormat) );
244 break;
246 case SwFieldIds::Filename:
247 pTypeStr = OOO_STRING_SW_HTML_FT_filename;
248 switch( static_cast<SwFileNameFormat>(nFormat & ~FF_FIXED) )
250 case FF_NAME: pFormatStr = OOO_STRING_SW_HTML_FF_name; break;
251 case FF_PATHNAME: pFormatStr = OOO_STRING_SW_HTML_FF_pathname; break;
252 case FF_PATH: pFormatStr = OOO_STRING_SW_HTML_FF_path; break;
253 case FF_NAME_NOEXT: pFormatStr = OOO_STRING_SW_HTML_FF_name_noext; break;
254 default:
257 bFixed = static_cast<const SwFileNameField*>(pField)->IsFixed();
258 OSL_ENSURE( pFormatStr, "unknown format for SwFileNameField" );
259 break;
260 default: break;
263 // ReqIF-XHTML doesn't allow <sdfield>.
264 if (rWrt.mbReqIF && pTypeStr)
266 pTypeStr = nullptr;
269 // Output the <sdfield> tag.
270 if( pTypeStr )
272 OStringBuffer sOut("<"
273 + rWrt.GetNamespace()
274 + OOO_STRING_SVTOOLS_HTML_sdfield
276 OOO_STRING_SVTOOLS_HTML_O_type
278 + pTypeStr);
279 if( pSubStr )
281 sOut.append(OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_subtype "=")
282 + pSubStr);
284 if( pFormatStr )
286 sOut.append(OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_format "=")
287 + pFormatStr);
289 if( !aName.isEmpty() )
291 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_name "=\"");
292 rWrt.Strm().WriteOString( sOut );
293 sOut.setLength(0);
294 HTMLOutFuncs::Out_String( rWrt.Strm(), aName );
295 sOut.append('\"');
297 if( !aValue.isEmpty() )
299 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_value "=\"");
300 rWrt.Strm().WriteOString( sOut );
301 sOut.setLength(0);
302 HTMLOutFuncs::Out_String( rWrt.Strm(), aValue );
303 sOut.append('\"');
305 if( bNumFormat )
307 OSL_ENSURE( nFormat, "number format is 0" );
308 sOut.append(HTMLOutFuncs::CreateTableDataOptionsValNum(
309 bNumValue, dNumValue, nFormat,
310 *rWrt.m_pDoc->GetNumberFormatter()));
312 if( bFixed )
314 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_sdfixed);
316 sOut.append('>');
317 rWrt.Strm().WriteOString( sOut );
318 sOut.setLength(0);
321 // output content of the field
322 OUString const sExpand( pField->ExpandField(true, nullptr) );
323 bool bNeedsCJKProcessing = false;
324 if( !sExpand.isEmpty() )
326 sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType( sExpand, 0 );
327 sal_Int32 nPos = g_pBreakIt->GetBreakIter()->endOfScript( sExpand, 0,
328 nScriptType );
330 sal_uInt16 nScript =
331 SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
332 if( (nPos < sExpand.getLength() && nPos >= 0) || nScript != rWrt.m_nCSS1Script )
334 bNeedsCJKProcessing = true;
338 if( bNeedsCJKProcessing )
340 //sequence of (start, end) property ranges we want to
341 //query
342 SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
343 RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
344 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
345 RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT>
346 aScriptItemSet( rWrt.m_pDoc->GetAttrPool() );
347 rTextNd.GetParaAttr(aScriptItemSet, nFieldPos, nFieldPos+1);
349 sal_uInt16 aWesternWhichIds[4] =
350 { RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
351 RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT };
352 sal_uInt16 aCJKWhichIds[4] =
353 { RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
354 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT };
355 sal_uInt16 aCTLWhichIds[4] =
356 { RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
357 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT };
359 sal_uInt16 *pRefWhichIds = nullptr;
360 switch( rWrt.m_nCSS1Script )
362 case CSS1_OUTMODE_WESTERN:
363 pRefWhichIds = aWesternWhichIds;
364 break;
365 case CSS1_OUTMODE_CJK:
366 pRefWhichIds = aCJKWhichIds;
367 break;
368 case CSS1_OUTMODE_CTL:
369 pRefWhichIds = aCTLWhichIds;
370 break;
373 sal_Int32 nPos = 0;
376 sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType( sExpand, nPos );
377 sal_uInt16 nScript =
378 SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
379 sal_Int32 nEndPos = g_pBreakIt->GetBreakIter()->endOfScript(
380 sExpand, nPos, nScriptType );
381 sal_Int32 nChunkLen = nEndPos - nPos;
382 if( nScript != CSS1_OUTMODE_ANY_SCRIPT &&
383 /* #108791# */ nScript != rWrt.m_nCSS1Script )
385 sal_uInt16 *pWhichIds = nullptr;
386 switch( nScript )
388 case CSS1_OUTMODE_WESTERN: pWhichIds = aWesternWhichIds; break;
389 case CSS1_OUTMODE_CJK: pWhichIds = aCJKWhichIds; break;
390 case CSS1_OUTMODE_CTL: pWhichIds = aCTLWhichIds; break;
393 rWrt.m_bTagOn = true;
395 const SfxPoolItem *aItems[5];
396 int nItems = 0;
398 assert(pWhichIds && pRefWhichIds);
399 if (pWhichIds && pRefWhichIds)
401 for( int i=0; i<4; i++ )
403 const SfxPoolItem *pRefItem =
404 aScriptItemSet.GetItem( pRefWhichIds[i] );
405 const SfxPoolItem *pItem =
406 aScriptItemSet.GetItem( pWhichIds[i] );
407 if( pRefItem && pItem &&
408 !(0==i ? swhtml_css1atr_equalFontItems( *pRefItem, *pItem )
409 : *pRefItem == *pItem) )
411 Out( aHTMLAttrFnTab, *pItem, rWrt );
412 aItems[nItems++] = pItem;
417 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.copy( nPos, nChunkLen ) );
419 rWrt.m_bTagOn = false;
420 while( nItems )
421 Out( aHTMLAttrFnTab, *aItems[--nItems], rWrt );
424 else
426 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.copy( nPos, nChunkLen ) );
428 nPos = nEndPos;
430 while( nPos < sExpand.getLength() );
432 else
434 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand );
437 // Output the closing tag.
438 if( pTypeStr )
439 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_sdfield), false );
441 return rWrt;
444 SwHTMLWriter& OutHTML_SwFormatField( SwHTMLWriter& rWrt, const SfxPoolItem& rHt )
446 const SwFormatField & rField = static_cast<const SwFormatField&>(rHt);
447 const SwField* pField = rField.GetField();
448 const SwFieldType* pFieldTyp = pField->GetTyp();
450 if( SwFieldIds::SetExp == pFieldTyp->Which() &&
451 (nsSwGetSetExpType::GSE_STRING & pField->GetSubType()) )
453 const bool bOn = pFieldTyp->GetName() == "HTML_ON";
454 if (!bOn && pFieldTyp->GetName() != "HTML_OFF")
455 return rWrt;
457 OUString rText(comphelper::string::strip(pField->GetPar2(), ' '));
458 rWrt.Strm().WriteChar( '<' );
459 if( !bOn )
460 rWrt.Strm().WriteChar( '/' );
461 // TODO: HTML-Tags are written without entities, that for, characters
462 // not contained in the destination encoding are lost!
463 OString sTmp(OUStringToOString(rText,
464 RTL_TEXTENCODING_UTF8));
465 rWrt.Strm().WriteOString( sTmp ).WriteChar( '>' );
467 else if( SwFieldIds::Postit == pFieldTyp->Which() )
469 // Comments will be written in ANSI character set, but with system
470 // line breaks.
471 const OUString& rComment = pField->GetPar2();
472 bool bWritten = false;
474 if( (rComment.getLength() >= 6 && rComment.startsWith("<") && rComment.endsWith(">") &&
475 o3tl::equalsIgnoreAsciiCase(rComment.subView( 1, 4 ), u"" OOO_STRING_SVTOOLS_HTML_meta) ) ||
476 (rComment.getLength() >= 7 &&
477 rComment.startsWith( "<!--" ) &&
478 rComment.endsWith( "-->" )) )
480 // directly output META tags
481 OUString sComment(convertLineEnd(rComment, GetSystemLineEnd()));
482 // TODO: HTML-Tags are written without entities, that for,
483 // characters not contained in the destination encoding are lost!
484 OString sTmp(OUStringToOString(sComment,
485 RTL_TEXTENCODING_UTF8));
486 rWrt.Strm().WriteOString( sTmp );
487 bWritten = true;
489 else if( rComment.getLength() >= 7 &&
490 rComment.endsWith(">") &&
491 rComment.startsWithIgnoreAsciiCase( "HTML:" ) )
493 OUString sComment(comphelper::string::stripStart(rComment.subView(5), ' '));
494 if( '<' == sComment[0] )
496 sComment = convertLineEnd(sComment, GetSystemLineEnd());
497 // TODO: HTML-Tags are written without entities, that for,
498 // characters not contained in the destination encoding are
499 // lost!
500 OString sTmp(OUStringToOString(sComment,
501 RTL_TEXTENCODING_UTF8));
502 rWrt.Strm().WriteOString( sTmp );
503 bWritten = true;
508 if( !bWritten )
510 OUString sComment(convertLineEnd(rComment, GetSystemLineEnd()));
511 // TODO: ???
512 OString sOut =
513 "<" OOO_STRING_SVTOOLS_HTML_comment
514 " " +
515 OUStringToOString(comphelper::string::encodeForXml(sComment), RTL_TEXTENCODING_UTF8) +
516 " -->";
517 rWrt.Strm().WriteOString( sOut );
520 else if( SwFieldIds::Script == pFieldTyp->Which() )
522 if( rWrt.m_bLFPossible )
523 rWrt.OutNewLine( true );
525 bool bURL = static_cast<const SwScriptField *>(pField)->IsCodeURL();
526 const OUString& rType = pField->GetPar1();
527 OUString aContents, aURL;
528 if(bURL)
529 aURL = pField->GetPar2();
530 else
531 aContents = pField->GetPar2();
533 // otherwise is the script content itself. Since only JavaScript
534 // is in fields, it must be JavaScript ...:)
535 HTMLOutFuncs::OutScript( rWrt.Strm(), rWrt.GetBaseURL(), aContents, rType, JAVASCRIPT,
536 aURL, nullptr, nullptr );
538 if( rWrt.m_bLFPossible )
539 rWrt.OutNewLine( true );
541 else
543 const SwTextField *pTextField = rField.GetTextField();
544 OSL_ENSURE( pTextField, "Where is the txt fld?" );
545 if (pTextField && rWrt.m_pDoc->GetDocShell() && rWrt.m_pDoc->GetDocShell()->GetView())
547 // ReqIF-XHTML doesn't allow specifying a background color.
548 const SwViewOption* pViewOptions = rWrt.m_pDoc->GetDocShell()->GetView()->GetWrtShell().GetViewOptions();
549 bool bFieldShadings = pViewOptions->IsFieldShadings() && !rWrt.mbReqIF;
550 if (bFieldShadings)
552 // If there is a text portion background started already, that should have priority.
553 auto it = rWrt.maStartedAttributes.find(RES_CHRATR_BACKGROUND);
554 if (it != rWrt.maStartedAttributes.end())
555 bFieldShadings = it->second <= 0;
558 if (bFieldShadings)
560 const Color& rColor = pViewOptions->GetFieldShadingsColor();
561 OString sOut(
562 "<" + rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
563 " " OOO_STRING_SVTOOLS_HTML_O_style "=\""
564 + sCSS1_P_background
565 + ": "
566 + GetCSS1_Color(rColor)
567 + "\">");
568 rWrt.Strm().WriteOString(sOut);
571 OutHTML_SwField( rWrt, pField, pTextField->GetTextNode(),
572 pTextField->GetStart() );
574 if (bFieldShadings)
575 HTMLOutFuncs::Out_AsciiTag(
576 rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false);
579 return rWrt;
582 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */