summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-05-09 09:13:25 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-05-09 15:29:09 +0000
commita3615d5517ee84ddf9a9b2c28ff6a3a37fcb70db (patch)
tree6f3db784e5696a2ca8b4896512059c1d5a5cec94 /writerfilter
parenta75aa73b2bf793faac1adb3b5f67e09d252d5fe9 (diff)
writerfilter: extract dispatch{destination,flag,symbol,value} from rtfdocimpl
These were half of the lines of rtfdocumentimpl. Change-Id: I3f24cd5d23c91bf0d53b898266c187699ae6ee56 Reviewed-on: https://gerrit.libreoffice.org/24790 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/Library_writerfilter.mk4
-rw-r--r--writerfilter/source/rtftok/rtfcontrolwords.hxx1
-rw-r--r--writerfilter/source/rtftok/rtfdispatchdestination.cxx623
-rw-r--r--writerfilter/source/rtftok/rtfdispatchflag.cxx1083
-rw-r--r--writerfilter/source/rtftok/rtfdispatchsymbol.cxx409
-rw-r--r--writerfilter/source/rtftok/rtfdispatchvalue.cxx1347
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx3391
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx12
-rw-r--r--writerfilter/source/rtftok/rtffly.hxx4
9 files changed, 3512 insertions, 3362 deletions
diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk
index 27eb752b02c3..b23256efff74 100644
--- a/writerfilter/Library_writerfilter.mk
+++ b/writerfilter/Library_writerfilter.mk
@@ -64,6 +64,10 @@ $(eval $(call gb_Library_use_externals,writerfilter,\
$(eval $(call gb_Library_add_exception_objects,writerfilter,\
writerfilter/source/rtftok/rtfcharsets \
writerfilter/source/rtftok/rtfcontrolwords \
+ writerfilter/source/rtftok/rtfdispatchdestination \
+ writerfilter/source/rtftok/rtfdispatchflag \
+ writerfilter/source/rtftok/rtfdispatchsymbol \
+ writerfilter/source/rtftok/rtfdispatchvalue \
writerfilter/source/rtftok/rtfdocumentfactory \
writerfilter/source/rtftok/rtfdocumentimpl \
writerfilter/source/rtftok/rtflookahead \
diff --git a/writerfilter/source/rtftok/rtfcontrolwords.hxx b/writerfilter/source/rtftok/rtfcontrolwords.hxx
index 80a2d1e465ed..2a7d5967148e 100644
--- a/writerfilter/source/rtftok/rtfcontrolwords.hxx
+++ b/writerfilter/source/rtftok/rtfcontrolwords.hxx
@@ -1980,6 +1980,7 @@ enum RTFKeyword
RTF_FLYHORZ,
RTF_FLYANCHOR
};
+const char* keywordToString(RTFKeyword nKeyword);
/// Types of an RTF Control Word
enum RTFControlTypes
diff --git a/writerfilter/source/rtftok/rtfdispatchdestination.cxx b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
new file mode 100644
index 000000000000..af8a3f19b933
--- /dev/null
+++ b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
@@ -0,0 +1,623 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <rtfdocumentimpl.hxx>
+
+#include <com/sun/star/document/DocumentProperties.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+
+#include <filter/msfilter/escherex.hxx>
+#include <tools/stream.hxx>
+
+#include <dmapper/DomainMapperFactory.hxx>
+#include <ooxml/resourceids.hxx>
+
+#include <rtflookahead.hxx>
+#include <rtfreferenceproperties.hxx>
+#include <rtfsdrimport.hxx>
+#include <rtfskipdestination.hxx>
+
+using namespace com::sun::star;
+
+namespace writerfilter
+{
+namespace rtftok
+{
+
+RTFError RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
+{
+ setNeedSect(true);
+ checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
+ RTFSkipDestination aSkip(*this);
+ // special case \upr: ignore everything except nested \ud
+ if (Destination::UPR == m_aStates.top().eDestination && RTF_UD != nKeyword)
+ {
+ m_aStates.top().eDestination = Destination::SKIP;
+ aSkip.setParsed(false);
+ }
+ else
+ switch (nKeyword)
+ {
+ case RTF_RTF:
+ break;
+ case RTF_FONTTBL:
+ m_aStates.top().eDestination = Destination::FONTTABLE;
+ break;
+ case RTF_COLORTBL:
+ m_aStates.top().eDestination = Destination::COLORTABLE;
+ break;
+ case RTF_STYLESHEET:
+ m_aStates.top().eDestination = Destination::STYLESHEET;
+ break;
+ case RTF_FIELD:
+ m_aStates.top().eDestination = Destination::FIELD;
+ break;
+ case RTF_FLDINST:
+ {
+ // Look for the field type
+ sal_Size nPos = Strm().Tell();
+ OStringBuffer aBuf;
+ char ch = 0;
+ bool bFoundCode = false;
+ bool bInKeyword = false;
+ while (!bFoundCode && ch != '}')
+ {
+ Strm().ReadChar(ch);
+ if ('\\' == ch)
+ bInKeyword = true;
+ if (!bInKeyword && isalnum(ch))
+ aBuf.append(ch);
+ else if (bInKeyword && isspace(ch))
+ bInKeyword = false;
+ if (!aBuf.isEmpty() && !isalnum(ch))
+ bFoundCode = true;
+ }
+
+ if (aBuf.toString() == "INCLUDEPICTURE")
+ {
+ // Extract the field argument of INCLUDEPICTURE: we handle that
+ // at a tokenizer level, as DOCX has no such field.
+ aBuf.append(ch);
+ while (true)
+ {
+ Strm().ReadChar(ch);
+ if (ch == '}')
+ break;
+ aBuf.append(ch);
+ }
+ OUString aFieldCommand = OStringToOUString(aBuf.toString(), RTL_TEXTENCODING_UTF8);
+ std::tuple<OUString, std::vector<OUString>, std::vector<OUString> > aResult = writerfilter::dmapper::splitFieldCommand(aFieldCommand);
+ m_aPicturePath = std::get<1>(aResult).empty() ? OUString() : std::get<1>(aResult).front();
+ }
+
+ Strm().Seek(nPos);
+
+ // Form data should be handled only for form fields if any
+ if (aBuf.toString().indexOf(OString("FORM")) != -1)
+ m_bFormField = true;
+
+ singleChar(cFieldStart);
+ m_aStates.top().eDestination = Destination::FIELDINSTRUCTION;
+ }
+ break;
+ case RTF_FLDRSLT:
+ m_aStates.top().eDestination = Destination::FIELDRESULT;
+ break;
+ case RTF_LISTTABLE:
+ m_aStates.top().eDestination = Destination::LISTTABLE;
+ break;
+ case RTF_LISTPICTURE:
+ m_aStates.top().eDestination = Destination::LISTPICTURE;
+ m_aStates.top().bInListpicture = true;
+ break;
+ case RTF_LIST:
+ m_aStates.top().eDestination = Destination::LISTENTRY;
+ break;
+ case RTF_LISTNAME:
+ m_aStates.top().eDestination = Destination::LISTNAME;
+ break;
+ case RTF_LFOLEVEL:
+ m_aStates.top().eDestination = Destination::LFOLEVEL;
+ m_aStates.top().aTableSprms.clear();
+ break;
+ case RTF_LISTOVERRIDETABLE:
+ m_aStates.top().eDestination = Destination::LISTOVERRIDETABLE;
+ break;
+ case RTF_LISTOVERRIDE:
+ m_aStates.top().eDestination = Destination::LISTOVERRIDEENTRY;
+ break;
+ case RTF_LISTLEVEL:
+ m_aStates.top().eDestination = Destination::LISTLEVEL;
+ break;
+ case RTF_LEVELTEXT:
+ m_aStates.top().eDestination = Destination::LEVELTEXT;
+ break;
+ case RTF_LEVELNUMBERS:
+ m_aStates.top().eDestination = Destination::LEVELNUMBERS;
+ break;
+ case RTF_SHPPICT:
+ resetFrame();
+ m_aStates.top().eDestination = Destination::SHPPICT;
+ break;
+ case RTF_PICT:
+ if (m_aStates.top().eDestination != Destination::SHAPEPROPERTYVALUE)
+ m_aStates.top().eDestination = Destination::PICT; // as character
+ else
+ m_aStates.top().eDestination = Destination::SHAPEPROPERTYVALUEPICT; // anchored inside a shape
+ break;
+ case RTF_PICPROP:
+ m_aStates.top().eDestination = Destination::PICPROP;
+ break;
+ case RTF_SP:
+ m_aStates.top().eDestination = Destination::SHAPEPROPERTY;
+ break;
+ case RTF_SN:
+ m_aStates.top().eDestination = Destination::SHAPEPROPERTYNAME;
+ break;
+ case RTF_SV:
+ m_aStates.top().eDestination = Destination::SHAPEPROPERTYVALUE;
+ break;
+ case RTF_SHP:
+ m_bNeedCrOrig = m_bNeedCr;
+ m_aStates.top().eDestination = Destination::SHAPE;
+ m_aStates.top().bInShape = true;
+ break;
+ case RTF_SHPINST:
+ m_aStates.top().eDestination = Destination::SHAPEINSTRUCTION;
+ break;
+ case RTF_NESTTABLEPROPS:
+ // do not set any properties of outer table at nested table!
+ m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
+ m_aStates.top().aTableCellAttributes =
+ m_aDefaultState.aTableCellAttributes;
+ m_aNestedTableCellsSprms.clear();
+ m_aNestedTableCellsAttributes.clear();
+ m_nNestedCells = 0;
+ m_aStates.top().eDestination = Destination::NESTEDTABLEPROPERTIES;
+ break;
+ case RTF_HEADER:
+ case RTF_FOOTER:
+ case RTF_HEADERL:
+ case RTF_HEADERR:
+ case RTF_HEADERF:
+ case RTF_FOOTERL:
+ case RTF_FOOTERR:
+ case RTF_FOOTERF:
+ if (!m_pSuperstream)
+ {
+ Id nId = 0;
+ sal_Size nPos = m_nGroupStartPos - 1;
+ switch (nKeyword)
+ {
+ case RTF_HEADER:
+ nId = NS_ooxml::LN_headerr;
+ break;
+ case RTF_FOOTER:
+ nId = NS_ooxml::LN_footerr;
+ break;
+ case RTF_HEADERL:
+ nId = NS_ooxml::LN_headerl;
+ break;
+ case RTF_HEADERR:
+ nId = NS_ooxml::LN_headerr;
+ break;
+ case RTF_HEADERF:
+ nId = NS_ooxml::LN_headerf;
+ break;
+ case RTF_FOOTERL:
+ nId = NS_ooxml::LN_footerl;
+ break;
+ case RTF_FOOTERR:
+ nId = NS_ooxml::LN_footerr;
+ break;
+ case RTF_FOOTERF:
+ nId = NS_ooxml::LN_footerf;
+ break;
+ default:
+ break;
+ }
+ m_nHeaderFooterPositions.push(std::make_pair(nId, nPos));
+ m_aStates.top().eDestination = Destination::SKIP;
+ }
+ break;
+ case RTF_FOOTNOTE:
+ checkFirstRun();
+ if (!m_pSuperstream)
+ {
+ Id nId = NS_ooxml::LN_footnote;
+
+ // Check if this is an endnote.
+ OStringBuffer aBuf;
+ char ch;
+ sal_Size nCurrent = Strm().Tell();
+ for (int i = 0; i < 7; ++i)
+ {
+ Strm().ReadChar(ch);
+ aBuf.append(ch);
+ }
+ Strm().Seek(nCurrent);
+ OString aKeyword = aBuf.makeStringAndClear();
+ if (aKeyword.equals("\\ftnalt"))
+ nId = NS_ooxml::LN_endnote;
+
+ if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
+ m_aStates.top().pCurrentBuffer = nullptr;
+ bool bCustomMark = false;
+ OUString aCustomMark;
+ while (m_aSuperBuffer.size())
+ {
+ Buf_t aTuple = m_aSuperBuffer.front();
+ m_aSuperBuffer.pop_front();
+ if (std::get<0>(aTuple) == BUFFER_UTEXT)
+ {
+ aCustomMark = std::get<1>(aTuple)->getString();
+ bCustomMark = true;
+ }
+ }
+ m_aStates.top().eDestination = Destination::FOOTNOTE;
+ if (bCustomMark)
+ Mapper().startCharacterGroup();
+ if (!m_aStates.top().pCurrentBuffer)
+ resolveSubstream(m_nGroupStartPos - 1, nId, aCustomMark);
+ else
+ {
+ RTFSprms aAttributes;
+ aAttributes.set(Id(0), std::make_shared<RTFValue>(m_nGroupStartPos - 1));
+ aAttributes.set(Id(1), std::make_shared<RTFValue>(nId));
+ aAttributes.set(Id(2), std::make_shared<RTFValue>(aCustomMark));
+ m_aStates.top().pCurrentBuffer->push_back(Buf_t(BUFFER_RESOLVESUBSTREAM, std::make_shared<RTFValue>(aAttributes), nullptr));
+ }
+ if (bCustomMark)
+ {
+ m_aStates.top().aCharacterAttributes.clear();
+ m_aStates.top().aCharacterSprms.clear();
+ auto pValue = std::make_shared<RTFValue>(1);
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows, pValue);
+ text(aCustomMark);
+ Mapper().endCharacterGroup();
+ }
+ m_aStates.top().eDestination = Destination::SKIP;
+ }
+ break;
+ case RTF_BKMKSTART:
+ m_aStates.top().eDestination = Destination::BOOKMARKSTART;
+ break;
+ case RTF_BKMKEND:
+ m_aStates.top().eDestination = Destination::BOOKMARKEND;
+ break;
+ case RTF_XE:
+ m_aStates.top().eDestination = Destination::INDEXENTRY;
+ break;
+ case RTF_TC:
+ case RTF_TCN:
+ m_aStates.top().eDestination = Destination::TOCENTRY;
+ break;
+ case RTF_REVTBL:
+ m_aStates.top().eDestination = Destination::REVISIONTABLE;
+ break;
+ case RTF_ANNOTATION:
+ if (!m_pSuperstream)
+ {
+ resolveSubstream(m_nGroupStartPos - 1, NS_ooxml::LN_annotation);
+ m_aStates.top().eDestination = Destination::SKIP;
+ }
+ else
+ {
+ // If there is an author set, emit it now.
+ if (!m_aAuthor.isEmpty() || !m_aAuthorInitials.isEmpty())
+ {
+ RTFSprms aAttributes;
+ if (!m_aAuthor.isEmpty())
+ {
+ auto pValue = std::make_shared<RTFValue>(m_aAuthor);
+ aAttributes.set(NS_ooxml::LN_CT_TrackChange_author, pValue);
+ }
+ if (!m_aAuthorInitials.isEmpty())
+ {
+ auto pValue = std::make_shared<RTFValue>(m_aAuthorInitials);
+ aAttributes.set(NS_ooxml::LN_CT_Comment_initials, pValue);
+ }
+ writerfilter::Reference<Properties>::Pointer_t pProperties = std::make_shared<RTFReferenceProperties>(aAttributes);
+ Mapper().props(pProperties);
+ }
+ }
+ break;
+ case RTF_SHPTXT:
+ case RTF_DPTXBXTEXT:
+ {
+ bool bPictureFrame = false;
+ for (std::size_t i = 0; i < m_aStates.top().aShape.aProperties.size(); ++i)
+ {
+ std::pair<OUString, OUString>& rProperty = m_aStates.top().aShape.aProperties[i];
+ if (rProperty.first == "shapeType" && rProperty.second == OUString::number(ESCHER_ShpInst_PictureFrame))
+ {
+ bPictureFrame = true;
+ break;
+ }
+ }
+ if (bPictureFrame)
+ // Skip text on picture frames.
+ m_aStates.top().eDestination = Destination::SKIP;
+ else
+ {
+ m_aStates.top().eDestination = Destination::SHAPETEXT;
+ checkFirstRun();
+ dispatchFlag(RTF_PARD);
+ m_bNeedPap = true;
+ if (nKeyword == RTF_SHPTXT)
+ {
+ if (!m_aStates.top().pCurrentBuffer)
+ m_pSdrImport->resolve(m_aStates.top().aShape, false, RTFSdrImport::SHAPE);
+ else
+ {
+ auto pValue = std::make_shared<RTFValue>(m_aStates.top().aShape);
+ m_aStates.top().pCurrentBuffer->push_back(Buf_t(BUFFER_STARTSHAPE, pValue, nullptr));
+ }
+ }
+ }
+ }
+ break;
+ case RTF_FORMFIELD:
+ if (m_aStates.top().eDestination == Destination::FIELDINSTRUCTION)
+ m_aStates.top().eDestination = Destination::FORMFIELD;
+ break;
+ case RTF_FFNAME:
+ m_aStates.top().eDestination = Destination::FORMFIELDNAME;
+ break;
+ case RTF_FFL:
+ m_aStates.top().eDestination = Destination::FORMFIELDLIST;
+ break;
+ case RTF_DATAFIELD:
+ m_aStates.top().eDestination = Destination::DATAFIELD;
+ break;
+ case RTF_INFO:
+ m_aStates.top().eDestination = Destination::INFO;
+ break;
+ case RTF_CREATIM:
+ m_aStates.top().eDestination = Destination::CREATIONTIME;
+ break;
+ case RTF_REVTIM:
+ m_aStates.top().eDestination = Destination::REVISIONTIME;
+ break;
+ case RTF_PRINTIM:
+ m_aStates.top().eDestination = Destination::PRINTTIME;
+ break;
+ case RTF_AUTHOR:
+ m_aStates.top().eDestination = Destination::AUTHOR;
+ break;
+ case RTF_KEYWORDS:
+ m_aStates.top().eDestination = Destination::KEYWORDS;
+ break;
+ case RTF_OPERATOR:
+ m_aStates.top().eDestination = Destination::OPERATOR;
+ break;
+ case RTF_COMPANY:
+ m_aStates.top().eDestination = Destination::COMPANY;
+ break;
+ case RTF_COMMENT:
+ m_aStates.top().eDestination = Destination::COMMENT;
+ break;
+ case RTF_OBJECT:
+ {
+ // beginning of an OLE Object
+ m_aStates.top().eDestination = Destination::OBJECT;
+
+ // check if the object is in a special container (e.g. a table)
+ if (!m_aStates.top().pCurrentBuffer)
+ {
+ // the object is in a table or another container.
+ // Don't try to treat it as an OLE object (fdo#53594).
+ // Use the \result (RTF_RESULT) element of the object instead,
+ // the result element contain picture representing the OLE Object.
+ m_bObject = true;
+ }
+ }
+ break;
+ case RTF_OBJDATA:
+ // check if the object is in a special container (e.g. a table)
+ if (m_aStates.top().pCurrentBuffer)
+ {
+ // the object is in a table or another container.
+ // Use the \result (RTF_RESULT) element of the object instead,
+ // of the \objdata.
+ m_aStates.top().eDestination = Destination::SKIP;
+ }
+ else
+ {
+ m_aStates.top().eDestination = Destination::OBJDATA;
+ }
+ break;
+ case RTF_OBJCLASS:
+ m_aStates.top().eDestination = Destination::OBJCLASS;
+ break;
+ case RTF_RESULT:
+ m_aStates.top().eDestination = Destination::RESULT;
+ break;
+ case RTF_ATNDATE:
+ m_aStates.top().eDestination = Destination::ANNOTATIONDATE;
+ break;
+ case RTF_ATNAUTHOR:
+ m_aStates.top().eDestination = Destination::ANNOTATIONAUTHOR;
+ break;
+ case RTF_ATNREF:
+ m_aStates.top().eDestination = Destination::ANNOTATIONREFERENCE;
+ break;
+ case RTF_FALT:
+ m_aStates.top().eDestination = Destination::FALT;
+ break;
+ case RTF_FLYMAINCNT:
+ m_aStates.top().eDestination = Destination::FLYMAINCONTENT;
+ break;
+ case RTF_LISTTEXT:
+ // Should be ignored by any reader that understands Word 97 through Word 2007 numbering.
+ case RTF_NONESTTABLES:
+ // This destination should be ignored by readers that support nested tables.
+ m_aStates.top().eDestination = Destination::SKIP;
+ break;
+ case RTF_DO:
+ m_aStates.top().eDestination = Destination::DRAWINGOBJECT;
+ break;
+ case RTF_PN:
+ m_aStates.top().eDestination = Destination::PARAGRAPHNUMBERING;
+ break;
+ case RTF_PNTEXT:
+ // This destination should be ignored by readers that support paragraph numbering.
+ m_aStates.top().eDestination = Destination::SKIP;
+ break;
+ case RTF_PNTXTA:
+ m_aStates.top().eDestination = Destination::PARAGRAPHNUMBERING_TEXTAFTER;
+ break;
+ case RTF_PNTXTB:
+ m_aStates.top().eDestination = Destination::PARAGRAPHNUMBERING_TEXTBEFORE;
+ break;
+ case RTF_TITLE:
+ m_aStates.top().eDestination = Destination::TITLE;
+ break;
+ case RTF_SUBJECT:
+ m_aStates.top().eDestination = Destination::SUBJECT;
+ break;
+ case RTF_DOCCOMM:
+ m_aStates.top().eDestination = Destination::DOCCOMM;
+ break;
+ case RTF_ATRFSTART:
+ m_aStates.top().eDestination = Destination::ANNOTATIONREFERENCESTART;
+ break;
+ case RTF_ATRFEND:
+ m_aStates.top().eDestination = Destination::ANNOTATIONREFERENCEEND;
+ break;
+ case RTF_ATNID:
+ m_aStates.top().eDestination = Destination::ATNID;
+ break;
+ case RTF_MMATH:
+ case RTF_MOMATHPARA:
+ // Nothing to do here (just enter the destination) till RTF_MMATHPR is implemented.
+ break;
+ case RTF_MR:
+ m_aStates.top().eDestination = Destination::MR;
+ break;
+ case RTF_MCHR:
+ m_aStates.top().eDestination = Destination::MCHR;
+ break;
+ case RTF_MPOS:
+ m_aStates.top().eDestination = Destination::MPOS;
+ break;
+ case RTF_MVERTJC:
+ m_aStates.top().eDestination = Destination::MVERTJC;
+ break;
+ case RTF_MSTRIKEH:
+ m_aStates.top().eDestination = Destination::MSTRIKEH;
+ break;
+ case RTF_MDEGHIDE:
+ m_aStates.top().eDestination = Destination::MDEGHIDE;
+ break;
+ case RTF_MTYPE:
+ m_aStates.top().eDestination = Destination::MTYPE;
+ break;
+ case RTF_MGROW:
+ m_aStates.top().eDestination = Destination::MGROW;
+ break;
+ case RTF_MHIDETOP:
+ case RTF_MHIDEBOT:
+ case RTF_MHIDELEFT:
+ case RTF_MHIDERIGHT:
+ // SmOoxmlImport::handleBorderBox will ignore these anyway, so silently ignore for now.
+ m_aStates.top().eDestination = Destination::SKIP;
+ break;
+ case RTF_MSUBHIDE:
+ m_aStates.top().eDestination = Destination::MSUBHIDE;
+ break;
+ case RTF_MSUPHIDE:
+ m_aStates.top().eDestination = Destination::MSUPHIDE;
+ break;
+ case RTF_MBEGCHR:
+ m_aStates.top().eDestination = Destination::MBEGCHR;
+ break;
+ case RTF_MSEPCHR:
+ m_aStates.top().eDestination = Destination::MSEPCHR;
+ break;
+ case RTF_MENDCHR:
+ m_aStates.top().eDestination = Destination::MENDCHR;
+ break;
+ case RTF_UPR:
+ m_aStates.top().eDestination = Destination::UPR;
+ break;
+ case RTF_UD:
+ // Anything inside \ud is just normal Unicode content.
+ m_aStates.top().eDestination = Destination::NORMAL;
+ break;
+ case RTF_BACKGROUND:
+ m_aStates.top().eDestination = Destination::BACKGROUND;
+ m_aStates.top().bInBackground = true;
+ break;
+ case RTF_SHPGRP:
+ {
+ RTFLookahead aLookahead(Strm(), m_pTokenizer->getGroupStart());
+ if (!aLookahead.hasTable())
+ {
+ uno::Reference<drawing::XShapes> xGroupShape(m_xModelFactory->createInstance("com.sun.star.drawing.GroupShape"), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier(m_xDstDoc, uno::UNO_QUERY);
+ if (xDrawSupplier.is())
+ {
+ uno::Reference<drawing::XShape> xShape(xGroupShape, uno::UNO_QUERY);
+ xDrawSupplier->getDrawPage()->add(xShape);
+ }
+ m_pSdrImport->pushParent(xGroupShape);
+ m_aStates.top().bCreatedShapeGroup = true;
+ }
+ m_aStates.top().eDestination = Destination::SHAPEGROUP;
+ m_aStates.top().bInShapeGroup = true;
+ }
+ break;
+ case RTF_FTNSEP:
+ m_aStates.top().eDestination = Destination::FOOTNOTESEPARATOR;
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_FtnEdn_type, std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_FtnEdn_separator));
+ break;
+ case RTF_USERPROPS:
+ // Container of all user-defined properties.
+ m_aStates.top().eDestination = Destination::USERPROPS;
+ if (m_xDocumentProperties.is())
+ // Create a custom document properties to be able to process them later all at once.
+ m_xDocumentProperties = document::DocumentProperties::create(m_xContext);
+ break;
+ case RTF_PROPNAME:
+ m_aStates.top().eDestination = Destination::PROPNAME;
+ break;
+ case RTF_STATICVAL:
+ m_aStates.top().eDestination = Destination::STATICVAL;
+ break;
+ default:
+ {
+ // Check if it's a math token.
+ RTFMathSymbol aSymbol;
+ aSymbol.eKeyword = nKeyword;
+ if (RTFTokenizer::lookupMathKeyword(aSymbol))
+ {
+ m_aMathBuffer.appendOpeningTag(aSymbol.nToken);
+ m_aStates.top().eDestination = aSymbol.eDestination;
+ return RTFError::OK;
+ }
+
+ SAL_INFO("writerfilter", "TODO handle destination '" << keywordToString(nKeyword) << "'");
+ // Make sure we skip destinations (even without \*) till we don't handle them
+ m_aStates.top().eDestination = Destination::SKIP;
+ aSkip.setParsed(false);
+ }
+ break;
+ }
+
+ // new destination => use new destination text
+ m_aStates.top().pDestinationText = &m_aStates.top().aDestinationText;
+
+ return RTFError::OK;
+}
+
+} // namespace rtftok
+} // namespace writerfilter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdispatchflag.cxx b/writerfilter/source/rtftok/rtfdispatchflag.cxx
new file mode 100644
index 000000000000..d3bc5175b282
--- /dev/null
+++ b/writerfilter/source/rtftok/rtfdispatchflag.cxx
@@ -0,0 +1,1083 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <rtfdocumentimpl.hxx>
+
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+
+#include <filter/msfilter/escherex.hxx>
+
+#include <ooxml/resourceids.hxx>
+
+#include <rtfsdrimport.hxx>
+#include <rtfskipdestination.hxx>
+
+using namespace com::sun::star;
+
+namespace writerfilter
+{
+namespace rtftok
+{
+
+RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
+{
+ setNeedSect(true);
+ checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
+ RTFSkipDestination aSkip(*this);
+ int nParam = -1;
+ int nSprm = -1;
+
+ // Underline flags.
+ switch (nKeyword)
+ {
+ case RTF_ULD:
+ nSprm = NS_ooxml::LN_Value_ST_Underline_dotted;
+ break;
+ case RTF_ULW:
+ nSprm = NS_ooxml::LN_Value_ST_Underline_words;
+ break;
+ default:
+ break;
+ }
+ if (nSprm >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nSprm);
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_Underline_val, pValue);
+ return RTFError::OK;
+ }
+
+ // Indentation
+ switch (nKeyword)
+ {
+ case RTF_QC:
+ nParam = NS_ooxml::LN_Value_ST_Jc_center;
+ break;
+ case RTF_QJ:
+ nParam = NS_ooxml::LN_Value_ST_Jc_both;
+ break;
+ case RTF_QL:
+ nParam = NS_ooxml::LN_Value_ST_Jc_left;
+ break;
+ case RTF_QR:
+ nParam = NS_ooxml::LN_Value_ST_Jc_right;
+ break;
+ case RTF_QD:
+ nParam = NS_ooxml::LN_Value_ST_Jc_both;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_jc, pValue);
+ m_bNeedPap = true;
+ return RTFError::OK;
+ }
+
+ // Font Alignment
+ switch (nKeyword)
+ {
+ case RTF_FAFIXED:
+ case RTF_FAAUTO:
+ nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_auto;
+ break;
+ case RTF_FAHANG:
+ nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_top;
+ break;
+ case RTF_FACENTER:
+ nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_center;
+ break;
+ case RTF_FAROMAN:
+ nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline;
+ break;
+ case RTF_FAVAR:
+ nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_textAlignment, pValue);
+ return RTFError::OK;
+ }
+
+ // Tab kind.
+ switch (nKeyword)
+ {
+ case RTF_TQR:
+ nParam = NS_ooxml::LN_Value_ST_TabJc_right;
+ break;
+ case RTF_TQC:
+ nParam = NS_ooxml::LN_Value_ST_TabJc_center;
+ break;
+ case RTF_TQDEC:
+ nParam = NS_ooxml::LN_Value_ST_TabJc_decimal;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_val, pValue);
+ return RTFError::OK;
+ }
+
+ // Tab lead.
+ switch (nKeyword)
+ {
+ case RTF_TLDOT:
+ nParam = NS_ooxml::LN_Value_ST_TabTlc_dot;
+ break;
+ case RTF_TLMDOT:
+ nParam = NS_ooxml::LN_Value_ST_TabTlc_middleDot;
+ break;
+ case RTF_TLHYPH:
+ nParam = NS_ooxml::LN_Value_ST_TabTlc_hyphen;
+ break;
+ case RTF_TLUL:
+ nParam = NS_ooxml::LN_Value_ST_TabTlc_underscore;
+ break;
+ case RTF_TLTH:
+ nParam = NS_ooxml::LN_Value_ST_TabTlc_hyphen;
+ break; // thick line is not supported by dmapper, this is just a hack
+ case RTF_TLEQ:
+ nParam = NS_ooxml::LN_Value_ST_TabTlc_none;
+ break; // equal sign isn't, either
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_leader, pValue);
+ return RTFError::OK;
+ }
+
+ // Border types
+ {
+ switch (nKeyword)
+ {
+ // brdrhair and brdrs are the same, brdrw will make a difference
+ // map to values in ooxml/model.xml resource ST_Border
+ case RTF_BRDRHAIR:
+ case RTF_BRDRS:
+ nParam = NS_ooxml::LN_Value_ST_Border_single;
+ break;
+ case RTF_BRDRDOT:
+ nParam = NS_ooxml::LN_Value_ST_Border_dotted;
+ break;
+ case RTF_BRDRDASH:
+ nParam = NS_ooxml::LN_Value_ST_Border_dashed;
+ break;
+ case RTF_BRDRDB:
+ nParam = NS_ooxml::LN_Value_ST_Border_double;
+ break;
+ case RTF_BRDRTNTHSG:
+ nParam = NS_ooxml::LN_Value_ST_Border_thinThickSmallGap;
+ break;
+ case RTF_BRDRTNTHMG:
+ nParam = NS_ooxml::LN_Value_ST_Border_thinThickMediumGap;
+ break;
+ case RTF_BRDRTNTHLG:
+ nParam = NS_ooxml::LN_Value_ST_Border_thinThickLargeGap;
+ break;
+ case RTF_BRDRTHTNSG:
+ nParam = NS_ooxml::LN_Value_ST_Border_thickThinSmallGap;
+ break;
+ case RTF_BRDRTHTNMG:
+ nParam = NS_ooxml::LN_Value_ST_Border_thickThinMediumGap;
+ break;
+ case RTF_BRDRTHTNLG:
+ nParam = NS_ooxml::LN_Value_ST_Border_thickThinLargeGap;
+ break;
+ case RTF_BRDREMBOSS:
+ nParam = NS_ooxml::LN_Value_ST_Border_threeDEmboss;
+ break;
+ case RTF_BRDRENGRAVE:
+ nParam = NS_ooxml::LN_Value_ST_Border_threeDEngrave;
+ break;
+ case RTF_BRDROUTSET:
+ nParam = NS_ooxml::LN_Value_ST_Border_outset;
+ break;
+ case RTF_BRDRINSET:
+ nParam = NS_ooxml::LN_Value_ST_Border_inset;
+ break;
+ case RTF_BRDRNONE:
+ nParam = NS_ooxml::LN_Value_ST_Border_none;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_val, pValue);
+ return RTFError::OK;
+ }
+ }
+
+ // Section breaks
+ switch (nKeyword)
+ {
+ case RTF_SBKNONE:
+ nParam = NS_ooxml::LN_Value_ST_SectionMark_continuous;
+ break;
+ case RTF_SBKCOL:
+ nParam = NS_ooxml::LN_Value_ST_SectionMark_nextColumn;
+ break;
+ case RTF_SBKPAGE:
+ nParam = NS_ooxml::LN_Value_ST_SectionMark_nextPage;
+ break;
+ case RTF_SBKEVEN:
+ nParam = NS_ooxml::LN_Value_ST_SectionMark_evenPage;
+ break;
+ case RTF_SBKODD:
+ nParam = NS_ooxml::LN_Value_ST_SectionMark_oddPage;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ if (m_nResetBreakOnSectBreak != RTF_invalid)
+ {
+ m_nResetBreakOnSectBreak = nKeyword;
+ }
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_type, pValue);
+ return RTFError::OK;
+ }
+
+ // Footnote numbering
+ switch (nKeyword)
+ {
+ case RTF_FTNNAR:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal;
+ break;
+ case RTF_FTNNALC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter;
+ break;
+ case RTF_FTNNAUC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter;
+ break;
+ case RTF_FTNNRLC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman;
+ break;
+ case RTF_FTNNRUC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman;
+ break;
+ case RTF_FTNNCHI:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt, pValue);
+ return RTFError::OK;
+ }
+
+ // Footnote restart type
+ switch (nKeyword)
+ {
+ case RTF_FTNRSTPG:
+ nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage;
+ break;
+ case RTF_FTNRESTART:
+ nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect;
+ break;
+ case RTF_FTNRSTCONT:
+ nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
+ return RTFError::OK;
+ }
+
+ // Endnote numbering
+ switch (nKeyword)
+ {
+ case RTF_AFTNNAR:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal;
+ break;
+ case RTF_AFTNNALC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter;
+ break;
+ case RTF_AFTNNAUC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter;
+ break;
+ case RTF_AFTNNRLC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman;
+ break;
+ case RTF_AFTNNRUC:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman;
+ break;
+ case RTF_AFTNNCHI:
+ nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_CT_EdnProps_numFmt, pValue);
+ return RTFError::OK;
+ }
+
+ switch (nKeyword)
+ {
+ case RTF_TRQL:
+ nParam = NS_ooxml::LN_Value_ST_Jc_left;
+ break;
+ case RTF_TRQC:
+ nParam = NS_ooxml::LN_Value_ST_Jc_center;
+ break;
+ case RTF_TRQR:
+ nParam = NS_ooxml::LN_Value_ST_Jc_right;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TrPrBase_jc, pValue);
+ return RTFError::OK;
+ }
+
+ // Cell Text Flow
+ switch (nKeyword)
+ {
+ case RTF_CLTXLRTB:
+ nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTb;
+ break;
+ case RTF_CLTXTBRL:
+ nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRl;
+ break;
+ case RTF_CLTXBTLR:
+ nParam = NS_ooxml::LN_Value_ST_TextDirection_btLr;
+ break;
+ case RTF_CLTXLRTBV:
+ nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTbV;
+ break;
+ case RTF_CLTXTBRLV:
+ nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRlV;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_textDirection, pValue);
+ }
+
+ // Trivial paragraph flags
+ switch (nKeyword)
+ {
+ case RTF_KEEP:
+ if (m_aStates.top().pCurrentBuffer != &m_aTableBufferStack.back())
+ nParam = NS_ooxml::LN_CT_PPrBase_keepLines;
+ break;
+ case RTF_KEEPN:
+ if (m_aStates.top().pCurrentBuffer != &m_aTableBufferStack.back())
+ nParam = NS_ooxml::LN_CT_PPrBase_keepNext;
+ break;
+ case RTF_INTBL:
+ {
+ m_aStates.top().pCurrentBuffer = &m_aTableBufferStack.back();
+ nParam = NS_ooxml::LN_inTbl;
+ }
+ break;
+ case RTF_PAGEBB:
+ nParam = NS_ooxml::LN_CT_PPrBase_pageBreakBefore;
+ break;
+ default:
+ break;
+ }
+ if (nParam >= 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(1);
+ m_aStates.top().aParagraphSprms.erase(NS_ooxml::LN_inTbl);
+ m_aStates.top().aParagraphSprms.set(nParam, pValue);
+ return RTFError::OK;
+ }
+
+ switch (nKeyword)
+ {
+ case RTF_FNIL:
+ case RTF_FROMAN:
+ case RTF_FSWISS:
+ case RTF_FMODERN:
+ case RTF_FSCRIPT:
+ case RTF_FDECOR:
+ case RTF_FTECH:
+ case RTF_FBIDI:
+ // TODO ooxml:CT_Font_family seems to be ignored by the domain mapper
+ break;
+ case RTF_ANSI:
+ m_aStates.top().nCurrentEncoding = RTL_TEXTENCODING_MS_1252;
+ break;
+ case RTF_MAC:
+ m_aDefaultState.nCurrentEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
+ m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
+ break;
+ case RTF_PC:
+ m_aDefaultState.nCurrentEncoding = RTL_TEXTENCODING_IBM_437;
+ m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
+ break;
+ case RTF_PCA:
+ m_aDefaultState.nCurrentEncoding = RTL_TEXTENCODING_IBM_850;
+ m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
+ break;
+ case RTF_PLAIN:
+ {
+ m_aStates.top().aCharacterSprms = getDefaultState().aCharacterSprms;
+ m_aStates.top().nCurrentEncoding = getEncoding(getFontIndex(m_nDefaultFontIndex));
+ m_aStates.top().aCharacterAttributes = getDefaultState().aCharacterAttributes;
+ m_aStates.top().nCurrentCharacterStyleIndex = -1;
+ m_aStates.top().isRightToLeft = false;
+ m_aStates.top().eRunType = RTFParserState::LOCH;
+ }
+ break;
+ case RTF_PARD:
+ if (m_bHadPicture)
+ dispatchSymbol(RTF_PAR);
+ // \pard is allowed between \cell and \row, but in that case it should not reset the fact that we're inside a table.
+ m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms;
+ m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes;
+
+ if (m_nTopLevelCells == 0 && m_nNestedCells == 0)
+ {
+ // Reset that we're in a table.
+ m_aStates.top().pCurrentBuffer = nullptr;
+ }
+ else
+ {
+ // We are still in a table.
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_inTbl, std::make_shared<RTFValue>(1));
+ // Ideally getDefaultSPRM() would take care of this, but it would not when we're buffering.
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_tabs, std::make_shared<RTFValue>());
+ }
+ resetFrame();
+
+ // Reset currently selected paragraph style as well.
+ // By default the style with index 0 is applied.
+ {
+ OUString const aName = getStyleName(0);
+ if (!aName.isEmpty())
+ {
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_pStyle, std::make_shared<RTFValue>(aName));
+ m_aStates.top().nCurrentStyleIndex = 0;
+ }
+ else
+ {
+ m_aStates.top().nCurrentStyleIndex = -1;
+ }
+ }
+ // Need to send paragraph properties again, if there will be any.
+ m_bNeedPap = true;
+ break;
+ case RTF_SECTD:
+ {
+ m_aStates.top().aSectionSprms = m_aDefaultState.aSectionSprms;
+ m_aStates.top().aSectionAttributes = m_aDefaultState.aSectionAttributes;
+ }
+ break;
+ case RTF_TROWD:
+ {
+ // Back these up, in case later we still need this info.
+ backupTableRowProperties();
+ resetTableRowProperties();
+ // In case the table definition is in the middle of the row
+ // (invalid), make sure table definition is emitted.
+ m_bNeedPap = true;
+ }
+ break;
+ case RTF_WIDCTLPAR:
+ case RTF_NOWIDCTLPAR:
+ {
+ auto pValue = std::make_shared<RTFValue>(int(nKeyword == RTF_WIDCTLPAR));
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_widowControl, pValue);
+ }
+ break;
+ case RTF_BOX:
+ {
+ RTFSprms aAttributes;
+ auto pValue = std::make_shared<RTFValue>(aAttributes);
+ for (int i = 0; i < 4; i++)
+ m_aStates.top().aParagraphSprms.set(getParagraphBorder(i), pValue);
+ m_aStates.top().nBorderState = RTFBorderState::PARAGRAPH_BOX;
+ }
+ break;
+ case RTF_LTRSECT:
+ case RTF_RTLSECT:
+ {
+ auto pValue = std::make_shared<RTFValue>(nKeyword == RTF_LTRSECT ? 0 : 1);
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_EG_SectPrContents_textDirection, pValue);
+ }
+ break;
+ case RTF_LTRPAR:
+ case RTF_RTLPAR:
+ {
+ auto pValue = std::make_shared<RTFValue>(nKeyword == RTF_LTRPAR ? 0 : 1);
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_bidi, pValue);
+ }
+ break;
+ case RTF_LTRROW:
+ case RTF_RTLROW:
+ m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblPrBase_bidiVisual, std::make_shared<RTFValue>(int(nKeyword == RTF_RTLROW)));
+ break;
+ case RTF_LTRCH:
+ // dmapper does not support this.
+ m_aStates.top().isRightToLeft = false;
+ break;
+ case RTF_RTLCH:
+ m_aStates.top().isRightToLeft = true;
+ if (m_aDefaultState.nCurrentEncoding == RTL_TEXTENCODING_MS_1255)
+ m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
+ break;
+ case RTF_ULNONE:
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Underline_none);
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_Underline_val, pValue);
+ }
+ break;
+ case RTF_NONSHPPICT:
+ case RTF_MMATHPICT: // Picture group used by readers not understanding \moMath group
+ m_aStates.top().eDestination = Destination::SKIP;
+ break;
+ case RTF_CLBRDRT:
+ case RTF_CLBRDRL:
+ case RTF_CLBRDRB:
+ case RTF_CLBRDRR:
+ {
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ auto pValue = std::make_shared<RTFValue>(aAttributes, aSprms);
+ switch (nKeyword)
+ {
+ case RTF_CLBRDRT:
+ nParam = NS_ooxml::LN_CT_TcBorders_top;
+ break;
+ case RTF_CLBRDRL:
+ nParam = NS_ooxml::LN_CT_TcBorders_left;
+ break;
+ case RTF_CLBRDRB:
+ nParam = NS_ooxml::LN_CT_TcBorders_bottom;
+ break;
+ case RTF_CLBRDRR:
+ nParam = NS_ooxml::LN_CT_TcBorders_right;
+ break;
+ default:
+ break;
+ }
+ putNestedSprm(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders, nParam, pValue);
+ m_aStates.top().nBorderState = RTFBorderState::CELL;
+ }
+ break;
+ case RTF_PGBRDRT:
+ case RTF_PGBRDRL:
+ case RTF_PGBRDRB:
+ case RTF_PGBRDRR:
+ {
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ auto pValue = std::make_shared<RTFValue>(aAttributes, aSprms);
+ switch (nKeyword)
+ {
+ case RTF_PGBRDRT:
+ nParam = NS_ooxml::LN_CT_PageBorders_top;
+ break;
+ case RTF_PGBRDRL:
+ nParam = NS_ooxml::LN_CT_PageBorders_left;
+ break;
+ case RTF_PGBRDRB:
+ nParam = NS_ooxml::LN_CT_PageBorders_bottom;
+ break;
+ case RTF_PGBRDRR:
+ nParam = NS_ooxml::LN_CT_PageBorders_right;
+ break;
+ default:
+ break;
+ }
+ putNestedSprm(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders, nParam, pValue);
+ m_aStates.top().nBorderState = RTFBorderState::PAGE;
+ }
+ break;
+ case RTF_BRDRT:
+ case RTF_BRDRL:
+ case RTF_BRDRB:
+ case RTF_BRDRR:
+ {
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ auto pValue = std::make_shared<RTFValue>(aAttributes, aSprms);
+ switch (nKeyword)
+ {
+ case RTF_BRDRT:
+ nParam = getParagraphBorder(0);
+ break;
+ case RTF_BRDRL:
+ nParam = getParagraphBorder(1);
+ break;
+ case RTF_BRDRB:
+ nParam = getParagraphBorder(2);
+ break;
+ case RTF_BRDRR:
+ nParam = getParagraphBorder(3);
+ break;
+ default:
+ break;
+ }
+ putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr, nParam, pValue);
+ m_aStates.top().nBorderState = RTFBorderState::PARAGRAPH;
+ }
+ break;
+ case RTF_CHBRDR:
+ {
+ RTFSprms aAttributes;
+ auto pValue = std::make_shared<RTFValue>(aAttributes);
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_bdr, pValue);
+ m_aStates.top().nBorderState = RTFBorderState::CHARACTER;
+ }
+ break;
+ case RTF_CLMGF:
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_restart);
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
+ }
+ break;
+ case RTF_CLMRG:
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_continue);
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
+ }
+ break;
+ case RTF_CLVMGF:
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_restart);
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
+ }
+ break;
+ case RTF_CLVMRG:
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_continue);
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
+ }
+ break;
+ case RTF_CLVERTALT:
+ case RTF_CLVERTALC:
+ case RTF_CLVERTALB:
+ {
+ switch (nKeyword)
+ {
+ case RTF_CLVERTALT:
+ nParam = NS_ooxml::LN_Value_ST_VerticalJc_top;
+ break;
+ case RTF_CLVERTALC:
+ nParam = NS_ooxml::LN_Value_ST_VerticalJc_center;
+ break;
+ case RTF_CLVERTALB:
+ nParam = NS_ooxml::LN_Value_ST_VerticalJc_bottom;
+ break;
+ default:
+ break;
+ }
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue);
+ }
+ break;
+ case RTF_TRKEEP:
+ {
+ auto pValue = std::make_shared<RTFValue>(1);
+ m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TrPrBase_cantSplit, pValue);
+ }
+ break;
+ case RTF_SECTUNLOCKED:
+ {
+ auto pValue = std::make_shared<RTFValue>(int(!nParam));
+ m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue);
+ }
+ break;
+ case RTF_PGNBIDIA:
+ case RTF_PGNBIDIB:
+ // These should be mapped to NS_ooxml::LN_EG_SectPrContents_pgNumType, but dmapper has no API for that at the moment.
+ break;
+ case RTF_LOCH:
+ m_aStates.top().eRunType = RTFParserState::LOCH;
+ break;
+ case RTF_HICH:
+ m_aStates.top().eRunType = RTFParserState::HICH;
+ break;
+ case RTF_DBCH:
+ m_aStates.top().eRunType = RTFParserState::DBCH;
+ break;
+ case RTF_TITLEPG:
+ {
+ auto pValue = std::make_shared<RTFValue>(1);
+ m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue);
+ }
+ break;
+ case RTF_SUPER:
+ {
+ if (!m_aStates.top().pCurrentBuffer)
+ m_aStates.top().pCurrentBuffer = &m_aSuperBuffer;
+
+ auto pValue = std::make_shared<RTFValue>("superscript");
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
+ }
+ break;
+ case RTF_SUB:
+ {
+ auto pValue = std::make_shared<RTFValue>("subscript");
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
+ }
+ break;
+ case RTF_NOSUPERSUB:
+ {
+ if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
+ {
+ replayBuffer(m_aSuperBuffer, nullptr, nullptr);
+ m_aStates.top().pCurrentBuffer = nullptr;
+ }
+ m_aStates.top().aCharacterSprms.erase(NS_ooxml::LN_EG_RPrBase_vertAlign);
+ }
+ break;
+ case RTF_LINEPPAGE:
+ case RTF_LINECONT:
+ {
+ auto pValue = std::make_shared<RTFValue>(nKeyword == RTF_LINEPPAGE ? NS_ooxml::LN_Value_ST_LineNumberRestart_newPage : NS_ooxml::LN_Value_ST_LineNumberRestart_continuous);
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_restart, pValue);
+ }
+ break;
+ case RTF_AENDDOC:
+ // Noop, this is the default in Writer.
+ break;
+ case RTF_AENDNOTES:
+ // Noop, Writer does not support having endnotes at the end of section.
+ break;
+ case RTF_AFTNRSTCONT:
+ // Noop, this is the default in Writer.
+ break;
+ case RTF_AFTNRESTART:
+ // Noop, Writer does not support restarting endnotes at each section.
+ break;
+ case RTF_FTNBJ:
+ // Noop, this is the default in Writer.
+ break;
+ case RTF_ENDDOC:
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_RestartNumber_eachSect);
+ putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
+ }
+ break;
+ case RTF_NOLINE:
+ eraseNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance);
+ break;
+ case RTF_FORMSHADE:
+ // Noop, this is the default in Writer.
+ break;
+ case RTF_PNGBLIP:
+ m_aStates.top().aPicture.eStyle = RTFBmpStyle::PNG;
+ break;
+ case RTF_JPEGBLIP:
+ m_aStates.top().aPicture.eStyle = RTFBmpStyle::JPEG;
+ break;
+ case RTF_POSYT:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_top);
+ break;
+ case RTF_POSYB:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_bottom);
+ break;
+ case RTF_POSYC:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_center);
+ break;
+ case RTF_POSYIN:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_inside);
+ break;
+ case RTF_POSYOUT:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_outside);
+ break;
+ case RTF_POSYIL:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_inline);
+ break;
+
+ case RTF_PHMRG:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_doc_ST_HAnchor_margin);
+ break;
+ case RTF_PVMRG:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_doc_ST_VAnchor_margin);
+ break;
+ case RTF_PHPG:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_doc_ST_HAnchor_page);
+ break;
+ case RTF_PVPG:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_doc_ST_VAnchor_page);
+ break;
+ case RTF_PHCOL:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_doc_ST_HAnchor_text);
+ break;
+ case RTF_PVPARA:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_doc_ST_VAnchor_text);
+ break;
+
+ case RTF_POSXC:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_center);
+ break;
+ case RTF_POSXI:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_inside);
+ break;
+ case RTF_POSXO:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_outside);
+ break;
+ case RTF_POSXL:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_left);
+ break;
+ case RTF_POSXR:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_right);
+ break;
+
+ case RTF_DPLINE:
+ case RTF_DPRECT:
+ case RTF_DPELLIPSE:
+ case RTF_DPTXBX:
+ case RTF_DPPOLYLINE:
+ case RTF_DPPOLYGON:
+ {
+ sal_Int32 nType = 0;
+ switch (nKeyword)
+ {
+ case RTF_DPLINE:
+ m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.LineShape"), uno::UNO_QUERY);
+ break;
+ case RTF_DPPOLYLINE:
+ // The reason this is not a simple CustomShape is that in the old syntax we have no ViewBox info.
+ m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.PolyLineShape"), uno::UNO_QUERY);
+ break;
+ case RTF_DPPOLYGON:
+ m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.PolyPolygonShape"), uno::UNO_QUERY);
+ break;
+ case RTF_DPRECT:
+ m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
+ break;
+ case RTF_DPELLIPSE:
+ nType = ESCHER_ShpInst_Ellipse;
+ break;
+ case RTF_DPTXBX:
+ {
+ m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.text.TextFrame"), uno::UNO_QUERY);
+ std::vector<beans::PropertyValue> aDefaults = RTFSdrImport::getTextFrameDefaults(false);
+ for (std::size_t i = 0; i < aDefaults.size(); ++i)
+ {
+ if (!findPropertyName(m_aStates.top().aDrawingObject.aPendingProperties, aDefaults[i].Name))
+ m_aStates.top().aDrawingObject.aPendingProperties.push_back(aDefaults[i]);
+ }
+ checkFirstRun();
+ Mapper().startShape(m_aStates.top().aDrawingObject.xShape);
+ m_aStates.top().aDrawingObject.bHadShapeText = true;
+ }
+ break;
+ default:
+ break;
+ }
+ if (nType)
+ m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.CustomShape"), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier(m_xDstDoc, uno::UNO_QUERY);
+ if (xDrawSupplier.is())
+ {
+ uno::Reference<drawing::XShapes> xShapes(xDrawSupplier->getDrawPage(), uno::UNO_QUERY);
+ if (xShapes.is() && nKeyword != RTF_DPTXBX)
+ xShapes->add(m_aStates.top().aDrawingObject.xShape);
+ }
+ if (nType)
+ {
+ uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
+ xDefaulter->createCustomShapeDefaults(OUString::number(nType));
+ }
+ m_aStates.top().aDrawingObject.xPropertySet.set(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
+ std::vector<beans::PropertyValue>& rPendingProperties = m_aStates.top().aDrawingObject.aPendingProperties;
+ for (std::vector<beans::PropertyValue>::iterator i = rPendingProperties.begin(); i != rPendingProperties.end(); ++i)
+ m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue(i->Name, i->Value);
+ m_pSdrImport->resolveDhgt(m_aStates.top().aDrawingObject.xPropertySet, m_aStates.top().aDrawingObject.nDhgt, /*bOldStyle=*/true);
+ }
+ break;
+ case RTF_DOBXMARGIN:
+ case RTF_DOBYMARGIN:
+ {
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = (nKeyword == RTF_DOBXMARGIN ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
+ aPropertyValue.Value <<= text::RelOrientation::PAGE_PRINT_AREA;
+ m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
+ }
+ break;
+ case RTF_DOBXPAGE:
+ case RTF_DOBYPAGE:
+ {
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = (nKeyword == RTF_DOBXPAGE ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
+ aPropertyValue.Value <<= text::RelOrientation::PAGE_FRAME;
+ m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
+ }
+ break;
+ case RTF_DOBYPARA:
+ {
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = "VertOrientRelation";
+ aPropertyValue.Value <<= text::RelOrientation::FRAME;
+ m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
+ }
+ break;
+ case RTF_CONTEXTUALSPACE:
+ {
+ auto pValue = std::make_shared<RTFValue>(1);
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_contextualSpacing, pValue);
+ }
+ break;
+ case RTF_LINKSTYLES:
+ {
+ auto pValue = std::make_shared<RTFValue>(1);
+ m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue);
+ }
+ break;
+ case RTF_PNLVLBODY:
+ {
+ auto pValue = std::make_shared<RTFValue>(2);
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, pValue);
+ }
+ break;
+ case RTF_PNDEC:
+ {
+ auto pValue = std::make_shared<RTFValue>(0); // decimal, same as \levelnfc0
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_numFmt, pValue);
+ }
+ break;
+ case RTF_PNLVLBLT:
+ {
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, std::make_shared<RTFValue>(1));
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_numFmt, std::make_shared<RTFValue>(23)); // bullets, same as \levelnfc23
+ }
+ break;
+ case RTF_LANDSCAPE: // fall through: set the default + current value
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_PageOrientation_landscape);
+ putNestedAttribute(m_aDefaultState.aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, pValue);
+ }
+ case RTF_LNDSCPSXN:
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_PageOrientation_landscape);
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, pValue);
+ }
+ break;
+ case RTF_SHPBXPAGE:
+ m_aStates.top().aShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
+ m_aStates.top().aShape.nHoriOrientRelationToken = NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page;
+ break;
+ case RTF_SHPBYPAGE:
+ m_aStates.top().aShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
+ m_aStates.top().aShape.nVertOrientRelationToken = NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page;
+ break;
+ case RTF_DPLINEHOLLOW:
+ m_aStates.top().aDrawingObject.nFLine = 0;
+ break;
+ case RTF_DPROUNDR:
+ if (m_aStates.top().aDrawingObject.xPropertySet.is())
+ // Seems this old syntax has no way to specify a custom radius, and this is the default
+ m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue("CornerRadius", uno::makeAny(sal_Int32(83)));
+ break;
+ case RTF_NOWRAP:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_wrap, NS_ooxml::LN_Value_doc_ST_Wrap_notBeside);
+ break;
+ case RTF_MNOR:
+ m_bMathNor = true;
+ break;
+ case RTF_REVISIONS:
+ m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_trackRevisions, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_BRDRSH:
+ putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_shadow, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_NOCOLBAL:
+ m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_noColumnBalance, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_MARGMIRROR:
+ m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_mirrorMargins, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_SAUTOUPD:
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Style_autoRedefine, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_WIDOWCTRL:
+ m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_widowControl, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_LINEBETCOL:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_sep, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_PGNRESTART:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_start, std::make_shared<RTFValue>(1));
+ break;
+ case RTF_PGNUCLTR:
+ {
+ auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_upperLetter);
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
+ }
+ break;
+ case RTF_PGNLCLTR:
+ {
+ auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter);
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
+ }
+ break;
+ case RTF_PGNUCRM:
+ {
+ auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_upperRoman);
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
+ }
+ break;
+ case RTF_PGNLCRM:
+ {
+ auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman);
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
+ }
+ break;
+ case RTF_PGNDEC:
+ {
+ auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_decimal);
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
+ }
+ break;
+ default:
+ {
+ SAL_INFO("writerfilter", "TODO handle flag '" << keywordToString(nKeyword) << "'");
+ aSkip.setParsed(false);
+ }
+ break;
+ }
+ return RTFError::OK;
+}
+
+} // namespace rtftok
+} // namespace writerfilter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
new file mode 100644
index 000000000000..98aa43d6bb9a
--- /dev/null
+++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
@@ -0,0 +1,409 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <rtfdocumentimpl.hxx>
+
+#include <svl/lngmisc.hxx>
+
+#include <ooxml/resourceids.hxx>
+
+#include <rtfreferenceproperties.hxx>
+#include <rtfskipdestination.hxx>
+
+using namespace com::sun::star;
+
+namespace writerfilter
+{
+namespace rtftok
+{
+
+RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
+{
+ setNeedSect(true);
+ if (nKeyword != RTF_HEXCHAR)
+ checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
+ else
+ checkUnicode(/*bUnicode =*/ true, /*bHex =*/ false);
+ RTFSkipDestination aSkip(*this);
+
+ if (RTF_LINE == nKeyword)
+ {
+ // very special handling since text() will eat lone '\n'
+ singleChar('\n');
+ return RTFError::OK;
+ }
+ // Trivial symbols
+ sal_uInt8 cCh = 0;
+ switch (nKeyword)
+ {
+ case RTF_TAB:
+ cCh = '\t';
+ break;
+ case RTF_BACKSLASH:
+ cCh = '\\';
+ break;
+ case RTF_LBRACE:
+ cCh = '{';
+ break;
+ case RTF_RBRACE:
+ cCh = '}';
+ break;
+ case RTF_EMDASH:
+ cCh = 151;
+ break;
+ case RTF_ENDASH:
+ cCh = 150;
+ break;
+ case RTF_BULLET:
+ cCh = 149;
+ break;
+ case RTF_LQUOTE:
+ cCh = 145;
+ break;
+ case RTF_RQUOTE:
+ cCh = 146;
+ break;
+ case RTF_LDBLQUOTE:
+ cCh = 147;
+ break;
+ case RTF_RDBLQUOTE:
+ cCh = 148;
+ break;
+ default:
+ break;
+ }
+ if (cCh > 0)
+ {
+ OUString aStr(OStringToOUString(OString(cCh), RTL_TEXTENCODING_MS_1252));
+ text(aStr);
+ return RTFError::OK;
+ }
+
+ switch (nKeyword)
+ {
+ case RTF_IGNORE:
+ {
+ m_bSkipUnknown = true;
+ aSkip.setReset(false);
+ return RTFError::OK;
+ }
+ break;
+ case RTF_PAR:
+ {
+ if (m_aStates.top().eDestination == Destination::FOOTNOTESEPARATOR)
+ break; // just ignore it - only thing we read in here is CHFTNSEP
+ checkFirstRun();
+ bool bNeedPap = m_bNeedPap;
+ checkNeedPap();
+ if (bNeedPap)
+ runProps();
+ if (!m_aStates.top().pCurrentBuffer)
+ {
+ parBreak();
+ // Not in table? Reset max width.
+ if (m_nCellxMax)
+ {
+ // Was in table, but not anymore -> tblEnd.
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ aSprms.set(NS_ooxml::LN_tblEnd, std::make_shared<RTFValue>(1));
+ writerfilter::Reference<Properties>::Pointer_t pProperties = std::make_shared<RTFReferenceProperties>(aAttributes, aSprms);
+ Mapper().props(pProperties);
+ }
+ m_nCellxMax = 0;
+ }
+ else if (m_aStates.top().eDestination != Destination::SHAPETEXT)
+ {
+ RTFValue::Pointer_t pValue;
+ m_aStates.top().pCurrentBuffer->push_back(
+ Buf_t(BUFFER_PAR, pValue, nullptr));
+ }
+ // but don't emit properties yet, since they may change till the first text token arrives
+ m_bNeedPap = true;
+ if (!m_aStates.top().aFrame.inFrame())
+ m_bNeedPar = false;
+ m_bNeedFinalPar = false;
+ }
+ break;
+ case RTF_SECT:
+ {
+ m_bHadSect = true;
+ if (m_bIgnoreNextContSectBreak)
+ m_bIgnoreNextContSectBreak = false;
+ else
+ {
+ sectBreak();
+ if (m_nResetBreakOnSectBreak != RTF_invalid)
+ {
+ // this should run on _second_ \sect after \page
+ dispatchSymbol(m_nResetBreakOnSectBreak); // lazy reset
+ m_nResetBreakOnSectBreak = RTF_invalid;
+ m_bNeedSect = false; // dispatchSymbol set it
+ }
+ }
+ }
+ break;
+ case RTF_NOBREAK:
+ {
+ OUString aStr(SVT_HARD_SPACE);
+ text(aStr);
+ }
+ break;
+ case RTF_NOBRKHYPH:
+ {
+ OUString aStr(SVT_HARD_HYPHEN);
+ text(aStr);
+ }
+ break;
+ case RTF_OPTHYPH:
+ {
+ OUString aStr(SVT_SOFT_HYPHEN);
+ text(aStr);
+ }
+ break;
+ case RTF_HEXCHAR:
+ m_aStates.top().nInternalState = RTFInternalState::HEX;
+ break;
+ case RTF_CELL:
+ case RTF_NESTCELL:
+ {
+ checkFirstRun();
+ if (m_bNeedPap)
+ {
+ // There were no runs in the cell, so we need to send paragraph and character properties here.
+ auto pPValue = std::make_shared<RTFValue>(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms);
+ m_aTableBufferStack.back().push_back(Buf_t(BUFFER_PROPS, pPValue, nullptr));
+ auto pCValue = std::make_shared<RTFValue>(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms);
+ m_aTableBufferStack.back().push_back(Buf_t(BUFFER_PROPS, pCValue, nullptr));
+ }
+
+ RTFValue::Pointer_t pValue;
+ m_aTableBufferStack.back().push_back(Buf_t(BUFFER_CELLEND, pValue, nullptr));
+ m_bNeedPap = true;
+ }
+ break;
+ case RTF_NESTROW:
+ {
+ std::shared_ptr<TableRowBuffer> const pBuffer(
+ new TableRowBuffer(
+ m_aTableBufferStack.back(),
+ m_aNestedTableCellsSprms,
+ m_aNestedTableCellsAttributes,
+ m_nNestedCells));
+ prepareProperties(m_aStates.top(),
+ pBuffer->pParaProperties,
+ pBuffer->pFrameProperties,
+ pBuffer->pRowProperties,
+ m_nNestedCells, m_nNestedCurrentCellX);
+
+ assert(m_aStates.top().pCurrentBuffer == &m_aTableBufferStack.back());
+ if (m_aTableBufferStack.size() == 1)
+ {
+ throw io::WrongFormatException(
+ "mismatch between \\itap and number of \\nestrow", nullptr);
+ }
+ // note: there may be several states pointing to table buffer!
+ for (std::size_t i = 0; i < m_aStates.size(); ++i)
+ {
+ if (m_aStates[i].pCurrentBuffer == &m_aTableBufferStack.back())
+ {
+ m_aStates[i].pCurrentBuffer =
+ &m_aTableBufferStack[m_aTableBufferStack.size()-2];
+ }
+ }
+ m_aTableBufferStack.pop_back();
+ m_aTableBufferStack.back().push_back(
+ Buf_t(BUFFER_NESTROW, RTFValue::Pointer_t(), pBuffer));
+
+ m_aNestedTableCellsSprms.clear();
+ m_aNestedTableCellsAttributes.clear();
+ m_nNestedCells = 0;
+ m_bNeedPap = true;
+ }
+ break;
+ case RTF_ROW:
+ {
+ bool bRestored = false;
+ // Ending a row, but no cells defined?
+ // See if there was an invalid table row reset, so we can restore cell infos to help invalid documents.
+ if (!m_nTopLevelCurrentCellX && m_nBackupTopLevelCurrentCellX)
+ {
+ restoreTableRowProperties();
+ bRestored = true;
+ }
+
+ // If the right edge of the last cell (row width) is smaller than the width of some other row, mimic WW8TabDesc::CalcDefaults(): resize the last cell
+ const int MINLAY = 23; // sw/inc/swtypes.hxx, minimal possible size of frames.
+ if ((m_nCellxMax - m_nTopLevelCurrentCellX) >= MINLAY)
+ {
+ auto pXValueLast = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblGridBase_gridCol, false);
+ auto pXValue = std::make_shared<RTFValue>(pXValueLast->getInt() + m_nCellxMax - m_nTopLevelCurrentCellX);
+ m_aStates.top().aTableRowSprms.eraseLast(NS_ooxml::LN_CT_TblGridBase_gridCol);
+ m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, RTFOverwrite::NO_APPEND);
+ m_nTopLevelCurrentCellX = m_nCellxMax;
+ }
+
+ if (m_nTopLevelCells)
+ {
+ // Make a backup before we start popping elements
+ m_aTableInheritingCellsSprms = m_aTopLevelTableCellsSprms;
+ m_aTableInheritingCellsAttributes = m_aTopLevelTableCellsAttributes;
+ m_nInheritingCells = m_nTopLevelCells;
+ }
+ else
+ {
+ // No table definition? Then inherit from the previous row
+ m_aTopLevelTableCellsSprms = m_aTableInheritingCellsSprms;
+ m_aTopLevelTableCellsAttributes = m_aTableInheritingCellsAttributes;
+ m_nTopLevelCells = m_nInheritingCells;
+ }
+
+ while (m_aTableBufferStack.size() > 1)
+ {
+ SAL_WARN("writerfilter.rtf", "dropping extra table buffer");
+ // note: there may be several states pointing to table buffer!
+ for (std::size_t i = 0; i < m_aStates.size(); ++i)
+ {
+ if (m_aStates[i].pCurrentBuffer == &m_aTableBufferStack.back())
+ {
+ m_aStates[i].pCurrentBuffer =
+ &m_aTableBufferStack.front();
+ }
+ }
+ m_aTableBufferStack.pop_back();
+ }
+
+ replayRowBuffer(m_aTableBufferStack.back(),
+ m_aTopLevelTableCellsSprms, m_aTopLevelTableCellsAttributes,
+ m_nTopLevelCells);
+
+ m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
+ m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
+
+ writerfilter::Reference<Properties>::Pointer_t paraProperties;
+ writerfilter::Reference<Properties>::Pointer_t frameProperties;
+ writerfilter::Reference<Properties>::Pointer_t rowProperties;
+ prepareProperties(m_aStates.top(),
+ paraProperties, frameProperties, rowProperties,
+ m_nTopLevelCells, m_nTopLevelCurrentCellX);
+ sendProperties(paraProperties, frameProperties, rowProperties);
+
+ m_bNeedPap = true;
+ m_bNeedFinalPar = true;
+ m_aTableBufferStack.back().clear();
+ m_nTopLevelCells = 0;
+
+ if (bRestored)
+ // We restored cell definitions, clear these now.
+ // This is necessary, as later cell definitions want to overwrite the restored ones.
+ resetTableRowProperties();
+ }
+ break;
+ case RTF_COLUMN:
+ {
+ bool bColumns = false; // If we have multiple columns
+ RTFValue::Pointer_t pCols = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_cols);
+ if (pCols.get())
+ {
+ RTFValue::Pointer_t pNum = pCols->getAttributes().find(NS_ooxml::LN_CT_Columns_num);
+ if (pNum.get() && pNum->getInt() > 1)
+ bColumns = true;
+ }
+ checkFirstRun();
+ if (bColumns)
+ {
+ sal_uInt8 sBreak[] = { 0xe };
+ Mapper().startCharacterGroup();
+ Mapper().text(sBreak, 1);
+ Mapper().endCharacterGroup();
+ }
+ else
+ dispatchSymbol(RTF_PAGE);
+ }
+ break;
+ case RTF_CHFTN:
+ {
+ if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
+ // Stop buffering, there will be no custom mark for this footnote or endnote.
+ m_aStates.top().pCurrentBuffer = nullptr;
+ break;
+ }
+ case RTF_PAGE:
+ {
+ // Ignore page breaks inside tables.
+ if (m_aStates.top().pCurrentBuffer == &m_aTableBufferStack.back())
+ break;
+
+ // If we're inside a continuous section, we should send a section break, not a page one.
+ RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_type);
+ // Unless we're on a title page.
+ RTFValue::Pointer_t pTitlePg = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_titlePg);
+ if (((pBreak.get() && pBreak->getInt() == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous))
+ || m_nResetBreakOnSectBreak == RTF_SBKNONE)
+ && !(pTitlePg.get() && pTitlePg->getInt()))
+ {
+ if (m_bWasInFrame)
+ {
+ dispatchSymbol(RTF_PAR);
+ m_bWasInFrame = false;
+ }
+ sectBreak();
+ // note: this will not affect the following section break
+ // but the one just pushed
+ dispatchFlag(RTF_SBKPAGE);
+ if (m_bNeedPar)
+ dispatchSymbol(RTF_PAR);
+ m_bIgnoreNextContSectBreak = true;
+ // arrange to clean up the synthetic RTF_SBKPAGE
+ m_nResetBreakOnSectBreak = RTF_SBKNONE;
+ }
+ else
+ {
+ checkFirstRun();
+ checkNeedPap();
+ sal_uInt8 sBreak[] = { 0xc };
+ Mapper().text(sBreak, 1);
+ if (!m_bNeedPap)
+ {
+ parBreak();
+ m_bNeedPap = true;
+ }
+ m_bNeedCr = true;
+ }
+ }
+ break;
+ case RTF_CHPGN:
+ {
+ OUString aStr("PAGE");
+ singleChar(cFieldStart);
+ text(aStr);
+ singleChar(cFieldSep, true);
+ singleChar(cFieldEnd);
+ }
+ break;
+ case RTF_CHFTNSEP:
+ {
+ static const sal_Unicode uFtnEdnSep = 0x3;
+ Mapper().utext(reinterpret_cast<const sal_uInt8*>(&uFtnEdnSep), 1);
+ }
+ break;
+ default:
+ {
+ SAL_INFO("writerfilter", "TODO handle symbol '" << keywordToString(nKeyword) << "'");
+ aSkip.setParsed(false);
+ }
+ break;
+ }
+ return RTFError::OK;
+}
+
+} // namespace rtftok
+} // namespace writerfilter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdispatchvalue.cxx b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
new file mode 100644
index 000000000000..76e24ddfe9e7
--- /dev/null
+++ b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
@@ -0,0 +1,1347 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <rtfdocumentimpl.hxx>
+
+#include <com/sun/star/text/WrapTextMode.hpp>
+
+#include <comphelper/sequence.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <rtl/tencinfo.h>
+#include <tools/colordata.hxx>
+#include <tools/mapunit.hxx>
+
+#include <ooxml/resourceids.hxx>
+
+#include <rtfcharsets.hxx>
+#include <rtffly.hxx>
+#include <rtfreferenceproperties.hxx>
+#include <rtfskipdestination.hxx>
+
+using namespace com::sun::star;
+
+namespace writerfilter
+{
+
+int getNumberFormat(int nParam)
+{
+ static const int aMap[] =
+ {
+ NS_ooxml::LN_Value_ST_NumberFormat_decimal,
+ NS_ooxml::LN_Value_ST_NumberFormat_upperRoman,
+ NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman,
+ NS_ooxml::LN_Value_ST_NumberFormat_upperLetter,
+ NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter,
+ NS_ooxml::LN_Value_ST_NumberFormat_ordinal,
+ NS_ooxml::LN_Value_ST_NumberFormat_cardinalText,
+ NS_ooxml::LN_Value_ST_NumberFormat_ordinalText,
+ NS_ooxml::LN_Value_ST_NumberFormat_none, // Undefined in RTF 1.8 spec.
+ NS_ooxml::LN_Value_ST_NumberFormat_none, // Undefined in RTF 1.8 spec.
+ NS_ooxml::LN_Value_ST_NumberFormat_ideographDigital,
+ NS_ooxml::LN_Value_ST_NumberFormat_japaneseCounting,
+ NS_ooxml::LN_Value_ST_NumberFormat_aiueo,
+ NS_ooxml::LN_Value_ST_NumberFormat_iroha,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalHalfWidth,
+ NS_ooxml::LN_Value_ST_NumberFormat_japaneseLegal,
+ NS_ooxml::LN_Value_ST_NumberFormat_japaneseDigitalTenThousand ,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth2,
+ NS_ooxml::LN_Value_ST_NumberFormat_aiueoFullWidth,
+ NS_ooxml::LN_Value_ST_NumberFormat_irohaFullWidth,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalZero,
+ NS_ooxml::LN_Value_ST_NumberFormat_bullet,
+ NS_ooxml::LN_Value_ST_NumberFormat_ganada,
+ NS_ooxml::LN_Value_ST_NumberFormat_chosung,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedFullstop,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedParen,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese,
+ NS_ooxml::LN_Value_ST_NumberFormat_ideographEnclosedCircle,
+ NS_ooxml::LN_Value_ST_NumberFormat_ideographTraditional,
+ NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiac,
+ NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiacTraditional,
+ NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCounting,
+ NS_ooxml::LN_Value_ST_NumberFormat_ideographLegalTraditional,
+ NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCountingThousand,
+ NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseDigital,
+ NS_ooxml::LN_Value_ST_NumberFormat_chineseCounting,
+ NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified,
+ NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand,
+ NS_ooxml::LN_Value_ST_NumberFormat_decimal,
+ NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital,
+ NS_ooxml::LN_Value_ST_NumberFormat_koreanCounting,
+ NS_ooxml::LN_Value_ST_NumberFormat_koreanLegal,
+ NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital2,
+ NS_ooxml::LN_Value_ST_NumberFormat_hebrew1,
+ NS_ooxml::LN_Value_ST_NumberFormat_arabicAlpha,
+ NS_ooxml::LN_Value_ST_NumberFormat_hebrew2,
+ NS_ooxml::LN_Value_ST_NumberFormat_arabicAbjad
+ };
+ const int nLen = SAL_N_ELEMENTS(aMap);
+ int nValue = 0;
+ if (nParam >= 0 && nParam < nLen)
+ nValue = aMap[nParam];
+ else // 255 and the other cases.
+ nValue = NS_ooxml::LN_Value_ST_NumberFormat_none;
+ return nValue;
+}
+
+namespace rtftok
+{
+
+RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
+{
+ setNeedSect(true);
+ checkUnicode(/*bUnicode =*/ nKeyword != RTF_U, /*bHex =*/ true);
+ RTFSkipDestination aSkip(*this);
+ int nSprm = 0;
+ auto pIntValue = std::make_shared<RTFValue>(nParam);
+ // Trivial table sprms.
+ switch (nKeyword)
+ {
+ case RTF_LEVELJC:
+ {
+ nSprm = NS_ooxml::LN_CT_Lvl_lvlJc;
+ int nValue = 0;
+ switch (nParam)
+ {
+ case 0:
+ nValue = NS_ooxml::LN_Value_ST_Jc_left;
+ break;
+ case 1:
+ nValue = NS_ooxml::LN_Value_ST_Jc_center;
+ break;
+ case 2:
+ nValue = NS_ooxml::LN_Value_ST_Jc_right;
+ break;
+ }
+ pIntValue = std::make_shared<RTFValue>(nValue);
+ break;
+ }
+ case RTF_LEVELNFC:
+ nSprm = NS_ooxml::LN_CT_Lvl_numFmt;
+ pIntValue = std::make_shared<RTFValue>(getNumberFormat(nParam));
+ break;
+ case RTF_LEVELSTARTAT:
+ nSprm = NS_ooxml::LN_CT_Lvl_start;
+ break;
+ case RTF_LEVELPICTURE:
+ nSprm = NS_ooxml::LN_CT_Lvl_lvlPicBulletId;
+ break;
+ case RTF_SBASEDON:
+ nSprm = NS_ooxml::LN_CT_Style_basedOn;
+ pIntValue = std::make_shared<RTFValue>(getStyleName(nParam));
+ break;
+ default:
+ break;
+ }
+ if (nSprm > 0)
+ {
+ m_aStates.top().aTableSprms.set(nSprm, pIntValue);
+ return RTFError::OK;
+ }
+ // Trivial character sprms.
+ switch (nKeyword)
+ {
+ case RTF_FS:
+ case RTF_AFS:
+ nSprm = (m_aStates.top().isRightToLeft || m_aStates.top().eRunType == RTFParserState::HICH) ? NS_ooxml::LN_EG_RPrBase_szCs : NS_ooxml::LN_EG_RPrBase_sz;
+ break;
+ case RTF_ANIMTEXT:
+ nSprm = NS_ooxml::LN_EG_RPrBase_effect;
+ break;
+ case RTF_EXPNDTW:
+ nSprm = NS_ooxml::LN_EG_RPrBase_spacing;
+ break;
+ case RTF_KERNING:
+ nSprm = NS_ooxml::LN_EG_RPrBase_kern;
+ break;
+ case RTF_CHARSCALEX:
+ nSprm = NS_ooxml::LN_EG_RPrBase_w;
+ break;
+ default:
+ break;
+ }
+ if (nSprm > 0)
+ {
+ m_aStates.top().aCharacterSprms.set(nSprm, pIntValue);
+ return RTFError::OK;
+ }
+ // Trivial character attributes.
+ switch (nKeyword)
+ {
+ case RTF_LANG:
+ case RTF_ALANG:
+ if (m_aStates.top().isRightToLeft || m_aStates.top().eRunType == RTFParserState::HICH)
+ {
+ nSprm = NS_ooxml::LN_CT_Language_bidi;
+ }
+ else if (m_aStates.top().eRunType == RTFParserState::DBCH)
+ {
+ nSprm = NS_ooxml::LN_CT_Language_eastAsia;
+ }
+ else
+ {
+ assert(m_aStates.top().eRunType == RTFParserState::LOCH);
+ nSprm = NS_ooxml::LN_CT_Language_val;
+ }
+ break;
+ case RTF_LANGFE: // this one is always CJK apparently
+ nSprm = NS_ooxml::LN_CT_Language_eastAsia;
+ break;
+ default:
+ break;
+ }
+ if (nSprm > 0)
+ {
+ LanguageTag aTag((LanguageType)nParam);
+ auto pValue = std::make_shared<RTFValue>(aTag.getBcp47());
+ putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_lang, nSprm, pValue);
+ // Language is a character property, but we should store it at a paragraph level as well for fields.
+ if (nKeyword == RTF_LANG && m_bNeedPap)
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_EG_RPrBase_lang, nSprm, pValue);
+ return RTFError::OK;
+ }
+ // Trivial paragraph sprms.
+ switch (nKeyword)
+ {
+ case RTF_ITAP:
+ nSprm = NS_ooxml::LN_tblDepth;
+ break;
+ default:
+ break;
+ }
+ if (nSprm > 0)
+ {
+ m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
+ if (nKeyword == RTF_ITAP && nParam > 0)
+ {
+ while (m_aTableBufferStack.size() < sal::static_int_cast<std::size_t>(nParam))
+ {
+ m_aTableBufferStack.push_back(RTFBuffer_t());
+ }
+ // Invalid tables may omit INTBL after ITAP
+ dispatchFlag(RTF_INTBL); // sets newly pushed buffer as current
+ assert(m_aStates.top().pCurrentBuffer == &m_aTableBufferStack.back());
+ }
+ return RTFError::OK;
+ }
+
+ // Info group.
+ switch (nKeyword)
+ {
+ case RTF_YR:
+ {
+ m_aStates.top().nYear = nParam;
+ nSprm = 1;
+ }
+ break;
+ case RTF_MO:
+ {
+ m_aStates.top().nMonth = nParam;
+ nSprm = 1;
+ }
+ break;
+ case RTF_DY:
+ {
+ m_aStates.top().nDay = nParam;
+ nSprm = 1;
+ }
+ break;
+ case RTF_HR:
+ {
+ m_aStates.top().nHour = nParam;
+ nSprm = 1;
+ }
+ break;
+ case RTF_MIN:
+ {
+ m_aStates.top().nMinute = nParam;
+ nSprm = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ if (nSprm > 0)
+ return RTFError::OK;
+
+ // Frame size / position.
+ Id nId = 0;
+ switch (nKeyword)
+ {
+ case RTF_ABSW:
+ nId = NS_ooxml::LN_CT_FramePr_w;
+ break;
+ case RTF_ABSH:
+ nId = NS_ooxml::LN_CT_FramePr_h;
+ break;
+ case RTF_POSX:
+ {
+ nId = NS_ooxml::LN_CT_FramePr_x;
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, 0);
+ }
+ break;
+ case RTF_POSY:
+ {
+ nId = NS_ooxml::LN_CT_FramePr_y;
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, 0);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (nId > 0)
+ {
+ m_bNeedPap = true;
+ // Don't try to support text frames inside tables for now.
+ if (m_aStates.top().pCurrentBuffer != &m_aTableBufferStack.back())
+ m_aStates.top().aFrame.setSprm(nId, nParam);
+
+ return RTFError::OK;
+ }
+
+ // Then check for the more complex ones.
+ switch (nKeyword)
+ {
+ case RTF_F:
+ case RTF_AF:
+ if (m_aStates.top().isRightToLeft || m_aStates.top().eRunType == RTFParserState::HICH)
+ {
+ nSprm = NS_ooxml::LN_CT_Fonts_cs;
+ }
+ else if (m_aStates.top().eRunType == RTFParserState::DBCH)
+ {
+ nSprm = NS_ooxml::LN_CT_Fonts_eastAsia;
+ }
+ else
+ {
+ assert(m_aStates.top().eRunType == RTFParserState::LOCH);
+ nSprm = NS_ooxml::LN_CT_Fonts_ascii;
+ }
+ if (m_aStates.top().eDestination == Destination::FONTTABLE || m_aStates.top().eDestination == Destination::FONTENTRY)
+ {
+ m_aFontIndexes.push_back(nParam);
+ m_nCurrentFontIndex = getFontIndex(nParam);
+ }
+ else if (m_aStates.top().eDestination == Destination::LISTLEVEL)
+ {
+ RTFSprms aFontAttributes;
+ aFontAttributes.set(nSprm, std::make_shared<RTFValue>(m_aFontNames[getFontIndex(nParam)]));
+ RTFSprms aRunPropsSprms;
+ aRunPropsSprms.set(NS_ooxml::LN_EG_RPrBase_rFonts, std::make_shared<RTFValue>(aFontAttributes));
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_rPr, std::make_shared<RTFValue>(RTFSprms(), aRunPropsSprms), RTFOverwrite::NO_APPEND);
+ }
+ else
+ {
+ m_nCurrentFontIndex = getFontIndex(nParam);
+ auto pValue = std::make_shared<RTFValue>(getFontName(m_nCurrentFontIndex));
+ putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, nSprm, pValue);
+ if (nKeyword == RTF_F)
+ m_aStates.top().nCurrentEncoding = getEncoding(m_nCurrentFontIndex);
+ }
+ break;
+ case RTF_RED:
+ m_aStates.top().aCurrentColor.nRed = nParam;
+ break;
+ case RTF_GREEN:
+ m_aStates.top().aCurrentColor.nGreen = nParam;
+ break;
+ case RTF_BLUE:
+ m_aStates.top().aCurrentColor.nBlue = nParam;
+ break;
+ case RTF_FCHARSET:
+ {
+ // we always send text to the domain mapper in OUString, so no
+ // need to send encoding info
+ int i;
+ for (i = 0; i < nRTFEncodings; i++)
+ {
+ if (aRTFEncodings[i].charset == nParam)
+ break;
+ }
+ if (i == nRTFEncodings)
+ // not found
+ return RTFError::OK;
+
+ m_nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(aRTFEncodings[i].codepage);
+ m_aStates.top().nCurrentEncoding = m_nCurrentEncoding;
+ }
+ break;
+ case RTF_ANSICPG:
+ {
+ m_aDefaultState.nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
+ m_aStates.top().nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
+ }
+ break;
+ case RTF_CPG:
+ m_nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
+ m_aStates.top().nCurrentEncoding = m_nCurrentEncoding;
+ break;
+ case RTF_CF:
+ {
+ RTFSprms aAttributes;
+ auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
+ aAttributes.set(NS_ooxml::LN_CT_Color_val, pValue);
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_color, std::make_shared<RTFValue>(aAttributes));
+ }
+ break;
+ case RTF_S:
+ {
+ m_aStates.top().nCurrentStyleIndex = nParam;
+
+ if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
+ {
+ m_nCurrentStyleIndex = nParam;
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_StyleType_paragraph);
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // paragraph style
+ }
+ else
+ {
+ OUString aName = getStyleName(nParam);
+ if (!aName.isEmpty())
+ {
+ if (m_aStates.top().eDestination == Destination::LISTLEVEL)
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_pStyle, std::make_shared<RTFValue>(aName));
+ else
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_pStyle, std::make_shared<RTFValue>(aName));
+
+ }
+ }
+ }
+ break;
+ case RTF_CS:
+ m_aStates.top().nCurrentCharacterStyleIndex = nParam;
+ if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
+ {
+ m_nCurrentStyleIndex = nParam;
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_StyleType_character);
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // character style
+ }
+ else
+ {
+ OUString aName = getStyleName(nParam);
+ if (!aName.isEmpty())
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_rStyle, std::make_shared<RTFValue>(aName));
+ }
+ break;
+ case RTF_DS:
+ if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
+ {
+ m_nCurrentStyleIndex = nParam;
+ auto pValue = std::make_shared<RTFValue>(0); // TODO no value in enum StyleType?
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // section style
+ }
+ break;
+ case RTF_TS:
+ if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
+ {
+ m_nCurrentStyleIndex = nParam;
+ // FIXME the correct value would be NS_ooxml::LN_Value_ST_StyleType_table but maybe table styles mess things up in dmapper, be cautious and disable them for now
+ auto pValue = std::make_shared<RTFValue>(0);
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // table style
+ }
+ break;
+ case RTF_DEFF:
+ m_nDefaultFontIndex = nParam;
+ break;
+ case RTF_DEFLANG:
+ case RTF_ADEFLANG:
+ {
+ LanguageTag aTag((LanguageType)nParam);
+ auto pValue = std::make_shared<RTFValue>(aTag.getBcp47());
+ putNestedAttribute(m_aStates.top().aCharacterSprms, (nKeyword == RTF_DEFLANG ? NS_ooxml::LN_EG_RPrBase_lang : NS_ooxml::LN_CT_Language_bidi), nSprm, pValue);
+ }
+ break;
+ case RTF_CHCBPAT:
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam ? getColorTable(nParam) : COL_AUTO);
+ putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
+ }
+ break;
+ case RTF_CLCBPAT:
+ {
+ auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
+ putNestedAttribute(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
+ }
+ break;
+ case RTF_CBPAT:
+ if (nParam)
+ {
+ auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
+ }
+ break;
+ case RTF_ULC:
+ {
+ auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
+ m_aStates.top().aCharacterSprms.set(0x6877, pValue);
+ }
+ break;
+ case RTF_HIGHLIGHT:
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam ? getColorTable(nParam) : COL_AUTO);
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_highlight, pValue);
+ }
+ break;
+ case RTF_UP:
+ case RTF_DN:
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam * (nKeyword == RTF_UP ? 1 : -1));
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_position, pValue);
+ }
+ break;
+ case RTF_HORZVERT:
+ {
+ auto pValue = std::make_shared<RTFValue>(int(true));
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vert, pValue);
+ if (nParam)
+ // rotate fits to a single line
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vertCompress, pValue);
+ }
+ break;
+ case RTF_EXPND:
+ {
+ auto pValue = std::make_shared<RTFValue>(nParam/5);
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_spacing, pValue);
+ }
+ break;
+ case RTF_TWOINONE:
+ {
+ auto pValue = std::make_shared<RTFValue>(int(true));
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combine, pValue);
+ nId = 0;
+ switch (nParam)
+ {
+ case 0:
+ nId = NS_ooxml::LN_Value_ST_CombineBrackets_none;
+ break;
+ case 1:
+ nId = NS_ooxml::LN_Value_ST_CombineBrackets_round;
+ break;
+ case 2:
+ nId = NS_ooxml::LN_Value_ST_CombineBrackets_square;
+ break;
+ case 3:
+ nId = NS_ooxml::LN_Value_ST_CombineBrackets_angle;
+ break;
+ case 4:
+ nId = NS_ooxml::LN_Value_ST_CombineBrackets_curly;
+ break;
+ }
+ if (nId > 0)
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combineBrackets, std::make_shared<RTFValue>(nId));
+ }
+ break;
+ case RTF_SL:
+ {
+ // This is similar to RTF_ABSH, negative value means 'exact', positive means 'at least'.
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast);
+ if (nParam < 0)
+ {
+ pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact);
+ pIntValue = std::make_shared<RTFValue>(-nParam);
+ }
+ m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
+ m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_line, pIntValue);
+ }
+ break;
+ case RTF_SLMULT:
+ if (nParam > 0)
+ {
+ auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto);
+ m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
+ }
+ break;
+ case RTF_BRDRW:
+ {
+ // dmapper expects it in 1/8 pt, we have it in twip - but avoid rounding 1 to 0
+ if (nParam > 1)
+ nParam = nParam * 2 / 5;
+ auto pValue = std::make_shared<RTFValue>(nParam);
+ putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_sz, pValue);
+ }
+ break;
+ case RTF_BRDRCF:
+ {
+ auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
+ putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_color, pValue);
+ }
+ break;
+ case RTF_BRSP:
+ {
+ // dmapper expects it in points, we have it in twip
+ auto pValue = std::make_shared<RTFValue>(nParam / 20);
+ putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_space, pValue);
+ }
+ break;
+ case RTF_TX:
+ {
+ m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_pos, pIntValue);
+ auto pValue = std::make_shared<RTFValue>(m_aStates.top().aTabAttributes);
+ putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_Tabs_tab, pValue);
+ m_aStates.top().aTabAttributes.clear();
+ }
+ break;
+ case RTF_ILVL:
+ putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_ooxml::LN_CT_NumPr_ilvl, pIntValue);
+ break;
+ case RTF_LISTTEMPLATEID:
+ // This one is not referenced anywhere, so it's pointless to store it at the moment.
+ break;
+ case RTF_LISTID:
+ {
+ if (m_aStates.top().eDestination == Destination::LISTENTRY)
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIntValue);
+ else if (m_aStates.top().eDestination == Destination::LISTOVERRIDEENTRY)
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIntValue);
+ }
+ break;
+ case RTF_LS:
+ {
+ if (m_aStates.top().eDestination == Destination::LISTOVERRIDEENTRY)
+ m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, pIntValue);
+ else
+ putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_NumPr_numId, pIntValue);
+ }
+ break;
+ case RTF_UC:
+ if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_INT16))
+ m_aStates.top().nUc = nParam;
+ break;
+ case RTF_U:
+ // sal_Unicode is unsigned 16-bit, RTF may represent that as a
+ // signed SAL_MIN_INT16..SAL_MAX_INT16 or 0..SAL_MAX_UINT16. The
+ // static_cast() will do the right thing.
+ if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_UINT16))
+ {
+ if (m_aStates.top().eDestination == Destination::LEVELNUMBERS)
+ {
+ if (nParam != ';')
+ m_aStates.top().aLevelNumbers.push_back(sal_Int32(nParam));
+ }
+ else
+ m_aUnicodeBuffer.append(static_cast<sal_Unicode>(nParam));
+ m_aStates.top().nCharsToSkip = m_aStates.top().nUc;
+ }
+ break;
+ case RTF_LEVELFOLLOW:
+ {
+ OUString sValue;
+ switch (nParam)
+ {
+ case 0:
+ sValue = "tab";
+ break;
+ case 1:
+ sValue = "space";
+ break;
+ case 2:
+ sValue = "nothing";
+ break;
+ }
+ if (!sValue.isEmpty())
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_suff, std::make_shared<RTFValue>(sValue));
+ }
+ break;
+ case RTF_FPRQ:
+ {
+ sal_Int32 nValue = 0;
+ switch (nParam)
+ {
+ case 0:
+ nValue = NS_ooxml::LN_Value_ST_Pitch_default;
+ break;
+ case 1:
+ nValue = NS_ooxml::LN_Value_ST_Pitch_fixed;
+ break;
+ case 2:
+ nValue = NS_ooxml::LN_Value_ST_Pitch_variable;
+ break;
+ }
+ if (nValue)
+ {
+ RTFSprms aAttributes;
+ aAttributes.set(NS_ooxml::LN_CT_Pitch_val, std::make_shared<RTFValue>(nValue));
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Font_pitch, std::make_shared<RTFValue>(aAttributes));
+ }
+ }
+ break;
+ case RTF_LISTOVERRIDECOUNT:
+ // Ignore this for now, the exporter always emits it with a zero parameter.
+ break;
+ case RTF_PICSCALEX:
+ m_aStates.top().aPicture.nScaleX = nParam;
+ break;
+ case RTF_PICSCALEY:
+ m_aStates.top().aPicture.nScaleY = nParam;
+ break;
+ case RTF_PICW:
+ m_aStates.top().aPicture.nWidth = nParam;
+ break;
+ case RTF_PICH:
+ m_aStates.top().aPicture.nHeight = nParam;
+ break;
+ case RTF_PICWGOAL:
+ m_aStates.top().aPicture.nGoalWidth = convertTwipToMm100(nParam);
+ break;
+ case RTF_PICHGOAL:
+ m_aStates.top().aPicture.nGoalHeight = convertTwipToMm100(nParam);
+ break;
+ case RTF_PICCROPL:
+ m_aStates.top().aPicture.nCropL = convertTwipToMm100(nParam);
+ break;
+ case RTF_PICCROPR:
+ m_aStates.top().aPicture.nCropR = convertTwipToMm100(nParam);
+ break;
+ case RTF_PICCROPT:
+ m_aStates.top().aPicture.nCropT = convertTwipToMm100(nParam);
+ break;
+ case RTF_PICCROPB:
+ m_aStates.top().aPicture.nCropB = convertTwipToMm100(nParam);
+ break;
+ case RTF_SHPWRK:
+ {
+ int nValue = 0;
+ switch (nParam)
+ {
+ case 0:
+ nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides;
+ break;
+ case 1:
+ nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left;
+ break;
+ case 2:
+ nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right;
+ break;
+ case 3:
+ nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest;
+ break;
+ default:
+ break;
+ }
+ auto pValue = std::make_shared<RTFValue>(nValue);
+ RTFValue::Pointer_t pTight = m_aStates.top().aCharacterSprms.find(NS_ooxml::LN_EG_WrapType_wrapTight);
+ if (pTight)
+ pTight->getAttributes().set(NS_ooxml::LN_CT_WrapTight_wrapText, pValue);
+ else
+ m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_WrapSquare_wrapText, pValue);
+ }
+ break;
+ case RTF_SHPWR:
+ {
+ switch (nParam)
+ {
+ case 1:
+ m_aStates.top().aShape.nWrap = text::WrapTextMode_NONE;
+ break;
+ case 2:
+ m_aStates.top().aShape.nWrap = text::WrapTextMode_PARALLEL;
+ break;
+ case 3:
+ m_aStates.top().aShape.nWrap = text::WrapTextMode_THROUGHT;
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_WrapType_wrapNone, std::make_shared<RTFValue>());
+ break;
+ case 4:
+ m_aStates.top().aShape.nWrap = text::WrapTextMode_PARALLEL;
+ m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_WrapType_wrapTight, std::make_shared<RTFValue>());
+ break;
+ case 5:
+ m_aStates.top().aShape.nWrap = text::WrapTextMode_THROUGHT;
+ break;
+ }
+ }
+ break;
+ case RTF_CELLX:
+ {
+ int& rCurrentCellX((Destination::NESTEDTABLEPROPERTIES == m_aStates.top().eDestination) ? m_nNestedCurrentCellX : m_nTopLevelCurrentCellX);
+ int nCellX = nParam - rCurrentCellX;
+ const int COL_DFLT_WIDTH = 41; // sw/source/filter/inc/wrtswtbl.hxx, minimal possible width of cells.
+ if (!nCellX)
+ nCellX = COL_DFLT_WIDTH;
+
+ // If there is a negative left margin, then the first cellx is relative to that.
+ RTFValue::Pointer_t pTblInd = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblInd);
+ if (rCurrentCellX == 0 && pTblInd.get())
+ {
+ RTFValue::Pointer_t pWidth = pTblInd->getAttributes().find(NS_ooxml::LN_CT_TblWidth_w);
+ if (pWidth.get() && pWidth->getInt() < 0)
+ nCellX = -1 * (pWidth->getInt() - nParam);
+ }
+
+ rCurrentCellX = nParam;
+ auto pXValue = std::make_shared<RTFValue>(nCellX);
+ m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, RTFOverwrite::NO_APPEND);
+ if (Destination::NESTEDTABLEPROPERTIES == m_aStates.top().eDestination)
+ {
+ m_nNestedCells++;
+ // Push cell properties.
+ m_aNestedTableCellsSprms.push_back(
+ m_aStates.top().aTableCellSprms);
+ m_aNestedTableCellsAttributes.push_back(
+ m_aStates.top().aTableCellAttributes);
+ }
+ else
+ {
+ m_nTopLevelCells++;
+ // Push cell properties.
+ m_aTopLevelTableCellsSprms.push_back(
+ m_aStates.top().aTableCellSprms);
+ m_aTopLevelTableCellsAttributes.push_back(
+ m_aStates.top().aTableCellAttributes);
+ }
+
+ m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
+ m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
+ // We assume text after a row definition always belongs to the table, to handle text before the real INTBL token
+ dispatchFlag(RTF_INTBL);
+ if (!m_nCellxMax)
+ {
+ // Wasn't in table, but now is -> tblStart.
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ aSprms.set(NS_ooxml::LN_tblStart, std::make_shared<RTFValue>(1));
+ writerfilter::Reference<Properties>::Pointer_t pProperties = std::make_shared<RTFReferenceProperties>(aAttributes, aSprms);
+ Mapper().props(pProperties);
+ }
+ m_nCellxMax = std::max(m_nCellxMax, nParam);
+ }
+ break;
+ case RTF_TRRH:
+ {
+ OUString hRule("auto");
+ if (nParam < 0)
+ {
+ auto pAbsValue = std::make_shared<RTFValue>(-nParam);
+ pIntValue.swap(pAbsValue);
+
+ hRule = "exact";
+ }
+ else if (nParam > 0)
+ hRule = "atLeast";
+
+ putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_val, pIntValue);
+
+ auto pHRule = std::make_shared<RTFValue>(hRule);
+ putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_hRule, pHRule);
+ }
+ break;
+ case RTF_TRLEFT:
+ {
+ // the value is in twips
+ putNestedAttribute(m_aStates.top().aTableRowSprms,
+ NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_type,
+ std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_TblWidth_dxa));
+ putNestedAttribute(m_aStates.top().aTableRowSprms,
+ NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_w,
+ std::make_shared<RTFValue>(nParam));
+ }
+ break;
+ case RTF_COLS:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_num, pIntValue);
+ break;
+ case RTF_COLSX:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_space, pIntValue);
+ break;
+ case RTF_COLNO:
+ putNestedSprm(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_col, pIntValue);
+ break;
+ case RTF_COLW:
+ case RTF_COLSR:
+ {
+ RTFSprms& rAttributes = getLastAttributes(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols);
+ rAttributes.set((nKeyword == RTF_COLW ? NS_ooxml::LN_CT_Column_w : NS_ooxml::LN_CT_Column_space), pIntValue);
+ }
+ break;
+ case RTF_PAPERH: // fall through: set the default + current value
+ putNestedAttribute(m_aDefaultState.aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue);
+ case RTF_PGHSXN:
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue);
+ break;
+ case RTF_PAPERW: // fall through: set the default + current value
+ putNestedAttribute(m_aDefaultState.aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue);
+ case RTF_PGWSXN:
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue);
+ break;
+ case RTF_MARGL: // fall through: set the default + current value
+ putNestedAttribute(m_aDefaultState.aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue);
+ case RTF_MARGLSXN:
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue);
+ break;
+ case RTF_MARGR: // fall through: set the default + current value
+ putNestedAttribute(m_aDefaultState.aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue);
+ case RTF_MARGRSXN:
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue);
+ break;
+ case RTF_MARGT: // fall through: set the default + current value
+ putNestedAttribute(m_aDefaultState.aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue);
+ case RTF_MARGTSXN:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue);
+ break;
+ case RTF_MARGB: // fall through: set the default + current value
+ putNestedAttribute(m_aDefaultState.aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue);
+ case RTF_MARGBSXN:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue);
+ break;
+ case RTF_HEADERY:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_header, pIntValue);
+ break;
+ case RTF_FOOTERY:
+ putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_footer, pIntValue);
+ break;
+ case RTF_DEFTAB:
+ m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_defaultTabStop, pIntValue);
+ break;
+ case RTF_LINEMOD:
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_countBy, pIntValue);
+ break;
+ case RTF_LINEX:
+ if (nParam)
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance, pIntValue);
+ break;
+ case RTF_LINESTARTS:
+ putNestedAttribute(m_aStates.top().aSectionSprms,
+ NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_start, pIntValue);
+ break;
+ case RTF_REVAUTH:
+ case RTF_REVAUTHDEL:
+ {
+ auto pValue = std::make_shared<RTFValue>(m_aAuthors[nParam]);
+ putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_author, pValue);
+ }
+ break;
+ case RTF_REVDTTM:
+ case RTF_REVDTTMDEL:
+ {
+ OUString aStr(OStringToOUString(DTTM22OString(nParam), m_aStates.top().nCurrentEncoding));
+ auto pValue = std::make_shared<RTFValue>(aStr);
+ putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_date, pValue);
+ }
+ break;
+ case RTF_SHPLEFT:
+ m_aStates.top().aShape.nLeft = convertTwipToMm100(nParam);
+ break;
+ case RTF_SHPTOP:
+ m_aStates.top().aShape.nTop = convertTwipToMm100(nParam);
+ break;
+ case RTF_SHPRIGHT:
+ m_aStates.top().aShape.nRight = convertTwipToMm100(nParam);
+ break;
+ case RTF_SHPBOTTOM:
+ m_aStates.top().aShape.nBottom = convertTwipToMm100(nParam);
+ break;
+ case RTF_SHPZ:
+ m_aStates.top().aShape.oZ.reset(nParam);
+ break;
+ case RTF_FFTYPE:
+ switch (nParam)
+ {
+ case 0:
+ m_nFormFieldType = RTFFormFieldType::TEXT;
+ break;
+ case 1:
+ m_nFormFieldType = RTFFormFieldType::CHECKBOX;
+ break;
+ case 2:
+ m_nFormFieldType = RTFFormFieldType::LIST;
+ break;
+ default:
+ m_nFormFieldType = RTFFormFieldType::NONE;
+ break;
+ }
+ break;
+ case RTF_FFDEFRES:
+ if (m_nFormFieldType == RTFFormFieldType::CHECKBOX)
+ m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_default, pIntValue);
+ else if (m_nFormFieldType == RTFFormFieldType::LIST)
+ m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_default, pIntValue);
+ break;
+ case RTF_FFRES:
+ // 25 means undefined, see [MS-DOC] 2.9.79, FFDataBits.
+ if (m_nFormFieldType == RTFFormFieldType::CHECKBOX && nParam != 25)
+ m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_checked, pIntValue);
+ else if (m_nFormFieldType == RTFFormFieldType::LIST)
+ m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_result, pIntValue);
+ break;
+ case RTF_EDMINS:
+ if (m_xDocumentProperties.is())
+ m_xDocumentProperties->setEditingDuration(nParam);
+ break;
+ case RTF_NOFPAGES:
+ case RTF_NOFWORDS:
+ case RTF_NOFCHARS:
+ case RTF_NOFCHARSWS:
+ if (m_xDocumentProperties.is())
+ {
+ comphelper::SequenceAsHashMap aSeq = m_xDocumentProperties->getDocumentStatistics();
+ OUString aName;
+ switch (nKeyword)
+ {
+ case RTF_NOFPAGES:
+ aName = "PageCount";
+ nParam = 99;
+ break;
+ case RTF_NOFWORDS:
+ aName = "WordCount";
+ break;
+ case RTF_NOFCHARS:
+ aName = "CharacterCount";
+ break;
+ case RTF_NOFCHARSWS:
+ aName = "NonWhitespaceCharacterCount";
+ break;
+ default:
+ break;
+ }
+ if (!aName.isEmpty())
+ {
+ aSeq[aName] = uno::makeAny(sal_Int32(nParam));
+ m_xDocumentProperties->setDocumentStatistics(aSeq.getAsConstNamedValueList());
+ }
+ }
+ break;
+ case RTF_VERSION:
+ if (m_xDocumentProperties.is())
+ m_xDocumentProperties->setEditingCycles(nParam);
+ break;
+ case RTF_VERN:
+ // Ignore this for now, later the RTF writer version could be used to add hacks for older buggy writers.
+ break;
+ case RTF_FTNSTART:
+ putNestedSprm(m_aDefaultState.aParagraphSprms,
+ NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
+ break;
+ case RTF_AFTNSTART:
+ putNestedSprm(m_aDefaultState.aParagraphSprms,
+ NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
+ break;
+ case RTF_DFRMTXTX:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hSpace, nParam);
+ break;
+ case RTF_DFRMTXTY:
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vSpace, nParam);
+ break;
+ case RTF_DXFRTEXT:
+ {
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hSpace, nParam);
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vSpace, nParam);
+ }
+ break;
+ case RTF_FLYVERT:
+ {
+ RTFVertOrient aVertOrient(nParam);
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, aVertOrient.GetAlign());
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, aVertOrient.GetAnchor());
+ }
+ break;
+ case RTF_FLYHORZ:
+ {
+ RTFHoriOrient aHoriOrient(nParam);
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, aHoriOrient.GetAlign());
+ m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, aHoriOrient.GetAnchor());
+ }
+ break;
+ case RTF_FLYANCHOR:
+ m_aStates.top().aFrame.m_nAnchorType = nParam;
+ break;
+ case RTF_WMETAFILE:
+ m_aStates.top().aPicture.eWMetafile = nParam;
+ break;
+ case RTF_SB:
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before, pIntValue);
+ break;
+ case RTF_SA:
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after, pIntValue);
+ break;
+ case RTF_DPX:
+ m_aStates.top().aDrawingObject.nLeft = convertTwipToMm100(nParam);
+ break;
+ case RTF_DPY:
+ m_aStates.top().aDrawingObject.nTop = convertTwipToMm100(nParam);
+ break;
+ case RTF_DPXSIZE:
+ m_aStates.top().aDrawingObject.nRight = convertTwipToMm100(nParam);
+ break;
+ case RTF_DPYSIZE:
+ m_aStates.top().aDrawingObject.nBottom = convertTwipToMm100(nParam);
+ break;
+ case RTF_PNSTART:
+ m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_start, pIntValue);
+ break;
+ case RTF_PNF:
+ {
+ auto pValue = std::make_shared<RTFValue>(m_aFontNames[getFontIndex(nParam)]);
+ RTFSprms aAttributes;
+ aAttributes.set(NS_ooxml::LN_CT_Fonts_ascii, pValue);
+ putNestedSprm(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_Lvl_rPr, NS_ooxml::LN_EG_RPrBase_rFonts, std::make_shared<RTFValue>(aAttributes));
+ }
+ break;
+ case RTF_VIEWSCALE:
+ m_aSettingsTableAttributes.set(NS_ooxml::LN_CT_Zoom_percent, pIntValue);
+ break;
+ case RTF_BIN:
+ {
+ m_aStates.top().nInternalState = RTFInternalState::BIN;
+ m_aStates.top().nBinaryToRead = nParam;
+ }
+ break;
+ case RTF_DPLINECOR:
+ m_aStates.top().aDrawingObject.nLineColorR = nParam;
+ m_aStates.top().aDrawingObject.bHasLineColor = true;
+ break;
+ case RTF_DPLINECOG:
+ m_aStates.top().aDrawingObject.nLineColorG = nParam;
+ m_aStates.top().aDrawingObject.bHasLineColor = true;
+ break;
+ case RTF_DPLINECOB:
+ m_aStates.top().aDrawingObject.nLineColorB = nParam;
+ m_aStates.top().aDrawingObject.bHasLineColor = true;
+ break;
+ case RTF_DPFILLBGCR:
+ m_aStates.top().aDrawingObject.nFillColorR = nParam;
+ m_aStates.top().aDrawingObject.bHasFillColor = true;
+ break;
+ case RTF_DPFILLBGCG:
+ m_aStates.top().aDrawingObject.nFillColorG = nParam;
+ m_aStates.top().aDrawingObject.bHasFillColor = true;
+ break;
+ case RTF_DPFILLBGCB:
+ m_aStates.top().aDrawingObject.nFillColorB = nParam;
+ m_aStates.top().aDrawingObject.bHasFillColor = true;
+ break;
+ case RTF_CLSHDNG:
+ {
+ int nValue = -1;
+ switch (nParam)
+ {
+ case 500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct5;
+ break;
+ case 1000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct10;
+ break;
+ case 1200:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct12;
+ break;
+ case 1500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct15;
+ break;
+ case 2000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct20;
+ break;
+ case 2500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct25;
+ break;
+ case 3000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct30;
+ break;
+ case 3500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct35;
+ break;
+ case 3700:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct37;
+ break;
+ case 4000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct40;
+ break;
+ case 4500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct45;
+ break;
+ case 5000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct50;
+ break;
+ case 5500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct55;
+ break;
+ case 6000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct60;
+ break;
+ case 6200:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct62;
+ break;
+ case 6500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct65;
+ break;
+ case 7000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct70;
+ break;
+ case 7500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct75;
+ break;
+ case 8000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct80;
+ break;
+ case 8500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct85;
+ break;
+ case 8700:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct87;
+ break;
+ case 9000:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct90;
+ break;
+ case 9500:
+ nValue = NS_ooxml::LN_Value_ST_Shd_pct95;
+ break;
+ default:
+ break;
+ }
+ if (nValue != -1)
+ putNestedAttribute(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_val, std::make_shared<RTFValue>(nValue));
+ }
+ break;
+ case RTF_DODHGT:
+ m_aStates.top().aDrawingObject.nDhgt = nParam;
+ break;
+ case RTF_DPPOLYCOUNT:
+ if (nParam >= 0)
+ {
+ m_aStates.top().aDrawingObject.nPolyLineCount = nParam;
+ }
+ break;
+ case RTF_DPPTX:
+ {
+ RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
+
+ if (rDrawingObject.aPolyLinePoints.empty())
+ dispatchValue(RTF_DPPOLYCOUNT, 2);
+
+ rDrawingObject.aPolyLinePoints.push_back(awt::Point(convertTwipToMm100(nParam), 0));
+ }
+ break;
+ case RTF_DPPTY:
+ {
+ RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
+ if (!rDrawingObject.aPolyLinePoints.empty())
+ {
+ rDrawingObject.aPolyLinePoints.back().Y = convertTwipToMm100(nParam);
+ rDrawingObject.nPolyLineCount--;
+ if (rDrawingObject.nPolyLineCount == 0)
+ {
+ uno::Sequence< uno::Sequence<awt::Point> >aPointSequenceSequence =
+ {
+ comphelper::containerToSequence(rDrawingObject.aPolyLinePoints)
+ };
+ rDrawingObject.xPropertySet->setPropertyValue("PolyPolygon", uno::Any(aPointSequenceSequence));
+ }
+ }
+ }
+ break;
+ case RTF_SHPFBLWTXT:
+ // Shape is below text -> send it to the background.
+ m_aStates.top().aShape.bInBackground = nParam;
+ break;
+ case RTF_CLPADB:
+ case RTF_CLPADL:
+ case RTF_CLPADR:
+ case RTF_CLPADT:
+ {
+ RTFSprms aAttributes;
+ aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_TblWidth_dxa));
+ aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, std::make_shared<RTFValue>(nParam));
+ // Top and left is swapped, that's what Word does.
+ switch (nKeyword)
+ {
+ case RTF_CLPADB:
+ nSprm = NS_ooxml::LN_CT_TcMar_bottom;
+ break;
+ case RTF_CLPADL:
+ nSprm = NS_ooxml::LN_CT_TcMar_top;
+ break;
+ case RTF_CLPADR:
+ nSprm = NS_ooxml::LN_CT_TcMar_right;
+ break;
+ case RTF_CLPADT:
+ nSprm = NS_ooxml::LN_CT_TcMar_left;
+ break;
+ default:
+ break;
+ }
+ putNestedSprm(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcMar, nSprm, std::make_shared<RTFValue>(aAttributes));
+ }
+ break;
+ case RTF_FI:
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_firstLine, pIntValue);
+ break;
+ case RTF_LI:
+ {
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_left, pIntValue);
+ // It turns out \li should reset the \fi inherited from the stylesheet.
+ // So set the direct formatting to zero, if we don't have such direct formatting yet.
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_firstLine, std::make_shared<RTFValue>(0),
+ RTFOverwrite::NO_IGNORE);
+ }
+ break;
+ case RTF_RI:
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_right, pIntValue);
+ break;
+ case RTF_LIN:
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_start, pIntValue);
+ break;
+ case RTF_RIN:
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_end, pIntValue);
+ break;
+ case RTF_OUTLINELEVEL:
+ m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_outlineLvl, pIntValue);
+ break;
+ case RTF_TRGAPH:
+ // Half of the space between the cells of a table row: default left/right table cell margin.
+ if (nParam > 0)
+ {
+ RTFSprms aAttributes;
+ aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_TblWidth_dxa));
+ aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, pIntValue);
+ putNestedSprm(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left, std::make_shared<RTFValue>(aAttributes));
+ putNestedSprm(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right, std::make_shared<RTFValue>(aAttributes));
+ }
+ break;
+ case RTF_TRFTSWIDTH:
+ putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pIntValue);
+ break;
+ case RTF_TRWWIDTH:
+ putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pIntValue);
+ break;
+ case RTF_PROPTYPE:
+ {
+ switch (nParam)
+ {
+ case 30:
+ m_aStates.top().aPropType = cppu::UnoType<OUString>::get();
+ break;
+ }
+ }
+ break;
+ case RTF_DIBITMAP:
+ m_aStates.top().aPicture.eStyle = RTFBmpStyle::DIBITMAP;
+ break;
+ default:
+ {
+ SAL_INFO("writerfilter", "TODO handle value '" << keywordToString(nKeyword) << "'");
+ aSkip.setParsed(false);
+ }
+ break;
+ }
+ return RTFError::OK;
+}
+
+} // namespace rtftok
+} // namespace writerfilter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 01ad171601c2..33d46ece5c09 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -55,7 +55,7 @@ namespace writerfilter
namespace rtftok
{
-static Id lcl_getParagraphBorder(sal_uInt32 nIndex)
+Id getParagraphBorder(sal_uInt32 nIndex)
{
static const Id aBorderIds[] =
{
@@ -65,8 +65,7 @@ static Id lcl_getParagraphBorder(sal_uInt32 nIndex)
return aBorderIds[nIndex];
}
-static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue,
- RTFOverwrite eOverwrite = RTFOverwrite::YES, bool bAttribute = true)
+void putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue, RTFOverwrite eOverwrite, bool bAttribute)
{
RTFValue::Pointer_t pParent = rSprms.find(nParent, /*bFirst=*/true, /*bForWrite=*/true);
if (!pParent.get())
@@ -86,9 +85,9 @@ static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const R
rAttributes.set(nId, pValue, eOverwrite);
}
-static void lcl_putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue)
+void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue)
{
- lcl_putNestedAttribute(rSprms, nParent, nId, pValue, RTFOverwrite::NO_APPEND, false);
+ putNestedAttribute(rSprms, nParent, nId, pValue, RTFOverwrite::NO_APPEND, false);
}
static RTFValue::Pointer_t lcl_getNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId)
@@ -100,17 +99,17 @@ static RTFValue::Pointer_t lcl_getNestedAttribute(RTFSprms& rSprms, Id nParent,
return rAttributes.find(nId);
}
-static bool lcl_eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId)
+bool eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId)
{
RTFValue::Pointer_t pParent = rSprms.find(nParent);
if (!pParent.get())
- // It doesn't even have a parent, we're done!
+ // It doesn't even have a parent, we're done.
return false;
RTFSprms& rAttributes = pParent->getAttributes();
return rAttributes.erase(nId);
}
-static RTFSprms& lcl_getLastAttributes(RTFSprms& rSprms, Id nId)
+RTFSprms& getLastAttributes(RTFSprms& rSprms, Id nId)
{
RTFValue::Pointer_t p = rSprms.find(nId);
if (p.get() && p->getSprms().size())
@@ -122,14 +121,13 @@ static RTFSprms& lcl_getLastAttributes(RTFSprms& rSprms, Id nId)
}
}
-static void
-lcl_putBorderProperty(RTFStack& aStates, Id nId, const RTFValue::Pointer_t& pValue)
+void putBorderProperty(RTFStack& aStates, Id nId, const RTFValue::Pointer_t& pValue)
{
RTFSprms* pAttributes = nullptr;
if (aStates.top().nBorderState == RTFBorderState::PARAGRAPH_BOX)
for (int i = 0; i < 4; i++)
{
- RTFValue::Pointer_t p = aStates.top().aParagraphSprms.find(lcl_getParagraphBorder(i));
+ RTFValue::Pointer_t p = aStates.top().aParagraphSprms.find(getParagraphBorder(i));
if (p.get())
{
RTFSprms& rAttributes = p->getAttributes();
@@ -147,18 +145,18 @@ lcl_putBorderProperty(RTFStack& aStates, Id nId, const RTFValue::Pointer_t& pVal
}
// Attributes of the last border type
else if (aStates.top().nBorderState == RTFBorderState::PARAGRAPH)
- pAttributes = &lcl_getLastAttributes(aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr);
+ pAttributes = &getLastAttributes(aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr);
else if (aStates.top().nBorderState == RTFBorderState::CELL)
- pAttributes = &lcl_getLastAttributes(aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders);
+ pAttributes = &getLastAttributes(aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders);
else if (aStates.top().nBorderState == RTFBorderState::PAGE)
- pAttributes = &lcl_getLastAttributes(aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders);
+ pAttributes = &getLastAttributes(aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders);
if (pAttributes)
pAttributes->set(nId, pValue);
}
-static OString lcl_DTTM22OString(long lDTTM)
+OString DTTM22OString(long nDTTM)
{
- return DateTimeToOString(msfilter::util::DTTM2DateTime(lDTTM));
+ return DateTimeToOString(msfilter::util::DTTM2DateTime(nDTTM));
}
static RTFSprms lcl_getBookmarkProperties(int nPos, OUString& rString)
@@ -175,7 +173,7 @@ static RTFSprms lcl_getBookmarkProperties(int nPos, OUString& rString)
return aAttributes;
}
-static const char* lcl_RtfToString(RTFKeyword nKeyword)
+const char* keywordToString(RTFKeyword nKeyword)
{
for (int i = 0; i < nRTFControlWords; i++)
{
@@ -390,7 +388,7 @@ void RTFDocumentImpl::checkFirstRun()
RTFValue::Pointer_t pFont = lcl_getNestedAttribute(m_aDefaultState.aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, NS_ooxml::LN_CT_Fonts_ascii);
RTFValue::Pointer_t pCurrentFont = lcl_getNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, NS_ooxml::LN_CT_Fonts_ascii);
if (pFont && !pCurrentFont)
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, NS_ooxml::LN_CT_Fonts_ascii, pFont);
+ putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, NS_ooxml::LN_CT_Fonts_ascii, pFont);
}
}
@@ -578,7 +576,7 @@ void RTFDocumentImpl::parBreak()
Mapper().startParagraphGroup();
}
-void RTFDocumentImpl::sectBreak(bool bFinal = false)
+void RTFDocumentImpl::sectBreak(bool bFinal)
{
SAL_INFO("writerfilter", OSL_THIS_FUNC << ": final? " << bFinal << ", needed? " << m_bNeedSect);
bool bNeedSect = m_bNeedSect;
@@ -1404,9 +1402,9 @@ void RTFDocumentImpl::prepareProperties(
if (!pTableWidthProps.get())
{
auto pUnitValue = std::make_shared<RTFValue>(3);
- lcl_putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pUnitValue);
+ putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pUnitValue);
auto pWValue = std::make_shared<RTFValue>(nCurrentCellX);
- lcl_putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pWValue);
+ putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pWValue);
}
auto pRowValue = std::make_shared<RTFValue>(1);
@@ -1420,8 +1418,8 @@ void RTFDocumentImpl::prepareProperties(
RTFSprms aAttributes;
aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_TblWidth_dxa));
aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, std::make_shared<RTFValue>(0));
- lcl_putNestedSprm(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left, std::make_shared<RTFValue>(aAttributes));
- lcl_putNestedSprm(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right, std::make_shared<RTFValue>(aAttributes));
+ putNestedSprm(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left, std::make_shared<RTFValue>(aAttributes));
+ putNestedSprm(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right, std::make_shared<RTFValue>(aAttributes));
}
o_rpTableRowProperties = std::make_shared<RTFReferenceProperties>(rState.aTableRowAttributes, rState.aTableRowSprms);
@@ -1535,1040 +1533,7 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer,
}
-RTFError RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
-{
- setNeedSect(true);
- checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
- RTFSkipDestination aSkip(*this);
- // special case \upr: ignore everything except nested \ud
- if (Destination::UPR == m_aStates.top().eDestination && RTF_UD != nKeyword)
- {
- m_aStates.top().eDestination = Destination::SKIP;
- aSkip.setParsed(false);
- }
- else
- switch (nKeyword)
- {
- case RTF_RTF:
- break;
- case RTF_FONTTBL:
- m_aStates.top().eDestination = Destination::FONTTABLE;
- break;
- case RTF_COLORTBL:
- m_aStates.top().eDestination = Destination::COLORTABLE;
- break;
- case RTF_STYLESHEET:
- m_aStates.top().eDestination = Destination::STYLESHEET;
- break;
- case RTF_FIELD:
- m_aStates.top().eDestination = Destination::FIELD;
- break;
- case RTF_FLDINST:
- {
- // Look for the field type
- sal_Size nPos = Strm().Tell();
- OStringBuffer aBuf;
- char ch = 0;
- bool bFoundCode = false;
- bool bInKeyword = false;
- while (!bFoundCode && ch != '}')
- {
- Strm().ReadChar(ch);
- if ('\\' == ch)
- bInKeyword = true;
- if (!bInKeyword && isalnum(ch))
- aBuf.append(ch);
- else if (bInKeyword && isspace(ch))
- bInKeyword = false;
- if (!aBuf.isEmpty() && !isalnum(ch))
- bFoundCode = true;
- }
-
- if (aBuf.toString() == "INCLUDEPICTURE")
- {
- // Extract the field argument of INCLUDEPICTURE: we handle that
- // at a tokenizer level, as DOCX has no such field.
- aBuf.append(ch);
- while (true)
- {
- Strm().ReadChar(ch);
- if (ch == '}')
- break;
- aBuf.append(ch);
- }
- OUString aFieldCommand = OStringToOUString(aBuf.toString(), RTL_TEXTENCODING_UTF8);
- std::tuple<OUString, std::vector<OUString>, std::vector<OUString> > aResult = writerfilter::dmapper::splitFieldCommand(aFieldCommand);
- m_aPicturePath = std::get<1>(aResult).empty() ? OUString() : std::get<1>(aResult).front();
- }
-
- Strm().Seek(nPos);
-
- // Form data should be handled only for form fields if any
- if (aBuf.toString().indexOf(OString("FORM")) != -1)
- m_bFormField = true;
-
- singleChar(cFieldStart);
- m_aStates.top().eDestination = Destination::FIELDINSTRUCTION;
- }
- break;
- case RTF_FLDRSLT:
- m_aStates.top().eDestination = Destination::FIELDRESULT;
- break;
- case RTF_LISTTABLE:
- m_aStates.top().eDestination = Destination::LISTTABLE;
- break;
- case RTF_LISTPICTURE:
- m_aStates.top().eDestination = Destination::LISTPICTURE;
- m_aStates.top().bInListpicture = true;
- break;
- case RTF_LIST:
- m_aStates.top().eDestination = Destination::LISTENTRY;
- break;
- case RTF_LISTNAME:
- m_aStates.top().eDestination = Destination::LISTNAME;
- break;
- case RTF_LFOLEVEL:
- m_aStates.top().eDestination = Destination::LFOLEVEL;
- m_aStates.top().aTableSprms.clear();
- break;
- case RTF_LISTOVERRIDETABLE:
- m_aStates.top().eDestination = Destination::LISTOVERRIDETABLE;
- break;
- case RTF_LISTOVERRIDE:
- m_aStates.top().eDestination = Destination::LISTOVERRIDEENTRY;
- break;
- case RTF_LISTLEVEL:
- m_aStates.top().eDestination = Destination::LISTLEVEL;
- break;
- case RTF_LEVELTEXT:
- m_aStates.top().eDestination = Destination::LEVELTEXT;
- break;
- case RTF_LEVELNUMBERS:
- m_aStates.top().eDestination = Destination::LEVELNUMBERS;
- break;
- case RTF_SHPPICT:
- resetFrame();
- m_aStates.top().eDestination = Destination::SHPPICT;
- break;
- case RTF_PICT:
- if (m_aStates.top().eDestination != Destination::SHAPEPROPERTYVALUE)
- m_aStates.top().eDestination = Destination::PICT; // as character
- else
- m_aStates.top().eDestination = Destination::SHAPEPROPERTYVALUEPICT; // anchored inside a shape
- break;
- case RTF_PICPROP:
- m_aStates.top().eDestination = Destination::PICPROP;
- break;
- case RTF_SP:
- m_aStates.top().eDestination = Destination::SHAPEPROPERTY;
- break;
- case RTF_SN:
- m_aStates.top().eDestination = Destination::SHAPEPROPERTYNAME;
- break;
- case RTF_SV:
- m_aStates.top().eDestination = Destination::SHAPEPROPERTYVALUE;
- break;
- case RTF_SHP:
- m_bNeedCrOrig = m_bNeedCr;
- m_aStates.top().eDestination = Destination::SHAPE;
- m_aStates.top().bInShape = true;
- break;
- case RTF_SHPINST:
- m_aStates.top().eDestination = Destination::SHAPEINSTRUCTION;
- break;
- case RTF_NESTTABLEPROPS:
- // do not set any properties of outer table at nested table!
- m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
- m_aStates.top().aTableCellAttributes =
- m_aDefaultState.aTableCellAttributes;
- m_aNestedTableCellsSprms.clear();
- m_aNestedTableCellsAttributes.clear();
- m_nNestedCells = 0;
- m_aStates.top().eDestination = Destination::NESTEDTABLEPROPERTIES;
- break;
- case RTF_HEADER:
- case RTF_FOOTER:
- case RTF_HEADERL:
- case RTF_HEADERR:
- case RTF_HEADERF:
- case RTF_FOOTERL:
- case RTF_FOOTERR:
- case RTF_FOOTERF:
- if (!m_pSuperstream)
- {
- Id nId = 0;
- sal_Size nPos = m_nGroupStartPos - 1;
- switch (nKeyword)
- {
- case RTF_HEADER:
- nId = NS_ooxml::LN_headerr;
- break;
- case RTF_FOOTER:
- nId = NS_ooxml::LN_footerr;
- break;
- case RTF_HEADERL:
- nId = NS_ooxml::LN_headerl;
- break;
- case RTF_HEADERR:
- nId = NS_ooxml::LN_headerr;
- break;
- case RTF_HEADERF:
- nId = NS_ooxml::LN_headerf;
- break;
- case RTF_FOOTERL:
- nId = NS_ooxml::LN_footerl;
- break;
- case RTF_FOOTERR:
- nId = NS_ooxml::LN_footerr;
- break;
- case RTF_FOOTERF:
- nId = NS_ooxml::LN_footerf;
- break;
- default:
- break;
- }
- m_nHeaderFooterPositions.push(std::make_pair(nId, nPos));
- m_aStates.top().eDestination = Destination::SKIP;
- }
- break;
- case RTF_FOOTNOTE:
- checkFirstRun();
- if (!m_pSuperstream)
- {
- Id nId = NS_ooxml::LN_footnote;
-
- // Check if this is an endnote.
- OStringBuffer aBuf;
- char ch;
- sal_Size nCurrent = Strm().Tell();
- for (int i = 0; i < 7; ++i)
- {
- Strm().ReadChar(ch);
- aBuf.append(ch);
- }
- Strm().Seek(nCurrent);
- OString aKeyword = aBuf.makeStringAndClear();
- if (aKeyword.equals("\\ftnalt"))
- nId = NS_ooxml::LN_endnote;
-
- if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
- m_aStates.top().pCurrentBuffer = nullptr;
- bool bCustomMark = false;
- OUString aCustomMark;
- while (m_aSuperBuffer.size())
- {
- Buf_t aTuple = m_aSuperBuffer.front();
- m_aSuperBuffer.pop_front();
- if (std::get<0>(aTuple) == BUFFER_UTEXT)
- {
- aCustomMark = std::get<1>(aTuple)->getString();
- bCustomMark = true;
- }
- }
- m_aStates.top().eDestination = Destination::FOOTNOTE;
- if (bCustomMark)
- Mapper().startCharacterGroup();
- if (!m_aStates.top().pCurrentBuffer)
- resolveSubstream(m_nGroupStartPos - 1, nId, aCustomMark);
- else
- {
- RTFSprms aAttributes;
- aAttributes.set(Id(0), std::make_shared<RTFValue>(m_nGroupStartPos - 1));
- aAttributes.set(Id(1), std::make_shared<RTFValue>(nId));
- aAttributes.set(Id(2), std::make_shared<RTFValue>(aCustomMark));
- m_aStates.top().pCurrentBuffer->push_back(Buf_t(BUFFER_RESOLVESUBSTREAM, std::make_shared<RTFValue>(aAttributes), nullptr));
- }
- if (bCustomMark)
- {
- m_aStates.top().aCharacterAttributes.clear();
- m_aStates.top().aCharacterSprms.clear();
- auto pValue = std::make_shared<RTFValue>(1);
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows, pValue);
- text(aCustomMark);
- Mapper().endCharacterGroup();
- }
- m_aStates.top().eDestination = Destination::SKIP;
- }
- break;
- case RTF_BKMKSTART:
- m_aStates.top().eDestination = Destination::BOOKMARKSTART;
- break;
- case RTF_BKMKEND:
- m_aStates.top().eDestination = Destination::BOOKMARKEND;
- break;
- case RTF_XE:
- m_aStates.top().eDestination = Destination::INDEXENTRY;
- break;
- case RTF_TC:
- case RTF_TCN:
- m_aStates.top().eDestination = Destination::TOCENTRY;
- break;
- case RTF_REVTBL:
- m_aStates.top().eDestination = Destination::REVISIONTABLE;
- break;
- case RTF_ANNOTATION:
- if (!m_pSuperstream)
- {
- resolveSubstream(m_nGroupStartPos - 1, NS_ooxml::LN_annotation);
- m_aStates.top().eDestination = Destination::SKIP;
- }
- else
- {
- // If there is an author set, emit it now.
- if (!m_aAuthor.isEmpty() || !m_aAuthorInitials.isEmpty())
- {
- RTFSprms aAttributes;
- if (!m_aAuthor.isEmpty())
- {
- auto pValue = std::make_shared<RTFValue>(m_aAuthor);
- aAttributes.set(NS_ooxml::LN_CT_TrackChange_author, pValue);
- }
- if (!m_aAuthorInitials.isEmpty())
- {
- auto pValue = std::make_shared<RTFValue>(m_aAuthorInitials);
- aAttributes.set(NS_ooxml::LN_CT_Comment_initials, pValue);
- }
- writerfilter::Reference<Properties>::Pointer_t pProperties = std::make_shared<RTFReferenceProperties>(aAttributes);
- Mapper().props(pProperties);
- }
- }
- break;
- case RTF_SHPTXT:
- case RTF_DPTXBXTEXT:
- {
- bool bPictureFrame = false;
- for (std::size_t i = 0; i < m_aStates.top().aShape.aProperties.size(); ++i)
- {
- std::pair<OUString, OUString>& rProperty = m_aStates.top().aShape.aProperties[i];
- if (rProperty.first == "shapeType" && rProperty.second == OUString::number(ESCHER_ShpInst_PictureFrame))
- {
- bPictureFrame = true;
- break;
- }
- }
- if (bPictureFrame)
- // Skip text on picture frames.
- m_aStates.top().eDestination = Destination::SKIP;
- else
- {
- m_aStates.top().eDestination = Destination::SHAPETEXT;
- checkFirstRun();
- dispatchFlag(RTF_PARD);
- m_bNeedPap = true;
- if (nKeyword == RTF_SHPTXT)
- {
- if (!m_aStates.top().pCurrentBuffer)
- m_pSdrImport->resolve(m_aStates.top().aShape, false, RTFSdrImport::SHAPE);
- else
- {
- auto pValue = std::make_shared<RTFValue>(m_aStates.top().aShape);
- m_aStates.top().pCurrentBuffer->push_back(Buf_t(BUFFER_STARTSHAPE, pValue, nullptr));
- }
- }
- }
- }
- break;
- case RTF_FORMFIELD:
- if (m_aStates.top().eDestination == Destination::FIELDINSTRUCTION)
- m_aStates.top().eDestination = Destination::FORMFIELD;
- break;
- case RTF_FFNAME:
- m_aStates.top().eDestination = Destination::FORMFIELDNAME;
- break;
- case RTF_FFL:
- m_aStates.top().eDestination = Destination::FORMFIELDLIST;
- break;
- case RTF_DATAFIELD:
- m_aStates.top().eDestination = Destination::DATAFIELD;
- break;
- case RTF_INFO:
- m_aStates.top().eDestination = Destination::INFO;
- break;
- case RTF_CREATIM:
- m_aStates.top().eDestination = Destination::CREATIONTIME;
- break;
- case RTF_REVTIM:
- m_aStates.top().eDestination = Destination::REVISIONTIME;
- break;
- case RTF_PRINTIM:
- m_aStates.top().eDestination = Destination::PRINTTIME;
- break;
- case RTF_AUTHOR:
- m_aStates.top().eDestination = Destination::AUTHOR;
- break;
- case RTF_KEYWORDS:
- m_aStates.top().eDestination = Destination::KEYWORDS;
- break;
- case RTF_OPERATOR:
- m_aStates.top().eDestination = Destination::OPERATOR;
- break;
- case RTF_COMPANY:
- m_aStates.top().eDestination = Destination::COMPANY;
- break;
- case RTF_COMMENT:
- m_aStates.top().eDestination = Destination::COMMENT;
- break;
- case RTF_OBJECT:
- {
- // beginning of an OLE Object
- m_aStates.top().eDestination = Destination::OBJECT;
-
- // check if the object is in a special container (e.g. a table)
- if (!m_aStates.top().pCurrentBuffer)
- {
- // the object is in a table or another container.
- // Don't try to treat it as an OLE object (fdo#53594).
- // Use the \result (RTF_RESULT) element of the object instead,
- // the result element contain picture representing the OLE Object.
- m_bObject = true;
- }
- }
- break;
- case RTF_OBJDATA:
- // check if the object is in a special container (e.g. a table)
- if (m_aStates.top().pCurrentBuffer)
- {
- // the object is in a table or another container.
- // Use the \result (RTF_RESULT) element of the object instead,
- // of the \objdata.
- m_aStates.top().eDestination = Destination::SKIP;
- }
- else
- {
- m_aStates.top().eDestination = Destination::OBJDATA;
- }
- break;
- case RTF_OBJCLASS:
- m_aStates.top().eDestination = Destination::OBJCLASS;
- break;
- case RTF_RESULT:
- m_aStates.top().eDestination = Destination::RESULT;
- break;
- case RTF_ATNDATE:
- m_aStates.top().eDestination = Destination::ANNOTATIONDATE;
- break;
- case RTF_ATNAUTHOR:
- m_aStates.top().eDestination = Destination::ANNOTATIONAUTHOR;
- break;
- case RTF_ATNREF:
- m_aStates.top().eDestination = Destination::ANNOTATIONREFERENCE;
- break;
- case RTF_FALT:
- m_aStates.top().eDestination = Destination::FALT;
- break;
- case RTF_FLYMAINCNT:
- m_aStates.top().eDestination = Destination::FLYMAINCONTENT;
- break;
- case RTF_LISTTEXT:
- // Should be ignored by any reader that understands Word 97 through Word 2007 numbering.
- case RTF_NONESTTABLES:
- // This destination should be ignored by readers that support nested tables.
- m_aStates.top().eDestination = Destination::SKIP;
- break;
- case RTF_DO:
- m_aStates.top().eDestination = Destination::DRAWINGOBJECT;
- break;
- case RTF_PN:
- m_aStates.top().eDestination = Destination::PARAGRAPHNUMBERING;
- break;
- case RTF_PNTEXT:
- // This destination should be ignored by readers that support paragraph numbering.
- m_aStates.top().eDestination = Destination::SKIP;
- break;
- case RTF_PNTXTA:
- m_aStates.top().eDestination = Destination::PARAGRAPHNUMBERING_TEXTAFTER;
- break;
- case RTF_PNTXTB:
- m_aStates.top().eDestination = Destination::PARAGRAPHNUMBERING_TEXTBEFORE;
- break;
- case RTF_TITLE:
- m_aStates.top().eDestination = Destination::TITLE;
- break;
- case RTF_SUBJECT:
- m_aStates.top().eDestination = Destination::SUBJECT;
- break;
- case RTF_DOCCOMM:
- m_aStates.top().eDestination = Destination::DOCCOMM;
- break;
- case RTF_ATRFSTART:
- m_aStates.top().eDestination = Destination::ANNOTATIONREFERENCESTART;
- break;
- case RTF_ATRFEND:
- m_aStates.top().eDestination = Destination::ANNOTATIONREFERENCEEND;
- break;
- case RTF_ATNID:
- m_aStates.top().eDestination = Destination::ATNID;
- break;
- case RTF_MMATH:
- case RTF_MOMATHPARA:
- // Nothing to do here (just enter the destination) till RTF_MMATHPR is implemented.
- break;
- case RTF_MR:
- m_aStates.top().eDestination = Destination::MR;
- break;
- case RTF_MCHR:
- m_aStates.top().eDestination = Destination::MCHR;
- break;
- case RTF_MPOS:
- m_aStates.top().eDestination = Destination::MPOS;
- break;
- case RTF_MVERTJC:
- m_aStates.top().eDestination = Destination::MVERTJC;
- break;
- case RTF_MSTRIKEH:
- m_aStates.top().eDestination = Destination::MSTRIKEH;
- break;
- case RTF_MDEGHIDE:
- m_aStates.top().eDestination = Destination::MDEGHIDE;
- break;
- case RTF_MTYPE:
- m_aStates.top().eDestination = Destination::MTYPE;
- break;
- case RTF_MGROW:
- m_aStates.top().eDestination = Destination::MGROW;
- break;
- case RTF_MHIDETOP:
- case RTF_MHIDEBOT:
- case RTF_MHIDELEFT:
- case RTF_MHIDERIGHT:
- // SmOoxmlImport::handleBorderBox will ignore these anyway, so silently ignore for now.
- m_aStates.top().eDestination = Destination::SKIP;
- break;
- case RTF_MSUBHIDE:
- m_aStates.top().eDestination = Destination::MSUBHIDE;
- break;
- case RTF_MSUPHIDE:
- m_aStates.top().eDestination = Destination::MSUPHIDE;
- break;
- case RTF_MBEGCHR:
- m_aStates.top().eDestination = Destination::MBEGCHR;
- break;
- case RTF_MSEPCHR:
- m_aStates.top().eDestination = Destination::MSEPCHR;
- break;
- case RTF_MENDCHR:
- m_aStates.top().eDestination = Destination::MENDCHR;
- break;
- case RTF_UPR:
- m_aStates.top().eDestination = Destination::UPR;
- break;
- case RTF_UD:
- // Anything inside \ud is just normal Unicode content.
- m_aStates.top().eDestination = Destination::NORMAL;
- break;
- case RTF_BACKGROUND:
- m_aStates.top().eDestination = Destination::BACKGROUND;
- m_aStates.top().bInBackground = true;
- break;
- case RTF_SHPGRP:
- {
- RTFLookahead aLookahead(Strm(), m_pTokenizer->getGroupStart());
- if (!aLookahead.hasTable())
- {
- uno::Reference<drawing::XShapes> xGroupShape(m_xModelFactory->createInstance("com.sun.star.drawing.GroupShape"), uno::UNO_QUERY);
- uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier(m_xDstDoc, uno::UNO_QUERY);
- if (xDrawSupplier.is())
- {
- uno::Reference<drawing::XShape> xShape(xGroupShape, uno::UNO_QUERY);
- xDrawSupplier->getDrawPage()->add(xShape);
- }
- m_pSdrImport->pushParent(xGroupShape);
- m_aStates.top().bCreatedShapeGroup = true;
- }
- m_aStates.top().eDestination = Destination::SHAPEGROUP;
- m_aStates.top().bInShapeGroup = true;
- }
- break;
- case RTF_FTNSEP:
- m_aStates.top().eDestination = Destination::FOOTNOTESEPARATOR;
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_FtnEdn_type, std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_FtnEdn_separator));
- break;
- case RTF_USERPROPS:
- // Container of all user-defined properties.
- m_aStates.top().eDestination = Destination::USERPROPS;
- if (m_xDocumentProperties.is())
- // Create a custom document properties to be able to process them later all at once.
- m_xDocumentProperties = document::DocumentProperties::create(m_xContext);
- break;
- case RTF_PROPNAME:
- m_aStates.top().eDestination = Destination::PROPNAME;
- break;
- case RTF_STATICVAL:
- m_aStates.top().eDestination = Destination::STATICVAL;
- break;
- default:
- {
- // Check if it's a math token.
- RTFMathSymbol aSymbol;
- aSymbol.eKeyword = nKeyword;
- if (RTFTokenizer::lookupMathKeyword(aSymbol))
- {
- m_aMathBuffer.appendOpeningTag(aSymbol.nToken);
- m_aStates.top().eDestination = aSymbol.eDestination;
- return RTFError::OK;
- }
-
- SAL_INFO("writerfilter", "TODO handle destination '" << lcl_RtfToString(nKeyword) << "'");
- // Make sure we skip destinations (even without \*) till we don't handle them
- m_aStates.top().eDestination = Destination::SKIP;
- aSkip.setParsed(false);
- }
- break;
- }
-
- // new destination => use new destination text
- m_aStates.top().pDestinationText = &m_aStates.top().aDestinationText;
-
- return RTFError::OK;
-}
-
-RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
-{
- setNeedSect(true);
- if (nKeyword != RTF_HEXCHAR)
- checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
- else
- checkUnicode(/*bUnicode =*/ true, /*bHex =*/ false);
- RTFSkipDestination aSkip(*this);
-
- if (RTF_LINE == nKeyword)
- {
- // very special handling since text() will eat lone '\n'
- singleChar('\n');
- return RTFError::OK;
- }
- // Trivial symbols
- sal_uInt8 cCh = 0;
- switch (nKeyword)
- {
- case RTF_TAB:
- cCh = '\t';
- break;
- case RTF_BACKSLASH:
- cCh = '\\';
- break;
- case RTF_LBRACE:
- cCh = '{';
- break;
- case RTF_RBRACE:
- cCh = '}';
- break;
- case RTF_EMDASH:
- cCh = 151;
- break;
- case RTF_ENDASH:
- cCh = 150;
- break;
- case RTF_BULLET:
- cCh = 149;
- break;
- case RTF_LQUOTE:
- cCh = 145;
- break;
- case RTF_RQUOTE:
- cCh = 146;
- break;
- case RTF_LDBLQUOTE:
- cCh = 147;
- break;
- case RTF_RDBLQUOTE:
- cCh = 148;
- break;
- default:
- break;
- }
- if (cCh > 0)
- {
- OUString aStr(OStringToOUString(OString(cCh), RTL_TEXTENCODING_MS_1252));
- text(aStr);
- return RTFError::OK;
- }
-
- switch (nKeyword)
- {
- case RTF_IGNORE:
- {
- m_bSkipUnknown = true;
- aSkip.setReset(false);
- return RTFError::OK;
- }
- break;
- case RTF_PAR:
- {
- if (m_aStates.top().eDestination == Destination::FOOTNOTESEPARATOR)
- break; // just ignore it - only thing we read in here is CHFTNSEP
- checkFirstRun();
- bool bNeedPap = m_bNeedPap;
- checkNeedPap();
- if (bNeedPap)
- runProps();
- if (!m_aStates.top().pCurrentBuffer)
- {
- parBreak();
- // Not in table? Reset max width.
- if (m_nCellxMax)
- {
- // Was in table, but not anymore -> tblEnd.
- RTFSprms aAttributes;
- RTFSprms aSprms;
- aSprms.set(NS_ooxml::LN_tblEnd, std::make_shared<RTFValue>(1));
- writerfilter::Reference<Properties>::Pointer_t pProperties = std::make_shared<RTFReferenceProperties>(aAttributes, aSprms);
- Mapper().props(pProperties);
- }
- m_nCellxMax = 0;
- }
- else if (m_aStates.top().eDestination != Destination::SHAPETEXT)
- {
- RTFValue::Pointer_t pValue;
- m_aStates.top().pCurrentBuffer->push_back(
- Buf_t(BUFFER_PAR, pValue, nullptr));
- }
- // but don't emit properties yet, since they may change till the first text token arrives
- m_bNeedPap = true;
- if (!m_aStates.top().aFrame.inFrame())
- m_bNeedPar = false;
- m_bNeedFinalPar = false;
- }
- break;
- case RTF_SECT:
- {
- m_bHadSect = true;
- if (m_bIgnoreNextContSectBreak)
- m_bIgnoreNextContSectBreak = false;
- else
- {
- sectBreak();
- if (m_nResetBreakOnSectBreak != RTF_invalid)
- {
- // this should run on _second_ \sect after \page
- dispatchSymbol(m_nResetBreakOnSectBreak); // lazy reset
- m_nResetBreakOnSectBreak = RTF_invalid;
- m_bNeedSect = false; // dispatchSymbol set it
- }
- }
- }
- break;
- case RTF_NOBREAK:
- {
- OUString aStr(SVT_HARD_SPACE);
- text(aStr);
- }
- break;
- case RTF_NOBRKHYPH:
- {
- OUString aStr(SVT_HARD_HYPHEN);
- text(aStr);
- }
- break;
- case RTF_OPTHYPH:
- {
- OUString aStr(SVT_SOFT_HYPHEN);
- text(aStr);
- }
- break;
- case RTF_HEXCHAR:
- m_aStates.top().nInternalState = RTFInternalState::HEX;
- break;
- case RTF_CELL:
- case RTF_NESTCELL:
- {
- checkFirstRun();
- if (m_bNeedPap)
- {
- // There were no runs in the cell, so we need to send paragraph and character properties here.
- auto pPValue = std::make_shared<RTFValue>(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms);
- m_aTableBufferStack.back().push_back(Buf_t(BUFFER_PROPS, pPValue, nullptr));
- auto pCValue = std::make_shared<RTFValue>(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms);
- m_aTableBufferStack.back().push_back(Buf_t(BUFFER_PROPS, pCValue, nullptr));
- }
-
- RTFValue::Pointer_t pValue;
- m_aTableBufferStack.back().push_back(Buf_t(BUFFER_CELLEND, pValue, nullptr));
- m_bNeedPap = true;
- }
- break;
- case RTF_NESTROW:
- {
- std::shared_ptr<TableRowBuffer> const pBuffer(
- new TableRowBuffer(
- m_aTableBufferStack.back(),
- m_aNestedTableCellsSprms,
- m_aNestedTableCellsAttributes,
- m_nNestedCells));
- prepareProperties(m_aStates.top(),
- pBuffer->pParaProperties,
- pBuffer->pFrameProperties,
- pBuffer->pRowProperties,
- m_nNestedCells, m_nNestedCurrentCellX);
-
- assert(m_aStates.top().pCurrentBuffer == &m_aTableBufferStack.back());
- if (m_aTableBufferStack.size() == 1)
- {
- throw io::WrongFormatException(
- "mismatch between \\itap and number of \\nestrow", nullptr);
- }
- // note: there may be several states pointing to table buffer!
- for (std::size_t i = 0; i < m_aStates.size(); ++i)
- {
- if (m_aStates[i].pCurrentBuffer == &m_aTableBufferStack.back())
- {
- m_aStates[i].pCurrentBuffer =
- &m_aTableBufferStack[m_aTableBufferStack.size()-2];
- }
- }
- m_aTableBufferStack.pop_back();
- m_aTableBufferStack.back().push_back(
- Buf_t(BUFFER_NESTROW, RTFValue::Pointer_t(), pBuffer));
-
- m_aNestedTableCellsSprms.clear();
- m_aNestedTableCellsAttributes.clear();
- m_nNestedCells = 0;
- m_bNeedPap = true;
- }
- break;
- case RTF_ROW:
- {
- bool bRestored = false;
- // Ending a row, but no cells defined?
- // See if there was an invalid table row reset, so we can restore cell infos to help invalid documents.
- if (!m_nTopLevelCurrentCellX && m_nBackupTopLevelCurrentCellX)
- {
- restoreTableRowProperties();
- bRestored = true;
- }
-
- // If the right edge of the last cell (row width) is smaller than the width of some other row, mimic WW8TabDesc::CalcDefaults(): resize the last cell
- const int MINLAY = 23; // sw/inc/swtypes.hxx, minimal possible size of frames.
- if ((m_nCellxMax - m_nTopLevelCurrentCellX) >= MINLAY)
- {
- auto pXValueLast = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblGridBase_gridCol, false);
- auto pXValue = std::make_shared<RTFValue>(pXValueLast->getInt() + m_nCellxMax - m_nTopLevelCurrentCellX);
- m_aStates.top().aTableRowSprms.eraseLast(NS_ooxml::LN_CT_TblGridBase_gridCol);
- m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, RTFOverwrite::NO_APPEND);
- m_nTopLevelCurrentCellX = m_nCellxMax;
- }
-
- if (m_nTopLevelCells)
- {
- // Make a backup before we start popping elements
- m_aTableInheritingCellsSprms = m_aTopLevelTableCellsSprms;
- m_aTableInheritingCellsAttributes = m_aTopLevelTableCellsAttributes;
- m_nInheritingCells = m_nTopLevelCells;
- }
- else
- {
- // No table definition? Then inherit from the previous row
- m_aTopLevelTableCellsSprms = m_aTableInheritingCellsSprms;
- m_aTopLevelTableCellsAttributes = m_aTableInheritingCellsAttributes;
- m_nTopLevelCells = m_nInheritingCells;
- }
-
- while (m_aTableBufferStack.size() > 1)
- {
- SAL_WARN("writerfilter.rtf", "dropping extra table buffer");
- // note: there may be several states pointing to table buffer!
- for (std::size_t i = 0; i < m_aStates.size(); ++i)
- {
- if (m_aStates[i].pCurrentBuffer == &m_aTableBufferStack.back())
- {
- m_aStates[i].pCurrentBuffer =
- &m_aTableBufferStack.front();
- }
- }
- m_aTableBufferStack.pop_back();
- }
-
- replayRowBuffer(m_aTableBufferStack.back(),
- m_aTopLevelTableCellsSprms, m_aTopLevelTableCellsAttributes,
- m_nTopLevelCells);
-
- m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
- m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
-
- writerfilter::Reference<Properties>::Pointer_t paraProperties;
- writerfilter::Reference<Properties>::Pointer_t frameProperties;
- writerfilter::Reference<Properties>::Pointer_t rowProperties;
- prepareProperties(m_aStates.top(),
- paraProperties, frameProperties, rowProperties,
- m_nTopLevelCells, m_nTopLevelCurrentCellX);
- sendProperties(paraProperties, frameProperties, rowProperties);
-
- m_bNeedPap = true;
- m_bNeedFinalPar = true;
- m_aTableBufferStack.back().clear();
- m_nTopLevelCells = 0;
-
- if (bRestored)
- // We restored cell definitions, clear these now.
- // This is necessary, as later cell definitions want to overwrite the restored ones.
- resetTableRowProperties();
- }
- break;
- case RTF_COLUMN:
- {
- bool bColumns = false; // If we have multiple columns
- RTFValue::Pointer_t pCols = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_cols);
- if (pCols.get())
- {
- RTFValue::Pointer_t pNum = pCols->getAttributes().find(NS_ooxml::LN_CT_Columns_num);
- if (pNum.get() && pNum->getInt() > 1)
- bColumns = true;
- }
- checkFirstRun();
- if (bColumns)
- {
- sal_uInt8 sBreak[] = { 0xe };
- Mapper().startCharacterGroup();
- Mapper().text(sBreak, 1);
- Mapper().endCharacterGroup();
- }
- else
- dispatchSymbol(RTF_PAGE);
- }
- break;
- case RTF_CHFTN:
- {
- if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
- // Stop buffering, there will be no custom mark for this footnote or endnote.
- m_aStates.top().pCurrentBuffer = nullptr;
- break;
- }
- case RTF_PAGE:
- {
- // Ignore page breaks inside tables.
- if (m_aStates.top().pCurrentBuffer == &m_aTableBufferStack.back())
- break;
-
- // If we're inside a continuous section, we should send a section break, not a page one.
- RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_type);
- // Unless we're on a title page.
- RTFValue::Pointer_t pTitlePg = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_titlePg);
- if (((pBreak.get() && pBreak->getInt() == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous))
- || m_nResetBreakOnSectBreak == RTF_SBKNONE)
- && !(pTitlePg.get() && pTitlePg->getInt()))
- {
- if (m_bWasInFrame)
- {
- dispatchSymbol(RTF_PAR);
- m_bWasInFrame = false;
- }
- sectBreak();
- // note: this will not affect the following section break
- // but the one just pushed
- dispatchFlag(RTF_SBKPAGE);
- if (m_bNeedPar)
- dispatchSymbol(RTF_PAR);
- m_bIgnoreNextContSectBreak = true;
- // arrange to clean up the synthetic RTF_SBKPAGE
- m_nResetBreakOnSectBreak = RTF_SBKNONE;
- }
- else
- {
- checkFirstRun();
- checkNeedPap();
- sal_uInt8 sBreak[] = { 0xc };
- Mapper().text(sBreak, 1);
- if (!m_bNeedPap)
- {
- parBreak();
- m_bNeedPap = true;
- }
- m_bNeedCr = true;
- }
- }
- break;
- case RTF_CHPGN:
- {
- OUString aStr("PAGE");
- singleChar(cFieldStart);
- text(aStr);
- singleChar(cFieldSep, true);
- singleChar(cFieldEnd);
- }
- break;
- case RTF_CHFTNSEP:
- {
- static const sal_Unicode uFtnEdnSep = 0x3;
- Mapper().utext(reinterpret_cast<const sal_uInt8*>(&uFtnEdnSep), 1);
- }
- break;
- default:
- {
- SAL_INFO("writerfilter", "TODO handle symbol '" << lcl_RtfToString(nKeyword) << "'");
- aSkip.setParsed(false);
- }
- break;
- }
- return RTFError::OK;
-}
-
-
-static int lcl_getNumberFormat(int nParam)
-{
- static const int aMap[] =
- {
- NS_ooxml::LN_Value_ST_NumberFormat_decimal,
- NS_ooxml::LN_Value_ST_NumberFormat_upperRoman,
- NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman,
- NS_ooxml::LN_Value_ST_NumberFormat_upperLetter,
- NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter,
- NS_ooxml::LN_Value_ST_NumberFormat_ordinal,
- NS_ooxml::LN_Value_ST_NumberFormat_cardinalText,
- NS_ooxml::LN_Value_ST_NumberFormat_ordinalText,
- NS_ooxml::LN_Value_ST_NumberFormat_none, // Undefined in RTF 1.8 spec.
- NS_ooxml::LN_Value_ST_NumberFormat_none, // Undefined in RTF 1.8 spec.
- NS_ooxml::LN_Value_ST_NumberFormat_ideographDigital,
- NS_ooxml::LN_Value_ST_NumberFormat_japaneseCounting,
- NS_ooxml::LN_Value_ST_NumberFormat_aiueo,
- NS_ooxml::LN_Value_ST_NumberFormat_iroha,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalHalfWidth,
- NS_ooxml::LN_Value_ST_NumberFormat_japaneseLegal,
- NS_ooxml::LN_Value_ST_NumberFormat_japaneseDigitalTenThousand ,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth2,
- NS_ooxml::LN_Value_ST_NumberFormat_aiueoFullWidth,
- NS_ooxml::LN_Value_ST_NumberFormat_irohaFullWidth,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalZero,
- NS_ooxml::LN_Value_ST_NumberFormat_bullet,
- NS_ooxml::LN_Value_ST_NumberFormat_ganada,
- NS_ooxml::LN_Value_ST_NumberFormat_chosung,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedFullstop,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedParen,
- NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese,
- NS_ooxml::LN_Value_ST_NumberFormat_ideographEnclosedCircle,
- NS_ooxml::LN_Value_ST_NumberFormat_ideographTraditional,
- NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiac,
- NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiacTraditional,
- NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCounting,
- NS_ooxml::LN_Value_ST_NumberFormat_ideographLegalTraditional,
- NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCountingThousand,
- NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseDigital,
- NS_ooxml::LN_Value_ST_NumberFormat_chineseCounting,
- NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified,
- NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand,
- NS_ooxml::LN_Value_ST_NumberFormat_decimal,
- NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital,
- NS_ooxml::LN_Value_ST_NumberFormat_koreanCounting,
- NS_ooxml::LN_Value_ST_NumberFormat_koreanLegal,
- NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital2,
- NS_ooxml::LN_Value_ST_NumberFormat_hebrew1,
- NS_ooxml::LN_Value_ST_NumberFormat_arabicAlpha,
- NS_ooxml::LN_Value_ST_NumberFormat_hebrew2,
- NS_ooxml::LN_Value_ST_NumberFormat_arabicAbjad
- };
- const int nLen = SAL_N_ELEMENTS(aMap);
- int nValue = 0;
- if (nParam >= 0 && nParam < nLen)
- nValue = aMap[nParam];
- else // 255 and the other cases.
- nValue = NS_ooxml::LN_Value_ST_NumberFormat_none;
- return nValue;
-}
-
-
-// Checks if rName is contained at least once in rProperties as a key.
-bool lcl_findPropertyName(const std::vector<beans::PropertyValue>& rProperties, const OUString& rName)
+bool findPropertyName(const std::vector<beans::PropertyValue>& rProperties, const OUString& rName)
{
for (std::vector<beans::PropertyValue>::const_iterator it = rProperties.begin(); it != rProperties.end(); ++it)
{
@@ -2606,2302 +1571,6 @@ void RTFDocumentImpl::resetTableRowProperties()
m_nTopLevelCurrentCellX = 0;
}
-RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
-{
- setNeedSect(true);
- checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
- RTFSkipDestination aSkip(*this);
- int nParam = -1;
- int nSprm = -1;
-
- // Underline flags.
- switch (nKeyword)
- {
- case RTF_ULD:
- nSprm = NS_ooxml::LN_Value_ST_Underline_dotted;
- break;
- case RTF_ULW:
- nSprm = NS_ooxml::LN_Value_ST_Underline_words;
- break;
- default:
- break;
- }
- if (nSprm >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nSprm);
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_Underline_val, pValue);
- return RTFError::OK;
- }
-
- // Indentation
- switch (nKeyword)
- {
- case RTF_QC:
- nParam = NS_ooxml::LN_Value_ST_Jc_center;
- break;
- case RTF_QJ:
- nParam = NS_ooxml::LN_Value_ST_Jc_both;
- break;
- case RTF_QL:
- nParam = NS_ooxml::LN_Value_ST_Jc_left;
- break;
- case RTF_QR:
- nParam = NS_ooxml::LN_Value_ST_Jc_right;
- break;
- case RTF_QD:
- nParam = NS_ooxml::LN_Value_ST_Jc_both;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_jc, pValue);
- m_bNeedPap = true;
- return RTFError::OK;
- }
-
- // Font Alignment
- switch (nKeyword)
- {
- case RTF_FAFIXED:
- case RTF_FAAUTO:
- nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_auto;
- break;
- case RTF_FAHANG:
- nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_top;
- break;
- case RTF_FACENTER:
- nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_center;
- break;
- case RTF_FAROMAN:
- nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline;
- break;
- case RTF_FAVAR:
- nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_textAlignment, pValue);
- return RTFError::OK;
- }
-
- // Tab kind.
- switch (nKeyword)
- {
- case RTF_TQR:
- nParam = NS_ooxml::LN_Value_ST_TabJc_right;
- break;
- case RTF_TQC:
- nParam = NS_ooxml::LN_Value_ST_TabJc_center;
- break;
- case RTF_TQDEC:
- nParam = NS_ooxml::LN_Value_ST_TabJc_decimal;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_val, pValue);
- return RTFError::OK;
- }
-
- // Tab lead.
- switch (nKeyword)
- {
- case RTF_TLDOT:
- nParam = NS_ooxml::LN_Value_ST_TabTlc_dot;
- break;
- case RTF_TLMDOT:
- nParam = NS_ooxml::LN_Value_ST_TabTlc_middleDot;
- break;
- case RTF_TLHYPH:
- nParam = NS_ooxml::LN_Value_ST_TabTlc_hyphen;
- break;
- case RTF_TLUL:
- nParam = NS_ooxml::LN_Value_ST_TabTlc_underscore;
- break;
- case RTF_TLTH:
- nParam = NS_ooxml::LN_Value_ST_TabTlc_hyphen;
- break; // thick line is not supported by dmapper, this is just a hack
- case RTF_TLEQ:
- nParam = NS_ooxml::LN_Value_ST_TabTlc_none;
- break; // equal sign isn't, either
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_leader, pValue);
- return RTFError::OK;
- }
-
- // Border types
- {
- switch (nKeyword)
- {
- // brdrhair and brdrs are the same, brdrw will make a difference
- // map to values in ooxml/model.xml resource ST_Border
- case RTF_BRDRHAIR:
- case RTF_BRDRS:
- nParam = NS_ooxml::LN_Value_ST_Border_single;
- break;
- case RTF_BRDRDOT:
- nParam = NS_ooxml::LN_Value_ST_Border_dotted;
- break;
- case RTF_BRDRDASH:
- nParam = NS_ooxml::LN_Value_ST_Border_dashed;
- break;
- case RTF_BRDRDB:
- nParam = NS_ooxml::LN_Value_ST_Border_double;
- break;
- case RTF_BRDRTNTHSG:
- nParam = NS_ooxml::LN_Value_ST_Border_thinThickSmallGap;
- break;
- case RTF_BRDRTNTHMG:
- nParam = NS_ooxml::LN_Value_ST_Border_thinThickMediumGap;
- break;
- case RTF_BRDRTNTHLG:
- nParam = NS_ooxml::LN_Value_ST_Border_thinThickLargeGap;
- break;
- case RTF_BRDRTHTNSG:
- nParam = NS_ooxml::LN_Value_ST_Border_thickThinSmallGap;
- break;
- case RTF_BRDRTHTNMG:
- nParam = NS_ooxml::LN_Value_ST_Border_thickThinMediumGap;
- break;
- case RTF_BRDRTHTNLG:
- nParam = NS_ooxml::LN_Value_ST_Border_thickThinLargeGap;
- break;
- case RTF_BRDREMBOSS:
- nParam = NS_ooxml::LN_Value_ST_Border_threeDEmboss;
- break;
- case RTF_BRDRENGRAVE:
- nParam = NS_ooxml::LN_Value_ST_Border_threeDEngrave;
- break;
- case RTF_BRDROUTSET:
- nParam = NS_ooxml::LN_Value_ST_Border_outset;
- break;
- case RTF_BRDRINSET:
- nParam = NS_ooxml::LN_Value_ST_Border_inset;
- break;
- case RTF_BRDRNONE:
- nParam = NS_ooxml::LN_Value_ST_Border_none;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_val, pValue);
- return RTFError::OK;
- }
- }
-
- // Section breaks
- switch (nKeyword)
- {
- case RTF_SBKNONE:
- nParam = NS_ooxml::LN_Value_ST_SectionMark_continuous;
- break;
- case RTF_SBKCOL:
- nParam = NS_ooxml::LN_Value_ST_SectionMark_nextColumn;
- break;
- case RTF_SBKPAGE:
- nParam = NS_ooxml::LN_Value_ST_SectionMark_nextPage;
- break;
- case RTF_SBKEVEN:
- nParam = NS_ooxml::LN_Value_ST_SectionMark_evenPage;
- break;
- case RTF_SBKODD:
- nParam = NS_ooxml::LN_Value_ST_SectionMark_oddPage;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- if (m_nResetBreakOnSectBreak != RTF_invalid)
- {
- m_nResetBreakOnSectBreak = nKeyword;
- }
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_type, pValue);
- return RTFError::OK;
- }
-
- // Footnote numbering
- switch (nKeyword)
- {
- case RTF_FTNNAR:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal;
- break;
- case RTF_FTNNALC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter;
- break;
- case RTF_FTNNAUC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter;
- break;
- case RTF_FTNNRLC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman;
- break;
- case RTF_FTNNRUC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman;
- break;
- case RTF_FTNNCHI:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt, pValue);
- return RTFError::OK;
- }
-
- // Footnote restart type
- switch (nKeyword)
- {
- case RTF_FTNRSTPG:
- nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage;
- break;
- case RTF_FTNRESTART:
- nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect;
- break;
- case RTF_FTNRSTCONT:
- nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
- return RTFError::OK;
- }
-
- // Endnote numbering
- switch (nKeyword)
- {
- case RTF_AFTNNAR:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal;
- break;
- case RTF_AFTNNALC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter;
- break;
- case RTF_AFTNNAUC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter;
- break;
- case RTF_AFTNNRLC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman;
- break;
- case RTF_AFTNNRUC:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman;
- break;
- case RTF_AFTNNCHI:
- nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_CT_EdnProps_numFmt, pValue);
- return RTFError::OK;
- }
-
- switch (nKeyword)
- {
- case RTF_TRQL:
- nParam = NS_ooxml::LN_Value_ST_Jc_left;
- break;
- case RTF_TRQC:
- nParam = NS_ooxml::LN_Value_ST_Jc_center;
- break;
- case RTF_TRQR:
- nParam = NS_ooxml::LN_Value_ST_Jc_right;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TrPrBase_jc, pValue);
- return RTFError::OK;
- }
-
- // Cell Text Flow
- switch (nKeyword)
- {
- case RTF_CLTXLRTB:
- nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTb;
- break;
- case RTF_CLTXTBRL:
- nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRl;
- break;
- case RTF_CLTXBTLR:
- nParam = NS_ooxml::LN_Value_ST_TextDirection_btLr;
- break;
- case RTF_CLTXLRTBV:
- nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTbV;
- break;
- case RTF_CLTXTBRLV:
- nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRlV;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_textDirection, pValue);
- }
-
- // Trivial paragraph flags
- switch (nKeyword)
- {
- case RTF_KEEP:
- if (m_aStates.top().pCurrentBuffer != &m_aTableBufferStack.back())
- nParam = NS_ooxml::LN_CT_PPrBase_keepLines;
- break;
- case RTF_KEEPN:
- if (m_aStates.top().pCurrentBuffer != &m_aTableBufferStack.back())
- nParam = NS_ooxml::LN_CT_PPrBase_keepNext;
- break;
- case RTF_INTBL:
- {
- m_aStates.top().pCurrentBuffer = &m_aTableBufferStack.back();
- nParam = NS_ooxml::LN_inTbl;
- }
- break;
- case RTF_PAGEBB:
- nParam = NS_ooxml::LN_CT_PPrBase_pageBreakBefore;
- break;
- default:
- break;
- }
- if (nParam >= 0)
- {
- auto pValue = std::make_shared<RTFValue>(1);
- m_aStates.top().aParagraphSprms.erase(NS_ooxml::LN_inTbl);
- m_aStates.top().aParagraphSprms.set(nParam, pValue);
- return RTFError::OK;
- }
-
- switch (nKeyword)
- {
- case RTF_FNIL:
- case RTF_FROMAN:
- case RTF_FSWISS:
- case RTF_FMODERN:
- case RTF_FSCRIPT:
- case RTF_FDECOR:
- case RTF_FTECH:
- case RTF_FBIDI:
- // TODO ooxml:CT_Font_family seems to be ignored by the domain mapper
- break;
- case RTF_ANSI:
- m_aStates.top().nCurrentEncoding = RTL_TEXTENCODING_MS_1252;
- break;
- case RTF_MAC:
- m_aDefaultState.nCurrentEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
- m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
- break;
- case RTF_PC:
- m_aDefaultState.nCurrentEncoding = RTL_TEXTENCODING_IBM_437;
- m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
- break;
- case RTF_PCA:
- m_aDefaultState.nCurrentEncoding = RTL_TEXTENCODING_IBM_850;
- m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
- break;
- case RTF_PLAIN:
- {
- m_aStates.top().aCharacterSprms = getDefaultState().aCharacterSprms;
- m_aStates.top().nCurrentEncoding = getEncoding(getFontIndex(m_nDefaultFontIndex));
- m_aStates.top().aCharacterAttributes = getDefaultState().aCharacterAttributes;
- m_aStates.top().nCurrentCharacterStyleIndex = -1;
- m_aStates.top().isRightToLeft = false;
- m_aStates.top().eRunType = RTFParserState::LOCH;
- }
- break;
- case RTF_PARD:
- if (m_bHadPicture)
- dispatchSymbol(RTF_PAR);
- // \pard is allowed between \cell and \row, but in that case it should not reset the fact that we're inside a table.
- m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms;
- m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes;
-
- if (m_nTopLevelCells == 0 && m_nNestedCells == 0)
- {
- // Reset that we're in a table.
- m_aStates.top().pCurrentBuffer = nullptr;
- }
- else
- {
- // We are still in a table.
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_inTbl, std::make_shared<RTFValue>(1));
- // Ideally getDefaultSPRM() would take care of this, but it would not when we're buffering.
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_tabs, std::make_shared<RTFValue>());
- }
- resetFrame();
-
- // Reset currently selected paragraph style as well.
- // By default the style with index 0 is applied.
- {
- OUString const aName = getStyleName(0);
- if (!aName.isEmpty())
- {
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_pStyle, std::make_shared<RTFValue>(aName));
- m_aStates.top().nCurrentStyleIndex = 0;
- }
- else
- {
- m_aStates.top().nCurrentStyleIndex = -1;
- }
- }
- // Need to send paragraph properties again, if there will be any.
- m_bNeedPap = true;
- break;
- case RTF_SECTD:
- {
- m_aStates.top().aSectionSprms = m_aDefaultState.aSectionSprms;
- m_aStates.top().aSectionAttributes = m_aDefaultState.aSectionAttributes;
- }
- break;
- case RTF_TROWD:
- {
- // Back these up, in case later we still need this info.
- backupTableRowProperties();
- resetTableRowProperties();
- // In case the table definition is in the middle of the row
- // (invalid), make sure table definition is emitted.
- m_bNeedPap = true;
- }
- break;
- case RTF_WIDCTLPAR:
- case RTF_NOWIDCTLPAR:
- {
- auto pValue = std::make_shared<RTFValue>(int(nKeyword == RTF_WIDCTLPAR));
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_widowControl, pValue);
- }
- break;
- case RTF_BOX:
- {
- RTFSprms aAttributes;
- auto pValue = std::make_shared<RTFValue>(aAttributes);
- for (int i = 0; i < 4; i++)
- m_aStates.top().aParagraphSprms.set(lcl_getParagraphBorder(i), pValue);
- m_aStates.top().nBorderState = RTFBorderState::PARAGRAPH_BOX;
- }
- break;
- case RTF_LTRSECT:
- case RTF_RTLSECT:
- {
- auto pValue = std::make_shared<RTFValue>(nKeyword == RTF_LTRSECT ? 0 : 1);
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_EG_SectPrContents_textDirection, pValue);
- }
- break;
- case RTF_LTRPAR:
- case RTF_RTLPAR:
- {
- auto pValue = std::make_shared<RTFValue>(nKeyword == RTF_LTRPAR ? 0 : 1);
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_bidi, pValue);
- }
- break;
- case RTF_LTRROW:
- case RTF_RTLROW:
- m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblPrBase_bidiVisual, std::make_shared<RTFValue>(int(nKeyword == RTF_RTLROW)));
- break;
- case RTF_LTRCH:
- // dmapper does not support this.
- m_aStates.top().isRightToLeft = false;
- break;
- case RTF_RTLCH:
- m_aStates.top().isRightToLeft = true;
- if (m_aDefaultState.nCurrentEncoding == RTL_TEXTENCODING_MS_1255)
- m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
- break;
- case RTF_ULNONE:
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Underline_none);
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_Underline_val, pValue);
- }
- break;
- case RTF_NONSHPPICT:
- case RTF_MMATHPICT: // Picture group used by readers not understanding \moMath group
- m_aStates.top().eDestination = Destination::SKIP;
- break;
- case RTF_CLBRDRT:
- case RTF_CLBRDRL:
- case RTF_CLBRDRB:
- case RTF_CLBRDRR:
- {
- RTFSprms aAttributes;
- RTFSprms aSprms;
- auto pValue = std::make_shared<RTFValue>(aAttributes, aSprms);
- switch (nKeyword)
- {
- case RTF_CLBRDRT:
- nParam = NS_ooxml::LN_CT_TcBorders_top;
- break;
- case RTF_CLBRDRL:
- nParam = NS_ooxml::LN_CT_TcBorders_left;
- break;
- case RTF_CLBRDRB:
- nParam = NS_ooxml::LN_CT_TcBorders_bottom;
- break;
- case RTF_CLBRDRR:
- nParam = NS_ooxml::LN_CT_TcBorders_right;
- break;
- default:
- break;
- }
- lcl_putNestedSprm(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders, nParam, pValue);
- m_aStates.top().nBorderState = RTFBorderState::CELL;
- }
- break;
- case RTF_PGBRDRT:
- case RTF_PGBRDRL:
- case RTF_PGBRDRB:
- case RTF_PGBRDRR:
- {
- RTFSprms aAttributes;
- RTFSprms aSprms;
- auto pValue = std::make_shared<RTFValue>(aAttributes, aSprms);
- switch (nKeyword)
- {
- case RTF_PGBRDRT:
- nParam = NS_ooxml::LN_CT_PageBorders_top;
- break;
- case RTF_PGBRDRL:
- nParam = NS_ooxml::LN_CT_PageBorders_left;
- break;
- case RTF_PGBRDRB:
- nParam = NS_ooxml::LN_CT_PageBorders_bottom;
- break;
- case RTF_PGBRDRR:
- nParam = NS_ooxml::LN_CT_PageBorders_right;
- break;
- default:
- break;
- }
- lcl_putNestedSprm(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders, nParam, pValue);
- m_aStates.top().nBorderState = RTFBorderState::PAGE;
- }
- break;
- case RTF_BRDRT:
- case RTF_BRDRL:
- case RTF_BRDRB:
- case RTF_BRDRR:
- {
- RTFSprms aAttributes;
- RTFSprms aSprms;
- auto pValue = std::make_shared<RTFValue>(aAttributes, aSprms);
- switch (nKeyword)
- {
- case RTF_BRDRT:
- nParam = lcl_getParagraphBorder(0);
- break;
- case RTF_BRDRL:
- nParam = lcl_getParagraphBorder(1);
- break;
- case RTF_BRDRB:
- nParam = lcl_getParagraphBorder(2);
- break;
- case RTF_BRDRR:
- nParam = lcl_getParagraphBorder(3);
- break;
- default:
- break;
- }
- lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr, nParam, pValue);
- m_aStates.top().nBorderState = RTFBorderState::PARAGRAPH;
- }
- break;
- case RTF_CHBRDR:
- {
- RTFSprms aAttributes;
- auto pValue = std::make_shared<RTFValue>(aAttributes);
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_bdr, pValue);
- m_aStates.top().nBorderState = RTFBorderState::CHARACTER;
- }
- break;
- case RTF_CLMGF:
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_restart);
- m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
- }
- break;
- case RTF_CLMRG:
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_continue);
- m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
- }
- break;
- case RTF_CLVMGF:
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_restart);
- m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
- }
- break;
- case RTF_CLVMRG:
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_Merge_continue);
- m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
- }
- break;
- case RTF_CLVERTALT:
- case RTF_CLVERTALC:
- case RTF_CLVERTALB:
- {
- switch (nKeyword)
- {
- case RTF_CLVERTALT:
- nParam = NS_ooxml::LN_Value_ST_VerticalJc_top;
- break;
- case RTF_CLVERTALC:
- nParam = NS_ooxml::LN_Value_ST_VerticalJc_center;
- break;
- case RTF_CLVERTALB:
- nParam = NS_ooxml::LN_Value_ST_VerticalJc_bottom;
- break;
- default:
- break;
- }
- auto pValue = std::make_shared<RTFValue>(nParam);
- m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue);
- }
- break;
- case RTF_TRKEEP:
- {
- auto pValue = std::make_shared<RTFValue>(1);
- m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TrPrBase_cantSplit, pValue);
- }
- break;
- case RTF_SECTUNLOCKED:
- {
- auto pValue = std::make_shared<RTFValue>(int(!nParam));
- m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue);
- }
- break;
- case RTF_PGNBIDIA:
- case RTF_PGNBIDIB:
- // These should be mapped to NS_ooxml::LN_EG_SectPrContents_pgNumType, but dmapper has no API for that at the moment.
- break;
- case RTF_LOCH:
- m_aStates.top().eRunType = RTFParserState::LOCH;
- break;
- case RTF_HICH:
- m_aStates.top().eRunType = RTFParserState::HICH;
- break;
- case RTF_DBCH:
- m_aStates.top().eRunType = RTFParserState::DBCH;
- break;
- case RTF_TITLEPG:
- {
- auto pValue = std::make_shared<RTFValue>(1);
- m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue);
- }
- break;
- case RTF_SUPER:
- {
- if (!m_aStates.top().pCurrentBuffer)
- m_aStates.top().pCurrentBuffer = &m_aSuperBuffer;
-
- auto pValue = std::make_shared<RTFValue>("superscript");
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
- }
- break;
- case RTF_SUB:
- {
- auto pValue = std::make_shared<RTFValue>("subscript");
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
- }
- break;
- case RTF_NOSUPERSUB:
- {
- if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
- {
- replayBuffer(m_aSuperBuffer, nullptr, nullptr);
- m_aStates.top().pCurrentBuffer = nullptr;
- }
- m_aStates.top().aCharacterSprms.erase(NS_ooxml::LN_EG_RPrBase_vertAlign);
- }
- break;
- case RTF_LINEPPAGE:
- case RTF_LINECONT:
- {
- auto pValue = std::make_shared<RTFValue>(nKeyword == RTF_LINEPPAGE ? NS_ooxml::LN_Value_ST_LineNumberRestart_newPage : NS_ooxml::LN_Value_ST_LineNumberRestart_continuous);
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_restart, pValue);
- }
- break;
- case RTF_AENDDOC:
- // Noop, this is the default in Writer.
- break;
- case RTF_AENDNOTES:
- // Noop, Writer does not support having endnotes at the end of section.
- break;
- case RTF_AFTNRSTCONT:
- // Noop, this is the default in Writer.
- break;
- case RTF_AFTNRESTART:
- // Noop, Writer does not support restarting endnotes at each section.
- break;
- case RTF_FTNBJ:
- // Noop, this is the default in Writer.
- break;
- case RTF_ENDDOC:
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_RestartNumber_eachSect);
- lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
- }
- break;
- case RTF_NOLINE:
- lcl_eraseNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance);
- break;
- case RTF_FORMSHADE:
- // Noop, this is the default in Writer.
- break;
- case RTF_PNGBLIP:
- m_aStates.top().aPicture.eStyle = RTFBmpStyle::PNG;
- break;
- case RTF_JPEGBLIP:
- m_aStates.top().aPicture.eStyle = RTFBmpStyle::JPEG;
- break;
- case RTF_POSYT:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_top);
- break;
- case RTF_POSYB:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_bottom);
- break;
- case RTF_POSYC:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_center);
- break;
- case RTF_POSYIN:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_inside);
- break;
- case RTF_POSYOUT:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_outside);
- break;
- case RTF_POSYIL:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_doc_ST_YAlign_inline);
- break;
-
- case RTF_PHMRG:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_doc_ST_HAnchor_margin);
- break;
- case RTF_PVMRG:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_doc_ST_VAnchor_margin);
- break;
- case RTF_PHPG:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_doc_ST_HAnchor_page);
- break;
- case RTF_PVPG:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_doc_ST_VAnchor_page);
- break;
- case RTF_PHCOL:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_doc_ST_HAnchor_text);
- break;
- case RTF_PVPARA:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_doc_ST_VAnchor_text);
- break;
-
- case RTF_POSXC:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_center);
- break;
- case RTF_POSXI:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_inside);
- break;
- case RTF_POSXO:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_outside);
- break;
- case RTF_POSXL:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_left);
- break;
- case RTF_POSXR:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_doc_ST_XAlign_right);
- break;
-
- case RTF_DPLINE:
- case RTF_DPRECT:
- case RTF_DPELLIPSE:
- case RTF_DPTXBX:
- case RTF_DPPOLYLINE:
- case RTF_DPPOLYGON:
- {
- sal_Int32 nType = 0;
- switch (nKeyword)
- {
- case RTF_DPLINE:
- m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.LineShape"), uno::UNO_QUERY);
- break;
- case RTF_DPPOLYLINE:
- // The reason this is not a simple CustomShape is that in the old syntax we have no ViewBox info.
- m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.PolyLineShape"), uno::UNO_QUERY);
- break;
- case RTF_DPPOLYGON:
- m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.PolyPolygonShape"), uno::UNO_QUERY);
- break;
- case RTF_DPRECT:
- m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
- break;
- case RTF_DPELLIPSE:
- nType = ESCHER_ShpInst_Ellipse;
- break;
- case RTF_DPTXBX:
- {
- m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.text.TextFrame"), uno::UNO_QUERY);
- std::vector<beans::PropertyValue> aDefaults = RTFSdrImport::getTextFrameDefaults(false);
- for (std::size_t i = 0; i < aDefaults.size(); ++i)
- {
- if (!lcl_findPropertyName(m_aStates.top().aDrawingObject.aPendingProperties, aDefaults[i].Name))
- m_aStates.top().aDrawingObject.aPendingProperties.push_back(aDefaults[i]);
- }
- checkFirstRun();
- Mapper().startShape(m_aStates.top().aDrawingObject.xShape);
- m_aStates.top().aDrawingObject.bHadShapeText = true;
- }
- break;
- default:
- break;
- }
- if (nType)
- m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.CustomShape"), uno::UNO_QUERY);
- uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier(m_xDstDoc, uno::UNO_QUERY);
- if (xDrawSupplier.is())
- {
- uno::Reference<drawing::XShapes> xShapes(xDrawSupplier->getDrawPage(), uno::UNO_QUERY);
- if (xShapes.is() && nKeyword != RTF_DPTXBX)
- xShapes->add(m_aStates.top().aDrawingObject.xShape);
- }
- if (nType)
- {
- uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
- xDefaulter->createCustomShapeDefaults(OUString::number(nType));
- }
- m_aStates.top().aDrawingObject.xPropertySet.set(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
- std::vector<beans::PropertyValue>& rPendingProperties = m_aStates.top().aDrawingObject.aPendingProperties;
- for (std::vector<beans::PropertyValue>::iterator i = rPendingProperties.begin(); i != rPendingProperties.end(); ++i)
- m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue(i->Name, i->Value);
- m_pSdrImport->resolveDhgt(m_aStates.top().aDrawingObject.xPropertySet, m_aStates.top().aDrawingObject.nDhgt, /*bOldStyle=*/true);
- }
- break;
- case RTF_DOBXMARGIN:
- case RTF_DOBYMARGIN:
- {
- beans::PropertyValue aPropertyValue;
- aPropertyValue.Name = (nKeyword == RTF_DOBXMARGIN ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
- aPropertyValue.Value <<= text::RelOrientation::PAGE_PRINT_AREA;
- m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
- }
- break;
- case RTF_DOBXPAGE:
- case RTF_DOBYPAGE:
- {
- beans::PropertyValue aPropertyValue;
- aPropertyValue.Name = (nKeyword == RTF_DOBXPAGE ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
- aPropertyValue.Value <<= text::RelOrientation::PAGE_FRAME;
- m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
- }
- break;
- case RTF_DOBYPARA:
- {
- beans::PropertyValue aPropertyValue;
- aPropertyValue.Name = "VertOrientRelation";
- aPropertyValue.Value <<= text::RelOrientation::FRAME;
- m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
- }
- break;
- case RTF_CONTEXTUALSPACE:
- {
- auto pValue = std::make_shared<RTFValue>(1);
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_contextualSpacing, pValue);
- }
- break;
- case RTF_LINKSTYLES:
- {
- auto pValue = std::make_shared<RTFValue>(1);
- m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue);
- }
- break;
- case RTF_PNLVLBODY:
- {
- auto pValue = std::make_shared<RTFValue>(2);
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, pValue);
- }
- break;
- case RTF_PNDEC:
- {
- auto pValue = std::make_shared<RTFValue>(0); // decimal, same as \levelnfc0
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_numFmt, pValue);
- }
- break;
- case RTF_PNLVLBLT:
- {
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, std::make_shared<RTFValue>(1));
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_numFmt, std::make_shared<RTFValue>(23)); // bullets, same as \levelnfc23
- }
- break;
- case RTF_LANDSCAPE: // fall through: set the default + current value
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_PageOrientation_landscape);
- lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, pValue);
- }
- case RTF_LNDSCPSXN:
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_PageOrientation_landscape);
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, pValue);
- }
- break;
- case RTF_SHPBXPAGE:
- m_aStates.top().aShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
- m_aStates.top().aShape.nHoriOrientRelationToken = NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page;
- break;
- case RTF_SHPBYPAGE:
- m_aStates.top().aShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
- m_aStates.top().aShape.nVertOrientRelationToken = NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page;
- break;
- case RTF_DPLINEHOLLOW:
- m_aStates.top().aDrawingObject.nFLine = 0;
- break;
- case RTF_DPROUNDR:
- if (m_aStates.top().aDrawingObject.xPropertySet.is())
- // Seems this old syntax has no way to specify a custom radius, and this is the default
- m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue("CornerRadius", uno::makeAny(sal_Int32(83)));
- break;
- case RTF_NOWRAP:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_wrap, NS_ooxml::LN_Value_doc_ST_Wrap_notBeside);
- break;
- case RTF_MNOR:
- m_bMathNor = true;
- break;
- case RTF_REVISIONS:
- m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_trackRevisions, std::make_shared<RTFValue>(1));
- break;
- case RTF_BRDRSH:
- lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_shadow, std::make_shared<RTFValue>(1));
- break;
- case RTF_NOCOLBAL:
- m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_noColumnBalance, std::make_shared<RTFValue>(1));
- break;
- case RTF_MARGMIRROR:
- m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_mirrorMargins, std::make_shared<RTFValue>(1));
- break;
- case RTF_SAUTOUPD:
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Style_autoRedefine, std::make_shared<RTFValue>(1));
- break;
- case RTF_WIDOWCTRL:
- m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_widowControl, std::make_shared<RTFValue>(1));
- break;
- case RTF_LINEBETCOL:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_sep, std::make_shared<RTFValue>(1));
- break;
- case RTF_PGNRESTART:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_start, std::make_shared<RTFValue>(1));
- break;
- case RTF_PGNUCLTR:
- {
- auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_upperLetter);
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
- }
- break;
- case RTF_PGNLCLTR:
- {
- auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter);
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
- }
- break;
- case RTF_PGNUCRM:
- {
- auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_upperRoman);
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
- }
- break;
- case RTF_PGNLCRM:
- {
- auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman);
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
- }
- break;
- case RTF_PGNDEC:
- {
- auto pIntValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_NumberFormat_decimal);
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgNumType, NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
- }
- break;
- default:
- {
- SAL_INFO("writerfilter", "TODO handle flag '" << lcl_RtfToString(nKeyword) << "'");
- aSkip.setParsed(false);
- }
- break;
- }
- return RTFError::OK;
-}
-
-RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
-{
- setNeedSect(true);
- checkUnicode(/*bUnicode =*/ nKeyword != RTF_U, /*bHex =*/ true);
- RTFSkipDestination aSkip(*this);
- int nSprm = 0;
- auto pIntValue = std::make_shared<RTFValue>(nParam);
- // Trivial table sprms.
- switch (nKeyword)
- {
- case RTF_LEVELJC:
- {
- nSprm = NS_ooxml::LN_CT_Lvl_lvlJc;
- int nValue = 0;
- switch (nParam)
- {
- case 0:
- nValue = NS_ooxml::LN_Value_ST_Jc_left;
- break;
- case 1:
- nValue = NS_ooxml::LN_Value_ST_Jc_center;
- break;
- case 2:
- nValue = NS_ooxml::LN_Value_ST_Jc_right;
- break;
- }
- pIntValue = std::make_shared<RTFValue>(nValue);
- break;
- }
- case RTF_LEVELNFC:
- nSprm = NS_ooxml::LN_CT_Lvl_numFmt;
- pIntValue = std::make_shared<RTFValue>(lcl_getNumberFormat(nParam));
- break;
- case RTF_LEVELSTARTAT:
- nSprm = NS_ooxml::LN_CT_Lvl_start;
- break;
- case RTF_LEVELPICTURE:
- nSprm = NS_ooxml::LN_CT_Lvl_lvlPicBulletId;
- break;
- case RTF_SBASEDON:
- nSprm = NS_ooxml::LN_CT_Style_basedOn;
- pIntValue = std::make_shared<RTFValue>(getStyleName(nParam));
- break;
- default:
- break;
- }
- if (nSprm > 0)
- {
- m_aStates.top().aTableSprms.set(nSprm, pIntValue);
- return RTFError::OK;
- }
- // Trivial character sprms.
- switch (nKeyword)
- {
- case RTF_FS:
- case RTF_AFS:
- nSprm = (m_aStates.top().isRightToLeft || m_aStates.top().eRunType == RTFParserState::HICH) ? NS_ooxml::LN_EG_RPrBase_szCs : NS_ooxml::LN_EG_RPrBase_sz;
- break;
- case RTF_ANIMTEXT:
- nSprm = NS_ooxml::LN_EG_RPrBase_effect;
- break;
- case RTF_EXPNDTW:
- nSprm = NS_ooxml::LN_EG_RPrBase_spacing;
- break;
- case RTF_KERNING:
- nSprm = NS_ooxml::LN_EG_RPrBase_kern;
- break;
- case RTF_CHARSCALEX:
- nSprm = NS_ooxml::LN_EG_RPrBase_w;
- break;
- default:
- break;
- }
- if (nSprm > 0)
- {
- m_aStates.top().aCharacterSprms.set(nSprm, pIntValue);
- return RTFError::OK;
- }
- // Trivial character attributes.
- switch (nKeyword)
- {
- case RTF_LANG:
- case RTF_ALANG:
- if (m_aStates.top().isRightToLeft || m_aStates.top().eRunType == RTFParserState::HICH)
- {
- nSprm = NS_ooxml::LN_CT_Language_bidi;
- }
- else if (m_aStates.top().eRunType == RTFParserState::DBCH)
- {
- nSprm = NS_ooxml::LN_CT_Language_eastAsia;
- }
- else
- {
- assert(m_aStates.top().eRunType == RTFParserState::LOCH);
- nSprm = NS_ooxml::LN_CT_Language_val;
- }
- break;
- case RTF_LANGFE: // this one is always CJK apparently
- nSprm = NS_ooxml::LN_CT_Language_eastAsia;
- break;
- default:
- break;
- }
- if (nSprm > 0)
- {
- LanguageTag aTag((LanguageType)nParam);
- auto pValue = std::make_shared<RTFValue>(aTag.getBcp47());
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_lang, nSprm, pValue);
- // Language is a character property, but we should store it at a paragraph level as well for fields.
- if (nKeyword == RTF_LANG && m_bNeedPap)
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_EG_RPrBase_lang, nSprm, pValue);
- return RTFError::OK;
- }
- // Trivial paragraph sprms.
- switch (nKeyword)
- {
- case RTF_ITAP:
- nSprm = NS_ooxml::LN_tblDepth;
- break;
- default:
- break;
- }
- if (nSprm > 0)
- {
- m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
- if (nKeyword == RTF_ITAP && nParam > 0)
- {
- while (m_aTableBufferStack.size() < sal::static_int_cast<std::size_t>(nParam))
- {
- m_aTableBufferStack.push_back(RTFBuffer_t());
- }
- // Invalid tables may omit INTBL after ITAP
- dispatchFlag(RTF_INTBL); // sets newly pushed buffer as current
- assert(m_aStates.top().pCurrentBuffer == &m_aTableBufferStack.back());
- }
- return RTFError::OK;
- }
-
- // Info group.
- switch (nKeyword)
- {
- case RTF_YR:
- {
- m_aStates.top().nYear = nParam;
- nSprm = 1;
- }
- break;
- case RTF_MO:
- {
- m_aStates.top().nMonth = nParam;
- nSprm = 1;
- }
- break;
- case RTF_DY:
- {
- m_aStates.top().nDay = nParam;
- nSprm = 1;
- }
- break;
- case RTF_HR:
- {
- m_aStates.top().nHour = nParam;
- nSprm = 1;
- }
- break;
- case RTF_MIN:
- {
- m_aStates.top().nMinute = nParam;
- nSprm = 1;
- }
- break;
- default:
- break;
- }
- if (nSprm > 0)
- return RTFError::OK;
-
- // Frame size / position.
- Id nId = 0;
- switch (nKeyword)
- {
- case RTF_ABSW:
- nId = NS_ooxml::LN_CT_FramePr_w;
- break;
- case RTF_ABSH:
- nId = NS_ooxml::LN_CT_FramePr_h;
- break;
- case RTF_POSX:
- {
- nId = NS_ooxml::LN_CT_FramePr_x;
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, 0);
- }
- break;
- case RTF_POSY:
- {
- nId = NS_ooxml::LN_CT_FramePr_y;
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, 0);
- }
- break;
- default:
- break;
- }
-
- if (nId > 0)
- {
- m_bNeedPap = true;
- // Don't try to support text frames inside tables for now.
- if (m_aStates.top().pCurrentBuffer != &m_aTableBufferStack.back())
- m_aStates.top().aFrame.setSprm(nId, nParam);
-
- return RTFError::OK;
- }
-
- // Then check for the more complex ones.
- switch (nKeyword)
- {
- case RTF_F:
- case RTF_AF:
- if (m_aStates.top().isRightToLeft || m_aStates.top().eRunType == RTFParserState::HICH)
- {
- nSprm = NS_ooxml::LN_CT_Fonts_cs;
- }
- else if (m_aStates.top().eRunType == RTFParserState::DBCH)
- {
- nSprm = NS_ooxml::LN_CT_Fonts_eastAsia;
- }
- else
- {
- assert(m_aStates.top().eRunType == RTFParserState::LOCH);
- nSprm = NS_ooxml::LN_CT_Fonts_ascii;
- }
- if (m_aStates.top().eDestination == Destination::FONTTABLE || m_aStates.top().eDestination == Destination::FONTENTRY)
- {
- m_aFontIndexes.push_back(nParam);
- m_nCurrentFontIndex = getFontIndex(nParam);
- }
- else if (m_aStates.top().eDestination == Destination::LISTLEVEL)
- {
- RTFSprms aFontAttributes;
- aFontAttributes.set(nSprm, std::make_shared<RTFValue>(m_aFontNames[getFontIndex(nParam)]));
- RTFSprms aRunPropsSprms;
- aRunPropsSprms.set(NS_ooxml::LN_EG_RPrBase_rFonts, std::make_shared<RTFValue>(aFontAttributes));
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_rPr, std::make_shared<RTFValue>(RTFSprms(), aRunPropsSprms), RTFOverwrite::NO_APPEND);
- }
- else
- {
- m_nCurrentFontIndex = getFontIndex(nParam);
- auto pValue = std::make_shared<RTFValue>(getFontName(m_nCurrentFontIndex));
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, nSprm, pValue);
- if (nKeyword == RTF_F)
- m_aStates.top().nCurrentEncoding = getEncoding(m_nCurrentFontIndex);
- }
- break;
- case RTF_RED:
- m_aStates.top().aCurrentColor.nRed = nParam;
- break;
- case RTF_GREEN:
- m_aStates.top().aCurrentColor.nGreen = nParam;
- break;
- case RTF_BLUE:
- m_aStates.top().aCurrentColor.nBlue = nParam;
- break;
- case RTF_FCHARSET:
- {
- // we always send text to the domain mapper in OUString, so no
- // need to send encoding info
- int i;
- for (i = 0; i < nRTFEncodings; i++)
- {
- if (aRTFEncodings[i].charset == nParam)
- break;
- }
- if (i == nRTFEncodings)
- // not found
- return RTFError::OK;
-
- m_nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(aRTFEncodings[i].codepage);
- m_aStates.top().nCurrentEncoding = m_nCurrentEncoding;
- }
- break;
- case RTF_ANSICPG:
- {
- m_aDefaultState.nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
- m_aStates.top().nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
- }
- break;
- case RTF_CPG:
- m_nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
- m_aStates.top().nCurrentEncoding = m_nCurrentEncoding;
- break;
- case RTF_CF:
- {
- RTFSprms aAttributes;
- auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
- aAttributes.set(NS_ooxml::LN_CT_Color_val, pValue);
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_color, std::make_shared<RTFValue>(aAttributes));
- }
- break;
- case RTF_S:
- {
- m_aStates.top().nCurrentStyleIndex = nParam;
-
- if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
- {
- m_nCurrentStyleIndex = nParam;
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_StyleType_paragraph);
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // paragraph style
- }
- else
- {
- OUString aName = getStyleName(nParam);
- if (!aName.isEmpty())
- {
- if (m_aStates.top().eDestination == Destination::LISTLEVEL)
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_pStyle, std::make_shared<RTFValue>(aName));
- else
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_pStyle, std::make_shared<RTFValue>(aName));
-
- }
- }
- }
- break;
- case RTF_CS:
- m_aStates.top().nCurrentCharacterStyleIndex = nParam;
- if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
- {
- m_nCurrentStyleIndex = nParam;
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_StyleType_character);
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // character style
- }
- else
- {
- OUString aName = getStyleName(nParam);
- if (!aName.isEmpty())
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_rStyle, std::make_shared<RTFValue>(aName));
- }
- break;
- case RTF_DS:
- if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
- {
- m_nCurrentStyleIndex = nParam;
- auto pValue = std::make_shared<RTFValue>(0); // TODO no value in enum StyleType?
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // section style
- }
- break;
- case RTF_TS:
- if (m_aStates.top().eDestination == Destination::STYLESHEET || m_aStates.top().eDestination == Destination::STYLEENTRY)
- {
- m_nCurrentStyleIndex = nParam;
- // FIXME the correct value would be NS_ooxml::LN_Value_ST_StyleType_table but maybe table styles mess things up in dmapper, be cautious and disable them for now
- auto pValue = std::make_shared<RTFValue>(0);
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_type, pValue); // table style
- }
- break;
- case RTF_DEFF:
- m_nDefaultFontIndex = nParam;
- break;
- case RTF_DEFLANG:
- case RTF_ADEFLANG:
- {
- LanguageTag aTag((LanguageType)nParam);
- auto pValue = std::make_shared<RTFValue>(aTag.getBcp47());
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, (nKeyword == RTF_DEFLANG ? NS_ooxml::LN_EG_RPrBase_lang : NS_ooxml::LN_CT_Language_bidi), nSprm, pValue);
- }
- break;
- case RTF_CHCBPAT:
- {
- auto pValue = std::make_shared<RTFValue>(nParam ? getColorTable(nParam) : COL_AUTO);
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_EG_RPrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
- }
- break;
- case RTF_CLCBPAT:
- {
- auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
- lcl_putNestedAttribute(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
- }
- break;
- case RTF_CBPAT:
- if (nParam)
- {
- auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
- }
- break;
- case RTF_ULC:
- {
- auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
- m_aStates.top().aCharacterSprms.set(0x6877, pValue);
- }
- break;
- case RTF_HIGHLIGHT:
- {
- auto pValue = std::make_shared<RTFValue>(nParam ? getColorTable(nParam) : COL_AUTO);
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_highlight, pValue);
- }
- break;
- case RTF_UP:
- case RTF_DN:
- {
- auto pValue = std::make_shared<RTFValue>(nParam * (nKeyword == RTF_UP ? 1 : -1));
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_position, pValue);
- }
- break;
- case RTF_HORZVERT:
- {
- auto pValue = std::make_shared<RTFValue>(int(true));
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vert, pValue);
- if (nParam)
- // rotate fits to a single line
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vertCompress, pValue);
- }
- break;
- case RTF_EXPND:
- {
- auto pValue = std::make_shared<RTFValue>(nParam/5);
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_spacing, pValue);
- }
- break;
- case RTF_TWOINONE:
- {
- auto pValue = std::make_shared<RTFValue>(int(true));
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combine, pValue);
- nId = 0;
- switch (nParam)
- {
- case 0:
- nId = NS_ooxml::LN_Value_ST_CombineBrackets_none;
- break;
- case 1:
- nId = NS_ooxml::LN_Value_ST_CombineBrackets_round;
- break;
- case 2:
- nId = NS_ooxml::LN_Value_ST_CombineBrackets_square;
- break;
- case 3:
- nId = NS_ooxml::LN_Value_ST_CombineBrackets_angle;
- break;
- case 4:
- nId = NS_ooxml::LN_Value_ST_CombineBrackets_curly;
- break;
- }
- if (nId > 0)
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combineBrackets, std::make_shared<RTFValue>(nId));
- }
- break;
- case RTF_SL:
- {
- // This is similar to RTF_ABSH, negative value means 'exact', positive means 'at least'.
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast);
- if (nParam < 0)
- {
- pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact);
- pIntValue = std::make_shared<RTFValue>(-nParam);
- }
- m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
- m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_line, pIntValue);
- }
- break;
- case RTF_SLMULT:
- if (nParam > 0)
- {
- auto pValue = std::make_shared<RTFValue>(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto);
- m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
- }
- break;
- case RTF_BRDRW:
- {
- // dmapper expects it in 1/8 pt, we have it in twip - but avoid rounding 1 to 0
- if (nParam > 1)
- nParam = nParam * 2 / 5;
- auto pValue = std::make_shared<RTFValue>(nParam);
- lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_sz, pValue);
- }
- break;
- case RTF_BRDRCF:
- {
- auto pValue = std::make_shared<RTFValue>(getColorTable(nParam));
- lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_color, pValue);
- }
- break;
- case RTF_BRSP:
- {
- // dmapper expects it in points, we have it in twip
- auto pValue = std::make_shared<RTFValue>(nParam / 20);
- lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_space, pValue);
- }
- break;
- case RTF_TX:
- {
- m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_pos, pIntValue);
- auto pValue = std::make_shared<RTFValue>(m_aStates.top().aTabAttributes);
- lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_Tabs_tab, pValue);
- m_aStates.top().aTabAttributes.clear();
- }
- break;
- case RTF_ILVL:
- lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_ooxml::LN_CT_NumPr_ilvl, pIntValue);
- break;
- case RTF_LISTTEMPLATEID:
- // This one is not referenced anywhere, so it's pointless to store it at the moment.
- break;
- case RTF_LISTID:
- {
- if (m_aStates.top().eDestination == Destination::LISTENTRY)
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIntValue);
- else if (m_aStates.top().eDestination == Destination::LISTOVERRIDEENTRY)
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIntValue);
- }
- break;
- case RTF_LS:
- {
- if (m_aStates.top().eDestination == Destination::LISTOVERRIDEENTRY)
- m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, pIntValue);
- else
- lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_NumPr_numId, pIntValue);
- }
- break;
- case RTF_UC:
- if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_INT16))
- m_aStates.top().nUc = nParam;
- break;
- case RTF_U:
- // sal_Unicode is unsigned 16-bit, RTF may represent that as a
- // signed SAL_MIN_INT16..SAL_MAX_INT16 or 0..SAL_MAX_UINT16. The
- // static_cast() will do the right thing.
- if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_UINT16))
- {
- if (m_aStates.top().eDestination == Destination::LEVELNUMBERS)
- {
- if (nParam != ';')
- m_aStates.top().aLevelNumbers.push_back(sal_Int32(nParam));
- }
- else
- m_aUnicodeBuffer.append(static_cast<sal_Unicode>(nParam));
- m_aStates.top().nCharsToSkip = m_aStates.top().nUc;
- }
- break;
- case RTF_LEVELFOLLOW:
- {
- OUString sValue;
- switch (nParam)
- {
- case 0:
- sValue = "tab";
- break;
- case 1:
- sValue = "space";
- break;
- case 2:
- sValue = "nothing";
- break;
- }
- if (!sValue.isEmpty())
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_suff, std::make_shared<RTFValue>(sValue));
- }
- break;
- case RTF_FPRQ:
- {
- sal_Int32 nValue = 0;
- switch (nParam)
- {
- case 0:
- nValue = NS_ooxml::LN_Value_ST_Pitch_default;
- break;
- case 1:
- nValue = NS_ooxml::LN_Value_ST_Pitch_fixed;
- break;
- case 2:
- nValue = NS_ooxml::LN_Value_ST_Pitch_variable;
- break;
- }
- if (nValue)
- {
- RTFSprms aAttributes;
- aAttributes.set(NS_ooxml::LN_CT_Pitch_val, std::make_shared<RTFValue>(nValue));
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Font_pitch, std::make_shared<RTFValue>(aAttributes));
- }
- }
- break;
- case RTF_LISTOVERRIDECOUNT:
- // Ignore this for now, the exporter always emits it with a zero parameter.
- break;
- case RTF_PICSCALEX:
- m_aStates.top().aPicture.nScaleX = nParam;
- break;
- case RTF_PICSCALEY:
- m_aStates.top().aPicture.nScaleY = nParam;
- break;
- case RTF_PICW:
- m_aStates.top().aPicture.nWidth = nParam;
- break;
- case RTF_PICH:
- m_aStates.top().aPicture.nHeight = nParam;
- break;
- case RTF_PICWGOAL:
- m_aStates.top().aPicture.nGoalWidth = convertTwipToMm100(nParam);
- break;
- case RTF_PICHGOAL:
- m_aStates.top().aPicture.nGoalHeight = convertTwipToMm100(nParam);
- break;
- case RTF_PICCROPL:
- m_aStates.top().aPicture.nCropL = convertTwipToMm100(nParam);
- break;
- case RTF_PICCROPR:
- m_aStates.top().aPicture.nCropR = convertTwipToMm100(nParam);
- break;
- case RTF_PICCROPT:
- m_aStates.top().aPicture.nCropT = convertTwipToMm100(nParam);
- break;
- case RTF_PICCROPB:
- m_aStates.top().aPicture.nCropB = convertTwipToMm100(nParam);
- break;
- case RTF_SHPWRK:
- {
- int nValue = 0;
- switch (nParam)
- {
- case 0:
- nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides;
- break;
- case 1:
- nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left;
- break;
- case 2:
- nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right;
- break;
- case 3:
- nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest;
- break;
- default:
- break;
- }
- auto pValue = std::make_shared<RTFValue>(nValue);
- RTFValue::Pointer_t pTight = m_aStates.top().aCharacterSprms.find(NS_ooxml::LN_EG_WrapType_wrapTight);
- if (pTight)
- pTight->getAttributes().set(NS_ooxml::LN_CT_WrapTight_wrapText, pValue);
- else
- m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_WrapSquare_wrapText, pValue);
- }
- break;
- case RTF_SHPWR:
- {
- switch (nParam)
- {
- case 1:
- m_aStates.top().aShape.nWrap = css::text::WrapTextMode_NONE;
- break;
- case 2:
- m_aStates.top().aShape.nWrap = css::text::WrapTextMode_PARALLEL;
- break;
- case 3:
- m_aStates.top().aShape.nWrap = css::text::WrapTextMode_THROUGHT;
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_WrapType_wrapNone, std::make_shared<RTFValue>());
- break;
- case 4:
- m_aStates.top().aShape.nWrap = css::text::WrapTextMode_PARALLEL;
- m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_WrapType_wrapTight, std::make_shared<RTFValue>());
- break;
- case 5:
- m_aStates.top().aShape.nWrap = css::text::WrapTextMode_THROUGHT;
- break;
- }
- }
- break;
- case RTF_CELLX:
- {
- int& rCurrentCellX((Destination::NESTEDTABLEPROPERTIES == m_aStates.top().eDestination) ? m_nNestedCurrentCellX : m_nTopLevelCurrentCellX);
- int nCellX = nParam - rCurrentCellX;
- const int COL_DFLT_WIDTH = 41; // sw/source/filter/inc/wrtswtbl.hxx, minimal possible width of cells.
- if (!nCellX)
- nCellX = COL_DFLT_WIDTH;
-
- // If there is a negative left margin, then the first cellx is relative to that.
- RTFValue::Pointer_t pTblInd = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblInd);
- if (rCurrentCellX == 0 && pTblInd.get())
- {
- RTFValue::Pointer_t pWidth = pTblInd->getAttributes().find(NS_ooxml::LN_CT_TblWidth_w);
- if (pWidth.get() && pWidth->getInt() < 0)
- nCellX = -1 * (pWidth->getInt() - nParam);
- }
-
- rCurrentCellX = nParam;
- auto pXValue = std::make_shared<RTFValue>(nCellX);
- m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, RTFOverwrite::NO_APPEND);
- if (Destination::NESTEDTABLEPROPERTIES == m_aStates.top().eDestination)
- {
- m_nNestedCells++;
- // Push cell properties.
- m_aNestedTableCellsSprms.push_back(
- m_aStates.top().aTableCellSprms);
- m_aNestedTableCellsAttributes.push_back(
- m_aStates.top().aTableCellAttributes);
- }
- else
- {
- m_nTopLevelCells++;
- // Push cell properties.
- m_aTopLevelTableCellsSprms.push_back(
- m_aStates.top().aTableCellSprms);
- m_aTopLevelTableCellsAttributes.push_back(
- m_aStates.top().aTableCellAttributes);
- }
-
- m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
- m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
- // We assume text after a row definition always belongs to the table, to handle text before the real INTBL token
- dispatchFlag(RTF_INTBL);
- if (!m_nCellxMax)
- {
- // Wasn't in table, but now is -> tblStart.
- RTFSprms aAttributes;
- RTFSprms aSprms;
- aSprms.set(NS_ooxml::LN_tblStart, std::make_shared<RTFValue>(1));
- writerfilter::Reference<Properties>::Pointer_t pProperties = std::make_shared<RTFReferenceProperties>(aAttributes, aSprms);
- Mapper().props(pProperties);
- }
- m_nCellxMax = std::max(m_nCellxMax, nParam);
- }
- break;
- case RTF_TRRH:
- {
- OUString hRule("auto");
- if (nParam < 0)
- {
- auto pAbsValue = std::make_shared<RTFValue>(-nParam);
- pIntValue.swap(pAbsValue);
-
- hRule = "exact";
- }
- else if (nParam > 0)
- hRule = "atLeast";
-
- lcl_putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_val, pIntValue);
-
- auto pHRule = std::make_shared<RTFValue>(hRule);
- lcl_putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_hRule, pHRule);
- }
- break;
- case RTF_TRLEFT:
- {
- // the value is in twips
- lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
- NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_type,
- std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_TblWidth_dxa));
- lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
- NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_w,
- std::make_shared<RTFValue>(nParam));
- }
- break;
- case RTF_COLS:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_num, pIntValue);
- break;
- case RTF_COLSX:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_space, pIntValue);
- break;
- case RTF_COLNO:
- lcl_putNestedSprm(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_col, pIntValue);
- break;
- case RTF_COLW:
- case RTF_COLSR:
- {
- RTFSprms& rAttributes = lcl_getLastAttributes(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols);
- rAttributes.set((nKeyword == RTF_COLW ? NS_ooxml::LN_CT_Column_w : NS_ooxml::LN_CT_Column_space), pIntValue);
- }
- break;
- case RTF_PAPERH: // fall through: set the default + current value
- lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue);
- case RTF_PGHSXN:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue);
- break;
- case RTF_PAPERW: // fall through: set the default + current value
- lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue);
- case RTF_PGWSXN:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue);
- break;
- case RTF_MARGL: // fall through: set the default + current value
- lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue);
- case RTF_MARGLSXN:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue);
- break;
- case RTF_MARGR: // fall through: set the default + current value
- lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue);
- case RTF_MARGRSXN:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue);
- break;
- case RTF_MARGT: // fall through: set the default + current value
- lcl_putNestedAttribute(m_aDefaultState.aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue);
- case RTF_MARGTSXN:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue);
- break;
- case RTF_MARGB: // fall through: set the default + current value
- lcl_putNestedAttribute(m_aDefaultState.aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue);
- case RTF_MARGBSXN:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue);
- break;
- case RTF_HEADERY:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_header, pIntValue);
- break;
- case RTF_FOOTERY:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_footer, pIntValue);
- break;
- case RTF_DEFTAB:
- m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_defaultTabStop, pIntValue);
- break;
- case RTF_LINEMOD:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_countBy, pIntValue);
- break;
- case RTF_LINEX:
- if (nParam)
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance, pIntValue);
- break;
- case RTF_LINESTARTS:
- lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
- NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_start, pIntValue);
- break;
- case RTF_REVAUTH:
- case RTF_REVAUTHDEL:
- {
- auto pValue = std::make_shared<RTFValue>(m_aAuthors[nParam]);
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_author, pValue);
- }
- break;
- case RTF_REVDTTM:
- case RTF_REVDTTMDEL:
- {
- OUString aStr(OStringToOUString(lcl_DTTM22OString(nParam), m_aStates.top().nCurrentEncoding));
- auto pValue = std::make_shared<RTFValue>(aStr);
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_date, pValue);
- }
- break;
- case RTF_SHPLEFT:
- m_aStates.top().aShape.nLeft = convertTwipToMm100(nParam);
- break;
- case RTF_SHPTOP:
- m_aStates.top().aShape.nTop = convertTwipToMm100(nParam);
- break;
- case RTF_SHPRIGHT:
- m_aStates.top().aShape.nRight = convertTwipToMm100(nParam);
- break;
- case RTF_SHPBOTTOM:
- m_aStates.top().aShape.nBottom = convertTwipToMm100(nParam);
- break;
- case RTF_SHPZ:
- m_aStates.top().aShape.oZ.reset(nParam);
- break;
- case RTF_FFTYPE:
- switch (nParam)
- {
- case 0:
- m_nFormFieldType = RTFFormFieldType::TEXT;
- break;
- case 1:
- m_nFormFieldType = RTFFormFieldType::CHECKBOX;
- break;
- case 2:
- m_nFormFieldType = RTFFormFieldType::LIST;
- break;
- default:
- m_nFormFieldType = RTFFormFieldType::NONE;
- break;
- }
- break;
- case RTF_FFDEFRES:
- if (m_nFormFieldType == RTFFormFieldType::CHECKBOX)
- m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_default, pIntValue);
- else if (m_nFormFieldType == RTFFormFieldType::LIST)
- m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_default, pIntValue);
- break;
- case RTF_FFRES:
- // 25 means undefined, see [MS-DOC] 2.9.79, FFDataBits.
- if (m_nFormFieldType == RTFFormFieldType::CHECKBOX && nParam != 25)
- m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_checked, pIntValue);
- else if (m_nFormFieldType == RTFFormFieldType::LIST)
- m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_result, pIntValue);
- break;
- case RTF_EDMINS:
- if (m_xDocumentProperties.is())
- m_xDocumentProperties->setEditingDuration(nParam);
- break;
- case RTF_NOFPAGES:
- case RTF_NOFWORDS:
- case RTF_NOFCHARS:
- case RTF_NOFCHARSWS:
- if (m_xDocumentProperties.is())
- {
- comphelper::SequenceAsHashMap aSeq = m_xDocumentProperties->getDocumentStatistics();
- OUString aName;
- switch (nKeyword)
- {
- case RTF_NOFPAGES:
- aName = "PageCount";
- nParam = 99;
- break;
- case RTF_NOFWORDS:
- aName = "WordCount";
- break;
- case RTF_NOFCHARS:
- aName = "CharacterCount";
- break;
- case RTF_NOFCHARSWS:
- aName = "NonWhitespaceCharacterCount";
- break;
- default:
- break;
- }
- if (!aName.isEmpty())
- {
- aSeq[aName] = uno::makeAny(sal_Int32(nParam));
- m_xDocumentProperties->setDocumentStatistics(aSeq.getAsConstNamedValueList());
- }
- }
- break;
- case RTF_VERSION:
- if (m_xDocumentProperties.is())
- m_xDocumentProperties->setEditingCycles(nParam);
- break;
- case RTF_VERN:
- // Ignore this for now, later the RTF writer version could be used to add hacks for older buggy writers.
- break;
- case RTF_FTNSTART:
- lcl_putNestedSprm(m_aDefaultState.aParagraphSprms,
- NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
- break;
- case RTF_AFTNSTART:
- lcl_putNestedSprm(m_aDefaultState.aParagraphSprms,
- NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
- break;
- case RTF_DFRMTXTX:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hSpace, nParam);
- break;
- case RTF_DFRMTXTY:
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vSpace, nParam);
- break;
- case RTF_DXFRTEXT:
- {
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hSpace, nParam);
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vSpace, nParam);
- }
- break;
- case RTF_FLYVERT:
- {
- RTFVertOrient aVertOrient(nParam);
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, aVertOrient.GetAlign());
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, aVertOrient.GetAnchor());
- }
- break;
- case RTF_FLYHORZ:
- {
- RTFHoriOrient aHoriOrient(nParam);
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, aHoriOrient.GetAlign());
- m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, aHoriOrient.GetAnchor());
- }
- break;
- case RTF_FLYANCHOR:
- m_aStates.top().aFrame.m_nAnchorType = nParam;
- break;
- case RTF_WMETAFILE:
- m_aStates.top().aPicture.eWMetafile = nParam;
- break;
- case RTF_SB:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before, pIntValue);
- break;
- case RTF_SA:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after, pIntValue);
- break;
- case RTF_DPX:
- m_aStates.top().aDrawingObject.nLeft = convertTwipToMm100(nParam);
- break;
- case RTF_DPY:
- m_aStates.top().aDrawingObject.nTop = convertTwipToMm100(nParam);
- break;
- case RTF_DPXSIZE:
- m_aStates.top().aDrawingObject.nRight = convertTwipToMm100(nParam);
- break;
- case RTF_DPYSIZE:
- m_aStates.top().aDrawingObject.nBottom = convertTwipToMm100(nParam);
- break;
- case RTF_PNSTART:
- m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_start, pIntValue);
- break;
- case RTF_PNF:
- {
- auto pValue = std::make_shared<RTFValue>(m_aFontNames[getFontIndex(nParam)]);
- RTFSprms aAttributes;
- aAttributes.set(NS_ooxml::LN_CT_Fonts_ascii, pValue);
- lcl_putNestedSprm(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_Lvl_rPr, NS_ooxml::LN_EG_RPrBase_rFonts, std::make_shared<RTFValue>(aAttributes));
- }
- break;
- case RTF_VIEWSCALE:
- m_aSettingsTableAttributes.set(NS_ooxml::LN_CT_Zoom_percent, pIntValue);
- break;
- case RTF_BIN:
- {
- m_aStates.top().nInternalState = RTFInternalState::BIN;
- m_aStates.top().nBinaryToRead = nParam;
- }
- break;
- case RTF_DPLINECOR:
- m_aStates.top().aDrawingObject.nLineColorR = nParam;
- m_aStates.top().aDrawingObject.bHasLineColor = true;
- break;
- case RTF_DPLINECOG:
- m_aStates.top().aDrawingObject.nLineColorG = nParam;
- m_aStates.top().aDrawingObject.bHasLineColor = true;
- break;
- case RTF_DPLINECOB:
- m_aStates.top().aDrawingObject.nLineColorB = nParam;
- m_aStates.top().aDrawingObject.bHasLineColor = true;
- break;
- case RTF_DPFILLBGCR:
- m_aStates.top().aDrawingObject.nFillColorR = nParam;
- m_aStates.top().aDrawingObject.bHasFillColor = true;
- break;
- case RTF_DPFILLBGCG:
- m_aStates.top().aDrawingObject.nFillColorG = nParam;
- m_aStates.top().aDrawingObject.bHasFillColor = true;
- break;
- case RTF_DPFILLBGCB:
- m_aStates.top().aDrawingObject.nFillColorB = nParam;
- m_aStates.top().aDrawingObject.bHasFillColor = true;
- break;
- case RTF_CLSHDNG:
- {
- int nValue = -1;
- switch (nParam)
- {
- case 500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct5;
- break;
- case 1000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct10;
- break;
- case 1200:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct12;
- break;
- case 1500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct15;
- break;
- case 2000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct20;
- break;
- case 2500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct25;
- break;
- case 3000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct30;
- break;
- case 3500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct35;
- break;
- case 3700:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct37;
- break;
- case 4000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct40;
- break;
- case 4500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct45;
- break;
- case 5000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct50;
- break;
- case 5500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct55;
- break;
- case 6000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct60;
- break;
- case 6200:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct62;
- break;
- case 6500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct65;
- break;
- case 7000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct70;
- break;
- case 7500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct75;
- break;
- case 8000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct80;
- break;
- case 8500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct85;
- break;
- case 8700:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct87;
- break;
- case 9000:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct90;
- break;
- case 9500:
- nValue = NS_ooxml::LN_Value_ST_Shd_pct95;
- break;
- default:
- break;
- }
- if (nValue != -1)
- lcl_putNestedAttribute(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_val, std::make_shared<RTFValue>(nValue));
- }
- break;
- case RTF_DODHGT:
- m_aStates.top().aDrawingObject.nDhgt = nParam;
- break;
- case RTF_DPPOLYCOUNT:
- if (nParam >= 0)
- {
- m_aStates.top().aDrawingObject.nPolyLineCount = nParam;
- }
- break;
- case RTF_DPPTX:
- {
- RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
-
- if (rDrawingObject.aPolyLinePoints.empty())
- dispatchValue(RTF_DPPOLYCOUNT, 2);
-
- rDrawingObject.aPolyLinePoints.push_back(awt::Point(convertTwipToMm100(nParam), 0));
- }
- break;
- case RTF_DPPTY:
- {
- RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
- if (!rDrawingObject.aPolyLinePoints.empty())
- {
- rDrawingObject.aPolyLinePoints.back().Y = convertTwipToMm100(nParam);
- rDrawingObject.nPolyLineCount--;
- if (rDrawingObject.nPolyLineCount == 0)
- {
- uno::Sequence< uno::Sequence<awt::Point> >aPointSequenceSequence =
- {
- comphelper::containerToSequence(rDrawingObject.aPolyLinePoints)
- };
- rDrawingObject.xPropertySet->setPropertyValue("PolyPolygon", uno::Any(aPointSequenceSequence));
- }
- }
- }
- break;
- case RTF_SHPFBLWTXT:
- // Shape is below text -> send it to the background.
- m_aStates.top().aShape.bInBackground = nParam;
- break;
- case RTF_CLPADB:
- case RTF_CLPADL:
- case RTF_CLPADR:
- case RTF_CLPADT:
- {
- RTFSprms aAttributes;
- aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_TblWidth_dxa));
- aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, std::make_shared<RTFValue>(nParam));
- // Top and left is swapped, that's what Word does.
- switch (nKeyword)
- {
- case RTF_CLPADB:
- nSprm = NS_ooxml::LN_CT_TcMar_bottom;
- break;
- case RTF_CLPADL:
- nSprm = NS_ooxml::LN_CT_TcMar_top;
- break;
- case RTF_CLPADR:
- nSprm = NS_ooxml::LN_CT_TcMar_right;
- break;
- case RTF_CLPADT:
- nSprm = NS_ooxml::LN_CT_TcMar_left;
- break;
- default:
- break;
- }
- lcl_putNestedSprm(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcMar, nSprm, std::make_shared<RTFValue>(aAttributes));
- }
- break;
- case RTF_FI:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_firstLine, pIntValue);
- break;
- case RTF_LI:
- {
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_left, pIntValue);
- // It turns out \li should reset the \fi inherited from the stylesheet.
- // So set the direct formatting to zero, if we don't have such direct formatting yet.
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_firstLine, std::make_shared<RTFValue>(0),
- RTFOverwrite::NO_IGNORE);
- }
- break;
- case RTF_RI:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_right, pIntValue);
- break;
- case RTF_LIN:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_start, pIntValue);
- break;
- case RTF_RIN:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_end, pIntValue);
- break;
- case RTF_OUTLINELEVEL:
- m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_outlineLvl, pIntValue);
- break;
- case RTF_TRGAPH:
- // Half of the space between the cells of a table row: default left/right table cell margin.
- if (nParam > 0)
- {
- RTFSprms aAttributes;
- aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, std::make_shared<RTFValue>(NS_ooxml::LN_Value_ST_TblWidth_dxa));
- aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, pIntValue);
- lcl_putNestedSprm(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left, std::make_shared<RTFValue>(aAttributes));
- lcl_putNestedSprm(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right, std::make_shared<RTFValue>(aAttributes));
- }
- break;
- case RTF_TRFTSWIDTH:
- lcl_putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pIntValue);
- break;
- case RTF_TRWWIDTH:
- lcl_putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pIntValue);
- break;
- case RTF_PROPTYPE:
- {
- switch (nParam)
- {
- case 30:
- m_aStates.top().aPropType = cppu::UnoType<OUString>::get();
- break;
- }
- }
- break;
- case RTF_DIBITMAP:
- m_aStates.top().aPicture.eStyle = RTFBmpStyle::DIBITMAP;
- break;
- default:
- {
- SAL_INFO("writerfilter", "TODO handle value '" << lcl_RtfToString(nKeyword) << "'");
- aSkip.setParsed(false);
- }
- break;
- }
- return RTFError::OK;
-}
-
RTFError RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam)
{
setNeedSect(true);
@@ -5049,14 +1718,14 @@ RTFError RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int n
case RTF_REVISED:
{
auto pValue = std::make_shared<RTFValue>(nKeyword == RTF_DELETED ? oox::XML_del : oox::XML_ins);
- lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_trackchange, NS_ooxml::LN_token, pValue);
+ putNestedAttribute(m_aStates.top().aCharacterSprms, NS_ooxml::LN_trackchange, NS_ooxml::LN_token, pValue);
}
break;
case RTF_SBAUTO:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_beforeAutospacing, pBoolValue);
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_beforeAutospacing, pBoolValue);
break;
case RTF_SAAUTO:
- lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_afterAutospacing, pBoolValue);
+ putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_afterAutospacing, pBoolValue);
break;
case RTF_FACINGP:
m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_evenAndOddHeaders, pBoolValue);
@@ -5069,7 +1738,7 @@ RTFError RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int n
break;
default:
{
- SAL_INFO("writerfilter", "TODO handle toggle '" << lcl_RtfToString(nKeyword) << "'");
+ SAL_INFO("writerfilter", "TODO handle toggle '" << keywordToString(nKeyword) << "'");
aSkip.setParsed(false);
}
break;
@@ -5224,7 +1893,7 @@ RTFError RTFDocumentImpl::popState()
if (m_nDefaultFontIndex >= 0)
{
auto pValue = std::make_shared<RTFValue>(m_aFontNames[getFontIndex(m_nDefaultFontIndex)]);
- lcl_putNestedAttribute(m_aDefaultState.aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, NS_ooxml::LN_CT_Fonts_ascii, pValue);
+ putNestedAttribute(m_aDefaultState.aCharacterSprms, NS_ooxml::LN_EG_RPrBase_rFonts, NS_ooxml::LN_CT_Fonts_ascii, pValue);
}
}
break;
@@ -5637,7 +2306,7 @@ RTFError RTFDocumentImpl::popState()
{
if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
break; // not for nested group
- OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aStates.top().pDestinationText->makeStringAndClear().toInt32()),
+ OUString aStr(OStringToOUString(DTTM22OString(m_aStates.top().pDestinationText->makeStringAndClear().toInt32()),
aState.nCurrentEncoding));
auto pValue = std::make_shared<RTFValue>(aStr);
RTFSprms aAnnAttributes;
@@ -6158,8 +2827,8 @@ RTFError RTFDocumentImpl::popState()
Mapper().table(NS_ooxml::LN_NUMBERING, pTable);
// Use it
- lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_ooxml::LN_CT_NumPr_ilvl, pIlvlValue);
- lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_NumPr_numId, pIdValue);
+ putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_ooxml::LN_CT_NumPr_ilvl, pIlvlValue);
+ putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_NumPr_numId, pIdValue);
}
}
break;
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 434cab5e3941..662b554db6f5 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -322,6 +322,16 @@ struct RTFStack : public std::deque<RTFParserState>
}
};
+void putBorderProperty(RTFStack& aStates, Id nId, const RTFValue::Pointer_t& pValue);
+void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue);
+Id getParagraphBorder(sal_uInt32 nIndex);
+void putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue, RTFOverwrite eOverwrite = RTFOverwrite::YES, bool bAttribute = true);
+bool eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId);
+/// Checks if rName is contained at least once in rProperties as a key.
+bool findPropertyName(const std::vector<css::beans::PropertyValue>& rProperties, const OUString& rName);
+RTFSprms& getLastAttributes(RTFSprms& rSprms, Id nId);
+OString DTTM22OString(long nDTTM);
+
class RTFTokenizer;
class RTFSdrImport;
@@ -423,7 +433,7 @@ private:
void tableBreak();
writerfilter::Reference<Properties>::Pointer_t getProperties(RTFSprms& rAttributes, RTFSprms& rSprms);
void checkNeedPap();
- void sectBreak(bool bFinal);
+ void sectBreak(bool bFinal = false);
void prepareProperties(
RTFParserState& rState,
writerfilter::Reference<Properties>::Pointer_t&,
diff --git a/writerfilter/source/rtftok/rtffly.hxx b/writerfilter/source/rtftok/rtffly.hxx
index 2c78d28d4b26..14a84b54c5bb 100644
--- a/writerfilter/source/rtftok/rtffly.hxx
+++ b/writerfilter/source/rtftok/rtffly.hxx
@@ -10,6 +10,10 @@
#ifndef INCLUDED_WRITERFILTER_SOURCE_RTFTOK_RTFFLY_HXX
#define INCLUDED_WRITERFILTER_SOURCE_RTFTOK_RTFFLY_HXX
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+
namespace writerfilter
{
namespace rtftok