File: | home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchvalue.cxx |
Warning: | line 242, column 39 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 "rtfdocumentimpl.hxx" | ||||
11 | |||||
12 | #include <com/sun/star/beans/XPropertySet.hpp> | ||||
13 | #include <com/sun/star/text/WrapTextMode.hpp> | ||||
14 | #include <com/sun/star/document/XDocumentProperties.hpp> | ||||
15 | #include <comphelper/sequence.hxx> | ||||
16 | #include <i18nlangtag/languagetag.hxx> | ||||
17 | #include <osl/thread.h> | ||||
18 | #include <sal/log.hxx> | ||||
19 | #include <rtl/tencinfo.h> | ||||
20 | #include <tools/UnitConversion.hxx> | ||||
21 | |||||
22 | #include <ooxml/resourceids.hxx> | ||||
23 | |||||
24 | #include "rtfcharsets.hxx" | ||||
25 | #include "rtffly.hxx" | ||||
26 | #include "rtfreferenceproperties.hxx" | ||||
27 | #include "rtfskipdestination.hxx" | ||||
28 | |||||
29 | #include <unotools/defaultencoding.hxx> | ||||
30 | #include <unotools/wincodepage.hxx> | ||||
31 | |||||
32 | using namespace com::sun::star; | ||||
33 | |||||
34 | namespace writerfilter | ||||
35 | { | ||||
36 | static int getNumberFormat(int nParam) | ||||
37 | { | ||||
38 | static const int aMap[] | ||||
39 | = { NS_ooxml::LN_Value_ST_NumberFormat_decimal, | ||||
40 | NS_ooxml::LN_Value_ST_NumberFormat_upperRoman, | ||||
41 | NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman, | ||||
42 | NS_ooxml::LN_Value_ST_NumberFormat_upperLetter, | ||||
43 | NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter, | ||||
44 | NS_ooxml::LN_Value_ST_NumberFormat_ordinal, | ||||
45 | NS_ooxml::LN_Value_ST_NumberFormat_cardinalText, | ||||
46 | NS_ooxml::LN_Value_ST_NumberFormat_ordinalText, | ||||
47 | NS_ooxml::LN_Value_ST_NumberFormat_none, // Undefined in RTF 1.8 spec. | ||||
48 | NS_ooxml::LN_Value_ST_NumberFormat_none, // Undefined in RTF 1.8 spec. | ||||
49 | NS_ooxml::LN_Value_ST_NumberFormat_ideographDigital, | ||||
50 | NS_ooxml::LN_Value_ST_NumberFormat_japaneseCounting, | ||||
51 | NS_ooxml::LN_Value_ST_NumberFormat_aiueo, | ||||
52 | NS_ooxml::LN_Value_ST_NumberFormat_iroha, | ||||
53 | NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth, | ||||
54 | NS_ooxml::LN_Value_ST_NumberFormat_decimalHalfWidth, | ||||
55 | NS_ooxml::LN_Value_ST_NumberFormat_japaneseLegal, | ||||
56 | NS_ooxml::LN_Value_ST_NumberFormat_japaneseDigitalTenThousand, | ||||
57 | NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese, | ||||
58 | NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth2, | ||||
59 | NS_ooxml::LN_Value_ST_NumberFormat_aiueoFullWidth, | ||||
60 | NS_ooxml::LN_Value_ST_NumberFormat_irohaFullWidth, | ||||
61 | NS_ooxml::LN_Value_ST_NumberFormat_decimalZero, | ||||
62 | NS_ooxml::LN_Value_ST_NumberFormat_bullet, | ||||
63 | NS_ooxml::LN_Value_ST_NumberFormat_ganada, | ||||
64 | NS_ooxml::LN_Value_ST_NumberFormat_chosung, | ||||
65 | NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedFullstop, | ||||
66 | NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedParen, | ||||
67 | NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese, | ||||
68 | NS_ooxml::LN_Value_ST_NumberFormat_ideographEnclosedCircle, | ||||
69 | NS_ooxml::LN_Value_ST_NumberFormat_ideographTraditional, | ||||
70 | NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiac, | ||||
71 | NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiacTraditional, | ||||
72 | NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCounting, | ||||
73 | NS_ooxml::LN_Value_ST_NumberFormat_ideographLegalTraditional, | ||||
74 | NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCountingThousand, | ||||
75 | NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseDigital, | ||||
76 | NS_ooxml::LN_Value_ST_NumberFormat_chineseCounting, | ||||
77 | NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified, | ||||
78 | NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand, | ||||
79 | NS_ooxml::LN_Value_ST_NumberFormat_decimal, | ||||
80 | NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital, | ||||
81 | NS_ooxml::LN_Value_ST_NumberFormat_koreanCounting, | ||||
82 | NS_ooxml::LN_Value_ST_NumberFormat_koreanLegal, | ||||
83 | NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital2, | ||||
84 | NS_ooxml::LN_Value_ST_NumberFormat_hebrew1, | ||||
85 | NS_ooxml::LN_Value_ST_NumberFormat_arabicAlpha, | ||||
86 | NS_ooxml::LN_Value_ST_NumberFormat_hebrew2, | ||||
87 | NS_ooxml::LN_Value_ST_NumberFormat_arabicAbjad }; | ||||
88 | const int nLen = SAL_N_ELEMENTS(aMap)(sizeof(sal_n_array_size(aMap))); | ||||
89 | int nValue = 0; | ||||
90 | if (nParam >= 0 && nParam < nLen) | ||||
91 | nValue = aMap[nParam]; | ||||
92 | else // 255 and the other cases. | ||||
93 | nValue = NS_ooxml::LN_Value_ST_NumberFormat_none; | ||||
94 | return nValue; | ||||
95 | } | ||||
96 | |||||
97 | namespace rtftok | ||||
98 | { | ||||
99 | bool RTFDocumentImpl::dispatchTableSprmValue(RTFKeyword nKeyword, int nParam) | ||||
100 | { | ||||
101 | int nSprm = 0; | ||||
102 | tools::SvRef<RTFValue> pIntValue(new RTFValue(nParam)); | ||||
103 | switch (nKeyword) | ||||
104 | { | ||||
105 | case RTF_LEVELJC: | ||||
106 | { | ||||
107 | nSprm = NS_ooxml::LN_CT_Lvl_lvlJc; | ||||
108 | int nValue = 0; | ||||
109 | switch (nParam) | ||||
110 | { | ||||
111 | case 0: | ||||
112 | nValue = NS_ooxml::LN_Value_ST_Jc_left; | ||||
113 | break; | ||||
114 | case 1: | ||||
115 | nValue = NS_ooxml::LN_Value_ST_Jc_center; | ||||
116 | break; | ||||
117 | case 2: | ||||
118 | nValue = NS_ooxml::LN_Value_ST_Jc_right; | ||||
119 | break; | ||||
120 | } | ||||
121 | pIntValue = new RTFValue(nValue); | ||||
122 | break; | ||||
123 | } | ||||
124 | case RTF_LEVELSTARTAT: | ||||
125 | nSprm = NS_ooxml::LN_CT_Lvl_start; | ||||
126 | break; | ||||
127 | case RTF_LEVELPICTURE: | ||||
128 | nSprm = NS_ooxml::LN_CT_Lvl_lvlPicBulletId; | ||||
129 | break; | ||||
130 | case RTF_SBASEDON: | ||||
131 | nSprm = NS_ooxml::LN_CT_Style_basedOn; | ||||
132 | pIntValue = new RTFValue(getStyleName(nParam)); | ||||
133 | break; | ||||
134 | default: | ||||
135 | break; | ||||
136 | } | ||||
137 | if (nSprm > 0) | ||||
138 | { | ||||
139 | m_aStates.top().getTableSprms().set(nSprm, pIntValue); | ||||
140 | return true; | ||||
141 | } | ||||
142 | if (nKeyword == RTF_LEVELNFC) | ||||
143 | { | ||||
144 | pIntValue = new RTFValue(getNumberFormat(nParam)); | ||||
145 | putNestedAttribute(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_Lvl_numFmt, | ||||
146 | NS_ooxml::LN_CT_NumFmt_val, pIntValue); | ||||
147 | return true; | ||||
148 | } | ||||
149 | |||||
150 | return false; | ||||
151 | } | ||||
152 | |||||
153 | bool RTFDocumentImpl::dispatchCharacterSprmValue(RTFKeyword nKeyword, int nParam) | ||||
154 | { | ||||
155 | int nSprm = 0; | ||||
156 | tools::SvRef<RTFValue> pIntValue(new RTFValue(nParam)); | ||||
157 | |||||
158 | switch (nKeyword) | ||||
159 | { | ||||
160 | case RTF_FS: | ||||
161 | case RTF_AFS: | ||||
162 | switch (m_aStates.top().getRunType()) | ||||
163 | { | ||||
164 | case RTFParserState::RunType::HICH: | ||||
165 | case RTFParserState::RunType::RTLCH_LTRCH_1: | ||||
166 | case RTFParserState::RunType::LTRCH_RTLCH_2: | ||||
167 | case RTFParserState::RunType::DBCH: | ||||
168 | nSprm = NS_ooxml::LN_EG_RPrBase_szCs; | ||||
169 | break; | ||||
170 | case RTFParserState::RunType::NONE: | ||||
171 | case RTFParserState::RunType::LOCH: | ||||
172 | case RTFParserState::RunType::LTRCH_RTLCH_1: | ||||
173 | case RTFParserState::RunType::RTLCH_LTRCH_2: | ||||
174 | default: | ||||
175 | nSprm = NS_ooxml::LN_EG_RPrBase_sz; | ||||
176 | break; | ||||
177 | } | ||||
178 | break; | ||||
179 | case RTF_EXPNDTW: | ||||
180 | nSprm = NS_ooxml::LN_EG_RPrBase_spacing; | ||||
181 | break; | ||||
182 | case RTF_KERNING: | ||||
183 | nSprm = NS_ooxml::LN_EG_RPrBase_kern; | ||||
184 | break; | ||||
185 | case RTF_CHARSCALEX: | ||||
186 | nSprm = NS_ooxml::LN_EG_RPrBase_w; | ||||
187 | break; | ||||
188 | default: | ||||
189 | break; | ||||
190 | } | ||||
191 | if (nSprm > 0) | ||||
192 | { | ||||
193 | m_aStates.top().getCharacterSprms().set(nSprm, pIntValue); | ||||
194 | return true; | ||||
195 | } | ||||
196 | |||||
197 | return false; | ||||
198 | } | ||||
199 | |||||
200 | bool RTFDocumentImpl::dispatchCharacterAttributeValue(RTFKeyword nKeyword, int nParam) | ||||
201 | { | ||||
202 | int nSprm = 0; | ||||
203 | |||||
204 | switch (nKeyword) | ||||
205 | { | ||||
206 | case RTF_LANG: | ||||
207 | case RTF_ALANG: | ||||
208 | switch (m_aStates.top().getRunType()) | ||||
209 | { | ||||
210 | case RTFParserState::RunType::HICH: | ||||
211 | case RTFParserState::RunType::RTLCH_LTRCH_1: | ||||
212 | case RTFParserState::RunType::LTRCH_RTLCH_2: | ||||
213 | nSprm = NS_ooxml::LN_CT_Language_bidi; | ||||
214 | break; | ||||
215 | case RTFParserState::RunType::DBCH: | ||||
216 | nSprm = NS_ooxml::LN_CT_Language_eastAsia; | ||||
217 | break; | ||||
218 | case RTFParserState::RunType::NONE: | ||||
219 | case RTFParserState::RunType::LOCH: | ||||
220 | case RTFParserState::RunType::LTRCH_RTLCH_1: | ||||
221 | case RTFParserState::RunType::RTLCH_LTRCH_2: | ||||
222 | default: | ||||
223 | nSprm = NS_ooxml::LN_CT_Language_val; | ||||
224 | break; | ||||
225 | } | ||||
226 | break; | ||||
227 | case RTF_LANGFE: // this one is always CJK apparently | ||||
228 | nSprm = NS_ooxml::LN_CT_Language_eastAsia; | ||||
229 | break; | ||||
230 | default: | ||||
231 | break; | ||||
232 | } | ||||
233 | if (nSprm
| ||||
234 | { | ||||
235 | LanguageTag aTag((LanguageType(static_cast<sal_uInt16>(nParam)))); | ||||
236 | auto pValue = new RTFValue(aTag.getBcp47()); | ||||
237 | putNestedAttribute(m_aStates.top().getCharacterSprms(), NS_ooxml::LN_EG_RPrBase_lang, nSprm, | ||||
238 | pValue); | ||||
239 | // Language is a character property, but we should store it at a paragraph level as well for fields. | ||||
240 | if (nKeyword
| ||||
241 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_EG_RPrBase_lang, | ||||
242 | nSprm, pValue); | ||||
| |||||
243 | return true; | ||||
244 | } | ||||
245 | |||||
246 | return false; | ||||
247 | } | ||||
248 | |||||
249 | bool RTFDocumentImpl::dispatchParagraphSprmValue(RTFKeyword nKeyword, int nParam) | ||||
250 | { | ||||
251 | int nSprm = 0; | ||||
252 | tools::SvRef<RTFValue> pIntValue(new RTFValue(nParam)); | ||||
253 | |||||
254 | switch (nKeyword) | ||||
255 | { | ||||
256 | case RTF_ITAP: | ||||
257 | nSprm = NS_ooxml::LN_tblDepth; | ||||
258 | // tdf#117268: If \itap0 is encountered inside tables (between \cellxN and \cell), then | ||||
259 | // use the default value (1), as Word apparently does | ||||
260 | if (nParam == 0 && (m_nTopLevelCells != 0 || m_nNestedCells != 0)) | ||||
261 | { | ||||
262 | nParam = 1; | ||||
263 | pIntValue = new RTFValue(nParam); | ||||
264 | } | ||||
265 | break; | ||||
266 | default: | ||||
267 | break; | ||||
268 | } | ||||
269 | if (nSprm > 0) | ||||
270 | { | ||||
271 | m_aStates.top().getParagraphSprms().set(nSprm, pIntValue); | ||||
272 | if (nKeyword == RTF_ITAP && nParam > 0) | ||||
273 | { | ||||
274 | while (m_aTableBufferStack.size() < sal::static_int_cast<std::size_t>(nParam)) | ||||
275 | { | ||||
276 | m_aTableBufferStack.emplace_back(RTFBuffer_t()); | ||||
277 | } | ||||
278 | // Invalid tables may omit INTBL after ITAP | ||||
279 | dispatchFlag(RTF_INTBL); // sets newly pushed buffer as current | ||||
280 | assert(m_aStates.top().getCurrentBuffer() == &m_aTableBufferStack.back())(static_cast <bool> (m_aStates.top().getCurrentBuffer() == &m_aTableBufferStack.back()) ? void (0) : __assert_fail ("m_aStates.top().getCurrentBuffer() == &m_aTableBufferStack.back()" , "/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchvalue.cxx" , 280, __extension__ __PRETTY_FUNCTION__)); | ||||
281 | } | ||||
282 | return true; | ||||
283 | } | ||||
284 | |||||
285 | return false; | ||||
286 | } | ||||
287 | |||||
288 | bool RTFDocumentImpl::dispatchInfoValue(RTFKeyword nKeyword, int nParam) | ||||
289 | { | ||||
290 | int nSprm = 0; | ||||
291 | |||||
292 | switch (nKeyword) | ||||
293 | { | ||||
294 | case RTF_YR: | ||||
295 | { | ||||
296 | m_aStates.top().setYear(nParam); | ||||
297 | nSprm = 1; | ||||
298 | } | ||||
299 | break; | ||||
300 | case RTF_MO: | ||||
301 | { | ||||
302 | m_aStates.top().setMonth(nParam); | ||||
303 | nSprm = 1; | ||||
304 | } | ||||
305 | break; | ||||
306 | case RTF_DY: | ||||
307 | { | ||||
308 | m_aStates.top().setDay(nParam); | ||||
309 | nSprm = 1; | ||||
310 | } | ||||
311 | break; | ||||
312 | case RTF_HR: | ||||
313 | { | ||||
314 | m_aStates.top().setHour(nParam); | ||||
315 | nSprm = 1; | ||||
316 | } | ||||
317 | break; | ||||
318 | case RTF_MIN: | ||||
319 | { | ||||
320 | m_aStates.top().setMinute(nParam); | ||||
321 | nSprm = 1; | ||||
322 | } | ||||
323 | break; | ||||
324 | default: | ||||
325 | break; | ||||
326 | } | ||||
327 | |||||
328 | return nSprm > 0; | ||||
329 | } | ||||
330 | |||||
331 | bool RTFDocumentImpl::dispatchFrameValue(RTFKeyword nKeyword, int nParam) | ||||
332 | { | ||||
333 | Id nId = 0; | ||||
334 | switch (nKeyword) | ||||
335 | { | ||||
336 | case RTF_ABSW: | ||||
337 | nId = NS_ooxml::LN_CT_FramePr_w; | ||||
338 | break; | ||||
339 | case RTF_ABSH: | ||||
340 | nId = NS_ooxml::LN_CT_FramePr_h; | ||||
341 | break; | ||||
342 | case RTF_POSX: | ||||
343 | { | ||||
344 | nId = NS_ooxml::LN_CT_FramePr_x; | ||||
345 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign, 0); | ||||
346 | } | ||||
347 | break; | ||||
348 | case RTF_POSY: | ||||
349 | { | ||||
350 | nId = NS_ooxml::LN_CT_FramePr_y; | ||||
351 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, 0); | ||||
352 | } | ||||
353 | break; | ||||
354 | default: | ||||
355 | break; | ||||
356 | } | ||||
357 | |||||
358 | if (nId > 0) | ||||
359 | { | ||||
360 | m_bNeedPap = true; | ||||
361 | // Don't try to support text frames inside tables for now. | ||||
362 | if (m_aStates.top().getCurrentBuffer() != &m_aTableBufferStack.back()) | ||||
363 | m_aStates.top().getFrame().setSprm(nId, nParam); | ||||
364 | |||||
365 | return true; | ||||
366 | } | ||||
367 | |||||
368 | return false; | ||||
369 | } | ||||
370 | |||||
371 | bool RTFDocumentImpl::dispatchTableValue(RTFKeyword nKeyword, int nParam) | ||||
372 | { | ||||
373 | int nSprm = 0; | ||||
374 | tools::SvRef<RTFValue> pIntValue(new RTFValue(nParam)); | ||||
375 | |||||
376 | switch (nKeyword) | ||||
377 | { | ||||
378 | case RTF_CELLX: | ||||
379 | { | ||||
380 | int& rCurrentCellX( | ||||
381 | (Destination::NESTEDTABLEPROPERTIES == m_aStates.top().getDestination()) | ||||
382 | ? m_nNestedCurrentCellX | ||||
383 | : m_nTopLevelCurrentCellX); | ||||
384 | int nCellX = nParam - rCurrentCellX; | ||||
385 | const int COL_DFLT_WIDTH | ||||
386 | = 41; // sw/source/filter/inc/wrtswtbl.hxx, minimal possible width of cells. | ||||
387 | if (!nCellX) | ||||
388 | nCellX = COL_DFLT_WIDTH; | ||||
389 | |||||
390 | // If there is a negative left margin, then the first cellx is relative to that. | ||||
391 | RTFValue::Pointer_t pTblInd | ||||
392 | = m_aStates.top().getTableRowSprms().find(NS_ooxml::LN_CT_TblPrBase_tblInd); | ||||
393 | if (rCurrentCellX == 0 && pTblInd) | ||||
394 | { | ||||
395 | RTFValue::Pointer_t pWidth | ||||
396 | = pTblInd->getAttributes().find(NS_ooxml::LN_CT_TblWidth_w); | ||||
397 | if (pWidth && pWidth->getInt() < 0) | ||||
398 | nCellX = -1 * (pWidth->getInt() - nParam); | ||||
399 | } | ||||
400 | |||||
401 | rCurrentCellX = nParam; | ||||
402 | auto pXValue = new RTFValue(nCellX); | ||||
403 | m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, | ||||
404 | RTFOverwrite::NO_APPEND); | ||||
405 | if (Destination::NESTEDTABLEPROPERTIES == m_aStates.top().getDestination()) | ||||
406 | { | ||||
407 | m_nNestedCells++; | ||||
408 | // Push cell properties. | ||||
409 | m_aNestedTableCellsSprms.push_back(m_aStates.top().getTableCellSprms()); | ||||
410 | m_aNestedTableCellsAttributes.push_back(m_aStates.top().getTableCellAttributes()); | ||||
411 | } | ||||
412 | else | ||||
413 | { | ||||
414 | m_nTopLevelCells++; | ||||
415 | // Push cell properties. | ||||
416 | m_aTopLevelTableCellsSprms.push_back(m_aStates.top().getTableCellSprms()); | ||||
417 | m_aTopLevelTableCellsAttributes.push_back(m_aStates.top().getTableCellAttributes()); | ||||
418 | } | ||||
419 | |||||
420 | m_aStates.top().getTableCellSprms() = m_aDefaultState.getTableCellSprms(); | ||||
421 | m_aStates.top().getTableCellAttributes() = m_aDefaultState.getTableCellAttributes(); | ||||
422 | // We assume text after a row definition always belongs to the table, to handle text before the real INTBL token | ||||
423 | dispatchFlag(RTF_INTBL); | ||||
424 | if (!m_nCellxMax) | ||||
425 | { | ||||
426 | // Wasn't in table, but now is -> tblStart. | ||||
427 | RTFSprms aAttributes; | ||||
428 | RTFSprms aSprms; | ||||
429 | aSprms.set(NS_ooxml::LN_tblStart, new RTFValue(1)); | ||||
430 | writerfilter::Reference<Properties>::Pointer_t pProperties | ||||
431 | = new RTFReferenceProperties(aAttributes, aSprms); | ||||
432 | Mapper().props(pProperties); | ||||
433 | } | ||||
434 | m_nCellxMax = std::max(m_nCellxMax, nParam); | ||||
435 | return true; | ||||
436 | } | ||||
437 | break; | ||||
438 | case RTF_TRRH: | ||||
439 | { | ||||
440 | OUString hRule("auto"); | ||||
441 | if (nParam < 0) | ||||
442 | { | ||||
443 | tools::SvRef<RTFValue> pAbsValue(new RTFValue(-nParam)); | ||||
444 | std::swap(pIntValue, pAbsValue); | ||||
445 | |||||
446 | hRule = "exact"; | ||||
447 | } | ||||
448 | else if (nParam > 0) | ||||
449 | hRule = "atLeast"; | ||||
450 | |||||
451 | putNestedAttribute(m_aStates.top().getTableRowSprms(), | ||||
452 | NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_val, | ||||
453 | pIntValue); | ||||
454 | |||||
455 | auto pHRule = new RTFValue(hRule); | ||||
456 | putNestedAttribute(m_aStates.top().getTableRowSprms(), | ||||
457 | NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_hRule, | ||||
458 | pHRule); | ||||
459 | return true; | ||||
460 | } | ||||
461 | break; | ||||
462 | case RTF_TRLEFT: | ||||
463 | { | ||||
464 | // the value is in twips | ||||
465 | putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblInd, | ||||
466 | NS_ooxml::LN_CT_TblWidth_type, | ||||
467 | new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)); | ||||
468 | putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblInd, | ||||
469 | NS_ooxml::LN_CT_TblWidth_w, new RTFValue(nParam)); | ||||
470 | auto const aDestination = m_aStates.top().getDestination(); | ||||
471 | int& rCurrentTRLeft((Destination::NESTEDTABLEPROPERTIES == aDestination) | ||||
472 | ? m_nNestedTRLeft | ||||
473 | : m_nTopLevelTRLeft); | ||||
474 | int& rCurrentCellX((Destination::NESTEDTABLEPROPERTIES == aDestination) | ||||
475 | ? m_nNestedCurrentCellX | ||||
476 | : m_nTopLevelCurrentCellX); | ||||
477 | rCurrentTRLeft = rCurrentCellX = nParam; | ||||
478 | return true; | ||||
479 | } | ||||
480 | break; | ||||
481 | case RTF_CLSHDNG: | ||||
482 | { | ||||
483 | int nValue = -1; | ||||
484 | switch (nParam) | ||||
485 | { | ||||
486 | case 500: | ||||
487 | nValue = NS_ooxml::LN_Value_ST_Shd_pct5; | ||||
488 | break; | ||||
489 | case 1000: | ||||
490 | nValue = NS_ooxml::LN_Value_ST_Shd_pct10; | ||||
491 | break; | ||||
492 | case 1200: | ||||
493 | nValue = NS_ooxml::LN_Value_ST_Shd_pct12; | ||||
494 | break; | ||||
495 | case 1500: | ||||
496 | nValue = NS_ooxml::LN_Value_ST_Shd_pct15; | ||||
497 | break; | ||||
498 | case 2000: | ||||
499 | nValue = NS_ooxml::LN_Value_ST_Shd_pct20; | ||||
500 | break; | ||||
501 | case 2500: | ||||
502 | nValue = NS_ooxml::LN_Value_ST_Shd_pct25; | ||||
503 | break; | ||||
504 | case 3000: | ||||
505 | nValue = NS_ooxml::LN_Value_ST_Shd_pct30; | ||||
506 | break; | ||||
507 | case 3500: | ||||
508 | nValue = NS_ooxml::LN_Value_ST_Shd_pct35; | ||||
509 | break; | ||||
510 | case 3700: | ||||
511 | nValue = NS_ooxml::LN_Value_ST_Shd_pct37; | ||||
512 | break; | ||||
513 | case 4000: | ||||
514 | nValue = NS_ooxml::LN_Value_ST_Shd_pct40; | ||||
515 | break; | ||||
516 | case 4500: | ||||
517 | nValue = NS_ooxml::LN_Value_ST_Shd_pct45; | ||||
518 | break; | ||||
519 | case 5000: | ||||
520 | nValue = NS_ooxml::LN_Value_ST_Shd_pct50; | ||||
521 | break; | ||||
522 | case 5500: | ||||
523 | nValue = NS_ooxml::LN_Value_ST_Shd_pct55; | ||||
524 | break; | ||||
525 | case 6000: | ||||
526 | nValue = NS_ooxml::LN_Value_ST_Shd_pct60; | ||||
527 | break; | ||||
528 | case 6200: | ||||
529 | nValue = NS_ooxml::LN_Value_ST_Shd_pct62; | ||||
530 | break; | ||||
531 | case 6500: | ||||
532 | nValue = NS_ooxml::LN_Value_ST_Shd_pct65; | ||||
533 | break; | ||||
534 | case 7000: | ||||
535 | nValue = NS_ooxml::LN_Value_ST_Shd_pct70; | ||||
536 | break; | ||||
537 | case 7500: | ||||
538 | nValue = NS_ooxml::LN_Value_ST_Shd_pct75; | ||||
539 | break; | ||||
540 | case 8000: | ||||
541 | nValue = NS_ooxml::LN_Value_ST_Shd_pct80; | ||||
542 | break; | ||||
543 | case 8500: | ||||
544 | nValue = NS_ooxml::LN_Value_ST_Shd_pct85; | ||||
545 | break; | ||||
546 | case 8700: | ||||
547 | nValue = NS_ooxml::LN_Value_ST_Shd_pct87; | ||||
548 | break; | ||||
549 | case 9000: | ||||
550 | nValue = NS_ooxml::LN_Value_ST_Shd_pct90; | ||||
551 | break; | ||||
552 | case 9500: | ||||
553 | nValue = NS_ooxml::LN_Value_ST_Shd_pct95; | ||||
554 | break; | ||||
555 | default: | ||||
556 | break; | ||||
557 | } | ||||
558 | if (nValue != -1) | ||||
559 | putNestedAttribute(m_aStates.top().getTableCellSprms(), | ||||
560 | NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_val, | ||||
561 | new RTFValue(nValue)); | ||||
562 | return true; | ||||
563 | } | ||||
564 | break; | ||||
565 | case RTF_CLPADB: | ||||
566 | case RTF_CLPADL: | ||||
567 | case RTF_CLPADR: | ||||
568 | case RTF_CLPADT: | ||||
569 | { | ||||
570 | RTFSprms aAttributes; | ||||
571 | aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, | ||||
572 | new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)); | ||||
573 | aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, new RTFValue(nParam)); | ||||
574 | // Top and left is swapped, that's what Word does. | ||||
575 | switch (nKeyword) | ||||
576 | { | ||||
577 | case RTF_CLPADB: | ||||
578 | nSprm = NS_ooxml::LN_CT_TcMar_bottom; | ||||
579 | break; | ||||
580 | case RTF_CLPADL: | ||||
581 | nSprm = NS_ooxml::LN_CT_TcMar_top; | ||||
582 | break; | ||||
583 | case RTF_CLPADR: | ||||
584 | nSprm = NS_ooxml::LN_CT_TcMar_right; | ||||
585 | break; | ||||
586 | case RTF_CLPADT: | ||||
587 | nSprm = NS_ooxml::LN_CT_TcMar_left; | ||||
588 | break; | ||||
589 | default: | ||||
590 | break; | ||||
591 | } | ||||
592 | putNestedSprm(m_aStates.top().getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_tcMar, | ||||
593 | nSprm, new RTFValue(aAttributes)); | ||||
594 | return true; | ||||
595 | } | ||||
596 | break; | ||||
597 | case RTF_TRPADDFB: | ||||
598 | case RTF_TRPADDFL: | ||||
599 | case RTF_TRPADDFR: | ||||
600 | case RTF_TRPADDFT: | ||||
601 | { | ||||
602 | RTFSprms aAttributes; | ||||
603 | switch (nParam) | ||||
604 | { | ||||
605 | case 3: | ||||
606 | aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, | ||||
607 | new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)); | ||||
608 | break; | ||||
609 | } | ||||
610 | switch (nKeyword) | ||||
611 | { | ||||
612 | case RTF_TRPADDFB: | ||||
613 | nSprm = NS_ooxml::LN_CT_TcMar_bottom; | ||||
614 | break; | ||||
615 | case RTF_TRPADDFL: | ||||
616 | nSprm = NS_ooxml::LN_CT_TcMar_left; | ||||
617 | break; | ||||
618 | case RTF_TRPADDFR: | ||||
619 | nSprm = NS_ooxml::LN_CT_TcMar_right; | ||||
620 | break; | ||||
621 | case RTF_TRPADDFT: | ||||
622 | nSprm = NS_ooxml::LN_CT_TcMar_top; | ||||
623 | break; | ||||
624 | default: | ||||
625 | break; | ||||
626 | } | ||||
627 | putNestedAttribute(m_aStates.top().getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_tcMar, | ||||
628 | nSprm, new RTFValue(aAttributes)); | ||||
629 | putNestedAttribute(m_aDefaultState.getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_tcMar, | ||||
630 | nSprm, new RTFValue(aAttributes)); | ||||
631 | return true; | ||||
632 | } | ||||
633 | break; | ||||
634 | case RTF_TRPADDB: | ||||
635 | case RTF_TRPADDL: | ||||
636 | case RTF_TRPADDR: | ||||
637 | case RTF_TRPADDT: | ||||
638 | { | ||||
639 | RTFSprms aAttributes; | ||||
640 | aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, new RTFValue(nParam)); | ||||
641 | switch (nKeyword) | ||||
642 | { | ||||
643 | case RTF_TRPADDB: | ||||
644 | nSprm = NS_ooxml::LN_CT_TcMar_bottom; | ||||
645 | break; | ||||
646 | case RTF_TRPADDL: | ||||
647 | nSprm = NS_ooxml::LN_CT_TcMar_left; | ||||
648 | break; | ||||
649 | case RTF_TRPADDR: | ||||
650 | nSprm = NS_ooxml::LN_CT_TcMar_right; | ||||
651 | break; | ||||
652 | case RTF_TRPADDT: | ||||
653 | nSprm = NS_ooxml::LN_CT_TcMar_top; | ||||
654 | break; | ||||
655 | default: | ||||
656 | break; | ||||
657 | } | ||||
658 | putNestedSprm(m_aStates.top().getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_tcMar, | ||||
659 | nSprm, new RTFValue(aAttributes)); | ||||
660 | putNestedSprm(m_aDefaultState.getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_tcMar, | ||||
661 | nSprm, new RTFValue(aAttributes)); | ||||
662 | return true; | ||||
663 | } | ||||
664 | break; | ||||
665 | case RTF_TRGAPH: | ||||
666 | // Half of the space between the cells of a table row: default left/right table cell margin. | ||||
667 | if (nParam > 0) | ||||
668 | { | ||||
669 | RTFSprms aAttributes; | ||||
670 | aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, | ||||
671 | new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)); | ||||
672 | aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, pIntValue); | ||||
673 | putNestedSprm(m_aStates.top().getTableRowSprms(), | ||||
674 | NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left, | ||||
675 | new RTFValue(aAttributes)); | ||||
676 | putNestedSprm(m_aStates.top().getTableRowSprms(), | ||||
677 | NS_ooxml::LN_CT_TblPrBase_tblCellMar, | ||||
678 | NS_ooxml::LN_CT_TblCellMar_right, new RTFValue(aAttributes)); | ||||
679 | } | ||||
680 | return true; | ||||
681 | break; | ||||
682 | case RTF_TRFTSWIDTH: | ||||
683 | putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblW, | ||||
684 | NS_ooxml::LN_CT_TblWidth_type, pIntValue); | ||||
685 | return true; | ||||
686 | break; | ||||
687 | case RTF_TRWWIDTH: | ||||
688 | putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblW, | ||||
689 | NS_ooxml::LN_CT_TblWidth_w, pIntValue); | ||||
690 | return true; | ||||
691 | break; | ||||
692 | default: | ||||
693 | break; | ||||
694 | } | ||||
695 | |||||
696 | return false; | ||||
697 | } | ||||
698 | |||||
699 | RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) | ||||
700 | { | ||||
701 | setNeedSect(true); | ||||
702 | checkUnicode(/*bUnicode =*/nKeyword != RTF_U, /*bHex =*/true); | ||||
| |||||
703 | RTFSkipDestination aSkip(*this); | ||||
704 | int nSprm = 0; | ||||
705 | tools::SvRef<RTFValue> pIntValue(new RTFValue(nParam)); | ||||
706 | // Trivial table sprms. | ||||
707 | if (dispatchTableSprmValue(nKeyword, nParam)) | ||||
708 | { | ||||
709 | return RTFError::OK; | ||||
710 | } | ||||
711 | |||||
712 | // Trivial character sprms. | ||||
713 | if (dispatchCharacterSprmValue(nKeyword, nParam)) | ||||
714 | { | ||||
715 | return RTFError::OK; | ||||
716 | } | ||||
717 | |||||
718 | // Trivial character attributes. | ||||
719 | if (dispatchCharacterAttributeValue(nKeyword, nParam)) | ||||
720 | { | ||||
721 | return RTFError::OK; | ||||
722 | } | ||||
723 | |||||
724 | // Trivial paragraph sprms. | ||||
725 | if (dispatchParagraphSprmValue(nKeyword, nParam)) | ||||
726 | { | ||||
727 | return RTFError::OK; | ||||
728 | } | ||||
729 | |||||
730 | // Info group. | ||||
731 | if (dispatchInfoValue(nKeyword, nParam)) | ||||
732 | { | ||||
733 | return RTFError::OK; | ||||
734 | } | ||||
735 | |||||
736 | // Frame size / position. | ||||
737 | if (dispatchFrameValue(nKeyword, nParam)) | ||||
738 | { | ||||
739 | return RTFError::OK; | ||||
740 | } | ||||
741 | |||||
742 | // Table-related values. | ||||
743 | if (dispatchTableValue(nKeyword, nParam)) | ||||
744 | { | ||||
745 | return RTFError::OK; | ||||
746 | } | ||||
747 | |||||
748 | // Then check for the more complex ones. | ||||
749 | switch (nKeyword) | ||||
750 | { | ||||
751 | case RTF_F: | ||||
752 | case RTF_AF: | ||||
753 | switch (m_aStates.top().getRunType()) | ||||
754 | { | ||||
755 | case RTFParserState::RunType::HICH: | ||||
756 | case RTFParserState::RunType::RTLCH_LTRCH_1: | ||||
757 | case RTFParserState::RunType::LTRCH_RTLCH_2: | ||||
758 | nSprm = NS_ooxml::LN_CT_Fonts_cs; | ||||
759 | break; | ||||
760 | case RTFParserState::RunType::DBCH: | ||||
761 | nSprm = NS_ooxml::LN_CT_Fonts_eastAsia; | ||||
762 | break; | ||||
763 | case RTFParserState::RunType::NONE: | ||||
764 | case RTFParserState::RunType::LOCH: | ||||
765 | case RTFParserState::RunType::LTRCH_RTLCH_1: | ||||
766 | case RTFParserState::RunType::RTLCH_LTRCH_2: | ||||
767 | default: | ||||
768 | nSprm = NS_ooxml::LN_CT_Fonts_ascii; | ||||
769 | break; | ||||
770 | } | ||||
771 | |||||
772 | if (m_aStates.top().getDestination() == Destination::FONTTABLE | ||||
773 | || m_aStates.top().getDestination() == Destination::FONTENTRY) | ||||
774 | { | ||||
775 | m_aFontIndexes.push_back(nParam); | ||||
776 | m_nCurrentFontIndex = getFontIndex(nParam); | ||||
777 | } | ||||
778 | else if (m_aStates.top().getDestination() == Destination::LISTLEVEL) | ||||
779 | { | ||||
780 | RTFSprms aFontAttributes; | ||||
781 | aFontAttributes.set(nSprm, new RTFValue(m_aFontNames[getFontIndex(nParam)])); | ||||
782 | RTFSprms aRunPropsSprms; | ||||
783 | aRunPropsSprms.set(NS_ooxml::LN_EG_RPrBase_rFonts, new RTFValue(aFontAttributes)); | ||||
784 | m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Lvl_rPr, | ||||
785 | new RTFValue(RTFSprms(), aRunPropsSprms), | ||||
786 | RTFOverwrite::NO_APPEND); | ||||
787 | } | ||||
788 | else | ||||
789 | { | ||||
790 | m_nCurrentFontIndex = getFontIndex(nParam); | ||||
791 | auto pValue = new RTFValue(getFontName(m_nCurrentFontIndex)); | ||||
792 | putNestedAttribute(m_aStates.top().getCharacterSprms(), | ||||
793 | NS_ooxml::LN_EG_RPrBase_rFonts, nSprm, pValue); | ||||
794 | if (nKeyword == RTF_F) | ||||
795 | m_aStates.top().setCurrentEncoding(getEncoding(m_nCurrentFontIndex)); | ||||
796 | } | ||||
797 | break; | ||||
798 | case RTF_RED: | ||||
799 | m_aStates.top().getCurrentColor().SetRed(nParam); | ||||
800 | break; | ||||
801 | case RTF_GREEN: | ||||
802 | m_aStates.top().getCurrentColor().SetGreen(nParam); | ||||
803 | break; | ||||
804 | case RTF_BLUE: | ||||
805 | m_aStates.top().getCurrentColor().SetBlue(nParam); | ||||
806 | break; | ||||
807 | case RTF_FCHARSET: | ||||
808 | { | ||||
809 | // we always send text to the domain mapper in OUString, so no | ||||
810 | // need to send encoding info | ||||
811 | int i; | ||||
812 | for (i = 0; i < nRTFEncodings; i++) | ||||
813 | { | ||||
814 | if (aRTFEncodings[i].charset == nParam) | ||||
815 | break; | ||||
816 | } | ||||
817 | if (i == nRTFEncodings) | ||||
818 | // not found | ||||
819 | return RTFError::OK; | ||||
820 | |||||
821 | m_nCurrentEncoding | ||||
822 | = aRTFEncodings[i].codepage == 0 // Default (CP_ACP) | ||||
823 | ? osl_getThreadTextEncoding() | ||||
824 | : rtl_getTextEncodingFromWindowsCodePage(aRTFEncodings[i].codepage); | ||||
825 | m_aStates.top().setCurrentEncoding(m_nCurrentEncoding); | ||||
826 | } | ||||
827 | break; | ||||
828 | case RTF_ANSICPG: | ||||
829 | case RTF_CPG: | ||||
830 | { | ||||
831 | rtl_TextEncoding nEncoding | ||||
832 | = (nParam == 0) | ||||
833 | ? utl_getWinTextEncodingFromLangStr(utl_getLocaleForGlobalDefaultEncoding()) | ||||
834 | : rtl_getTextEncodingFromWindowsCodePage(nParam); | ||||
835 | if (nKeyword == RTF_ANSICPG) | ||||
836 | m_aDefaultState.setCurrentEncoding(nEncoding); | ||||
837 | else | ||||
838 | m_nCurrentEncoding = nEncoding; | ||||
839 | m_aStates.top().setCurrentEncoding(nEncoding); | ||||
840 | } | ||||
841 | break; | ||||
842 | case RTF_CF: | ||||
843 | { | ||||
844 | RTFSprms aAttributes; | ||||
845 | auto pValue = new RTFValue(sal_uInt32(getColorTable(nParam))); | ||||
846 | aAttributes.set(NS_ooxml::LN_CT_Color_val, pValue); | ||||
847 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_color, | ||||
848 | new RTFValue(aAttributes)); | ||||
849 | } | ||||
850 | break; | ||||
851 | case RTF_S: | ||||
852 | { | ||||
853 | m_aStates.top().setCurrentStyleIndex(nParam); | ||||
854 | |||||
855 | if (m_aStates.top().getDestination() == Destination::STYLESHEET | ||||
856 | || m_aStates.top().getDestination() == Destination::STYLEENTRY) | ||||
857 | { | ||||
858 | m_nCurrentStyleIndex = nParam; | ||||
859 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_StyleType_paragraph); | ||||
860 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_Style_type, | ||||
861 | pValue); // paragraph style | ||||
862 | } | ||||
863 | else | ||||
864 | { | ||||
865 | OUString aName = getStyleName(nParam); | ||||
866 | if (!aName.isEmpty()) | ||||
867 | { | ||||
868 | if (m_aStates.top().getDestination() == Destination::LISTLEVEL) | ||||
869 | m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Lvl_pStyle, | ||||
870 | new RTFValue(aName)); | ||||
871 | else | ||||
872 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_pStyle, | ||||
873 | new RTFValue(aName)); | ||||
874 | } | ||||
875 | } | ||||
876 | } | ||||
877 | break; | ||||
878 | case RTF_CS: | ||||
879 | m_aStates.top().setCurrentCharacterStyleIndex(nParam); | ||||
880 | if (m_aStates.top().getDestination() == Destination::STYLESHEET | ||||
881 | || m_aStates.top().getDestination() == Destination::STYLEENTRY) | ||||
882 | { | ||||
883 | m_nCurrentStyleIndex = nParam; | ||||
884 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_StyleType_character); | ||||
885 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_Style_type, | ||||
886 | pValue); // character style | ||||
887 | } | ||||
888 | else | ||||
889 | { | ||||
890 | OUString aName = getStyleName(nParam); | ||||
891 | if (!aName.isEmpty()) | ||||
892 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_rStyle, | ||||
893 | new RTFValue(aName)); | ||||
894 | } | ||||
895 | break; | ||||
896 | case RTF_DS: | ||||
897 | if (m_aStates.top().getDestination() == Destination::STYLESHEET | ||||
898 | || m_aStates.top().getDestination() == Destination::STYLEENTRY) | ||||
899 | { | ||||
900 | m_nCurrentStyleIndex = nParam; | ||||
901 | auto pValue = new RTFValue(0); // TODO no value in enum StyleType? | ||||
902 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_Style_type, | ||||
903 | pValue); // section style | ||||
904 | } | ||||
905 | break; | ||||
906 | case RTF_TS: | ||||
907 | if (m_aStates.top().getDestination() == Destination::STYLESHEET | ||||
908 | || m_aStates.top().getDestination() == Destination::STYLEENTRY) | ||||
909 | { | ||||
910 | m_nCurrentStyleIndex = nParam; | ||||
911 | // FIXME the correct value would be NS_ooxml::LN_Value_ST_StyleType_table but maybe table styles mess things up in dmapper, be cautious and disable them for now | ||||
912 | auto pValue = new RTFValue(0); | ||||
913 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_Style_type, | ||||
914 | pValue); // table style | ||||
915 | } | ||||
916 | break; | ||||
917 | case RTF_DEFF: | ||||
918 | m_nDefaultFontIndex = nParam; | ||||
919 | break; | ||||
920 | case RTF_STSHFDBCH: | ||||
921 | // tdf#123703 switch off longer space sequence except in the case of the fixed compatibility setting font id 31505 | ||||
922 | if (nParam != 31505) | ||||
923 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_longerSpaceSequence, | ||||
924 | new RTFValue(0)); | ||||
925 | break; | ||||
926 | case RTF_DEFLANG: | ||||
927 | case RTF_ADEFLANG: | ||||
928 | { | ||||
929 | LanguageTag aTag((LanguageType(static_cast<sal_uInt16>(nParam)))); | ||||
930 | auto pValue = new RTFValue(aTag.getBcp47()); | ||||
931 | putNestedAttribute(m_aStates.top().getCharacterSprms(), | ||||
932 | (nKeyword == RTF_DEFLANG ? NS_ooxml::LN_EG_RPrBase_lang | ||||
933 | : NS_ooxml::LN_CT_Language_bidi), | ||||
934 | nSprm, pValue); | ||||
935 | } | ||||
936 | break; | ||||
937 | case RTF_CHCBPAT: | ||||
938 | { | ||||
939 | auto pValue = new RTFValue(sal_uInt32(nParam ? getColorTable(nParam) : COL_AUTO)); | ||||
940 | putNestedAttribute(m_aStates.top().getCharacterSprms(), NS_ooxml::LN_EG_RPrBase_shd, | ||||
941 | NS_ooxml::LN_CT_Shd_fill, pValue); | ||||
942 | } | ||||
943 | break; | ||||
944 | case RTF_CLCBPAT: | ||||
945 | case RTF_CLCBPATRAW: | ||||
946 | { | ||||
947 | auto pValue = new RTFValue(sal_uInt32(getColorTable(nParam))); | ||||
948 | putNestedAttribute(m_aStates.top().getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_shd, | ||||
949 | NS_ooxml::LN_CT_Shd_fill, pValue); | ||||
950 | } | ||||
951 | break; | ||||
952 | case RTF_CBPAT: | ||||
953 | if (nParam) | ||||
954 | { | ||||
955 | auto pValue = new RTFValue(sal_uInt32(getColorTable(nParam))); | ||||
956 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PrBase_shd, | ||||
957 | NS_ooxml::LN_CT_Shd_fill, pValue); | ||||
958 | } | ||||
959 | break; | ||||
960 | case RTF_ULC: | ||||
961 | { | ||||
962 | auto pValue = new RTFValue(sal_uInt32(getColorTable(nParam))); | ||||
963 | m_aStates.top().getCharacterSprms().set(0x6877, pValue); | ||||
964 | } | ||||
965 | break; | ||||
966 | case RTF_HIGHLIGHT: | ||||
967 | { | ||||
968 | auto pValue = new RTFValue(sal_uInt32(nParam ? getColorTable(nParam) : COL_AUTO)); | ||||
969 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_highlight, pValue); | ||||
970 | } | ||||
971 | break; | ||||
972 | case RTF_UP: | ||||
973 | case RTF_DN: | ||||
974 | { | ||||
975 | auto pValue = new RTFValue(nParam * (nKeyword == RTF_UP ? 1 : -1)); | ||||
976 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_position, pValue); | ||||
977 | } | ||||
978 | break; | ||||
979 | case RTF_HORZVERT: | ||||
980 | { | ||||
981 | auto pValue = new RTFValue(int(true)); | ||||
982 | m_aStates.top().getCharacterAttributes().set(NS_ooxml::LN_CT_EastAsianLayout_vert, | ||||
983 | pValue); | ||||
984 | if (nParam) | ||||
985 | // rotate fits to a single line | ||||
986 | m_aStates.top().getCharacterAttributes().set( | ||||
987 | NS_ooxml::LN_CT_EastAsianLayout_vertCompress, pValue); | ||||
988 | } | ||||
989 | break; | ||||
990 | case RTF_EXPND: | ||||
991 | { | ||||
992 | // Convert quarter-points to twentieths of a point | ||||
993 | auto pValue = new RTFValue(nParam * 5); | ||||
994 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_spacing, pValue); | ||||
995 | } | ||||
996 | break; | ||||
997 | case RTF_TWOINONE: | ||||
998 | { | ||||
999 | auto pValue = new RTFValue(int(true)); | ||||
1000 | m_aStates.top().getCharacterAttributes().set(NS_ooxml::LN_CT_EastAsianLayout_combine, | ||||
1001 | pValue); | ||||
1002 | Id nId = 0; | ||||
1003 | switch (nParam) | ||||
1004 | { | ||||
1005 | case 0: | ||||
1006 | nId = NS_ooxml::LN_Value_ST_CombineBrackets_none; | ||||
1007 | break; | ||||
1008 | case 1: | ||||
1009 | nId = NS_ooxml::LN_Value_ST_CombineBrackets_round; | ||||
1010 | break; | ||||
1011 | case 2: | ||||
1012 | nId = NS_ooxml::LN_Value_ST_CombineBrackets_square; | ||||
1013 | break; | ||||
1014 | case 3: | ||||
1015 | nId = NS_ooxml::LN_Value_ST_CombineBrackets_angle; | ||||
1016 | break; | ||||
1017 | case 4: | ||||
1018 | nId = NS_ooxml::LN_Value_ST_CombineBrackets_curly; | ||||
1019 | break; | ||||
1020 | } | ||||
1021 | if (nId > 0) | ||||
1022 | m_aStates.top().getCharacterAttributes().set( | ||||
1023 | NS_ooxml::LN_CT_EastAsianLayout_combineBrackets, new RTFValue(nId)); | ||||
1024 | } | ||||
1025 | break; | ||||
1026 | case RTF_SL: | ||||
1027 | { | ||||
1028 | // This is similar to RTF_ABSH, negative value means 'exact', positive means 'at least'. | ||||
1029 | tools::SvRef<RTFValue> pValue( | ||||
1030 | new RTFValue(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast)); | ||||
1031 | if (nParam < 0) | ||||
1032 | { | ||||
1033 | pValue = new RTFValue(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact); | ||||
1034 | pIntValue = new RTFValue(-nParam); | ||||
1035 | } | ||||
1036 | m_aStates.top().getParagraphAttributes().set(NS_ooxml::LN_CT_Spacing_lineRule, pValue); | ||||
1037 | m_aStates.top().getParagraphAttributes().set(NS_ooxml::LN_CT_Spacing_line, pIntValue); | ||||
1038 | } | ||||
1039 | break; | ||||
1040 | case RTF_SLMULT: | ||||
1041 | if (nParam > 0) | ||||
1042 | { | ||||
1043 | auto pValue = new RTFValue(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto); | ||||
1044 | m_aStates.top().getParagraphAttributes().set(NS_ooxml::LN_CT_Spacing_lineRule, | ||||
1045 | pValue); | ||||
1046 | } | ||||
1047 | break; | ||||
1048 | case RTF_BRDRW: | ||||
1049 | { | ||||
1050 | // dmapper expects it in 1/8 pt, we have it in twip - but avoid rounding 1 to 0 | ||||
1051 | if (nParam > 1) | ||||
1052 | nParam = nParam * 2 / 5; | ||||
1053 | auto pValue = new RTFValue(nParam); | ||||
1054 | putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_sz, pValue); | ||||
1055 | } | ||||
1056 | break; | ||||
1057 | case RTF_BRDRCF: | ||||
1058 | { | ||||
1059 | auto pValue = new RTFValue(sal_uInt32(getColorTable(nParam))); | ||||
1060 | putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_color, pValue); | ||||
1061 | } | ||||
1062 | break; | ||||
1063 | case RTF_BRSP: | ||||
1064 | { | ||||
1065 | // dmapper expects it in points, we have it in twip | ||||
1066 | auto pValue = new RTFValue(nParam / 20); | ||||
1067 | putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_space, pValue); | ||||
1068 | } | ||||
1069 | break; | ||||
1070 | case RTF_TX: | ||||
1071 | { | ||||
1072 | m_aStates.top().getTabAttributes().set(NS_ooxml::LN_CT_TabStop_pos, pIntValue); | ||||
1073 | auto pValue = new RTFValue(m_aStates.top().getTabAttributes()); | ||||
1074 | if (m_aStates.top().getDestination() == Destination::LISTLEVEL) | ||||
1075 | putNestedSprm(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_PPrBase_tabs, | ||||
1076 | NS_ooxml::LN_CT_Tabs_tab, pValue); | ||||
1077 | else | ||||
1078 | putNestedSprm(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_tabs, | ||||
1079 | NS_ooxml::LN_CT_Tabs_tab, pValue); | ||||
1080 | m_aStates.top().getTabAttributes().clear(); | ||||
1081 | } | ||||
1082 | break; | ||||
1083 | case RTF_ILVL: | ||||
1084 | putNestedSprm(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_numPr, | ||||
1085 | NS_ooxml::LN_CT_NumPr_ilvl, pIntValue); | ||||
1086 | break; | ||||
1087 | case RTF_LISTTEMPLATEID: | ||||
1088 | // This one is not referenced anywhere, so it's pointless to store it at the moment. | ||||
1089 | break; | ||||
1090 | case RTF_LISTID: | ||||
1091 | { | ||||
1092 | if (m_aStates.top().getDestination() == Destination::LISTENTRY) | ||||
1093 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, | ||||
1094 | pIntValue); | ||||
1095 | else if (m_aStates.top().getDestination() == Destination::LISTOVERRIDEENTRY) | ||||
1096 | m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Num_abstractNumId, pIntValue); | ||||
1097 | m_aStates.top().setCurrentListIndex(nParam); | ||||
1098 | } | ||||
1099 | break; | ||||
1100 | case RTF_LS: | ||||
1101 | { | ||||
1102 | if (m_aStates.top().getDestination() == Destination::LISTOVERRIDEENTRY) | ||||
1103 | { | ||||
1104 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_AbstractNum_nsid, | ||||
1105 | pIntValue); | ||||
1106 | m_aStates.top().setCurrentListOverrideIndex(nParam); | ||||
1107 | } | ||||
1108 | else | ||||
1109 | { | ||||
1110 | // Insert at the start, so properties inherited from the list | ||||
1111 | // can be overridden by direct formatting. But still allow the | ||||
1112 | // case when old-style paragraph numbering is already | ||||
1113 | // tokenized. | ||||
1114 | putNestedSprm(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_numPr, | ||||
1115 | NS_ooxml::LN_CT_NumPr_numId, pIntValue, RTFOverwrite::YES_PREPEND); | ||||
1116 | } | ||||
1117 | } | ||||
1118 | break; | ||||
1119 | case RTF_UC: | ||||
1120 | if ((SAL_MIN_INT16((sal_Int16) (-0x7FFF - 1)) <= nParam) && (nParam <= SAL_MAX_INT16((sal_Int16) 0x7FFF))) | ||||
1121 | m_aStates.top().setUc(nParam); | ||||
1122 | break; | ||||
1123 | case RTF_U: | ||||
1124 | // sal_Unicode is unsigned 16-bit, RTF may represent that as a | ||||
1125 | // signed SAL_MIN_INT16..SAL_MAX_INT16 or 0..SAL_MAX_UINT16. The | ||||
1126 | // static_cast() will do the right thing. | ||||
1127 | if ((SAL_MIN_INT16((sal_Int16) (-0x7FFF - 1)) <= nParam) && (nParam <= SAL_MAX_UINT16((sal_uInt16) 0xFFFF))) | ||||
1128 | { | ||||
1129 | if (m_aStates.top().getDestination() == Destination::LEVELNUMBERS) | ||||
1130 | { | ||||
1131 | if (nParam != ';') | ||||
1132 | m_aStates.top().getLevelNumbers().push_back(sal_Int32(nParam)); | ||||
1133 | else | ||||
1134 | // ';' in \u form is not considered valid. | ||||
1135 | m_aStates.top().setLevelNumbersValid(false); | ||||
1136 | } | ||||
1137 | else | ||||
1138 | m_aUnicodeBuffer.append(static_cast<sal_Unicode>(nParam)); | ||||
1139 | m_aStates.top().getCharsToSkip() = m_aStates.top().getUc(); | ||||
1140 | } | ||||
1141 | break; | ||||
1142 | case RTF_LEVELFOLLOW: | ||||
1143 | { | ||||
1144 | OUString sValue; | ||||
1145 | switch (nParam) | ||||
1146 | { | ||||
1147 | case 0: | ||||
1148 | sValue = "tab"; | ||||
1149 | break; | ||||
1150 | case 1: | ||||
1151 | sValue = "space"; | ||||
1152 | break; | ||||
1153 | case 2: | ||||
1154 | sValue = "nothing"; | ||||
1155 | break; | ||||
1156 | } | ||||
1157 | if (!sValue.isEmpty()) | ||||
1158 | m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Lvl_suff, new RTFValue(sValue)); | ||||
1159 | } | ||||
1160 | break; | ||||
1161 | case RTF_FPRQ: | ||||
1162 | { | ||||
1163 | sal_Int32 nValue = 0; | ||||
1164 | switch (nParam) | ||||
1165 | { | ||||
1166 | case 0: | ||||
1167 | nValue = NS_ooxml::LN_Value_ST_Pitch_default; | ||||
1168 | break; | ||||
1169 | case 1: | ||||
1170 | nValue = NS_ooxml::LN_Value_ST_Pitch_fixed; | ||||
1171 | break; | ||||
1172 | case 2: | ||||
1173 | nValue = NS_ooxml::LN_Value_ST_Pitch_variable; | ||||
1174 | break; | ||||
1175 | } | ||||
1176 | if (nValue) | ||||
1177 | { | ||||
1178 | RTFSprms aAttributes; | ||||
1179 | aAttributes.set(NS_ooxml::LN_CT_Pitch_val, new RTFValue(nValue)); | ||||
1180 | m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Font_pitch, | ||||
1181 | new RTFValue(aAttributes)); | ||||
1182 | } | ||||
1183 | } | ||||
1184 | break; | ||||
1185 | case RTF_LISTOVERRIDECOUNT: | ||||
1186 | // Ignore this for now, the exporter always emits it with a zero parameter. | ||||
1187 | break; | ||||
1188 | case RTF_PICSCALEX: | ||||
1189 | m_aStates.top().getPicture().nScaleX = nParam; | ||||
1190 | break; | ||||
1191 | case RTF_PICSCALEY: | ||||
1192 | m_aStates.top().getPicture().nScaleY = nParam; | ||||
1193 | break; | ||||
1194 | case RTF_PICW: | ||||
1195 | m_aStates.top().getPicture().nWidth = nParam; | ||||
1196 | break; | ||||
1197 | case RTF_PICH: | ||||
1198 | m_aStates.top().getPicture().nHeight = nParam; | ||||
1199 | break; | ||||
1200 | case RTF_PICWGOAL: | ||||
1201 | m_aStates.top().getPicture().nGoalWidth = convertTwipToMm100(nParam); | ||||
1202 | break; | ||||
1203 | case RTF_PICHGOAL: | ||||
1204 | m_aStates.top().getPicture().nGoalHeight = convertTwipToMm100(nParam); | ||||
1205 | break; | ||||
1206 | case RTF_PICCROPL: | ||||
1207 | m_aStates.top().getPicture().nCropL = convertTwipToMm100(nParam); | ||||
1208 | break; | ||||
1209 | case RTF_PICCROPR: | ||||
1210 | m_aStates.top().getPicture().nCropR = convertTwipToMm100(nParam); | ||||
1211 | break; | ||||
1212 | case RTF_PICCROPT: | ||||
1213 | m_aStates.top().getPicture().nCropT = convertTwipToMm100(nParam); | ||||
1214 | break; | ||||
1215 | case RTF_PICCROPB: | ||||
1216 | m_aStates.top().getPicture().nCropB = convertTwipToMm100(nParam); | ||||
1217 | break; | ||||
1218 | case RTF_SHPWRK: | ||||
1219 | { | ||||
1220 | int nValue = 0; | ||||
1221 | switch (nParam) | ||||
1222 | { | ||||
1223 | case 0: | ||||
1224 | nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides; | ||||
1225 | break; | ||||
1226 | case 1: | ||||
1227 | nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left; | ||||
1228 | break; | ||||
1229 | case 2: | ||||
1230 | nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right; | ||||
1231 | break; | ||||
1232 | case 3: | ||||
1233 | nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest; | ||||
1234 | break; | ||||
1235 | default: | ||||
1236 | break; | ||||
1237 | } | ||||
1238 | auto pValue = new RTFValue(nValue); | ||||
1239 | RTFValue::Pointer_t pTight | ||||
1240 | = m_aStates.top().getCharacterSprms().find(NS_ooxml::LN_EG_WrapType_wrapTight); | ||||
1241 | if (pTight) | ||||
1242 | pTight->getAttributes().set(NS_ooxml::LN_CT_WrapTight_wrapText, pValue); | ||||
1243 | else | ||||
1244 | m_aStates.top().getCharacterAttributes().set(NS_ooxml::LN_CT_WrapSquare_wrapText, | ||||
1245 | pValue); | ||||
1246 | } | ||||
1247 | break; | ||||
1248 | case RTF_SHPWR: | ||||
1249 | { | ||||
1250 | switch (nParam) | ||||
1251 | { | ||||
1252 | case 1: | ||||
1253 | m_aStates.top().getShape().setWrap(text::WrapTextMode_NONE); | ||||
1254 | break; | ||||
1255 | case 2: | ||||
1256 | m_aStates.top().getShape().setWrap(text::WrapTextMode_PARALLEL); | ||||
1257 | break; | ||||
1258 | case 3: | ||||
1259 | m_aStates.top().getShape().setWrap(text::WrapTextMode_THROUGH); | ||||
1260 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_WrapType_wrapNone, | ||||
1261 | new RTFValue()); | ||||
1262 | break; | ||||
1263 | case 4: | ||||
1264 | m_aStates.top().getShape().setWrap(text::WrapTextMode_PARALLEL); | ||||
1265 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_WrapType_wrapTight, | ||||
1266 | new RTFValue()); | ||||
1267 | break; | ||||
1268 | case 5: | ||||
1269 | m_aStates.top().getShape().setWrap(text::WrapTextMode_THROUGH); | ||||
1270 | break; | ||||
1271 | } | ||||
1272 | } | ||||
1273 | break; | ||||
1274 | case RTF_COLS: | ||||
1275 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1276 | NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_num, | ||||
1277 | pIntValue); | ||||
1278 | break; | ||||
1279 | case RTF_COLSX: | ||||
1280 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1281 | NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_space, | ||||
1282 | pIntValue); | ||||
1283 | break; | ||||
1284 | case RTF_COLNO: | ||||
1285 | putNestedSprm(m_aStates.top().getSectionSprms(), NS_ooxml::LN_EG_SectPrContents_cols, | ||||
1286 | NS_ooxml::LN_CT_Columns_col, pIntValue); | ||||
1287 | break; | ||||
1288 | case RTF_COLW: | ||||
1289 | case RTF_COLSR: | ||||
1290 | { | ||||
1291 | RTFSprms& rAttributes = getLastAttributes(m_aStates.top().getSectionSprms(), | ||||
1292 | NS_ooxml::LN_EG_SectPrContents_cols); | ||||
1293 | rAttributes.set( | ||||
1294 | (nKeyword == RTF_COLW ? NS_ooxml::LN_CT_Column_w : NS_ooxml::LN_CT_Column_space), | ||||
1295 | pIntValue); | ||||
1296 | } | ||||
1297 | break; | ||||
1298 | case RTF_PAPERH: | ||||
1299 | putNestedAttribute(m_aDefaultState.getSectionSprms(), | ||||
1300 | NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, | ||||
1301 | pIntValue); | ||||
1302 | [[fallthrough]]; // set the default + current value | ||||
1303 | case RTF_PGHSXN: | ||||
1304 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1305 | NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, | ||||
1306 | pIntValue); | ||||
1307 | break; | ||||
1308 | case RTF_PAPERW: | ||||
1309 | putNestedAttribute(m_aDefaultState.getSectionSprms(), | ||||
1310 | NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, | ||||
1311 | pIntValue); | ||||
1312 | [[fallthrough]]; // set the default + current value | ||||
1313 | case RTF_PGWSXN: | ||||
1314 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1315 | NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, | ||||
1316 | pIntValue); | ||||
1317 | break; | ||||
1318 | case RTF_MARGL: | ||||
1319 | putNestedAttribute(m_aDefaultState.getSectionSprms(), | ||||
1320 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, | ||||
1321 | pIntValue); | ||||
1322 | [[fallthrough]]; // set the default + current value | ||||
1323 | case RTF_MARGLSXN: | ||||
1324 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1325 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, | ||||
1326 | pIntValue); | ||||
1327 | break; | ||||
1328 | case RTF_MARGR: | ||||
1329 | putNestedAttribute(m_aDefaultState.getSectionSprms(), | ||||
1330 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, | ||||
1331 | pIntValue); | ||||
1332 | [[fallthrough]]; // set the default + current value | ||||
1333 | case RTF_MARGRSXN: | ||||
1334 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1335 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, | ||||
1336 | pIntValue); | ||||
1337 | break; | ||||
1338 | case RTF_MARGT: | ||||
1339 | putNestedAttribute(m_aDefaultState.getSectionSprms(), | ||||
1340 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, | ||||
1341 | pIntValue); | ||||
1342 | [[fallthrough]]; // set the default + current value | ||||
1343 | case RTF_MARGTSXN: | ||||
1344 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1345 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, | ||||
1346 | pIntValue); | ||||
1347 | break; | ||||
1348 | case RTF_MARGB: | ||||
1349 | putNestedAttribute(m_aDefaultState.getSectionSprms(), | ||||
1350 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, | ||||
1351 | pIntValue); | ||||
1352 | [[fallthrough]]; // set the default + current value | ||||
1353 | case RTF_MARGBSXN: | ||||
1354 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1355 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, | ||||
1356 | pIntValue); | ||||
1357 | break; | ||||
1358 | case RTF_HEADERY: | ||||
1359 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1360 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_header, | ||||
1361 | pIntValue); | ||||
1362 | break; | ||||
1363 | case RTF_FOOTERY: | ||||
1364 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1365 | NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_footer, | ||||
1366 | pIntValue); | ||||
1367 | break; | ||||
1368 | case RTF_DEFTAB: | ||||
1369 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_defaultTabStop, pIntValue); | ||||
1370 | break; | ||||
1371 | case RTF_LINEMOD: | ||||
1372 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1373 | NS_ooxml::LN_EG_SectPrContents_lnNumType, | ||||
1374 | NS_ooxml::LN_CT_LineNumber_countBy, pIntValue); | ||||
1375 | break; | ||||
1376 | case RTF_LINEX: | ||||
1377 | if (nParam) | ||||
1378 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1379 | NS_ooxml::LN_EG_SectPrContents_lnNumType, | ||||
1380 | NS_ooxml::LN_CT_LineNumber_distance, pIntValue); | ||||
1381 | break; | ||||
1382 | case RTF_LINESTARTS: | ||||
1383 | { | ||||
1384 | // OOXML <w:lnNumType w:start="..."/> is 0-based, RTF is 1-based. | ||||
1385 | auto pStart = tools::make_ref<RTFValue>(nParam - 1); | ||||
1386 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1387 | NS_ooxml::LN_EG_SectPrContents_lnNumType, | ||||
1388 | NS_ooxml::LN_CT_LineNumber_start, pStart); | ||||
1389 | } | ||||
1390 | break; | ||||
1391 | case RTF_REVAUTH: | ||||
1392 | case RTF_REVAUTHDEL: | ||||
1393 | { | ||||
1394 | auto pValue = new RTFValue(m_aAuthors[nParam]); | ||||
1395 | putNestedAttribute(m_aStates.top().getCharacterSprms(), NS_ooxml::LN_trackchange, | ||||
1396 | NS_ooxml::LN_CT_TrackChange_author, pValue); | ||||
1397 | } | ||||
1398 | break; | ||||
1399 | case RTF_REVDTTM: | ||||
1400 | case RTF_REVDTTMDEL: | ||||
1401 | { | ||||
1402 | OUString aStr( | ||||
1403 | OStringToOUString(DTTM22OString(nParam), m_aStates.top().getCurrentEncoding())); | ||||
1404 | auto pValue = new RTFValue(aStr); | ||||
1405 | putNestedAttribute(m_aStates.top().getCharacterSprms(), NS_ooxml::LN_trackchange, | ||||
1406 | NS_ooxml::LN_CT_TrackChange_date, pValue); | ||||
1407 | } | ||||
1408 | break; | ||||
1409 | case RTF_SHPLEFT: | ||||
1410 | m_aStates.top().getShape().setLeft(convertTwipToMm100(nParam)); | ||||
1411 | break; | ||||
1412 | case RTF_SHPTOP: | ||||
1413 | m_aStates.top().getShape().setTop(convertTwipToMm100(nParam)); | ||||
1414 | break; | ||||
1415 | case RTF_SHPRIGHT: | ||||
1416 | m_aStates.top().getShape().setRight(convertTwipToMm100(nParam)); | ||||
1417 | break; | ||||
1418 | case RTF_SHPBOTTOM: | ||||
1419 | m_aStates.top().getShape().setBottom(convertTwipToMm100(nParam)); | ||||
1420 | break; | ||||
1421 | case RTF_SHPZ: | ||||
1422 | m_aStates.top().getShape().setZ(nParam); | ||||
1423 | break; | ||||
1424 | case RTF_FFTYPE: | ||||
1425 | switch (nParam) | ||||
1426 | { | ||||
1427 | case 0: | ||||
1428 | m_nFormFieldType = RTFFormFieldType::TEXT; | ||||
1429 | break; | ||||
1430 | case 1: | ||||
1431 | m_nFormFieldType = RTFFormFieldType::CHECKBOX; | ||||
1432 | break; | ||||
1433 | case 2: | ||||
1434 | m_nFormFieldType = RTFFormFieldType::LIST; | ||||
1435 | break; | ||||
1436 | default: | ||||
1437 | m_nFormFieldType = RTFFormFieldType::NONE; | ||||
1438 | break; | ||||
1439 | } | ||||
1440 | break; | ||||
1441 | case RTF_FFDEFRES: | ||||
1442 | if (m_nFormFieldType == RTFFormFieldType::CHECKBOX) | ||||
1443 | m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_default, pIntValue); | ||||
1444 | else if (m_nFormFieldType == RTFFormFieldType::LIST) | ||||
1445 | m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_default, pIntValue); | ||||
1446 | break; | ||||
1447 | case RTF_FFRES: | ||||
1448 | // 25 means undefined, see [MS-DOC] 2.9.79, FFDataBits. | ||||
1449 | if (m_nFormFieldType == RTFFormFieldType::CHECKBOX && nParam != 25) | ||||
1450 | m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_checked, pIntValue); | ||||
1451 | else if (m_nFormFieldType == RTFFormFieldType::LIST) | ||||
1452 | m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_result, pIntValue); | ||||
1453 | break; | ||||
1454 | case RTF_EDMINS: | ||||
1455 | if (m_xDocumentProperties.is()) | ||||
1456 | { | ||||
1457 | // tdf#116851 some RTF may be malformed | ||||
1458 | if (nParam < 0) | ||||
1459 | nParam = -nParam; | ||||
1460 | m_xDocumentProperties->setEditingDuration(nParam); | ||||
1461 | } | ||||
1462 | break; | ||||
1463 | case RTF_NOFPAGES: | ||||
1464 | case RTF_NOFWORDS: | ||||
1465 | case RTF_NOFCHARS: | ||||
1466 | case RTF_NOFCHARSWS: | ||||
1467 | if (m_xDocumentProperties.is()) | ||||
1468 | { | ||||
1469 | comphelper::SequenceAsHashMap aSeq = m_xDocumentProperties->getDocumentStatistics(); | ||||
1470 | OUString aName; | ||||
1471 | switch (nKeyword) | ||||
1472 | { | ||||
1473 | case RTF_NOFPAGES: | ||||
1474 | aName = "PageCount"; | ||||
1475 | nParam = 99; | ||||
1476 | break; | ||||
1477 | case RTF_NOFWORDS: | ||||
1478 | aName = "WordCount"; | ||||
1479 | break; | ||||
1480 | case RTF_NOFCHARS: | ||||
1481 | aName = "CharacterCount"; | ||||
1482 | break; | ||||
1483 | case RTF_NOFCHARSWS: | ||||
1484 | aName = "NonWhitespaceCharacterCount"; | ||||
1485 | break; | ||||
1486 | default: | ||||
1487 | break; | ||||
1488 | } | ||||
1489 | if (!aName.isEmpty()) | ||||
1490 | { | ||||
1491 | aSeq[aName] <<= sal_Int32(nParam); | ||||
1492 | m_xDocumentProperties->setDocumentStatistics(aSeq.getAsConstNamedValueList()); | ||||
1493 | } | ||||
1494 | } | ||||
1495 | break; | ||||
1496 | case RTF_VERSION: | ||||
1497 | if (m_xDocumentProperties.is()) | ||||
1498 | m_xDocumentProperties->setEditingCycles(nParam); | ||||
1499 | break; | ||||
1500 | case RTF_VERN: | ||||
1501 | // Ignore this for now, later the RTF writer version could be used to add hacks for older buggy writers. | ||||
1502 | break; | ||||
1503 | case RTF_FTNSTART: | ||||
1504 | putNestedSprm(m_aDefaultState.getParagraphSprms(), | ||||
1505 | NS_ooxml::LN_EG_SectPrContents_footnotePr, | ||||
1506 | NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue); | ||||
1507 | break; | ||||
1508 | case RTF_AFTNSTART: | ||||
1509 | putNestedSprm(m_aDefaultState.getParagraphSprms(), | ||||
1510 | NS_ooxml::LN_EG_SectPrContents_endnotePr, | ||||
1511 | NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue); | ||||
1512 | break; | ||||
1513 | case RTF_DFRMTXTX: | ||||
1514 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hSpace, nParam); | ||||
1515 | break; | ||||
1516 | case RTF_DFRMTXTY: | ||||
1517 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vSpace, nParam); | ||||
1518 | break; | ||||
1519 | case RTF_DXFRTEXT: | ||||
1520 | { | ||||
1521 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hSpace, nParam); | ||||
1522 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vSpace, nParam); | ||||
1523 | } | ||||
1524 | break; | ||||
1525 | case RTF_FLYVERT: | ||||
1526 | { | ||||
1527 | RTFVertOrient aVertOrient(nParam); | ||||
1528 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, | ||||
1529 | aVertOrient.GetAlign()); | ||||
1530 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, | ||||
1531 | aVertOrient.GetAnchor()); | ||||
1532 | } | ||||
1533 | break; | ||||
1534 | case RTF_FLYHORZ: | ||||
1535 | { | ||||
1536 | RTFHoriOrient aHoriOrient(nParam); | ||||
1537 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign, | ||||
1538 | aHoriOrient.GetAlign()); | ||||
1539 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, | ||||
1540 | aHoriOrient.GetAnchor()); | ||||
1541 | } | ||||
1542 | break; | ||||
1543 | case RTF_FLYANCHOR: | ||||
1544 | break; | ||||
1545 | case RTF_WMETAFILE: | ||||
1546 | m_aStates.top().getPicture().eWMetafile = nParam; | ||||
1547 | break; | ||||
1548 | case RTF_SB: | ||||
1549 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_spacing, | ||||
1550 | NS_ooxml::LN_CT_Spacing_before, pIntValue); | ||||
1551 | break; | ||||
1552 | case RTF_SA: | ||||
1553 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_spacing, | ||||
1554 | NS_ooxml::LN_CT_Spacing_after, pIntValue); | ||||
1555 | break; | ||||
1556 | case RTF_DPX: | ||||
1557 | m_aStates.top().getDrawingObject().setLeft(convertTwipToMm100(nParam)); | ||||
1558 | break; | ||||
1559 | case RTF_DPY: | ||||
1560 | m_aStates.top().getDrawingObject().setTop(convertTwipToMm100(nParam)); | ||||
1561 | break; | ||||
1562 | case RTF_DPXSIZE: | ||||
1563 | m_aStates.top().getDrawingObject().setRight(convertTwipToMm100(nParam)); | ||||
1564 | break; | ||||
1565 | case RTF_DPYSIZE: | ||||
1566 | m_aStates.top().getDrawingObject().setBottom(convertTwipToMm100(nParam)); | ||||
1567 | break; | ||||
1568 | case RTF_PNSTART: | ||||
1569 | m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Lvl_start, pIntValue); | ||||
1570 | break; | ||||
1571 | case RTF_PNF: | ||||
1572 | { | ||||
1573 | auto pValue = new RTFValue(m_aFontNames[getFontIndex(nParam)]); | ||||
1574 | RTFSprms aAttributes; | ||||
1575 | aAttributes.set(NS_ooxml::LN_CT_Fonts_ascii, pValue); | ||||
1576 | putNestedSprm(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_Lvl_rPr, | ||||
1577 | NS_ooxml::LN_EG_RPrBase_rFonts, new RTFValue(aAttributes)); | ||||
1578 | } | ||||
1579 | break; | ||||
1580 | case RTF_VIEWSCALE: | ||||
1581 | m_aSettingsTableAttributes.set(NS_ooxml::LN_CT_Zoom_percent, pIntValue); | ||||
1582 | break; | ||||
1583 | case RTF_BIN: | ||||
1584 | { | ||||
1585 | m_aStates.top().setInternalState(RTFInternalState::BIN); | ||||
1586 | m_aStates.top().setBinaryToRead(nParam); | ||||
1587 | } | ||||
1588 | break; | ||||
1589 | case RTF_DPLINECOR: | ||||
1590 | m_aStates.top().getDrawingObject().setLineColorR(nParam); | ||||
1591 | m_aStates.top().getDrawingObject().setHasLineColor(true); | ||||
1592 | break; | ||||
1593 | case RTF_DPLINECOG: | ||||
1594 | m_aStates.top().getDrawingObject().setLineColorG(nParam); | ||||
1595 | m_aStates.top().getDrawingObject().setHasLineColor(true); | ||||
1596 | break; | ||||
1597 | case RTF_DPLINECOB: | ||||
1598 | m_aStates.top().getDrawingObject().setLineColorB(nParam); | ||||
1599 | m_aStates.top().getDrawingObject().setHasLineColor(true); | ||||
1600 | break; | ||||
1601 | case RTF_DPFILLBGCR: | ||||
1602 | m_aStates.top().getDrawingObject().setFillColorR(nParam); | ||||
1603 | m_aStates.top().getDrawingObject().setHasFillColor(true); | ||||
1604 | break; | ||||
1605 | case RTF_DPFILLBGCG: | ||||
1606 | m_aStates.top().getDrawingObject().setFillColorG(nParam); | ||||
1607 | m_aStates.top().getDrawingObject().setHasFillColor(true); | ||||
1608 | break; | ||||
1609 | case RTF_DPFILLBGCB: | ||||
1610 | m_aStates.top().getDrawingObject().setFillColorB(nParam); | ||||
1611 | m_aStates.top().getDrawingObject().setHasFillColor(true); | ||||
1612 | break; | ||||
1613 | case RTF_DODHGT: | ||||
1614 | m_aStates.top().getDrawingObject().setDhgt(nParam); | ||||
1615 | break; | ||||
1616 | case RTF_DPPOLYCOUNT: | ||||
1617 | if (nParam >= 0) | ||||
1618 | { | ||||
1619 | m_aStates.top().getDrawingObject().setPolyLineCount(nParam); | ||||
1620 | } | ||||
1621 | break; | ||||
1622 | case RTF_DPPTX: | ||||
1623 | { | ||||
1624 | RTFDrawingObject& rDrawingObject = m_aStates.top().getDrawingObject(); | ||||
1625 | |||||
1626 | if (rDrawingObject.getPolyLinePoints().empty()) | ||||
1627 | dispatchValue(RTF_DPPOLYCOUNT, 2); | ||||
1628 | |||||
1629 | rDrawingObject.getPolyLinePoints().emplace_back( | ||||
1630 | awt::Point(convertTwipToMm100(nParam), 0)); | ||||
1631 | } | ||||
1632 | break; | ||||
1633 | case RTF_DPPTY: | ||||
1634 | { | ||||
1635 | RTFDrawingObject& rDrawingObject = m_aStates.top().getDrawingObject(); | ||||
1636 | if (!rDrawingObject.getPolyLinePoints().empty()) | ||||
1637 | { | ||||
1638 | rDrawingObject.getPolyLinePoints().back().Y = convertTwipToMm100(nParam); | ||||
1639 | rDrawingObject.setPolyLineCount(rDrawingObject.getPolyLineCount() - 1); | ||||
1640 | if (rDrawingObject.getPolyLineCount() == 0 && rDrawingObject.getPropertySet().is()) | ||||
1641 | { | ||||
1642 | uno::Sequence<uno::Sequence<awt::Point>> aPointSequenceSequence | ||||
1643 | = { comphelper::containerToSequence(rDrawingObject.getPolyLinePoints()) }; | ||||
1644 | rDrawingObject.getPropertySet()->setPropertyValue( | ||||
1645 | "PolyPolygon", uno::Any(aPointSequenceSequence)); | ||||
1646 | } | ||||
1647 | } | ||||
1648 | } | ||||
1649 | break; | ||||
1650 | case RTF_SHPFBLWTXT: | ||||
1651 | // Shape is below text -> send it to the background. | ||||
1652 | m_aStates.top().getShape().setInBackground(nParam != 0); | ||||
1653 | break; | ||||
1654 | case RTF_FI: | ||||
1655 | { | ||||
1656 | if (m_aStates.top().getDestination() == Destination::LISTLEVEL) | ||||
1657 | { | ||||
1658 | if (m_aStates.top().getLevelNumbersValid()) | ||||
1659 | putNestedAttribute(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1660 | NS_ooxml::LN_CT_Ind_firstLine, pIntValue); | ||||
1661 | else | ||||
1662 | m_aInvalidListLevelFirstIndents[m_nListLevel] = nParam; | ||||
1663 | } | ||||
1664 | else | ||||
1665 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1666 | NS_ooxml::LN_CT_Ind_firstLine, pIntValue); | ||||
1667 | break; | ||||
1668 | } | ||||
1669 | case RTF_LI: | ||||
1670 | { | ||||
1671 | if (m_aStates.top().getDestination() == Destination::LISTLEVEL) | ||||
1672 | { | ||||
1673 | if (m_aStates.top().getLevelNumbersValid()) | ||||
1674 | putNestedAttribute(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1675 | NS_ooxml::LN_CT_Ind_left, pIntValue); | ||||
1676 | } | ||||
1677 | else | ||||
1678 | { | ||||
1679 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1680 | NS_ooxml::LN_CT_Ind_left, pIntValue); | ||||
1681 | } | ||||
1682 | // It turns out \li should reset the \fi inherited from the stylesheet. | ||||
1683 | // So set the direct formatting to zero, if we don't have such direct formatting yet. | ||||
1684 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1685 | NS_ooxml::LN_CT_Ind_firstLine, new RTFValue(0), | ||||
1686 | RTFOverwrite::NO_IGNORE); | ||||
1687 | } | ||||
1688 | break; | ||||
1689 | case RTF_RI: | ||||
1690 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1691 | NS_ooxml::LN_CT_Ind_right, pIntValue); | ||||
1692 | break; | ||||
1693 | case RTF_LIN: | ||||
1694 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1695 | NS_ooxml::LN_CT_Ind_start, pIntValue); | ||||
1696 | break; | ||||
1697 | case RTF_RIN: | ||||
1698 | putNestedAttribute(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PPrBase_ind, | ||||
1699 | NS_ooxml::LN_CT_Ind_end, pIntValue); | ||||
1700 | break; | ||||
1701 | case RTF_OUTLINELEVEL: | ||||
1702 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_outlineLvl, pIntValue); | ||||
1703 | break; | ||||
1704 | case RTF_PROPTYPE: | ||||
1705 | { | ||||
1706 | switch (nParam) | ||||
1707 | { | ||||
1708 | case 3: | ||||
1709 | m_aStates.top().setPropType(cppu::UnoType<sal_Int32>::get()); | ||||
1710 | break; | ||||
1711 | case 5: | ||||
1712 | m_aStates.top().setPropType(cppu::UnoType<double>::get()); | ||||
1713 | break; | ||||
1714 | case 11: | ||||
1715 | m_aStates.top().setPropType(cppu::UnoType<bool>::get()); | ||||
1716 | break; | ||||
1717 | case 30: | ||||
1718 | m_aStates.top().setPropType(cppu::UnoType<OUString>::get()); | ||||
1719 | break; | ||||
1720 | case 64: | ||||
1721 | m_aStates.top().setPropType(cppu::UnoType<util::DateTime>::get()); | ||||
1722 | break; | ||||
1723 | } | ||||
1724 | } | ||||
1725 | break; | ||||
1726 | case RTF_DIBITMAP: | ||||
1727 | m_aStates.top().getPicture().eStyle = RTFBmpStyle::DIBITMAP; | ||||
1728 | break; | ||||
1729 | case RTF_TRWWIDTHA: | ||||
1730 | m_aStates.top().setTableRowWidthAfter(nParam); | ||||
1731 | break; | ||||
1732 | case RTF_ANIMTEXT: | ||||
1733 | { | ||||
1734 | Id nId = 0; | ||||
1735 | switch (nParam) | ||||
1736 | { | ||||
1737 | case 0: | ||||
1738 | nId = NS_ooxml::LN_Value_ST_TextEffect_none; | ||||
1739 | break; | ||||
1740 | case 2: | ||||
1741 | nId = NS_ooxml::LN_Value_ST_TextEffect_blinkBackground; | ||||
1742 | break; | ||||
1743 | } | ||||
1744 | |||||
1745 | if (nId > 0) | ||||
1746 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_effect, | ||||
1747 | new RTFValue(nId)); | ||||
1748 | break; | ||||
1749 | } | ||||
1750 | case RTF_VIEWBKSP: | ||||
1751 | { | ||||
1752 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_displayBackgroundShape, pIntValue); | ||||
1753 | // Send this token immediately, if it only appears before the first | ||||
1754 | // run, it will be too late, we ignored the background shape already by then. | ||||
1755 | outputSettingsTable(); | ||||
1756 | break; | ||||
1757 | } | ||||
1758 | case RTF_STEXTFLOW: | ||||
1759 | { | ||||
1760 | Id nId = 0; | ||||
1761 | switch (nParam) | ||||
1762 | { | ||||
1763 | case 0: | ||||
1764 | nId = NS_ooxml::LN_Value_ST_TextDirection_lrTb; | ||||
1765 | break; | ||||
1766 | case 1: | ||||
1767 | nId = NS_ooxml::LN_Value_ST_TextDirection_tbRl; | ||||
1768 | break; | ||||
1769 | } | ||||
1770 | |||||
1771 | if (nId > 0) | ||||
1772 | { | ||||
1773 | m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_textDirection, | ||||
1774 | new RTFValue(nId)); | ||||
1775 | } | ||||
1776 | } | ||||
1777 | break; | ||||
1778 | default: | ||||
1779 | { | ||||
1780 | SAL_INFO("writerfilter", "TODO handle value '" << keywordToString(nKeyword) << "'")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "TODO handle value '" << keywordToString(nKeyword) << "'") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchvalue.cxx" ":" "1780" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO handle value '" << keywordToString (nKeyword) << "'"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "TODO handle value '" << keywordToString (nKeyword) << "'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchvalue.cxx" ":" "1780" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "TODO handle value '" << keywordToString(nKeyword ) << "'") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchvalue.cxx" ":" "1780" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO handle value '" << keywordToString (nKeyword) << "'"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "TODO handle value '" << keywordToString (nKeyword) << "'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchvalue.cxx" ":" "1780" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
1781 | aSkip.setParsed(false); | ||||
1782 | } | ||||
1783 | break; | ||||
1784 | } | ||||
1785 | return RTFError::OK; | ||||
1786 | } | ||||
1787 | |||||
1788 | } // namespace rtftok | ||||
1789 | } // namespace writerfilter | ||||
1790 | |||||
1791 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_TOOLS_REF_HXX |
20 | #define INCLUDED_TOOLS_REF_HXX |
21 | |
22 | #include <sal/config.h> |
23 | #include <cassert> |
24 | #include <tools/toolsdllapi.h> |
25 | #include <utility> |
26 | |
27 | /** |
28 | This implements similar functionality to boost::intrusive_ptr |
29 | */ |
30 | |
31 | namespace tools { |
32 | |
33 | /** T must be a class that extends SvRefBase */ |
34 | template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final { |
35 | public: |
36 | SvRef(): pObj(nullptr) {} |
37 | |
38 | SvRef(SvRef&& rObj) noexcept |
39 | { |
40 | pObj = rObj.pObj; |
41 | rObj.pObj = nullptr; |
42 | } |
43 | |
44 | SvRef(SvRef const & rObj): pObj(rObj.pObj) |
45 | { |
46 | if (pObj != nullptr) pObj->AddNextRef(); |
47 | } |
48 | |
49 | SvRef(T * pObjP): pObj(pObjP) |
50 | { |
51 | if (pObj != nullptr) pObj->AddFirstRef(); |
52 | } |
53 | |
54 | ~SvRef() |
55 | { |
56 | if (pObj != nullptr) pObj->ReleaseRef(); |
57 | } |
58 | |
59 | void clear() |
60 | { |
61 | if (pObj != nullptr) { |
62 | T * pRefObj = pObj; |
63 | pObj = nullptr; |
64 | pRefObj->ReleaseRef(); |
65 | } |
66 | } |
67 | |
68 | SvRef & operator =(SvRef const & rObj) |
69 | { |
70 | if (rObj.pObj != nullptr) { |
71 | rObj.pObj->AddNextRef(); |
72 | } |
73 | T * pRefObj = pObj; |
74 | pObj = rObj.pObj; |
75 | if (pRefObj != nullptr) { |
76 | pRefObj->ReleaseRef(); |
77 | } |
78 | return *this; |
79 | } |
80 | |
81 | SvRef & operator =(SvRef && rObj) |
82 | { |
83 | if (pObj != nullptr) { |
84 | pObj->ReleaseRef(); |
85 | } |
86 | pObj = rObj.pObj; |
87 | rObj.pObj = nullptr; |
88 | return *this; |
89 | } |
90 | |
91 | bool is() const { return pObj != nullptr; } |
92 | |
93 | explicit operator bool() const { return is(); } |
94 | |
95 | T * get() const { return pObj; } |
96 | |
97 | T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 97, __extension__ __PRETTY_FUNCTION__)); return pObj; } |
98 | |
99 | T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 99, __extension__ __PRETTY_FUNCTION__)); return *pObj; } |
100 | |
101 | bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; } |
102 | bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); } |
103 | |
104 | private: |
105 | T * pObj; |
106 | }; |
107 | |
108 | /** |
109 | * This implements similar functionality to std::make_shared. |
110 | */ |
111 | template<typename T, typename... Args> |
112 | SvRef<T> make_ref(Args&& ... args) |
113 | { |
114 | return SvRef<T>(new T(std::forward<Args>(args)...)); |
115 | } |
116 | |
117 | } |
118 | |
119 | /** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */ |
120 | class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase |
121 | { |
122 | // work around a clang 3.5 optimization bug: if the bNoDelete is *first* |
123 | // it mis-compiles "if (--nRefCount == 0)" and never deletes any object |
124 | unsigned int nRefCount : 31; |
125 | // the only reason this is not bool is because MSVC cannot handle mixed type bitfields |
126 | unsigned int bNoDelete : 1; |
127 | |
128 | protected: |
129 | virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE; |
130 | |
131 | public: |
132 | SvRefBase() : nRefCount(0), bNoDelete(1) {} |
133 | SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {} |
134 | |
135 | SvRefBase & operator=(const SvRefBase &) { return *this; } |
136 | |
137 | void RestoreNoDelete() |
138 | { bNoDelete = 1; } |
139 | |
140 | void AddNextRef() |
141 | { |
142 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 142, __extension__ __PRETTY_FUNCTION__)); |
143 | ++nRefCount; |
144 | } |
145 | |
146 | void AddFirstRef() |
147 | { |
148 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 148, __extension__ __PRETTY_FUNCTION__)); |
149 | if( bNoDelete ) |
150 | bNoDelete = 0; |
151 | ++nRefCount; |
152 | } |
153 | |
154 | void ReleaseRef() |
155 | { |
156 | assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail ("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 156, __extension__ __PRETTY_FUNCTION__)); |
157 | if( --nRefCount == 0 && !bNoDelete) |
158 | { |
159 | // I'm not sure about the original purpose of this line, but right now |
160 | // it serves the purpose that anything that attempts to do an AddRef() |
161 | // after an object is deleted will trip an assert. |
162 | nRefCount = 1 << 30; |
163 | delete this; |
164 | } |
165 | } |
166 | |
167 | unsigned int GetRefCount() const |
168 | { return nRefCount; } |
169 | }; |
170 | |
171 | template<typename T> |
172 | class SvCompatWeakBase; |
173 | |
174 | /** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T. |
175 | */ |
176 | template<typename T> |
177 | class SvCompatWeakHdl final : public SvRefBase |
178 | { |
179 | friend class SvCompatWeakBase<T>; |
180 | T* _pObj; |
181 | |
182 | SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {} |
183 | |
184 | public: |
185 | void ResetWeakBase( ) { _pObj = nullptr; } |
186 | T* GetObj() { return _pObj; } |
187 | }; |
188 | |
189 | /** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame. |
190 | Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted. |
191 | */ |
192 | template<typename T> |
193 | class SvCompatWeakBase |
194 | { |
195 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
196 | |
197 | public: |
198 | /** Does not use initializer due to compiler warnings, |
199 | because the lifetime of the _xHdl object can exceed the lifetime of this class. |
200 | */ |
201 | SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); } |
202 | |
203 | ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); } |
204 | |
205 | SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); } |
206 | }; |
207 | |
208 | /** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak. |
209 | */ |
210 | template<typename T> |
211 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef |
212 | { |
213 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
214 | public: |
215 | SvCompatWeakRef( ) {} |
216 | SvCompatWeakRef( T* pObj ) |
217 | { if( pObj ) _xHdl = pObj->GetHdl(); } |
218 | #if defined(__COVERITY__) |
219 | ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {} |
220 | #endif |
221 | SvCompatWeakRef& operator = ( T * pObj ) |
222 | { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; } |
223 | bool is() const |
224 | { return _xHdl.is() && _xHdl->GetObj(); } |
225 | explicit operator bool() const { return is(); } |
226 | T* operator -> () const |
227 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } |
228 | operator T* () const |
229 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } |
230 | }; |
231 | |
232 | #endif |
233 | |
234 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |