summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@frugalware.org>2011-06-29 12:57:53 +0200
committerMiklos Vajna <vmiklos@frugalware.org>2011-06-29 17:01:21 +0200
commitfbdc98489973a33af4ef3f6ae072abe51716c564 (patch)
tree1c86305fc6eb261375fdc36b787d848efc405fbb
parentd68c6b5414e2c0bd9efa81f6a280da74c241c56a (diff)
RTF_FOOTNOTE: support custom marks
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx197
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx14
2 files changed, 159 insertions, 52 deletions
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 76d13bf97607..53933f00c3e8 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -150,6 +150,9 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
m_xStorage(),
m_aTableBuffer(),
m_bTable(false),
+ m_aSuperBuffer(),
+ m_bSuper(false),
+ m_bHasFootnote(false),
m_bIsSubstream(false),
m_nHeaderFooterPositions(),
m_nGroupStartPos(0)
@@ -184,12 +187,23 @@ void RTFDocumentImpl::setSubstream(bool bIsSubtream)
m_bIsSubstream = bIsSubtream;
}
-void RTFDocumentImpl::resolveSubstream(sal_uInt32& nPos, Id nId)
+void RTFDocumentImpl::setIgnoreFirst(OUString& rIgnoreFirst)
+{
+ m_aIgnoreFirst = rIgnoreFirst;
+}
+
+void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId)
+{
+ OUString aStr;
+ resolveSubstream(nPos, nId, aStr);
+}
+void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId, OUString& rIgnoreFirst)
{
sal_uInt32 nCurrent = Strm().Tell();
// Seek to header position, parse, then seek back.
RTFDocumentImpl::Pointer_t pImpl(new RTFDocumentImpl(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame));
pImpl->setSubstream(true);
+ pImpl->setIgnoreFirst(rIgnoreFirst);
pImpl->seek(nPos);
OSL_TRACE("substream start");
Mapper().substream(nId, pImpl);
@@ -484,6 +498,11 @@ void RTFDocumentImpl::text(OUString& rString)
m_aStates.top().aLevelText.append(rString);
return;
}
+ if (m_aIgnoreFirst.getLength() && m_aIgnoreFirst.equals(rString))
+ {
+ m_aIgnoreFirst = OUString();
+ return;
+ }
writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
new RTFReferenceProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
@@ -507,12 +526,15 @@ void RTFDocumentImpl::text(OUString& rString)
}
if (m_bNeedPap)
{
- if (!m_bTable)
+ if (!m_bTable && !m_bSuper)
Mapper().props(pParagraphProperties);
else
{
RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
- m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pValue));
+ if (m_bTable)
+ m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pValue));
+ else
+ m_aSuperBuffer.push_back(make_pair(BUFFER_PROPS, pValue));
}
m_bNeedPap = false;
}
@@ -524,16 +546,19 @@ void RTFDocumentImpl::text(OUString& rString)
Mapper().text(sFieldStart, 1);
Mapper().endCharacterGroup();
}
- if (!m_bTable)
+ if (!m_bTable && !m_bSuper && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
Mapper().startCharacterGroup();
else
{
RTFValue::Pointer_t pValue;
- m_aTableBuffer.push_back(make_pair(BUFFER_STARTRUN, pValue));
+ if (m_bTable)
+ m_aTableBuffer.push_back(make_pair(BUFFER_STARTRUN, pValue));
+ else
+ m_aSuperBuffer.push_back(make_pair(BUFFER_STARTRUN, pValue));
}
if (m_aStates.top().nDestinationState == DESTINATION_NORMAL || m_aStates.top().nDestinationState == DESTINATION_FIELDRESULT)
{
- if (!m_bTable)
+ if (!m_bTable && !m_bSuper)
{
writerfilter::Reference<Properties>::Pointer_t const pProperties(
new RTFReferenceProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms)
@@ -543,22 +568,40 @@ void RTFDocumentImpl::text(OUString& rString)
else
{
RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms));
- m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pValue));
+ if (m_bTable)
+ m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pValue));
+ else
+ m_aSuperBuffer.push_back(make_pair(BUFFER_PROPS, pValue));
}
}
- if (!m_bTable)
+ if (!m_bTable && !m_bSuper)
+ {
+ OSL_TRACE("not table or super");
Mapper().utext(reinterpret_cast<sal_uInt8 const*>(rString.getStr()), rString.getLength());
+ }
else
{
RTFValue::Pointer_t pValue(new RTFValue(rString));
- m_aTableBuffer.push_back(make_pair(BUFFER_UTEXT, pValue));
+ if (m_bTable)
+ {
+ OSL_TRACE("table");
+ m_aTableBuffer.push_back(make_pair(BUFFER_UTEXT, pValue));
+ }
+ else
+ {
+ OSL_TRACE("pushing utext to super buffer");
+ m_aSuperBuffer.push_back(make_pair(BUFFER_UTEXT, pValue));
+ }
}
- if (!m_bTable)
+ if (!m_bTable && !m_bSuper && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
Mapper().endCharacterGroup();
else
{
RTFValue::Pointer_t pValue;
- m_aTableBuffer.push_back(make_pair(BUFFER_ENDRUN, pValue));
+ if (m_bTable)
+ m_aTableBuffer.push_back(make_pair(BUFFER_ENDRUN, pValue));
+ else
+ m_aSuperBuffer.push_back(make_pair(BUFFER_ENDRUN, pValue));
}
if (m_aStates.top().nDestinationState == DESTINATION_FIELDINSTRUCTION)
{
@@ -569,6 +612,47 @@ void RTFDocumentImpl::text(OUString& rString)
}
}
+void RTFDocumentImpl::replayBuffer(std::deque<std::pair<RTFBufferTypes, RTFValue::Pointer_t>>& rBuffer)
+{
+ while (rBuffer.size())
+ {
+ std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = rBuffer.front();
+ rBuffer.pop_front();
+ if (aPair.first == BUFFER_PROPS)
+ {
+ writerfilter::Reference<Properties>::Pointer_t const pProp(
+ new RTFReferenceProperties(aPair.second->getAttributes(), aPair.second->getSprms())
+ );
+ Mapper().props(pProp);
+ }
+ else if (aPair.first == BUFFER_CELLEND)
+ {
+ RTFValue::Pointer_t pValue(new RTFValue(1));
+ m_aStates.top().aTableCellSprms.push_back(make_pair(NS_sprm::LN_PCell, pValue));
+ writerfilter::Reference<Properties>::Pointer_t const pTableCellProperties(
+ new RTFReferenceProperties(m_aStates.top().aTableCellAttributes, m_aStates.top().aTableCellSprms)
+ );
+ Mapper().props(pTableCellProperties);
+ lcl_TableBreak(Mapper());
+ break;
+ }
+ else if (aPair.first == BUFFER_STARTRUN)
+ Mapper().startCharacterGroup();
+ else if (aPair.first == BUFFER_UTEXT)
+ {
+ OUString aString(aPair.second->getString());
+ Mapper().utext(reinterpret_cast<sal_uInt8 const*>(aString.getStr()), aString.getLength());
+ }
+ else if (aPair.first == BUFFER_ENDRUN)
+ Mapper().endCharacterGroup();
+ else if (aPair.first == BUFFER_PAR)
+ parBreak();
+ else
+ OSL_FAIL("should not happen");
+ }
+
+}
+
int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
{
bool bParsed = true;
@@ -676,7 +760,33 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
case RTF_FOOTNOTE:
if (!m_bIsSubstream)
{
- resolveSubstream(m_nGroupStartPos - 1, NS_rtf::LN_footnote);
+ m_bHasFootnote = true;
+ m_bSuper = false;
+ bool bCustomMark = false;
+ OUString aCustomMark;
+ while (m_aSuperBuffer.size())
+ {
+ std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = m_aSuperBuffer.front();
+ m_aSuperBuffer.pop_front();
+ if (aPair.first == BUFFER_UTEXT)
+ {
+ aCustomMark = aPair.second->getString();
+ bCustomMark = true;
+ }
+ }
+ m_aStates.top().nDestinationState = DESTINATION_FOOTNOTE;
+ if (bCustomMark)
+ Mapper().startCharacterGroup();
+ resolveSubstream(m_nGroupStartPos - 1, NS_rtf::LN_footnote, aCustomMark);
+ if (bCustomMark)
+ {
+ m_aStates.top().aCharacterAttributes.clear();
+ m_aStates.top().aCharacterSprms.clear();
+ RTFValue::Pointer_t pValue(new RTFValue(1));
+ m_aStates.top().aCharacterAttributes.push_back(make_pair(NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows, pValue));
+ text(aCustomMark);
+ Mapper().endCharacterGroup();
+ }
m_aStates.top().nDestinationState = DESTINATION_SKIP;
}
break;
@@ -825,6 +935,9 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
Mapper().endCharacterGroup();
}
break;
+ case RTF_CHFTN:
+ // Nothing to do, dmapper assumes this is the default.
+ break;
default:
OSL_TRACE("%s: TODO handle symbol '%s'", OSL_THIS_FUNC, m_pCurrentKeyword->getStr());
bParsed = false;
@@ -1146,6 +1259,21 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
m_aStates.top().aSectionSprms.push_back(make_pair(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue));
}
break;
+ case RTF_SUPER:
+ {
+ m_bSuper = true;
+ OUString aValue(RTL_CONSTASCII_USTRINGPARAM("superscript"));
+ RTFValue::Pointer_t pValue(new RTFValue(aValue));
+ m_aStates.top().aCharacterSprms.push_back(make_pair(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue));
+ }
+ break;
+ case RTF_SUB:
+ {
+ OUString aValue(RTL_CONSTASCII_USTRINGPARAM("subscript"));
+ RTFValue::Pointer_t pValue(new RTFValue(aValue));
+ m_aStates.top().aCharacterSprms.push_back(make_pair(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue));
+ }
+ break;
default:
OSL_TRACE("%s: TODO handle flag '%s'", OSL_THIS_FUNC, m_pCurrentKeyword->getStr());
bParsed = false;
@@ -1355,7 +1483,6 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
m_aStates.top().aCharacterSprms.push_back(make_pair(0x6877, pValue));
}
break;
- case RTF_SUPER:
case RTF_UP: // TODO handle when point size is not shrinking
{
OUString aValue(RTL_CONSTASCII_USTRINGPARAM("superscript"));
@@ -1363,7 +1490,6 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
m_aStates.top().aCharacterSprms.push_back(make_pair(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue));
}
break;
- case RTF_SUB:
case RTF_DN:
{
OUString aValue(RTL_CONSTASCII_USTRINGPARAM("subscript"));
@@ -1496,42 +1622,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
RTFValue::Pointer_t pXValue(new RTFValue(nCellX));
m_aStates.top().aTableRowSprms.push_back(make_pair(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue));
- while (m_aTableBuffer.size())
- {
- std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = m_aTableBuffer.front();
- m_aTableBuffer.pop_front();
- if (aPair.first == BUFFER_PROPS)
- {
- writerfilter::Reference<Properties>::Pointer_t const pProp(
- new RTFReferenceProperties(aPair.second->getAttributes(), aPair.second->getSprms())
- );
- Mapper().props(pProp);
- }
- else if (aPair.first == BUFFER_CELLEND)
- {
- RTFValue::Pointer_t pValue(new RTFValue(1));
- m_aStates.top().aTableCellSprms.push_back(make_pair(NS_sprm::LN_PCell, pValue));
- writerfilter::Reference<Properties>::Pointer_t const pTableCellProperties(
- new RTFReferenceProperties(m_aStates.top().aTableCellAttributes, m_aStates.top().aTableCellSprms)
- );
- Mapper().props(pTableCellProperties);
- lcl_TableBreak(Mapper());
- break;
- }
- else if (aPair.first == BUFFER_STARTRUN)
- Mapper().startCharacterGroup();
- else if (aPair.first == BUFFER_UTEXT)
- {
- OUString aString(aPair.second->getString());
- Mapper().utext(reinterpret_cast<sal_uInt8 const*>(aString.getStr()), aString.getLength());
- }
- else if (aPair.first == BUFFER_ENDRUN)
- Mapper().endCharacterGroup();
- else if (aPair.first == BUFFER_PAR)
- parBreak();
- else
- OSL_FAIL("should not happen");
- }
+ replayBuffer(m_aTableBuffer);
// Reset cell properties.
RTFSprms::Pointer_t pTableCellSprms(new RTFSprms_t(m_aStates.top().aTableCellSprms));
@@ -2079,6 +2170,12 @@ int RTFDocumentImpl::popState()
m_aStates.top().aShapeProperties = aShapeProperties;
else if (bPicPropEnd)
resolveShapeProperties(aShapeProperties);
+ if (m_bSuper)
+ {
+ if (!m_bHasFootnote)
+ replayBuffer(m_aSuperBuffer);
+ m_bSuper = m_bHasFootnote = false;
+ }
return 0;
}
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 17d08ede8049..6af115bfd451 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -54,7 +54,8 @@ namespace writerfilter {
DESTINATION_SHAPE,
DESTINATION_SHAPEINSTRUCTION,
DESTINATION_SHAPEPROPERTYVALUEPICT,
- DESTINATION_NESTEDTABLEPROPERTIES
+ DESTINATION_NESTEDTABLEPROPERTIES,
+ DESTINATION_FOOTNOTE
};
enum RTFBorderState
@@ -197,7 +198,9 @@ namespace writerfilter {
RTFSprms_t mergeAttributes();
int asHex(char ch);
void setSubstream(bool bIsSubtream);
- void resolveSubstream(sal_uInt32& nPos, Id nId);
+ void setIgnoreFirst(rtl::OUString& rIgnoreFirst);
+ void resolveSubstream(sal_uInt32 nPos, Id nId);
+ void resolveSubstream(sal_uInt32 nPos, Id nId, rtl::OUString& rIgnoreFirst);
void seek(sal_uInt32 nPos);
private:
int resolveParse();
@@ -219,6 +222,7 @@ namespace writerfilter {
void text(rtl::OUString& rString);
void parBreak();
void sectBreak(bool bFinal);
+ void replayBuffer(std::deque<std::pair<RTFBufferTypes, RTFValue::Pointer_t>>& rBuffer);
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const& m_xContext;
com::sun::star::uno::Reference<com::sun::star::io::XInputStream> const& m_xInputStream;
@@ -253,10 +257,16 @@ namespace writerfilter {
/// Buffered table cells, till cell definitions are not reached.
std::deque<std::pair<RTFBufferTypes, RTFValue::Pointer_t>> m_aTableBuffer;
bool m_bTable;
+ /// Buffered superscript, till footnote is reached (or not).
+ std::deque<std::pair<RTFBufferTypes, RTFValue::Pointer_t>> m_aSuperBuffer;
+ bool m_bSuper;
+ bool m_bHasFootnote;
/// If this is a substream.
bool m_bIsSubstream;
std::deque<std::pair<Id, sal_uInt32>> m_nHeaderFooterPositions;
sal_uInt32 m_nGroupStartPos;
+ /// Ignore the first occurrence of this text.
+ rtl::OUString m_aIgnoreFirst;
};
} // namespace rtftok
} // namespace writerfilter