summaryrefslogtreecommitdiff
path: root/writerfilter/source
diff options
context:
space:
mode:
Diffstat (limited to 'writerfilter/source')
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx27
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx4
-rw-r--r--writerfilter/source/rtftok/rtfreferenceproperties.cxx10
-rw-r--r--writerfilter/source/rtftok/rtfreferenceproperties.hxx2
-rw-r--r--writerfilter/source/rtftok/rtfsprm.cxx20
-rw-r--r--writerfilter/source/rtftok/rtfsprm.hxx2
-rw-r--r--writerfilter/source/rtftok/rtfvalue.cxx5
-rw-r--r--writerfilter/source/rtftok/rtfvalue.hxx1
8 files changed, 65 insertions, 6 deletions
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index c8992ecfb780..d1888dc60f3e 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -399,6 +399,21 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar)
m_bNeedPar = bNeedPar;
}
+writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
+{
+ int nStyle = m_aStates.top().nCurrentStyleIndex;
+ RTFReferenceTable::Entries_t::iterator it = m_aStyleTableEntries.find(nStyle);
+ if (it != m_aStyleTableEntries.end())
+ {
+ RTFReferenceProperties& rProps = *(RTFReferenceProperties*)it->second.get();
+ // Get rid of direct formatting what is already in the style.
+ rSprms.deduplicate(rProps.getSprms());
+ rAttributes.deduplicate(rProps.getAttributes());
+ }
+ writerfilter::Reference<Properties>::Pointer_t pRet(new RTFReferenceProperties(rAttributes, rSprms));
+ return pRet;
+}
+
void RTFDocumentImpl::checkNeedPap()
{
if (m_bNeedPap)
@@ -407,7 +422,7 @@ void RTFDocumentImpl::checkNeedPap()
if (!m_pCurrentBuffer)
{
writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
- new RTFReferenceProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
+ getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
);
// Writer will ignore a page break before a text frame, so guard it with empty paragraphs
@@ -441,9 +456,7 @@ void RTFDocumentImpl::runProps()
{
if (!m_pCurrentBuffer)
{
- writerfilter::Reference<Properties>::Pointer_t const pProperties(
- new RTFReferenceProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms)
- );
+ writerfilter::Reference<Properties>::Pointer_t const pProperties = getProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms);
Mapper().props(pProperties);
}
else
@@ -1677,7 +1690,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
- new RTFReferenceProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
+ getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
);
Mapper().props(pParagraphProperties);
@@ -2623,6 +2636,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
}
break;
case RTF_S:
+ m_aStates.top().nCurrentStyleIndex = nParam;
if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
{
m_nCurrentStyleIndex = nParam;
@@ -4206,7 +4220,8 @@ RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
nMonth(0),
nDay(0),
nHour(0),
- nMinute(0)
+ nMinute(0),
+ nCurrentStyleIndex(-1)
{
}
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 4942facc0d3e..98011640306f 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -399,6 +399,9 @@ namespace writerfilter {
/// Text from special destinations.
rtl::OUStringBuffer aDestinationText;
+
+ /// Same as the int value of NS_rtf::LN_ISTD in aParagraphAttributes, for performance reasons.
+ int nCurrentStyleIndex;
};
class RTFTokenizer;
@@ -478,6 +481,7 @@ namespace writerfilter {
void runBreak();
void parBreak();
void tableBreak();
+ writerfilter::Reference<Properties>::Pointer_t getProperties(RTFSprms& rAttributes, RTFSprms& rSprms);
void checkNeedPap();
void sectBreak(bool bFinal);
void replayBuffer(RTFBuffer_t& rBuffer);
diff --git a/writerfilter/source/rtftok/rtfreferenceproperties.cxx b/writerfilter/source/rtftok/rtfreferenceproperties.cxx
index 03cd0e97293c..50f76e3e3e6c 100644
--- a/writerfilter/source/rtftok/rtfreferenceproperties.cxx
+++ b/writerfilter/source/rtftok/rtfreferenceproperties.cxx
@@ -62,6 +62,16 @@ std::string RTFReferenceProperties::getType() const
return "RTFReferenceProperties";
}
+RTFSprms& RTFReferenceProperties::getAttributes()
+{
+ return m_aAttributes;
+}
+
+RTFSprms& RTFReferenceProperties::getSprms()
+{
+ return m_aSprms;
+}
+
} // namespace rtftok
} // namespace writerfilter
diff --git a/writerfilter/source/rtftok/rtfreferenceproperties.hxx b/writerfilter/source/rtftok/rtfreferenceproperties.hxx
index d580de912ca8..369590b14cc2 100644
--- a/writerfilter/source/rtftok/rtfreferenceproperties.hxx
+++ b/writerfilter/source/rtftok/rtfreferenceproperties.hxx
@@ -42,6 +42,8 @@ namespace writerfilter {
virtual ~RTFReferenceProperties();
virtual void resolve(Properties & rHandler);
virtual std::string getType() const;
+ RTFSprms& getAttributes();
+ RTFSprms& getSprms();
private:
RTFSprms m_aAttributes;
RTFSprms m_aSprms;
diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx
index fb61d292a5b8..2958cde25cb8 100644
--- a/writerfilter/source/rtftok/rtfsprm.cxx
+++ b/writerfilter/source/rtftok/rtfsprm.cxx
@@ -29,6 +29,7 @@
#include <rtl/strbuf.hxx>
#include <resourcemodel/QNameToString.hxx>
+#include <doctok/resourceids.hxx> // NS_rtf namespace
using rtl::OStringBuffer;
@@ -130,6 +131,25 @@ bool RTFSprms::erase(Id nKeyword)
return false;
}
+void RTFSprms::deduplicate(RTFSprms& rReference)
+{
+ RTFSprms::Iterator_t i = m_aSprms.begin();
+ while (i != m_aSprms.end())
+ {
+ bool bIgnore = false;
+ if (i->first != NS_rtf::LN_ISTD)
+ {
+ RTFValue::Pointer_t pValue(rReference.find(i->first));
+ if (pValue.get() && i->second->equals(*pValue))
+ bIgnore = true;
+ }
+ if (bIgnore)
+ i = m_aSprms.erase(i);
+ else
+ ++i;
+ }
+}
+
RTFSprms::RTFSprms()
: m_aSprms()
{
diff --git a/writerfilter/source/rtftok/rtfsprm.hxx b/writerfilter/source/rtftok/rtfsprm.hxx
index df223fc697cd..80d41a3c0f69 100644
--- a/writerfilter/source/rtftok/rtfsprm.hxx
+++ b/writerfilter/source/rtftok/rtfsprm.hxx
@@ -47,6 +47,8 @@ namespace writerfilter {
/// Does the same as ->push_back(), except that it can overwrite existing entries.
void set(Id nKeyword, RTFValue::Pointer_t pValue, bool bOverwrite = true);
bool erase(Id nKeyword);
+ /// Removes elements, which are already in the reference set.
+ void deduplicate(RTFSprms& rReference);
void swap(RTFSprms& rOther);
size_t size() const { return m_aSprms.size(); }
bool empty() const { return m_aSprms.empty(); }
diff --git a/writerfilter/source/rtftok/rtfvalue.cxx b/writerfilter/source/rtftok/rtfvalue.cxx
index 488252209eea..eaacc2a8351e 100644
--- a/writerfilter/source/rtftok/rtfvalue.cxx
+++ b/writerfilter/source/rtftok/rtfvalue.cxx
@@ -200,6 +200,11 @@ RTFValue* RTFValue::Clone()
return new RTFValue(m_nValue, m_sValue, *m_pAttributes, *m_pSprms, m_xShape, m_xStream, m_xObject, m_bForceString);
}
+bool RTFValue::equals(RTFValue& rOther)
+{
+ return m_nValue == rOther.m_nValue;
+}
+
RTFSprms& RTFValue::getAttributes()
{
return *m_pAttributes;
diff --git a/writerfilter/source/rtftok/rtfvalue.hxx b/writerfilter/source/rtftok/rtfvalue.hxx
index 6751126ac3bc..3714d263fe78 100644
--- a/writerfilter/source/rtftok/rtfvalue.hxx
+++ b/writerfilter/source/rtftok/rtfvalue.hxx
@@ -62,6 +62,7 @@ namespace writerfilter {
virtual RTFValue* Clone();
RTFSprms& getAttributes();
RTFSprms& getSprms();
+ bool equals(RTFValue& rOther);
private:
RTFValue& operator=(RTFValue const& rOther);
int m_nValue;