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/.
13 #include <sectfrm.hxx>
15 #include <pagefrm.hxx>
17 #include <cellfrm.hxx>
20 #include <rootfrm.hxx>
22 #include <sortedobjs.hxx>
24 #include <txttypes.hxx>
25 #include <anchoredobject.hxx>
26 #include <libxml/xmlwriter.h>
27 #include <SwPortionHandler.hxx>
29 #include <flyfrms.hxx>
30 #include <svx/svdobj.hxx>
34 const char* sw::PortionTypeToString(PortionType nType
)
38 case PortionType::NONE
:
39 return "PortionType::NONE";
40 case PortionType::FlyCnt
:
41 return "PortionType::FlyCnt";
43 case PortionType::Hole
:
44 return "PortionType::Hole";
45 case PortionType::TempEnd
:
46 return "PortionType::TempEnd";
47 case PortionType::Break
:
48 return "PortionType::Break";
49 case PortionType::Kern
:
50 return "PortionType::Kern";
51 case PortionType::Arrow
:
52 return "PortionType::Arrow";
53 case PortionType::Multi
:
54 return "PortionType::Multi";
55 case PortionType::HiddenText
:
56 return "PortionType::HiddenText";
57 case PortionType::ControlChar
:
58 return "PortionType::ControlChar";
59 case PortionType::Bookmark
:
60 return "PortionType::Bookmark";
62 case PortionType::Text
:
63 return "PortionType::Text";
64 case PortionType::Lay
:
65 return "PortionType::Lay";
66 case PortionType::Para
:
67 return "PortionType::Para";
68 case PortionType::Hanging
:
69 return "PortionType::Hanging";
71 case PortionType::Drop
:
72 return "PortionType::Drop";
73 case PortionType::Tox
:
74 return "PortionType::Tox";
75 case PortionType::IsoTox
:
76 return "PortionType::IsoTox";
77 case PortionType::Ref
:
78 return "PortionType::Ref";
79 case PortionType::IsoRef
:
80 return "PortionType::IsoRef";
81 case PortionType::Meta
:
82 return "PortionType::Meta";
83 case PortionType::ContentControl
:
84 return "PortionType::ContentControl";
85 case PortionType::FieldMark
:
86 return "PortionType::FieldMark";
87 case PortionType::FieldFormCheckbox
:
88 return "PortionType::FieldFormCheckbox";
89 case PortionType::InputField
:
90 return "PortionType::InputField";
92 case PortionType::Expand
:
93 return "PortionType::Expand";
94 case PortionType::Blank
:
95 return "PortionType::Blank";
96 case PortionType::PostIts
:
97 return "PortionType::PostIts";
99 case PortionType::Hyphen
:
100 return "PortionType::Hyphen";
101 case PortionType::HyphenStr
:
102 return "PortionType::HyphenStr";
103 case PortionType::SoftHyphen
:
104 return "PortionType::SoftHyphen";
105 case PortionType::SoftHyphenStr
:
106 return "PortionType::SoftHyphenStr";
107 case PortionType::SoftHyphenComp
:
108 return "PortionType::SoftHyphenComp";
110 case PortionType::Field
:
111 return "PortionType::Field";
112 case PortionType::Hidden
:
113 return "PortionType::Hidden";
114 case PortionType::QuoVadis
:
115 return "PortionType::QuoVadis";
116 case PortionType::ErgoSum
:
117 return "PortionType::ErgoSum";
118 case PortionType::Combined
:
119 return "PortionType::Combined";
120 case PortionType::Footnote
:
121 return "PortionType::Footnote";
123 case PortionType::FootnoteNum
:
124 return "PortionType::FootnoteNum";
125 case PortionType::Number
:
126 return "PortionType::Number";
127 case PortionType::Bullet
:
128 return "PortionType::Bullet";
129 case PortionType::GrfNum
:
130 return "PortionType::GrfNum";
132 case PortionType::Glue
:
133 return "PortionType::Glue";
135 case PortionType::Margin
:
136 return "PortionType::Margin";
138 case PortionType::Fix
:
139 return "PortionType::Fix";
140 case PortionType::Fly
:
141 return "PortionType::Fly";
143 case PortionType::Tab
:
144 return "PortionType::Tab";
146 case PortionType::TabRight
:
147 return "PortionType::TabRight";
148 case PortionType::TabCenter
:
149 return "PortionType::TabCenter";
150 case PortionType::TabDecimal
:
151 return "PortionType::TabDecimal";
153 case PortionType::TabLeft
:
154 return "PortionType::TabLeft";
160 void SwFrame::dumpTopMostAsXml(xmlTextWriterPtr writer
) const
162 const SwFrame
* pFrame
= this;
163 while (pFrame
->GetUpper())
165 pFrame
= pFrame
->GetUpper();
168 pFrame
->dumpAsXml(writer
);
171 void SwFrame::dumpAsXml( xmlTextWriterPtr writer
) const
173 const char *name
= nullptr;
175 switch ( GetType( ) )
177 case SwFrameType::Txt
:
180 case SwFrameType::NoTxt
:
186 if ( name
!= nullptr )
188 (void)xmlTextWriterStartElement( writer
, reinterpret_cast<const xmlChar
*>(name
) );
190 dumpAsXmlAttributes( writer
);
194 const SwTextFrame
*pTextFrame
= static_cast<const SwTextFrame
*>(this);
195 sw::MergedPara
const*const pMerged(pTextFrame
->GetMergedPara());
198 (void)xmlTextWriterStartElement( writer
, BAD_CAST( "merged" ) );
199 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "paraPropsNodeIndex" ), "%" SAL_PRIdINT32
, sal_Int32(pMerged
->pParaPropsNode
->GetIndex()) );
200 for (auto const& e
: pMerged
->extents
)
202 (void)xmlTextWriterStartElement( writer
, BAD_CAST( "extent" ) );
203 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "txtNodeIndex" ), "%" SAL_PRIdINT32
, sal_Int32(e
.pNode
->GetIndex()) );
204 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "start" ), "%" SAL_PRIdINT32
, e
.nStart
);
205 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "end" ), "%" SAL_PRIdINT32
, e
.nEnd
);
206 (void)xmlTextWriterEndElement( writer
);
208 (void)xmlTextWriterEndElement( writer
);
212 (void)xmlTextWriterStartElement( writer
, BAD_CAST( "infos" ) );
213 dumpInfosAsXml( writer
);
214 (void)xmlTextWriterEndElement( writer
);
216 // Dump Anchored objects if any
217 const SwSortedObjs
* pAnchored
= GetDrawObjs();
218 if ( pAnchored
&& pAnchored
->size() > 0 )
220 (void)xmlTextWriterStartElement( writer
, BAD_CAST( "anchored" ) );
222 for (SwAnchoredObject
* pObject
: *pAnchored
)
224 pObject
->dumpAsXml( writer
);
227 (void)xmlTextWriterEndElement( writer
);
231 if ( IsTextFrame( ) )
233 const SwTextFrame
*pTextFrame
= static_cast<const SwTextFrame
*>(this);
234 OUString aText
= pTextFrame
->GetText( );
235 for ( int i
= 0; i
< 32; i
++ )
237 aText
= aText
.replace( i
, '*' );
239 auto nTextOffset
= static_cast<sal_Int32
>(pTextFrame
->GetOffset());
240 sal_Int32 nTextLength
= aText
.getLength() - nTextOffset
;
241 if (const SwTextFrame
* pTextFrameFollow
= pTextFrame
->GetFollow())
243 nTextLength
= static_cast<sal_Int32
>(pTextFrameFollow
->GetOffset() - pTextFrame
->GetOffset());
246 = OUStringToOString(aText
.subView(nTextOffset
, nTextLength
), RTL_TEXTENCODING_UTF8
);
247 (void)xmlTextWriterWriteString( writer
,
248 reinterpret_cast<const xmlChar
*>(aText8
.getStr( )) );
249 if (const SwParaPortion
* pPara
= pTextFrame
->GetPara())
251 (void)xmlTextWriterStartElement(writer
, BAD_CAST("SwParaPortion"));
252 TextFrameIndex
nOffset(0);
253 const OUString
& rText
= pTextFrame
->GetText();
254 (void)xmlTextWriterWriteFormatAttribute(writer
, BAD_CAST("ptr"), "%p", pPara
);
255 const SwLineLayout
* pLine
= pPara
;
256 if (pTextFrame
->IsFollow())
258 nOffset
+= pTextFrame
->GetOffset();
262 (void)xmlTextWriterStartElement(writer
, BAD_CAST("SwLineLayout"));
263 pLine
->dumpAsXmlAttributes(writer
, rText
, nOffset
);
264 const SwLinePortion
* pPor
= pLine
->GetFirstPortion();
267 pPor
->dumpAsXml(writer
, rText
, nOffset
);
268 pPor
= pPor
->GetNextPortion();
270 (void)xmlTextWriterEndElement(writer
);
271 pLine
= pLine
->GetNext();
273 (void)xmlTextWriterEndElement(writer
);
279 dumpChildrenAsXml( writer
);
281 (void)xmlTextWriterEndElement( writer
);
285 void SwFrame::dumpInfosAsXml( xmlTextWriterPtr writer
) const
288 (void)xmlTextWriterStartElement( writer
, BAD_CAST( "bounds" ) );
289 getFrameArea().dumpAsXmlAttributes(writer
);
290 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("mbFixSize"), BAD_CAST(OString::boolean(HasFixSize()).getStr()));
291 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("mbFrameAreaPositionValid"), BAD_CAST(OString::boolean(isFrameAreaPositionValid()).getStr()));
292 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("mbFrameAreaSizeValid"), BAD_CAST(OString::boolean(isFrameAreaSizeValid()).getStr()));
293 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("mbFramePrintAreaValid"), BAD_CAST(OString::boolean(isFramePrintAreaValid()).getStr()));
294 (void)xmlTextWriterEndElement( writer
);
296 // output the print area
297 (void)xmlTextWriterStartElement( writer
, BAD_CAST( "prtBounds" ) );
298 getFramePrintArea().dumpAsXmlAttributes(writer
);
299 (void)xmlTextWriterEndElement( writer
);
302 void SwFrame::dumpAsXmlAttributes( xmlTextWriterPtr writer
) const
304 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "ptr" ), "%p", this );
305 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "id" ), "%" SAL_PRIuUINT32
, GetFrameId() );
306 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "symbol" ), "%s", BAD_CAST( typeid( *this ).name( ) ) );
308 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "next" ), "%" SAL_PRIuUINT32
, GetNext()->GetFrameId() );
310 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "prev" ), "%" SAL_PRIuUINT32
, GetPrev()->GetFrameId() );
312 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "upper" ), "%" SAL_PRIuUINT32
, GetUpper()->GetFrameId() );
314 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "lower" ), "%" SAL_PRIuUINT32
, GetLower()->GetFrameId() );
315 if (IsFootnoteFrame())
317 SwFootnoteFrame
const*const pFF(static_cast<SwFootnoteFrame
const*>(this));
318 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST("ref"), "%" SAL_PRIuUINT32
, pFF
->GetRef()->GetFrameId() );
319 if (pFF
->GetMaster())
320 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST("master"), "%" SAL_PRIuUINT32
, pFF
->GetMaster()->GetFrameId() );
321 if (pFF
->GetFollow())
322 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST("follow"), "%" SAL_PRIuUINT32
, pFF
->GetFollow()->GetFrameId() );
326 SwSectionFrame
const*const pFrame(static_cast<SwSectionFrame
const*>(this));
327 SwSectionNode
const*const pNode(pFrame
->GetSection() ? pFrame
->GetSection()->GetFormat()->GetSectionNode() : nullptr);
328 (void)xmlTextWriterWriteFormatAttribute(writer
, BAD_CAST("sectionNodeIndex"), "%" SAL_PRIdINT32
, pNode
? sal_Int32(pNode
->GetIndex()) : -1);
330 if ( IsTextFrame( ) )
332 const SwTextFrame
*pTextFrame
= static_cast<const SwTextFrame
*>(this);
333 const SwTextNode
*pTextNode
= pTextFrame
->GetTextNodeFirst();
334 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "txtNodeIndex" ), "%" SAL_PRIdINT32
, sal_Int32(pTextNode
->GetIndex()) );
336 OString aMode
= "Horizontal";
345 else if (IsVertical())
349 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("WritingMode"), BAD_CAST(aMode
.getStr()));
351 if (IsHeaderFrame() || IsFooterFrame())
353 const SwHeadFootFrame
*pHeadFootFrame
= static_cast<const SwHeadFootFrame
*>(this);
354 OUString aFormatName
= pHeadFootFrame
->GetFormat()->GetName();
355 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "fmtName" ), "%s", BAD_CAST(OUStringToOString(aFormatName
, RTL_TEXTENCODING_UTF8
).getStr()));
356 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "fmtPtr" ), "%p", pHeadFootFrame
->GetFormat());
360 void SwFrame::dumpChildrenAsXml( xmlTextWriterPtr writer
) const
362 const SwFrame
*pFrame
= GetLower( );
363 for ( ; pFrame
!= nullptr; pFrame
= pFrame
->GetNext( ) )
365 pFrame
->dumpAsXml( writer
);
369 void SwAnchoredObject::dumpAsXml( xmlTextWriterPtr writer
) const
371 (void)xmlTextWriterStartElement( writer
, BAD_CAST( getElementName() ) );
372 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "ptr" ), "%p", this );
373 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("anchor-frame"), BAD_CAST(OString::number(mpAnchorFrame
->GetFrameId()).getStr()));
374 SwTextFrame
* pAnchorCharFrame
= const_cast<SwAnchoredObject
*>(this)->FindAnchorCharFrame();
375 if (pAnchorCharFrame
)
377 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("anchor-char-frame"), BAD_CAST(OString::number(pAnchorCharFrame
->GetFrameId()).getStr()));
380 (void)xmlTextWriterStartElement( writer
, BAD_CAST( "bounds" ) );
381 // don't call GetObjBoundRect(), it modifies the layout
382 SwRect(GetDrawObj()->GetLastBoundRect()).dumpAsXmlAttributes(writer
);
383 (void)xmlTextWriterEndElement( writer
);
385 if (const SdrObject
* pObject
= GetDrawObj())
386 pObject
->dumpAsXml(writer
);
388 (void)xmlTextWriterEndElement( writer
);
391 void SwFont::dumpAsXml(xmlTextWriterPtr writer
) const
393 (void)xmlTextWriterStartElement(writer
, BAD_CAST("SwFont"));
394 (void)xmlTextWriterWriteFormatAttribute(writer
, BAD_CAST("ptr"), "%p", this);
395 // do not use Color::AsRGBHexString() as that omits the transparency
396 (void)xmlTextWriterWriteFormatAttribute(writer
, BAD_CAST("color"), "%08" SAL_PRIxUINT32
, sal_uInt32(GetColor()));
397 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("height"), BAD_CAST(OString::number(GetSize(GetActual()).Height()).getStr()));
398 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("width"), BAD_CAST(OString::number(GetSize(GetActual()).Width()).getStr()));
400 std::stringstream ss
;
402 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("weight"), BAD_CAST(ss
.str().c_str()));
404 (void)xmlTextWriterEndElement(writer
);
407 void SwTextFrame::dumpAsXmlAttributes( xmlTextWriterPtr writer
) const
409 SwFrame::dumpAsXmlAttributes( writer
);
411 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32
, GetFollow()->GetFrameId() );
413 if (m_pPrecede
!= nullptr)
414 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32
, static_cast<SwTextFrame
*>(m_pPrecede
)->GetFrameId() );
416 (void)xmlTextWriterWriteAttribute(writer
, BAD_CAST("offset"), BAD_CAST(OString::number(static_cast<sal_Int32
>(mnOffset
)).getStr()));
419 void SwFlyAtContentFrame::dumpAsXmlAttributes(xmlTextWriterPtr pWriter
) const
421 SwFlyFreeFrame::dumpAsXmlAttributes(pWriter
);
423 if (m_pFollow
!= nullptr)
425 (void)xmlTextWriterWriteAttribute(
426 pWriter
, BAD_CAST("follow"),
427 BAD_CAST(OString::number(m_pFollow
->GetFrame().GetFrameId()).getStr()));
429 if (m_pPrecede
!= nullptr)
431 (void)xmlTextWriterWriteAttribute(
432 pWriter
, BAD_CAST("precede"),
433 BAD_CAST(OString::number(m_pPrecede
->GetFrame().GetFrameId()).getStr()));
437 void SwSectionFrame::dumpAsXmlAttributes( xmlTextWriterPtr writer
) const
439 SwFrame::dumpAsXmlAttributes( writer
);
441 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32
, GetFollow()->GetFrameId() );
443 if (m_pPrecede
!= nullptr)
444 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32
, static_cast<SwSectionFrame
*>( m_pPrecede
)->GetFrameId() );
447 void SwTabFrame::dumpAsXmlAttributes( xmlTextWriterPtr writer
) const
449 SwFrame::dumpAsXmlAttributes( writer
);
451 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32
, GetFollow()->GetFrameId() );
453 if (m_pPrecede
!= nullptr)
454 (void)xmlTextWriterWriteFormatAttribute( writer
, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32
, static_cast<SwTabFrame
*>( m_pPrecede
)->GetFrameId() );
457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */