/* -*- 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 <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <filter/msfilter/escherex.hxx>
#include <ooxml/resourceids.hxx>
#include <sal/log.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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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::RunType::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.
// It should not reset the paragraph style, either, so remember the old paragraph style.
RTFValue::Pointer_t pOldStyle
= m_aStates.top().aParagraphSprms.find(NS_ooxml::LN_CT_PPrBase_pStyle);
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, new RTFValue(1));
if (m_bAfterCellBeforeRow && pOldStyle)
// And we still have the same paragraph style.
m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_pStyle, pOldStyle);
// 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, new RTFValue());
}
resetFrame();
// Reset currently selected paragraph style as well, unless we are in the special "after \cell, before \row" state.
// By default the style with index 0 is applied.
if (!m_bAfterCellBeforeRow)
{
OUString const aName = getStyleName(0);
// But only in case it's not a character style.
if (!aName.isEmpty()
&& getStyleType(0) != NS_ooxml::LN_Value_ST_StyleType_character)
{
m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_pStyle,
new 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 = new 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 = new 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 = new 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 = new 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,
new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new 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 = new RTFValue(nParam);
m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue);
}
break;
case RTF_TRKEEP:
{
auto pValue = new RTFValue(1);
m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TrPrBase_cantSplit, pValue);
}
break;
case RTF_SECTUNLOCKED:
{
auto pValue = new 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::RunType::LOCH;
break;
case RTF_HICH:
m_aStates.top().eRunType = RTFParserState::RunType::HICH;
break;
case RTF_DBCH:
m_aStates.top().eRunType = RTFParserState::RunType::DBCH;
break;
case RTF_TITLEPG:
{
auto pValue = new 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 = new RTFValue("superscript");
m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
}
break;
case RTF_SUB:
{
auto pValue = new 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 = new 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 = new 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 (const auto& rDefault : aDefaults)
{
if (!findPropertyName(m_aStates.top().aDrawingObject.aPendingProperties,
rDefault.Name))
m_aStates.top().aDrawingObject.aPendingProperties.push_back(rDefault);
}
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);
m_aStates.top().aDrawingObject.xPropertySet.set(m_aStates.top().aDrawingObject.xShape,
uno::UNO_QUERY);
if (xDrawSupplier.is())
{
uno::Reference<drawing::XShapes> xShapes(xDrawSupplier->getDrawPage(),
uno::UNO_QUERY);
if (xShapes.is() && nKeyword != RTF_DPTXBX)
{
// set default VertOrient before inserting
m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue(
"VertOrient", uno::makeAny(text::VertOrientation::NONE));
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));
}
std::vector<beans::PropertyValue>& rPendingProperties
= m_aStates.top().aDrawingObject.aPendingProperties;
for (auto& rPendingProperty : rPendingProperties)
m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue(
rPendingProperty.Name, rPendingProperty.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 = new RTFValue(1);
m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_contextualSpacing, pValue);
}
break;
case RTF_LINKSTYLES:
{
auto pValue = new RTFValue(1);
m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue);
}
break;
case RTF_PNLVLBODY:
{
auto pValue = new RTFValue(2);
m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_nsid, pValue);
}
break;
case RTF_PNDEC:
{
auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_decimal);
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, new RTFValue(1));
m_aStates.top().aTableSprms.set(
NS_ooxml::LN_CT_Lvl_numFmt,
new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_bullet));
}
break;
case RTF_LANDSCAPE:
{
auto pValue = new 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);
SAL_FALLTHROUGH; // set the default + current value
}
case RTF_LNDSCPSXN:
{
auto pValue = new 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, new RTFValue(1));
break;
case RTF_BRDRSH:
putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_shadow, new RTFValue(1));
break;
case RTF_NOCOLBAL:
m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_noColumnBalance, new RTFValue(1));
break;
case RTF_MARGMIRROR:
m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_mirrorMargins, new RTFValue(1));
break;
case RTF_SAUTOUPD:
m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Style_autoRedefine, new RTFValue(1));
break;
case RTF_WIDOWCTRL:
m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_widowControl, new RTFValue(1));
break;
case RTF_LINEBETCOL:
putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols,
NS_ooxml::LN_CT_Columns_sep, new RTFValue(1));
break;
case RTF_PGNRESTART:
putNestedAttribute(m_aStates.top().aSectionSprms,
NS_ooxml::LN_EG_SectPrContents_pgNumType,
NS_ooxml::LN_CT_PageNumber_start, new RTFValue(1));
break;
case RTF_PGNUCLTR:
{
auto pIntValue = new 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 = new 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 = new 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 = new 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 = new 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;
case RTF_HTMAUTSP:
m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_doNotUseHTMLParagraphAutoSpacing,
new RTFValue(0));
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: */
↑ V547 Expression '!nParam' is always false.