1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/text/HoriOrientation.hpp>
21 #include <com/sun/star/text/VertOrientation.hpp>
23 #include <hintids.hxx>
24 #include <svl/itemiter.hxx>
25 #include <editeng/lrspitem.hxx>
26 #include <editeng/ulspitem.hxx>
27 #include <editeng/brushitem.hxx>
28 #include <editeng/fhgtitem.hxx>
29 #include <svtools/htmltokn.h>
30 #include <editeng/boxitem.hxx>
31 #include <osl/diagnose.h>
32 #include <o3tl/string_view.hxx>
36 #include <shellio.hxx>
38 #include "htmlnum.hxx"
45 using namespace ::com::sun::star
;
47 class HTMLAttrContext_SaveDoc
49 SwHTMLNumRuleInfo m_aNumRuleInfo
; // Numbering for this environment
50 std::unique_ptr
<SwPosition
>
51 m_pPos
; // Jump back to here when leaving context
52 std::shared_ptr
<HTMLAttrTable
>
53 m_xAttrTab
; // Valid attributes for the environment,
54 // if attributes shouldn't be preserved
56 size_t m_nContextStMin
; // Stack lower bound for the environment
57 // if stack needs to be protected
58 size_t m_nContextStAttrMin
; // Stack lower bound for the environment
59 // if the attributes shouldn't be preserved
60 bool m_bStripTrailingPara
: 1;
61 bool m_bKeepNumRules
: 1;
62 bool m_bFixHeaderDist
: 1;
63 bool m_bFixFooterDist
: 1;
67 HTMLAttrContext_SaveDoc() :
68 m_nContextStMin( SIZE_MAX
), m_nContextStAttrMin( SIZE_MAX
),
69 m_bStripTrailingPara( false ), m_bKeepNumRules( false ),
70 m_bFixHeaderDist( false ), m_bFixFooterDist( false )
73 // The position is ours, so we need to create and delete it
74 void SetPos( const SwPosition
& rPos
) { m_pPos
.reset( new SwPosition(rPos
) ); }
75 const SwPosition
*GetPos() const { return m_pPos
.get(); }
77 // The index isn't ours. So no creation or deletion
78 void SetNumInfo( const SwHTMLNumRuleInfo
& rInf
) { m_aNumRuleInfo
.Set(rInf
); }
79 const SwHTMLNumRuleInfo
& GetNumInfo() const { return m_aNumRuleInfo
; }
81 std::shared_ptr
<HTMLAttrTable
> const & GetAttrTab(bool bCreate
= false);
83 void SetContextStMin( size_t nMin
) { m_nContextStMin
= nMin
; }
84 size_t GetContextStMin() const { return m_nContextStMin
; }
86 void SetContextStAttrMin( size_t nMin
) { m_nContextStAttrMin
= nMin
; }
87 size_t GetContextStAttrMin() const { return m_nContextStAttrMin
; }
89 void SetStripTrailingPara( bool bSet
) { m_bStripTrailingPara
= bSet
; }
90 bool GetStripTrailingPara() const { return m_bStripTrailingPara
; }
92 void SetKeepNumRules( bool bSet
) { m_bKeepNumRules
= bSet
; }
93 bool GetKeepNumRules() const { return m_bKeepNumRules
; }
95 void SetFixHeaderDist( bool bSet
) { m_bFixHeaderDist
= bSet
; }
96 bool GetFixHeaderDist() const { return m_bFixHeaderDist
; }
98 void SetFixFooterDist( bool bSet
) { m_bFixFooterDist
= bSet
; }
99 bool GetFixFooterDist() const { return m_bFixFooterDist
; }
102 std::shared_ptr
<HTMLAttrTable
> const & HTMLAttrContext_SaveDoc::GetAttrTab( bool bCreate
)
104 if (!m_xAttrTab
&& bCreate
)
106 m_xAttrTab
= std::make_shared
<HTMLAttrTable
>();
107 memset(m_xAttrTab
.get(), 0, sizeof(HTMLAttrTable
));
112 HTMLAttrContext_SaveDoc
*HTMLAttrContext::GetSaveDocContext( bool bCreate
)
114 if( !m_pSaveDocContext
&& bCreate
)
115 m_pSaveDocContext
.reset(new HTMLAttrContext_SaveDoc
);
117 return m_pSaveDocContext
.get();
120 HTMLAttrContext::HTMLAttrContext( HtmlTokenId nTokn
, sal_uInt16 nPoolId
, OUString aClass
,
122 m_aClass(std::move( aClass
)),
124 m_nTextFormatColl( nPoolId
),
127 m_nFirstLineIndent( 0 ),
130 m_eAppend( AM_NONE
),
131 m_bLRSpaceChanged( false ),
132 m_bULSpaceChanged( false ),
133 m_bDefaultTextFormatColl( bDfltColl
),
134 m_bSpansSection( false ),
135 m_bPopStack( false ),
136 m_bFinishPREListingXMP( false ),
137 m_bRestartPRE( false ),
138 m_bRestartXMP( false ),
139 m_bRestartListing( false ),
140 m_bHeaderOrFooter( false )
143 HTMLAttrContext::HTMLAttrContext( HtmlTokenId nTokn
) :
145 m_nTextFormatColl( 0 ),
148 m_nFirstLineIndent( 0 ),
151 m_eAppend( AM_NONE
),
152 m_bLRSpaceChanged( false ),
153 m_bULSpaceChanged( false ),
154 m_bDefaultTextFormatColl( false ),
155 m_bSpansSection( false ),
156 m_bPopStack( false ),
157 m_bFinishPREListingXMP( false ),
158 m_bRestartPRE( false ),
159 m_bRestartXMP( false ),
160 m_bRestartListing( false ),
161 m_bHeaderOrFooter( false )
164 HTMLAttrContext::~HTMLAttrContext()
166 m_pSaveDocContext
.reset();
169 void HTMLAttrContext::ClearSaveDocContext()
171 m_pSaveDocContext
.reset();
174 void SwHTMLParser::SplitAttrTab( const SwPosition
& rNewPos
)
176 // preliminary paragraph attributes are not allowed here, they could
177 // be set here and then the pointers become invalid!
178 OSL_ENSURE(m_aParaAttrs
.empty(),
179 "Danger: there are non-final paragraph attributes");
180 m_aParaAttrs
.clear();
182 const SwPosition
* pOldEndPara
= m_pPam
->GetPoint();
184 auto const nOld(pOldEndPara
->GetNodeIndex());
186 sal_Int32 nOldEndCnt
= m_pPam
->GetPoint()->GetContentIndex();
188 const SwPosition
& rNewSttPara
= rNewPos
;
189 sal_Int32 nNewSttCnt
= rNewPos
.GetContentIndex();
191 bool bMoveBack
= false;
193 // close all open attributes and re-open them after the table
194 HTMLAttr
** pHTMLAttributes
= reinterpret_cast<HTMLAttr
**>(m_xAttrTab
.get());
195 for (auto nCnt
= sizeof(HTMLAttrTable
) / sizeof(HTMLAttr
*); nCnt
--; ++pHTMLAttributes
)
197 HTMLAttr
*pAttr
= *pHTMLAttributes
;
200 HTMLAttr
*pNext
= pAttr
->GetNext();
201 HTMLAttr
*pPrev
= pAttr
->GetPrev();
203 sal_uInt16 nWhich
= pAttr
->m_pItem
->Which();
204 if( !nOldEndCnt
&& RES_PARATR_BEGIN
<= nWhich
&&
205 pAttr
->GetStartParagraphIdx() < pOldEndPara
->GetNodeIndex() )
207 // The attribute needs to be closed one content position beforehand
210 bMoveBack
= m_pPam
->Move( fnMoveBackward
);
211 nOldEndCnt
= m_pPam
->GetPoint()->GetContentIndex();
216 m_pPam
->Move( fnMoveForward
);
217 nOldEndCnt
= m_pPam
->GetPoint()->GetContentIndex();
221 if( (RES_PARATR_BEGIN
<= nWhich
&& bMoveBack
) ||
222 pAttr
->GetStartParagraphIdx() < pOldEndPara
->GetNodeIndex() ||
223 (pAttr
->GetStartParagraph() == pOldEndPara
->GetNode() &&
224 pAttr
->GetStartContent() != nOldEndCnt
) )
226 // The attribute needs to be set. Because we still need the original, since
227 // pointers to the attribute still exists in the contexts, we need to clone it.
228 // The next-list gets lost but the previous-list is preserved
229 HTMLAttr
*pSetAttr
= pAttr
->Clone( pOldEndPara
->GetNode(), nOldEndCnt
);
232 pNext
->InsertPrev( pSetAttr
);
235 if (pSetAttr
->m_bInsAtStart
)
236 m_aSetAttrTab
.push_front( pSetAttr
);
238 m_aSetAttrTab
.push_back( pSetAttr
);
243 // The previous attributes still need to be set, even if the current attribute
244 // doesn't need to be set before the table
246 pNext
->InsertPrev( pPrev
);
249 if (pPrev
->m_bInsAtStart
)
250 m_aSetAttrTab
.push_front( pPrev
);
252 m_aSetAttrTab
.push_back( pPrev
);
256 // Set the start of the attribute
257 pAttr
->m_nStartPara
= rNewSttPara
.GetNode();
258 pAttr
->m_nEndPara
= rNewSttPara
.GetNode();
259 pAttr
->m_nStartContent
= nNewSttCnt
;
260 pAttr
->m_nEndContent
= nNewSttCnt
;
261 pAttr
->m_pPrev
= nullptr;
268 m_pPam
->Move( fnMoveForward
);
270 assert(m_pPam
->GetPoint()->GetNodeIndex() == nOld
);
273 void SwHTMLParser::SaveDocContext( HTMLAttrContext
*pCntxt
,
274 HtmlContextFlags nFlags
,
275 const SwPosition
*pNewPos
)
277 HTMLAttrContext_SaveDoc
*pSave
= pCntxt
->GetSaveDocContext( true );
278 pSave
->SetStripTrailingPara( bool(HtmlContextFlags::StripPara
& nFlags
) );
279 pSave
->SetKeepNumRules( bool(HtmlContextFlags::KeepNumrule
& nFlags
) );
280 pSave
->SetFixHeaderDist( bool(HtmlContextFlags::HeaderDist
& nFlags
) );
281 pSave
->SetFixFooterDist( bool(HtmlContextFlags::FooterDist
& nFlags
) );
285 // If the PaM needs to be set to a different position, we need to preserve numbering
286 if( !pSave
->GetKeepNumRules() )
288 // Numbering shall not be preserved. So we need to preserve the current state
289 // and turn off numbering afterwards
290 pSave
->SetNumInfo( GetNumInfo() );
291 GetNumInfo().Clear();
294 if( HtmlContextFlags::KeepAttrs
& nFlags
)
296 // Close attribute on current position and start on new one
297 SplitAttrTab( *pNewPos
);
301 std::shared_ptr
<HTMLAttrTable
> xSaveAttrTab
= pSave
->GetAttrTab(true);
302 SaveAttrTab(xSaveAttrTab
);
305 pSave
->SetPos( *m_pPam
->GetPoint() );
306 *m_pPam
->GetPoint() = *pNewPos
;
309 // Settings nContextStMin automatically means, that no
310 // currently open lists (DL/OL/UL) can be closed
311 if( HtmlContextFlags::ProtectStack
& nFlags
)
313 pSave
->SetContextStMin( m_nContextStMin
);
314 m_nContextStMin
= m_aContexts
.size();
316 if( HtmlContextFlags::KeepAttrs
& nFlags
)
318 pSave
->SetContextStAttrMin( m_nContextStAttrMin
);
319 m_nContextStAttrMin
= m_aContexts
.size();
324 void SwHTMLParser::RestoreDocContext( HTMLAttrContext
*pCntxt
)
326 HTMLAttrContext_SaveDoc
*pSave
= pCntxt
->GetSaveDocContext();
330 if( pSave
->GetStripTrailingPara() )
333 if( pSave
->GetPos() )
335 if( pSave
->GetFixHeaderDist() || pSave
->GetFixFooterDist() )
336 FixHeaderFooterDistance( pSave
->GetFixHeaderDist(),
339 std::shared_ptr
<HTMLAttrTable
> xSaveAttrTab
= pSave
->GetAttrTab();
342 // Close attribute on current position and start on the old one
343 SplitAttrTab( *pSave
->GetPos() );
347 RestoreAttrTab(xSaveAttrTab
);
350 *m_pPam
->GetPoint() = *pSave
->GetPos();
352 // We can already set the attributes so far
356 if( SIZE_MAX
!= pSave
->GetContextStMin() )
358 m_nContextStMin
= pSave
->GetContextStMin();
359 if( SIZE_MAX
!= pSave
->GetContextStAttrMin() )
360 m_nContextStAttrMin
= pSave
->GetContextStAttrMin();
363 if( !pSave
->GetKeepNumRules() )
365 // Set the preserved numbering back
366 GetNumInfo().Set( pSave
->GetNumInfo() );
369 pCntxt
->ClearSaveDocContext();
372 void SwHTMLParser::EndContext( HTMLAttrContext
*pContext
)
374 if( pContext
->GetPopStack() )
376 // Close all still open contexts. Our own context needs to be deleted already!
377 while( m_aContexts
.size() > m_nContextStMin
)
379 std::unique_ptr
<HTMLAttrContext
> xCntxt(PopContext());
380 OSL_ENSURE(xCntxt
.get() != pContext
,
381 "Context still on the stack" );
382 if (xCntxt
.get() == pContext
)
385 EndContext(xCntxt
.get());
389 // Close all still open attributes
390 if( pContext
->HasAttrs() )
391 EndContextAttrs( pContext
);
393 // If a section has been opened, end it. Since sections can be part of absolute-positioned
394 // objects, this needs to be done before restoring document context
395 if( pContext
->GetSpansSection() )
398 // Leave borders and other special sections
399 if( pContext
->HasSaveDocContext() )
400 RestoreDocContext( pContext
);
402 // Add a paragraph break if needed
403 if( AM_NONE
!= pContext
->GetAppendMode() &&
404 m_pPam
->GetPoint()->GetContentIndex() )
405 AppendTextNode( pContext
->GetAppendMode() );
407 // Restart PRE, LISTING and XMP environments
408 if( pContext
->IsFinishPREListingXMP() )
409 FinishPREListingXMP();
411 if( pContext
->IsRestartPRE() )
414 if( pContext
->IsRestartXMP() )
417 if( pContext
->IsRestartListing() )
421 void SwHTMLParser::ClearContext( HTMLAttrContext
*pContext
)
423 HTMLAttrs
&rAttrs
= pContext
->GetAttrs();
424 for( auto pAttr
: rAttrs
)
426 // Simple deletion doesn't to the job, since the attribute
427 // needs to be deregistered with its list.
428 // In theory, you could delete the list and its attributes separately
429 // but if you get that wrong, quite a lot is messed up
434 OSL_ENSURE( !pContext
->GetSpansSection(),
435 "Area can no longer be exited" );
437 OSL_ENSURE( !pContext
->HasSaveDocContext(),
438 "Frame can no longer be exited" );
440 // like RestoreDocContext reset enough of this to not catastrophically
441 // fail if we still have a SaveDocContext here
442 if (HTMLAttrContext_SaveDoc
*pSave
= pContext
->GetSaveDocContext())
444 if (SIZE_MAX
!= pSave
->GetContextStMin())
446 m_nContextStMin
= pSave
->GetContextStMin();
447 if (SIZE_MAX
!= pSave
->GetContextStAttrMin())
448 m_nContextStAttrMin
= pSave
->GetContextStAttrMin();
451 pContext
->ClearSaveDocContext();
454 // Restart PRE/LISTING/XMP environments
455 if( pContext
->IsFinishPREListingXMP() )
456 FinishPREListingXMP();
458 if( pContext
->IsRestartPRE() )
461 if( pContext
->IsRestartXMP() )
464 if( pContext
->IsRestartListing() )
468 bool SwHTMLParser::DoPositioning( SfxItemSet
&rItemSet
,
469 SvxCSS1PropertyInfo
&rPropInfo
,
470 HTMLAttrContext
*pContext
)
474 // A border is opened on the following conditions
475 // - the tag is absolute-positioned AND left/top are both known AND don't contain a % property
477 // - the tag should be floating AND
478 // - there's a given width
479 if( SwCSS1Parser::MayBePositioned( rPropInfo
) )
481 SfxItemSet
aFrameItemSet(SfxItemSet::makeFixedSfxItemSet
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1>(m_xDoc
->GetAttrPool()));
483 Reader::ResetFrameFormatAttrs(aFrameItemSet
);
485 SetAnchorAndAdjustment( text::VertOrientation::NONE
, text::HoriOrientation::NONE
, rPropInfo
,
488 SetVarSize( rPropInfo
, aFrameItemSet
);
490 SetSpace( Size(0,0), rItemSet
, rPropInfo
, aFrameItemSet
);
492 SetFrameFormatAttrs( rItemSet
,
493 HtmlFrameFormatFlags::Box
|HtmlFrameFormatFlags::Padding
|HtmlFrameFormatFlags::Background
|HtmlFrameFormatFlags::Direction
,
496 InsertFlyFrame(aFrameItemSet
, pContext
, rPropInfo
.m_aId
);
497 pContext
->SetPopStack( true );
498 rPropInfo
.m_aId
.clear();
505 bool SwHTMLParser::CreateContainer( std::u16string_view rClass
,
506 SfxItemSet
&rItemSet
,
507 SvxCSS1PropertyInfo
&rPropInfo
,
508 HTMLAttrContext
*pContext
)
511 if( o3tl::equalsIgnoreAsciiCase( rClass
, u
"sd-abs-pos" ) &&
512 SwCSS1Parser::MayBePositioned( rPropInfo
) )
515 SfxItemSet
*pFrameItemSet
= pContext
->GetFrameItemSet( m_xDoc
.get() );
517 Reader::ResetFrameFormatAttrs( *pFrameItemSet
);
519 SetAnchorAndAdjustment( text::VertOrientation::NONE
, text::HoriOrientation::NONE
,
520 rPropInfo
, *pFrameItemSet
);
522 SetFixSize( aDummy
, aDummy
, false, false, rPropInfo
, *pFrameItemSet
);
523 SetSpace( aDummy
, rItemSet
, rPropInfo
, *pFrameItemSet
);
524 SetFrameFormatAttrs( rItemSet
, HtmlFrameFormatFlags::Box
|HtmlFrameFormatFlags::Background
|HtmlFrameFormatFlags::Direction
,
533 void SwHTMLParser::InsertAttrs( SfxItemSet
&rItemSet
,
534 SvxCSS1PropertyInfo
const &rPropInfo
,
535 HTMLAttrContext
*pContext
,
538 // Put together a DropCap attribute, if a "float:left" is before the first character
539 if( bCharLvl
&& !m_pPam
->GetPoint()->GetContentIndex() &&
540 SvxAdjust::Left
== rPropInfo
.m_eFloat
)
545 m_pCSS1Parser
->FillDropCap( aDrop
, rItemSet
);
547 // We only set the DropCap attribute if the initial spans multiple lines
548 if( aDrop
.GetLines() > 1 )
550 NewAttr(m_xAttrTab
, &m_xAttrTab
->pDropCap
, aDrop
);
552 HTMLAttrs
&rAttrs
= pContext
->GetAttrs();
553 rAttrs
.push_back( m_xAttrTab
->pDropCap
);
560 m_pCSS1Parser
->SetFormatBreak( rItemSet
, rPropInfo
);
562 OSL_ENSURE(m_aContexts
.size() <= m_nContextStAttrMin
||
563 m_aContexts
.back().get() != pContext
,
564 "SwHTMLParser::InsertAttrs: Context already on the Stack");
566 SfxItemIter
aIter( rItemSet
);
568 const SvxFirstLineIndentItem
* pFirstLineItem(nullptr);
569 const SvxTextLeftMarginItem
* pTextLeftMargin(nullptr);
570 const SvxRightMarginItem
* pRightMargin(nullptr);
572 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
574 switch( pItem
->Which() )
576 case RES_MARGIN_FIRSTLINE
:
578 pFirstLineItem
= &(pItem
->StaticWhichCast(RES_MARGIN_FIRSTLINE
));
581 case RES_MARGIN_TEXTLEFT
:
583 pTextLeftMargin
= &(pItem
->StaticWhichCast(RES_MARGIN_TEXTLEFT
));
586 case RES_MARGIN_RIGHT
:
588 pRightMargin
= &(pItem
->StaticWhichCast(RES_MARGIN_RIGHT
));
596 // Paragraph indents need to be added and are generated for each paragraphs
597 // (here for the first paragraph only, all the following in SetTextCollAttrs)
599 // Get old paragraph indents without the top context (that's the one we're editing)
600 sal_uInt16 nOldLeft
= 0, nOldRight
= 0;
601 short nOldIndent
= 0;
602 bool bIgnoreTop
= m_aContexts
.size() > m_nContextStMin
&&
603 m_aContexts
.back().get() == pContext
;
604 GetMarginsFromContext( nOldLeft
, nOldRight
, nOldIndent
,
607 // ... and the currently valid ones
608 sal_uInt16 nLeft
= nOldLeft
, nRight
= nOldRight
;
609 short nIndent
= nOldIndent
;
610 pContext
->GetMargins( nLeft
, nRight
, nIndent
);
612 // ... and add the new indents to the old ones
613 // Here, we don't get the ones from the item but the separately remembered ones,
614 // since they could be negative. Accessing those via the item still works, since
615 // the item (with value 0) will be added
616 if( rPropInfo
.m_bLeftMargin
)
618 OSL_ENSURE(rPropInfo
.m_nLeftMargin
< 0 || !pTextLeftMargin
619 || rPropInfo
.m_nLeftMargin
620 == pTextLeftMargin
->ResolveTextLeft({}),
621 "left margin does not match with item");
622 if( rPropInfo
.m_nLeftMargin
< 0 &&
623 -rPropInfo
.m_nLeftMargin
> nOldLeft
)
626 nLeft
= nOldLeft
+ static_cast< sal_uInt16
>(rPropInfo
.m_nLeftMargin
);
628 if( rPropInfo
.m_bRightMargin
)
630 OSL_ENSURE(rPropInfo
.m_nRightMargin
< 0 || !pRightMargin
631 || rPropInfo
.m_nRightMargin
== pRightMargin
->ResolveRight({}),
632 "right margin does not match with item");
633 if( rPropInfo
.m_nRightMargin
< 0 &&
634 -rPropInfo
.m_nRightMargin
> nOldRight
)
637 nRight
= nOldRight
+ static_cast< sal_uInt16
>(rPropInfo
.m_nRightMargin
);
639 if (rPropInfo
.m_bTextIndent
&& pFirstLineItem
)
640 nIndent
= pFirstLineItem
->ResolveTextFirstLineOffset({});
642 // Remember the value for the following paragraphs
643 pContext
->SetMargins( nLeft
, nRight
, nIndent
);
645 // Set the attribute on the current paragraph
646 SvxFirstLineIndentItem
firstLine(SvxIndentValue::twips(nIndent
),
647 RES_MARGIN_FIRSTLINE
);
648 NewAttr(m_xAttrTab
, &m_xAttrTab
->pFirstLineIndent
, firstLine
);
649 EndAttr(m_xAttrTab
->pFirstLineIndent
, false);
650 SvxTextLeftMarginItem
const leftMargin(SvxIndentValue::twips(nLeft
),
651 RES_MARGIN_TEXTLEFT
);
652 NewAttr(m_xAttrTab
, &m_xAttrTab
->pTextLeftMargin
, leftMargin
);
653 EndAttr(m_xAttrTab
->pTextLeftMargin
, false);
654 SvxRightMarginItem
const rightMargin(SvxIndentValue::twips(nRight
),
656 NewAttr(m_xAttrTab
, &m_xAttrTab
->pRightMargin
, rightMargin
);
657 EndAttr(m_xAttrTab
->pRightMargin
, false);
661 SfxItemIter
aIter2(rItemSet
);
662 for (const SfxPoolItem
* pItem
= aIter2
.GetCurItem(); pItem
; pItem
= aIter2
.NextItem())
664 HTMLAttr
**ppAttr
= nullptr;
666 switch( pItem
->Which() )
670 if( !rPropInfo
.m_bTopMargin
|| !rPropInfo
.m_bBottomMargin
)
672 sal_uInt16 nUpper
= 0, nLower
= 0;
673 GetULSpaceFromContext( nUpper
, nLower
);
674 SvxULSpaceItem
aULSpace( pItem
->StaticWhichCast(RES_UL_SPACE
) );
675 if( !rPropInfo
.m_bTopMargin
)
676 aULSpace
.SetUpper( nUpper
);
677 if( !rPropInfo
.m_bBottomMargin
)
678 aULSpace
.SetLower( nLower
);
680 NewAttr(m_xAttrTab
, &m_xAttrTab
->pULSpace
, aULSpace
);
682 // save context information
683 HTMLAttrs
&rAttrs
= pContext
->GetAttrs();
684 rAttrs
.push_back( m_xAttrTab
->pULSpace
);
686 pContext
->SetULSpace( aULSpace
.GetUpper(), aULSpace
.GetLower() );
690 ppAttr
= &m_xAttrTab
->pULSpace
;
693 case RES_CHRATR_FONTSIZE
:
694 // don't set attributes with a % property
695 if( pItem
->StaticWhichCast(RES_CHRATR_FONTSIZE
).GetProp() == 100 )
696 ppAttr
= &m_xAttrTab
->pFontHeight
;
698 case RES_CHRATR_CJK_FONTSIZE
:
699 // don't set attributes with a % property
700 if( pItem
->StaticWhichCast(RES_CHRATR_CJK_FONTSIZE
).GetProp() == 100 )
701 ppAttr
= &m_xAttrTab
->pFontHeightCJK
;
703 case RES_CHRATR_CTL_FONTSIZE
:
704 // don't set attributes with a % property
705 if( pItem
->StaticWhichCast(RES_CHRATR_CTL_FONTSIZE
).GetProp() == 100 )
706 ppAttr
= &m_xAttrTab
->pFontHeightCTL
;
712 // Convert the Frame attribute to a Char attribute (if needed)
713 SvxBrushItem
aBrushItem( pItem
->StaticWhichCast(RES_BACKGROUND
) );
714 aBrushItem
.SetWhich( RES_CHRATR_BACKGROUND
);
717 NewAttr(m_xAttrTab
, &m_xAttrTab
->pCharBrush
, aBrushItem
);
719 // and save context information
720 HTMLAttrs
&rAttrs
= pContext
->GetAttrs();
721 rAttrs
.push_back( m_xAttrTab
->pCharBrush
);
723 else if( pContext
->GetToken() != HtmlTokenId::TABLEHEADER_ON
&&
724 pContext
->GetToken() != HtmlTokenId::TABLEDATA_ON
)
726 ppAttr
= &m_xAttrTab
->pBrush
;
733 SvxBoxItem
aBoxItem( pItem
->StaticWhichCast(RES_BOX
) );
734 aBoxItem
.SetWhich( RES_CHRATR_BOX
);
736 NewAttr(m_xAttrTab
, &m_xAttrTab
->pCharBox
, aBoxItem
);
738 HTMLAttrs
&rAttrs
= pContext
->GetAttrs();
739 rAttrs
.push_back( m_xAttrTab
->pCharBox
);
743 ppAttr
= &m_xAttrTab
->pBox
;
748 ppAttr
= GetAttrTabEntry( pItem
->Which() );
755 NewAttr(m_xAttrTab
, ppAttr
, *pItem
);
757 // and save context information
758 HTMLAttrs
&rAttrs
= pContext
->GetAttrs();
759 rAttrs
.push_back( *ppAttr
);
763 if( !rPropInfo
.m_aId
.isEmpty() )
764 InsertBookmark( rPropInfo
.m_aId
);
767 void SwHTMLParser::InsertAttr( HTMLAttr
**ppAttr
, const SfxPoolItem
& rItem
,
768 HTMLAttrContext
*pCntxt
)
772 ppAttr
= GetAttrTabEntry( rItem
.Which() );
778 NewAttr(m_xAttrTab
, ppAttr
, rItem
);
780 // save context information
781 HTMLAttrs
&rAttrs
= pCntxt
->GetAttrs();
782 rAttrs
.push_back( *ppAttr
);
785 void SwHTMLParser::SplitPREListingXMP( HTMLAttrContext
*pCntxt
)
787 // PRE/Listing/XMP need to be finished when finishing context
788 pCntxt
->SetFinishPREListingXMP( true );
790 // And set all now valid flags
792 pCntxt
->SetRestartPRE( true );
794 pCntxt
->SetRestartXMP( true );
795 if( IsReadListing() )
796 pCntxt
->SetRestartListing( true );
798 FinishPREListingXMP();
801 SfxItemSet
*HTMLAttrContext::GetFrameItemSet( SwDoc
*pCreateDoc
)
803 if( !m_pFrameItemSet
&& pCreateDoc
)
804 m_pFrameItemSet
= std::make_unique
<SfxItemSet
>(SfxItemSet::makeFixedSfxItemSet
<
805 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1>(pCreateDoc
->GetAttrPool()));
806 return m_pFrameItemSet
.get();
809 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */