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 <resourcemodel/QNameToString.hxx>
16 :
17 :
18 : namespace writerfilter
19 : {
20 : namespace rtftok
21 : {
22 :
23 72014 : RTFSprm::RTFSprm(Id nKeyword, RTFValue::Pointer_t& pValue)
24 : : m_nKeyword(nKeyword),
25 72014 : m_pValue(pValue)
26 : {
27 72014 : }
28 :
29 304928 : sal_uInt32 RTFSprm::getId() const
30 : {
31 304928 : return m_nKeyword;
32 : }
33 :
34 183916 : Value::Pointer_t RTFSprm::getValue()
35 : {
36 183916 : 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 39170 : writerfilter::Reference<Properties>::Pointer_t RTFSprm::getProps()
50 : {
51 39170 : 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 126156 : RTFValue::Pointer_t RTFSprms::find(Id nKeyword, bool bFirst, bool bForWrite)
84 : {
85 126156 : RTFValue::Pointer_t pValue;
86 :
87 126156 : if (bForWrite)
88 34508 : ensureCopyBeforeWrite();
89 :
90 270040 : for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
91 174726 : if (i->first == nKeyword)
92 : {
93 30842 : if (bFirst)
94 30842 : return i->second;
95 : else
96 0 : pValue = i->second;
97 : }
98 95314 : return pValue;
99 : }
100 :
101 97744 : void RTFSprms::set(Id nKeyword, RTFValue::Pointer_t pValue, RTFOverwrite eOverwrite)
102 : {
103 97744 : ensureCopyBeforeWrite();
104 97744 : bool bFound = false;
105 97744 : if (eOverwrite == OVERWRITE_YES || eOverwrite == OVERWRITE_NO_IGNORE)
106 : {
107 208294 : for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
108 133062 : if (i->first == nKeyword)
109 : {
110 15138 : if (eOverwrite == OVERWRITE_YES)
111 : {
112 14610 : i->second = pValue;
113 112354 : return;
114 : }
115 : else
116 : {
117 528 : bFound = true;
118 528 : break;
119 : }
120 : }
121 : }
122 83134 : if (eOverwrite == OVERWRITE_NO_APPEND || !bFound)
123 82606 : m_pSprms->push_back(std::make_pair(nKeyword, pValue));
124 : }
125 :
126 2254 : bool RTFSprms::erase(Id nKeyword)
127 : {
128 2254 : ensureCopyBeforeWrite();
129 10746 : for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
130 : {
131 9842 : if (i->first == nKeyword)
132 : {
133 1350 : m_pSprms->erase(i);
134 1350 : return true;
135 : }
136 : }
137 904 : return false;
138 : }
139 :
140 60998 : static RTFValue::Pointer_t getDefaultSPRM(Id const id)
141 : {
142 60998 : 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 452 : return RTFValue::Pointer_t(new RTFValue(0));
148 :
149 : default:
150 60546 : return RTFValue::Pointer_t();
151 : }
152 : }
153 :
154 40068 : RTFSprms RTFSprms::cloneAndDeduplicate(RTFSprms& rReference) const
155 : {
156 40068 : RTFSprms ret(*this);
157 40068 : 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 101134 : for (RTFSprms::Iterator_t i = rReference.begin(); i != rReference.end(); ++i)
162 : {
163 61066 : RTFValue::Pointer_t const pValue(ret.find(i->first));
164 61066 : if (pValue)
165 : {
166 68 : if (i->second->equals(*pValue))
167 : {
168 40 : ret.erase(i->first); // duplicate to style
169 : }
170 28 : else if (!i->second->getSprms().empty() || !i->second->getAttributes().empty())
171 : {
172 : RTFSprms const sprms(
173 26 : pValue->getSprms().cloneAndDeduplicate(i->second->getSprms()));
174 : RTFSprms const attributes(
175 52 : pValue->getAttributes().cloneAndDeduplicate(i->second->getAttributes()));
176 26 : ret.set(i->first, RTFValue::Pointer_t(
177 78 : pValue->CloneWithSprms(attributes, sprms)));
178 : }
179 : }
180 : else
181 : {
182 : // not found - try to override style with default
183 60998 : RTFValue::Pointer_t const pDefault(getDefaultSPRM(i->first));
184 60998 : if (pDefault)
185 : {
186 452 : ret.set(i->first, pDefault);
187 : }
188 60546 : else if (!i->second->getSprms().empty() || !i->second->getAttributes().empty())
189 : {
190 : RTFSprms const sprms(
191 17586 : RTFSprms().cloneAndDeduplicate(i->second->getSprms()));
192 : RTFSprms const attributes(
193 35172 : RTFSprms().cloneAndDeduplicate(i->second->getAttributes()));
194 17586 : if (!sprms.empty() || !attributes.empty())
195 : {
196 634 : ret.set(i->first, RTFValue::Pointer_t(new RTFValue(attributes, sprms)));
197 17586 : }
198 60998 : }
199 : }
200 61066 : }
201 40068 : return ret;
202 : }
203 :
204 94 : bool RTFSprms::equals(RTFValue& rOther)
205 : {
206 94 : RTFSprms::Iterator_t i = m_pSprms->begin();
207 94 : while (i != m_pSprms->end())
208 14 : if (!i->second->equals(rOther))
209 14 : return false;
210 80 : return true;
211 : }
212 :
213 174574 : void RTFSprms::ensureCopyBeforeWrite()
214 : {
215 174574 : if (m_pSprms->m_nRefCount > 1)
216 : {
217 64482 : boost::intrusive_ptr<RTFSprmsImpl> pClone(new RTFSprmsImpl());
218 99230 : for (std::vector< std::pair<Id, RTFValue::Pointer_t> >::const_iterator i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
219 34748 : pClone->push_back(std::make_pair(i->first, RTFValue::Pointer_t(i->second->Clone())));
220 64482 : m_pSprms = pClone;
221 : }
222 174574 : }
223 :
224 495652 : RTFSprms::RTFSprms()
225 495652 : : m_pSprms(new RTFSprmsImpl())
226 : {
227 495652 : }
228 :
229 2945426 : RTFSprms::~RTFSprms()
230 : {
231 2945426 : }
232 :
233 2449774 : RTFSprms::RTFSprms(const RTFSprms& rSprms)
234 : {
235 2449774 : *this = rSprms;
236 2449774 : }
237 :
238 2470638 : RTFSprms& RTFSprms::operator=(const RTFSprms& rOther)
239 : {
240 2470638 : m_pSprms = rOther.m_pSprms;
241 2470638 : return *this;
242 : }
243 :
244 22388 : void RTFSprms::clear()
245 : {
246 22388 : if (m_pSprms->m_nRefCount == 1)
247 22452 : return m_pSprms->clear();
248 : else
249 22324 : m_pSprms.reset(new RTFSprmsImpl());
250 : }
251 :
252 : } // namespace rtftok
253 114 : } // namespace writerfilter
254 :
255 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|