Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <rtfsprm.hxx>
11 :
12 : #include <rtl/strbuf.hxx>
13 :
14 : #include <ooxml/resourceids.hxx>
15 : #include <ooxml/QNameToString.hxx>
16 :
17 :
18 : namespace writerfilter
19 : {
20 : namespace rtftok
21 : {
22 :
23 56919 : RTFSprm::RTFSprm(Id nKeyword, RTFValue::Pointer_t& pValue)
24 : : m_nKeyword(nKeyword),
25 56919 : m_pValue(pValue)
26 : {
27 56919 : }
28 :
29 223747 : sal_uInt32 RTFSprm::getId() const
30 : {
31 223747 : return m_nKeyword;
32 : }
33 :
34 136331 : Value::Pointer_t RTFSprm::getValue()
35 : {
36 136331 : return Value::Pointer_t(m_pValue->Clone());
37 : }
38 :
39 0 : writerfilter::Reference<BinaryObj>::Pointer_t RTFSprm::getBinary()
40 : {
41 0 : return m_pValue->getBinary();
42 : }
43 :
44 0 : writerfilter::Reference<Stream>::Pointer_t RTFSprm::getStream()
45 : {
46 0 : return m_pValue->getStream();
47 : }
48 :
49 29598 : writerfilter::Reference<Properties>::Pointer_t RTFSprm::getProps()
50 : {
51 29598 : return m_pValue->getProperties();
52 : }
53 :
54 : #ifdef DEBUG_WRITERFILTER
55 : std::string RTFSprm::getName() const
56 : {
57 : return "RTFSprm";
58 : }
59 : #endif
60 :
61 : #ifdef DEBUG_WRITERFILTER
62 : std::string RTFSprm::toString() const
63 : {
64 : OStringBuffer aBuf("RTFSprm");
65 :
66 : std::string sResult;
67 :
68 : sResult = (*QNameToString::Instance())(m_nKeyword);
69 :
70 : aBuf.append(" ('");
71 : if (sResult.length() == 0)
72 : aBuf.append(sal_Int32(m_nKeyword));
73 : else
74 : aBuf.append(sResult.c_str());
75 : aBuf.append("', '");
76 : aBuf.append(m_pValue->toString().c_str());
77 : aBuf.append("')");
78 :
79 : return aBuf.makeStringAndClear().getStr();
80 : }
81 : #endif
82 :
83 139165 : RTFValue::Pointer_t RTFSprms::find(Id nKeyword, bool bFirst, bool bForWrite)
84 : {
85 139165 : RTFValue::Pointer_t pValue;
86 :
87 139165 : if (bForWrite)
88 36040 : ensureCopyBeforeWrite();
89 :
90 385183 : for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
91 297334 : if (i->first == nKeyword)
92 : {
93 51316 : if (bFirst)
94 51316 : return i->second;
95 : else
96 0 : pValue = i->second;
97 : }
98 87849 : return pValue;
99 : }
100 :
101 133833 : void RTFSprms::set(Id nKeyword, RTFValue::Pointer_t pValue, RTFOverwrite eOverwrite)
102 : {
103 133833 : ensureCopyBeforeWrite();
104 133833 : bool bFound = false;
105 133833 : if (eOverwrite == RTFOverwrite::YES || eOverwrite == RTFOverwrite::NO_IGNORE)
106 : {
107 353507 : for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
108 249815 : if (i->first == nKeyword)
109 : {
110 23043 : if (eOverwrite == RTFOverwrite::YES)
111 : {
112 21793 : i->second = pValue;
113 155626 : return;
114 : }
115 : else
116 : {
117 1250 : bFound = true;
118 1250 : break;
119 : }
120 : }
121 : }
122 112040 : if (eOverwrite == RTFOverwrite::NO_APPEND || !bFound)
123 110790 : m_pSprms->push_back(std::make_pair(nKeyword, pValue));
124 : }
125 :
126 14218 : bool RTFSprms::erase(Id nKeyword)
127 : {
128 14218 : ensureCopyBeforeWrite();
129 28171 : for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
130 : {
131 27576 : if (i->first == nKeyword)
132 : {
133 13623 : m_pSprms->erase(i);
134 13623 : return true;
135 : }
136 : }
137 595 : return false;
138 : }
139 :
140 67088 : static RTFValue::Pointer_t getDefaultSPRM(Id const id)
141 : {
142 67088 : switch (id)
143 : {
144 : case NS_ooxml::LN_CT_Spacing_before:
145 : case NS_ooxml::LN_CT_Spacing_after:
146 : case NS_ooxml::LN_EG_RPrBase_b:
147 221 : return std::make_shared<RTFValue>(0);
148 :
149 : default:
150 66867 : return RTFValue::Pointer_t();
151 : }
152 : }
153 :
154 43962 : RTFSprms RTFSprms::cloneAndDeduplicate(RTFSprms& rReference) const
155 : {
156 43962 : RTFSprms ret(*this);
157 43962 : ret.ensureCopyBeforeWrite();
158 :
159 : // Note: apparently some attributes are set with OVERWRITE_NO_APPEND;
160 : // it is probably a bad idea to mess with those in any way here?
161 129677 : for (RTFSprms::Iterator_t i = rReference.begin(); i != rReference.end(); ++i)
162 : {
163 85715 : RTFValue::Pointer_t const pValue(ret.find(i->first));
164 85715 : if (pValue)
165 : {
166 18627 : if (i->second->equals(*pValue))
167 : {
168 12870 : ret.erase(i->first); // duplicate to style
169 : }
170 5757 : else if (!i->second->getSprms().empty() || !i->second->getAttributes().empty())
171 : {
172 : RTFSprms const sprms(
173 4654 : pValue->getSprms().cloneAndDeduplicate(i->second->getSprms()));
174 : RTFSprms const attributes(
175 9308 : pValue->getAttributes().cloneAndDeduplicate(i->second->getAttributes()));
176 4654 : ret.set(i->first, RTFValue::Pointer_t(
177 13962 : pValue->CloneWithSprms(attributes, sprms)));
178 : }
179 : }
180 : else
181 : {
182 : // not found - try to override style with default
183 67088 : RTFValue::Pointer_t const pDefault(getDefaultSPRM(i->first));
184 67088 : if (pDefault)
185 : {
186 221 : ret.set(i->first, pDefault);
187 : }
188 66867 : else if (!i->second->getSprms().empty() || !i->second->getAttributes().empty())
189 : {
190 : RTFSprms const sprms(
191 14237 : RTFSprms().cloneAndDeduplicate(i->second->getSprms()));
192 : RTFSprms const attributes(
193 28474 : RTFSprms().cloneAndDeduplicate(i->second->getAttributes()));
194 14237 : if (!sprms.empty() || !attributes.empty())
195 : {
196 298 : ret.set(i->first, std::make_shared<RTFValue>(attributes, sprms));
197 14237 : }
198 67088 : }
199 : }
200 85715 : }
201 43962 : return ret;
202 : }
203 :
204 28404 : bool RTFSprms::equals(RTFValue& rOther)
205 : {
206 28404 : RTFSprms::Iterator_t i = m_pSprms->begin();
207 28404 : while (i != m_pSprms->end())
208 2664 : if (!i->second->equals(rOther))
209 2664 : return false;
210 25740 : return true;
211 : }
212 :
213 228053 : void RTFSprms::ensureCopyBeforeWrite()
214 : {
215 228053 : if (m_pSprms->m_nRefCount > 1)
216 : {
217 70699 : boost::intrusive_ptr<RTFSprmsImpl> pClone(new RTFSprmsImpl());
218 128075 : for (std::vector< std::pair<Id, RTFValue::Pointer_t> >::const_iterator i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
219 57376 : pClone->push_back(std::make_pair(i->first, RTFValue::Pointer_t(i->second->Clone())));
220 70699 : m_pSprms = pClone;
221 : }
222 228053 : }
223 :
224 667725 : RTFSprms::RTFSprms()
225 667725 : : m_pSprms(new RTFSprmsImpl())
226 : {
227 667725 : }
228 :
229 3051653 : RTFSprms::~RTFSprms()
230 : {
231 3051653 : }
232 :
233 2383928 : RTFSprms::RTFSprms(const RTFSprms& rSprms)
234 : {
235 2383928 : *this = rSprms;
236 2383928 : }
237 :
238 2400915 : RTFSprms& RTFSprms::operator=(const RTFSprms& rOther)
239 : {
240 2400915 : m_pSprms = rOther.m_pSprms;
241 2400915 : return *this;
242 : }
243 :
244 28910 : void RTFSprms::clear()
245 : {
246 28910 : if (m_pSprms->m_nRefCount == 1)
247 28942 : return m_pSprms->clear();
248 : else
249 28878 : m_pSprms.reset(new RTFSprmsImpl());
250 : }
251 :
252 : } // namespace rtftok
253 72 : } // namespace writerfilter
254 :
255 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|