Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Initial Developer of the Original Code is
16 : * Miklos Vajna <vmiklos@frugalware.org>
17 : * Portions created by the Initial Developer are Copyright (C) 2011 the
18 : * Initial Developer. All Rights Reserved.
19 : *
20 : * Contributor(s):
21 : *
22 : * Alternatively, the contents of this file may be used under the terms of
23 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : * instead of those above.
27 : */
28 :
29 : #include <com/sun/star/beans/PropertyAttribute.hpp>
30 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
31 : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
32 : #include <com/sun/star/graphic/GraphicProvider.hpp>
33 : #include <com/sun/star/io/UnexpectedEOFException.hpp>
34 : #include <com/sun/star/lang/XServiceInfo.hpp>
35 : #include <com/sun/star/text/XTextFrame.hpp>
36 : #include <com/sun/star/text/SizeType.hpp>
37 : #include <com/sun/star/text/HoriOrientation.hpp>
38 : #include <com/sun/star/text/VertOrientation.hpp>
39 : #include <com/sun/star/text/RelOrientation.hpp>
40 : #include <com/sun/star/text/WrapTextMode.hpp>
41 : #include <rtl/tencinfo.h>
42 : #include <svtools/wmf.hxx>
43 : #include <svl/lngmisc.hxx>
44 : #include <unotools/ucbstreamhelper.hxx>
45 : #include <unotools/streamwrap.hxx>
46 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
47 : #include <rtl/ustring.hxx>
48 : #include <vcl/graph.hxx>
49 : #include <svtools/grfmgr.hxx>
50 : #include <vcl/svapp.hxx>
51 : #include <filter/msfilter/util.hxx>
52 : #include <filter/msfilter/escherex.hxx>
53 : #include <comphelper/string.hxx>
54 : #include <tools/globname.hxx>
55 : #include <comphelper/classids.hxx>
56 : #include <comphelper/embeddedobjectcontainer.hxx>
57 : #include <sfx2/sfxbasemodel.hxx>
58 :
59 : #include <oox/mathml/import.hxx>
60 : #include <doctok/sprmids.hxx> // NS_sprm namespace
61 : #include <doctok/resourceids.hxx> // NS_rtf namespace
62 : #include <ooxml/resourceids.hxx> // NS_ooxml namespace
63 : #include <ooxml/OOXMLFastTokens.hxx> // ooxml namespace
64 : #include <oox/token/namespaces.hxx> // oox namespace
65 : #include <oox/token/tokens.hxx>
66 :
67 : #include <rtfsdrimport.hxx>
68 : #include <rtftokenizer.hxx>
69 : #include <rtfcharsets.hxx>
70 : #include <rtfreferenceproperties.hxx>
71 : #include <rtfskipdestination.hxx>
72 : #include <rtffly.hxx>
73 :
74 : #define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
75 : #define M_TOKEN(token) OOX_TOKEN(officeMath, token)
76 : #define OPEN_M_TOKEN( rtftok, ooxtok ) \
77 : case RTF_M##rtftok: \
78 : m_aMathBuffer.appendOpeningTag(M_TOKEN(ooxtok)); \
79 : m_aStates.top().nDestinationState = DESTINATION_M##rtftok; \
80 : break
81 :
82 : using std::make_pair;
83 : using rtl::OString;
84 : using rtl::OStringBuffer;
85 : using rtl::OUString;
86 : using rtl::OUStringBuffer;
87 : using rtl::OUStringToOString;
88 :
89 : namespace writerfilter {
90 : namespace rtftok {
91 :
92 69 : static Id lcl_getParagraphBorder(sal_uInt32 nIndex)
93 : {
94 : static const Id aBorderIds[] =
95 : {
96 : NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight
97 : };
98 :
99 69 : return aBorderIds[nIndex];
100 : }
101 :
102 2051 : static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue,
103 : bool bOverwrite = true, bool bAttribute = true)
104 : {
105 2051 : RTFValue::Pointer_t pParent = rSprms.find(nParent);
106 2051 : if (!pParent.get())
107 : {
108 683 : RTFSprms aAttributes;
109 683 : if (nParent == NS_ooxml::LN_CT_TcPrBase_shd)
110 : {
111 : // RTF default is 'auto', see writerfilter::dmapper::CellColorHandler
112 1 : aAttributes.set(NS_ooxml::LN_CT_Shd_color, RTFValue::Pointer_t(new RTFValue(0x0a)));
113 1 : aAttributes.set(NS_ooxml::LN_CT_Shd_fill, RTFValue::Pointer_t(new RTFValue(0x0a)));
114 : }
115 683 : RTFValue::Pointer_t pParentValue(new RTFValue(aAttributes));
116 683 : rSprms.set(nParent, pParentValue, bOverwrite);
117 683 : pParent = pParentValue;
118 : }
119 2051 : RTFSprms& rAttributes = (bAttribute ? pParent->getAttributes() : pParent->getSprms());
120 2051 : rAttributes.set(nId, pValue, bOverwrite);
121 2051 : }
122 :
123 804 : static void lcl_putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue, bool bOverwrite = false)
124 : {
125 804 : lcl_putNestedAttribute(rSprms, nParent, nId, pValue, bOverwrite, false);
126 804 : }
127 :
128 64 : static bool lcl_eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId)
129 : {
130 64 : RTFValue::Pointer_t pParent = rSprms.find(nParent);
131 64 : if (!pParent.get())
132 : // It doesn't even have a parent, we're done!
133 64 : return false;
134 0 : RTFSprms& rAttributes = pParent->getAttributes();
135 0 : return rAttributes.erase(nId);
136 : }
137 :
138 349 : static RTFSprms& lcl_getLastAttributes(RTFSprms& rSprms, Id nId)
139 : {
140 349 : RTFValue::Pointer_t p = rSprms.find(nId);
141 349 : if (p.get() && p->getSprms().size())
142 295 : return p->getSprms().back().second->getAttributes();
143 : else
144 : {
145 : SAL_WARN("writerfilter", "trying to set property when no type is defined");
146 54 : return rSprms;
147 349 : }
148 : }
149 :
150 380 : static void lcl_putBorderProperty(std::stack<RTFParserState>& aStates, Id nId, RTFValue::Pointer_t pValue)
151 : {
152 380 : RTFSprms* pAttributes = 0;
153 380 : if (aStates.top().nBorderState == BORDER_PARAGRAPH_BOX)
154 65 : for (int i = 0; i < 4; i++)
155 : {
156 52 : RTFValue::Pointer_t p = aStates.top().aParagraphSprms.find(lcl_getParagraphBorder(i));
157 52 : if (p.get())
158 : {
159 52 : RTFSprms& rAttributes = p->getAttributes();
160 52 : rAttributes.set(nId, pValue);
161 : }
162 52 : }
163 : // Attributes of the last border type
164 367 : else if (aStates.top().nBorderState == BORDER_PARAGRAPH)
165 3 : pAttributes = &lcl_getLastAttributes(aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr);
166 364 : else if (aStates.top().nBorderState == BORDER_CELL)
167 346 : pAttributes = &lcl_getLastAttributes(aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders);
168 18 : else if (aStates.top().nBorderState == BORDER_PAGE)
169 0 : pAttributes = &lcl_getLastAttributes(aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders);
170 380 : if (pAttributes)
171 349 : pAttributes->set(nId, pValue);
172 380 : }
173 :
174 2 : static OString lcl_DTTM22OString(long lDTTM)
175 : {
176 2 : return msfilter::util::DateTimeToOString(msfilter::util::DTTM2DateTime(lDTTM));
177 : }
178 :
179 0 : static writerfilter::Reference<Properties>::Pointer_t lcl_getBookmarkProperties(int nPos, OUString& rString)
180 : {
181 0 : RTFSprms aAttributes;
182 0 : RTFValue::Pointer_t pPos(new RTFValue(nPos));
183 0 : if (!rString.isEmpty())
184 : {
185 : // If present, this should be sent first.
186 0 : RTFValue::Pointer_t pString(new RTFValue(rString));
187 0 : aAttributes.set(NS_rtf::LN_BOOKMARKNAME, pString);
188 : }
189 0 : aAttributes.set(NS_rtf::LN_IBKL, pPos);
190 0 : return writerfilter::Reference<Properties>::Pointer_t(new RTFReferenceProperties(aAttributes));
191 : }
192 :
193 0 : static writerfilter::Reference<Properties>::Pointer_t lcl_getBookmarkProperties(int nPos)
194 : {
195 0 : OUString aStr;
196 0 : return lcl_getBookmarkProperties(nPos, aStr);
197 : }
198 :
199 0 : static const char* lcl_RtfToString(RTFKeyword nKeyword)
200 : {
201 0 : for (int i = 0; i < nRTFControlWords; i++)
202 : {
203 0 : if (nKeyword == aRTFControlWords[i].nIndex)
204 0 : return aRTFControlWords[i].sKeyword;
205 : }
206 0 : return NULL;
207 : }
208 :
209 89 : static util::DateTime lcl_getDateTime(std::stack<RTFParserState>& aStates)
210 : {
211 178 : return util::DateTime(0 /*100sec*/, 0 /*sec*/, aStates.top().nMinute, aStates.top().nHour,
212 267 : aStates.top().nDay, aStates.top().nMonth, aStates.top().nYear);
213 : }
214 :
215 1264 : static void lcl_DestinationToMath(OUStringBuffer& rDestinationText, oox::formulaimport::XmlStreamBuilder& rMathBuffer)
216 : {
217 1264 : OUString aStr = rDestinationText.makeStringAndClear();
218 1264 : if (!aStr.isEmpty())
219 : {
220 493 : rMathBuffer.appendOpeningTag(M_TOKEN(r));
221 493 : rMathBuffer.appendOpeningTag(M_TOKEN(t));
222 493 : rMathBuffer.appendCharacters(aStr);
223 493 : rMathBuffer.appendClosingTag(M_TOKEN(t));
224 493 : rMathBuffer.appendClosingTag(M_TOKEN(r));
225 1264 : }
226 1264 : }
227 :
228 138 : RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& xContext,
229 : uno::Reference<io::XInputStream> const& xInputStream,
230 : uno::Reference<lang::XComponent> const& xDstDoc,
231 : uno::Reference<frame::XFrame> const& xFrame,
232 : uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
233 : : m_xContext(xContext),
234 : m_xInputStream(xInputStream),
235 : m_xDstDoc(xDstDoc),
236 : m_xFrame(xFrame),
237 : m_xStatusIndicator(xStatusIndicator),
238 : m_aDefaultState(this),
239 : m_bSkipUnknown(false),
240 : m_aFontEncodings(),
241 : m_aFontIndexes(),
242 : m_aColorTable(),
243 : m_bFirstRun(true),
244 : m_bNeedPap(true),
245 : m_bNeedCr(false),
246 : m_bNeedPar(true),
247 : m_bNeedFinalPar(false),
248 : m_aListTableSprms(),
249 : m_aSettingsTableAttributes(),
250 : m_aSettingsTableSprms(),
251 : m_xStorage(),
252 : m_aTableBuffer(),
253 : m_aSuperBuffer(),
254 : m_aShapetextBuffer(),
255 : m_pCurrentBuffer(0),
256 : m_bHasFootnote(false),
257 : m_pSuperstream(0),
258 : m_nHeaderFooterPositions(),
259 : m_nGroupStartPos(0),
260 : m_aBookmarks(),
261 : m_aAuthors(),
262 : m_aFormfieldSprms(),
263 : m_aFormfieldAttributes(),
264 : m_nFormFieldType(FORMFIELD_NONE),
265 : m_aObjectSprms(),
266 : m_aObjectAttributes(),
267 : m_bObject(false),
268 : m_aFontTableEntries(),
269 : m_nCurrentFontIndex(0),
270 : m_aStyleTableEntries(),
271 : m_nCurrentStyleIndex(0),
272 : m_bFormField(false),
273 : m_bIsInFrame(false),
274 : m_aUnicodeBuffer(),
275 : m_aHexBuffer(),
276 : m_bIgnoreNextContSectBreak(false),
277 : m_bNeedSect(true),
278 : m_bWasInFrame(false),
279 : m_bHadPicture(false),
280 138 : m_bHadSect(false)
281 : {
282 : OSL_ASSERT(xInputStream.is());
283 138 : m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True));
284 :
285 138 : m_xModelFactory.set(m_xDstDoc, uno::UNO_QUERY);
286 :
287 138 : uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(m_xDstDoc, uno::UNO_QUERY);
288 138 : if (xDocumentPropertiesSupplier.is())
289 127 : m_xDocumentProperties.set(xDocumentPropertiesSupplier->getDocumentProperties(), uno::UNO_QUERY);
290 :
291 138 : m_pGraphicHelper.reset(new oox::GraphicHelper(m_xContext, xFrame, m_xStorage));
292 :
293 138 : m_pTokenizer.reset(new RTFTokenizer(*this, m_pInStream.get(), m_xStatusIndicator));
294 138 : m_pSdrImport.reset(new RTFSdrImport(*this, m_xDstDoc));
295 138 : }
296 :
297 276 : RTFDocumentImpl::~RTFDocumentImpl()
298 : {
299 276 : }
300 :
301 1546727 : SvStream& RTFDocumentImpl::Strm()
302 : {
303 1546727 : return *m_pInStream;
304 : }
305 :
306 20740 : Stream& RTFDocumentImpl::Mapper()
307 : {
308 20740 : return *m_pMapperStream;
309 : }
310 :
311 9 : void RTFDocumentImpl::setSuperstream(RTFDocumentImpl *pSuperstream)
312 : {
313 9 : m_pSuperstream = pSuperstream;
314 9 : }
315 :
316 2 : void RTFDocumentImpl::setAuthor(rtl::OUString& rAuthor)
317 : {
318 2 : m_aAuthor = rAuthor;
319 2 : }
320 :
321 2 : void RTFDocumentImpl::setAuthorInitials(rtl::OUString& rAuthorInitials)
322 : {
323 2 : m_aAuthorInitials = rAuthorInitials;
324 2 : }
325 :
326 135 : bool RTFDocumentImpl::isSubstream() const
327 : {
328 135 : return m_pSuperstream != 0;
329 : }
330 :
331 9 : void RTFDocumentImpl::finishSubstream()
332 : {
333 9 : checkUnicode();
334 : // At the end of a footnote stream, we need to emit a run break when importing from Word.
335 : // We can't do so unconditionally, as Writer already writes a \par at the end of the footnote.
336 9 : if (m_bNeedCr)
337 : {
338 0 : Mapper().startCharacterGroup();
339 0 : runBreak();
340 0 : Mapper().endCharacterGroup();
341 : }
342 9 : }
343 :
344 9 : void RTFDocumentImpl::setIgnoreFirst(OUString& rIgnoreFirst)
345 : {
346 9 : m_aIgnoreFirst = rIgnoreFirst;
347 9 : }
348 :
349 6 : void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId)
350 : {
351 6 : OUString aStr;
352 6 : resolveSubstream(nPos, nId, aStr);
353 6 : }
354 9 : void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId, OUString& rIgnoreFirst)
355 : {
356 9 : sal_uInt32 nCurrent = Strm().Tell();
357 : // Seek to header position, parse, then seek back.
358 9 : RTFDocumentImpl::Pointer_t pImpl(new RTFDocumentImpl(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator));
359 9 : pImpl->setSuperstream(this);
360 9 : pImpl->setIgnoreFirst(rIgnoreFirst);
361 9 : if (!m_aAuthor.isEmpty())
362 : {
363 2 : pImpl->setAuthor(m_aAuthor);
364 2 : m_aAuthor = OUString();
365 : }
366 9 : if (!m_aAuthorInitials.isEmpty())
367 : {
368 2 : pImpl->setAuthorInitials(m_aAuthorInitials);
369 2 : m_aAuthorInitials = OUString();
370 : }
371 9 : pImpl->seek(nPos);
372 : SAL_INFO("writerfilter", "substream start");
373 9 : Mapper().substream(nId, pImpl);
374 : SAL_INFO("writerfilter", "substream end");
375 9 : Strm().Seek(nCurrent);
376 9 : nPos = 0;
377 9 : }
378 :
379 4954 : void RTFDocumentImpl::checkFirstRun()
380 : {
381 4954 : if (m_bFirstRun)
382 : {
383 : // output settings table
384 133 : writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(m_aSettingsTableAttributes, m_aSettingsTableSprms));
385 133 : RTFReferenceTable::Entries_t aSettingsTableEntries;
386 133 : aSettingsTableEntries.insert(make_pair(0, pProp));
387 133 : writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aSettingsTableEntries));
388 133 : Mapper().table(NS_ooxml::LN_settings_settings, pTable);
389 : // start initial paragraph
390 133 : if (!m_pSuperstream)
391 124 : Mapper().startSectionGroup();
392 133 : Mapper().startParagraphGroup();
393 133 : m_bFirstRun = false;
394 : }
395 4954 : }
396 :
397 123 : bool RTFDocumentImpl::getFirstRun()
398 : {
399 123 : return m_bFirstRun;
400 : }
401 :
402 6 : void RTFDocumentImpl::setNeedPar(bool bNeedPar)
403 : {
404 6 : m_bNeedPar = bNeedPar;
405 6 : }
406 :
407 51195 : void RTFDocumentImpl::setNeedSect(bool bNeedSect)
408 : {
409 51195 : m_bNeedSect = bNeedSect;
410 51195 : }
411 :
412 4436 : writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
413 : {
414 4436 : int nStyle = m_aStates.top().nCurrentStyleIndex;
415 4436 : RTFReferenceTable::Entries_t::iterator it = m_aStyleTableEntries.find(nStyle);
416 4436 : if (it != m_aStyleTableEntries.end())
417 : {
418 202 : RTFReferenceProperties& rProps = *(RTFReferenceProperties*)it->second.get();
419 : // Get rid of direct formatting what is already in the style.
420 202 : rSprms.deduplicate(rProps.getSprms());
421 202 : rAttributes.deduplicate(rProps.getAttributes());
422 : }
423 4436 : writerfilter::Reference<Properties>::Pointer_t pRet(new RTFReferenceProperties(rAttributes, rSprms));
424 4436 : return pRet;
425 : }
426 :
427 4841 : void RTFDocumentImpl::checkNeedPap()
428 : {
429 4841 : if (m_bNeedPap)
430 : {
431 431 : m_bNeedPap = false; // reset early, so we can avoid recursion when calling ourselves
432 431 : if (!m_pCurrentBuffer)
433 : {
434 : writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
435 668 : getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
436 668 : );
437 :
438 : // Writer will ignore a page break before a text frame, so guard it with empty paragraphs
439 334 : bool hasBreakBeforeFrame = m_aStates.top().aFrame.hasProperties() &&
440 668 : m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PFPageBreakBefore).get();
441 334 : if (hasBreakBeforeFrame)
442 : {
443 0 : dispatchSymbol(RTF_PAR);
444 0 : m_bNeedPap = false;
445 : }
446 334 : Mapper().props(pParagraphProperties);
447 334 : if (hasBreakBeforeFrame)
448 0 : dispatchSymbol(RTF_PAR);
449 :
450 334 : if (m_aStates.top().aFrame.hasProperties())
451 : {
452 : writerfilter::Reference<Properties>::Pointer_t const pFrameProperties(
453 17 : new RTFReferenceProperties(RTFSprms(), m_aStates.top().aFrame.getSprms()));
454 17 : Mapper().props(pFrameProperties);
455 334 : }
456 : }
457 : else
458 : {
459 97 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
460 97 : m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
461 : }
462 : }
463 4841 : }
464 :
465 4237 : void RTFDocumentImpl::runProps()
466 : {
467 4237 : if (!m_pCurrentBuffer)
468 : {
469 4078 : writerfilter::Reference<Properties>::Pointer_t const pProperties = getProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms);
470 4078 : Mapper().props(pProperties);
471 : }
472 : else
473 : {
474 159 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms));
475 159 : m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
476 : }
477 4237 : }
478 :
479 514 : void RTFDocumentImpl::runBreak()
480 : {
481 514 : sal_uInt8 sBreak[] = { 0xd };
482 514 : Mapper().text(sBreak, 1);
483 514 : m_bNeedCr = false;
484 514 : }
485 :
486 123 : void RTFDocumentImpl::tableBreak()
487 : {
488 123 : runBreak();
489 123 : Mapper().endParagraphGroup();
490 123 : Mapper().startParagraphGroup();
491 123 : }
492 :
493 388 : void RTFDocumentImpl::parBreak()
494 : {
495 388 : checkFirstRun();
496 388 : checkNeedPap();
497 : // end previous paragraph
498 388 : Mapper().startCharacterGroup();
499 388 : runBreak();
500 388 : Mapper().endCharacterGroup();
501 388 : Mapper().endParagraphGroup();
502 :
503 388 : m_bHadPicture = false;
504 :
505 : // start new one
506 388 : Mapper().startParagraphGroup();
507 388 : }
508 :
509 137 : void RTFDocumentImpl::sectBreak(bool bFinal = false)
510 : {
511 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": final? " << bFinal << ", needed? " << m_bNeedSect);
512 137 : bool bNeedSect = m_bNeedSect;
513 : // If there is no paragraph in this section, then insert a dummy one, as required by Writer
514 137 : if (m_bNeedPar)
515 6 : dispatchSymbol(RTF_PAR);
516 : // It's allowed to not have a non-table paragraph at the end of an RTF doc, add it now if required.
517 137 : if (m_bNeedFinalPar && bFinal)
518 : {
519 1 : dispatchFlag(RTF_PARD);
520 1 : dispatchSymbol(RTF_PAR);
521 : }
522 278 : while (m_nHeaderFooterPositions.size())
523 : {
524 4 : std::pair<Id, sal_uInt32> aPair = m_nHeaderFooterPositions.front();
525 4 : m_nHeaderFooterPositions.pop();
526 4 : resolveSubstream(aPair.second, aPair.first);
527 : }
528 :
529 : // Normally a section break at the end of the doc is necessary. Unless the
530 : // last control word in the document is a section break itself.
531 137 : if (!bNeedSect || !m_bHadSect)
532 : {
533 131 : RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
534 : // In case the last section is a continous one, we don't need to output a section break.
535 131 : if (bFinal && pBreak.get() && !pBreak->getInt())
536 37 : m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc);
537 : }
538 :
539 : // Section properties are a paragraph sprm.
540 137 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aSectionAttributes, m_aStates.top().aSectionSprms));
541 137 : RTFSprms aAttributes;
542 137 : RTFSprms aSprms;
543 137 : aSprms.set(NS_ooxml::LN_CT_PPr_sectPr, pValue);
544 : writerfilter::Reference<Properties>::Pointer_t const pProperties(
545 137 : new RTFReferenceProperties(aAttributes, aSprms)
546 274 : );
547 : // The trick is that we send properties of the previous section right now, which will be exactly what dmapper expects.
548 137 : Mapper().props(pProperties);
549 137 : Mapper().endParagraphGroup();
550 137 : if (!m_pSuperstream)
551 128 : Mapper().endSectionGroup();
552 137 : if (!bFinal)
553 : {
554 5 : Mapper().startSectionGroup();
555 5 : Mapper().startParagraphGroup();
556 : }
557 137 : m_bNeedPar = true;
558 137 : m_bNeedSect = false;
559 137 : }
560 :
561 9 : void RTFDocumentImpl::seek(sal_uInt32 nPos)
562 : {
563 9 : Strm().Seek(nPos);
564 9 : }
565 :
566 168 : sal_uInt32 RTFDocumentImpl::getColorTable(sal_uInt32 nIndex)
567 : {
568 168 : if (nIndex < m_aColorTable.size())
569 156 : return m_aColorTable[nIndex];
570 12 : return 0;
571 : }
572 :
573 1140 : rtl_TextEncoding RTFDocumentImpl::getEncoding(sal_uInt32 nFontIndex)
574 : {
575 1140 : if (!m_pSuperstream)
576 : {
577 1136 : std::map<int, rtl_TextEncoding>::iterator it = m_aFontEncodings.find(nFontIndex);
578 1136 : if (it != m_aFontEncodings.end())
579 696 : return it->second;
580 440 : return msfilter::util::getBestTextEncodingFromLocale(Application::GetSettings().GetLanguageTag().getLocale());
581 : }
582 : else
583 4 : return m_pSuperstream->getEncoding(nFontIndex);
584 : }
585 :
586 1468 : int RTFDocumentImpl::getFontIndex(int nIndex)
587 : {
588 1468 : if (!m_pSuperstream)
589 1467 : return std::find(m_aFontIndexes.begin(), m_aFontIndexes.end(), nIndex) - m_aFontIndexes.begin();
590 : else
591 1 : return m_pSuperstream->getFontIndex(nIndex);
592 : }
593 :
594 328 : RTFParserState& RTFDocumentImpl::getDefaultState()
595 : {
596 328 : if (!m_pSuperstream)
597 318 : return m_aDefaultState;
598 : else
599 10 : return m_pSuperstream->getDefaultState();
600 : }
601 :
602 138 : void RTFDocumentImpl::resolve(Stream & rMapper)
603 : {
604 138 : m_pMapperStream = &rMapper;
605 138 : switch (m_pTokenizer->resolveParse())
606 : {
607 : case ERROR_OK:
608 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": finished without errors");
609 135 : break;
610 : case ERROR_GROUP_UNDER:
611 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unmatched '}'");
612 0 : break;
613 : case ERROR_GROUP_OVER:
614 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unmatched '{'");
615 2 : throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
616 : break;
617 : case ERROR_EOF:
618 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unexpected end of file");
619 0 : throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
620 : break;
621 : case ERROR_HEX_INVALID:
622 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": invalid hex char");
623 0 : throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
624 : break;
625 : case ERROR_CHAR_OVER:
626 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": characters after last '}'");
627 0 : break;
628 : }
629 135 : }
630 :
631 9 : int RTFDocumentImpl::resolvePict(bool bInline)
632 : {
633 9 : SvMemoryStream aStream;
634 9 : SvStream *pStream = 0;
635 9 : if (!m_pBinaryData.get())
636 : {
637 8 : pStream = &aStream;
638 8 : int b = 0, count = 2;
639 :
640 : // Feed the destination text to a stream.
641 8 : OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
642 8 : const char *str = aStr.getStr();
643 39696 : for (int i = 0; i < aStr.getLength(); ++i)
644 : {
645 39688 : char ch = str[i];
646 39688 : if (ch != 0x0d && ch != 0x0a && ch != 0x20)
647 : {
648 39688 : b = b << 4;
649 39688 : sal_Int8 parsed = m_pTokenizer->asHex(ch);
650 39688 : if (parsed == -1)
651 0 : return ERROR_HEX_INVALID;
652 39688 : b += parsed;
653 39688 : count--;
654 39688 : if (!count)
655 : {
656 19844 : aStream << (char)b;
657 19844 : count = 2;
658 19844 : b = 0;
659 : }
660 : }
661 8 : }
662 : }
663 : else
664 1 : pStream = m_pBinaryData.get();
665 :
666 9 : if (!pStream->Tell())
667 : // No destination text? Then we'll get it later.
668 1 : return 0;
669 :
670 : // Store, and get its URL.
671 8 : pStream->Seek(0);
672 8 : uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(pStream));
673 8 : WMF_EXTERNALHEADER aExtHeader;
674 8 : aExtHeader.mapMode = m_aStates.top().aPicture.eWMetafile;
675 8 : aExtHeader.xExt = m_aStates.top().aPicture.nWidth;
676 8 : aExtHeader.yExt = m_aStates.top().aPicture.nHeight;
677 8 : WMF_EXTERNALHEADER* pExtHeader = &aExtHeader;
678 8 : uno::Reference<lang::XServiceInfo> xServiceInfo(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
679 8 : if (xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
680 0 : pExtHeader = 0;
681 8 : OUString aGraphicUrl = m_pGraphicHelper->importGraphicObject(xInputStream, pExtHeader);
682 :
683 8 : if (m_aStates.top().aPicture.nStyle != BMPSTYLE_NONE)
684 : {
685 : // In case of PNG/JPEG, the real size is known, don't use the values
686 : // provided by picw and pich.
687 6 : OString aURLBS(OUStringToOString(aGraphicUrl, RTL_TEXTENCODING_UTF8));
688 6 : const char aURLBegin[] = "vnd.sun.star.GraphicObject:";
689 6 : if (aURLBS.compareTo(aURLBegin, RTL_CONSTASCII_LENGTH(aURLBegin)) == 0)
690 : {
691 6 : Graphic aGraphic = GraphicObject(aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin))).GetTransformedGraphic();
692 6 : Size aSize(aGraphic.GetPrefSize());
693 6 : MapMode aMap(MAP_100TH_MM);
694 6 : if (aGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL)
695 5 : aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap);
696 : else
697 1 : aSize = OutputDevice::LogicToLogic(aSize, aGraphic.GetPrefMapMode(), aMap);
698 6 : m_aStates.top().aPicture.nWidth = aSize.Width();
699 6 : m_aStates.top().aPicture.nHeight = aSize.Height();
700 6 : }
701 : }
702 :
703 : // Wrap it in an XShape.
704 8 : uno::Reference<drawing::XShape> xShape;
705 8 : if (m_xModelFactory.is())
706 8 : xShape.set(m_xModelFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY);
707 8 : uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
708 8 : uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier( m_xDstDoc, uno::UNO_QUERY);
709 8 : if ( xDrawSupplier.is() )
710 : {
711 8 : uno::Reference< drawing::XShapes > xShapes( xDrawSupplier->getDrawPage(), uno::UNO_QUERY );
712 8 : if ( xShapes.is() )
713 8 : xShapes->add( xShape );
714 : }
715 8 : if (m_bObject)
716 : {
717 : // Set bitmap
718 0 : beans::PropertyValues aMediaProperties(1);
719 0 : aMediaProperties[0].Name = "URL";
720 0 : aMediaProperties[0].Value <<= aGraphicUrl;
721 0 : uno::Reference<graphic::XGraphicProvider> xGraphicProvider(graphic::GraphicProvider::create(m_xContext));
722 0 : uno::Reference<graphic::XGraphic> xGraphic = xGraphicProvider->queryGraphic(aMediaProperties);
723 0 : xPropertySet->setPropertyValue("Graphic", uno::Any(xGraphic));
724 :
725 : // Set the object size
726 0 : awt::Size aSize;
727 0 : aSize.Width = (m_aStates.top().aPicture.nGoalWidth ? m_aStates.top().aPicture.nGoalWidth : m_aStates.top().aPicture.nWidth);
728 0 : aSize.Height = (m_aStates.top().aPicture.nGoalHeight ? m_aStates.top().aPicture.nGoalHeight : m_aStates.top().aPicture.nHeight);
729 0 : xShape->setSize( aSize );
730 :
731 0 : RTFValue::Pointer_t pShapeValue(new RTFValue(xShape));
732 0 : m_aObjectAttributes.set(NS_ooxml::LN_shape, pShapeValue);
733 0 : return 0;
734 : }
735 8 : if (xPropertySet.is())
736 8 : xPropertySet->setPropertyValue("GraphicURL", uno::Any(aGraphicUrl));
737 :
738 : // Send it to the dmapper.
739 8 : RTFSprms aSprms;
740 8 : RTFSprms aAttributes;
741 : // shape attribute
742 8 : RTFSprms aPicAttributes;
743 8 : RTFValue::Pointer_t pShapeValue(new RTFValue(xShape));
744 8 : aPicAttributes.set(NS_ooxml::LN_shape, pShapeValue);
745 : // pic sprm
746 8 : RTFSprms aGraphicDataAttributes;
747 8 : RTFSprms aGraphicDataSprms;
748 8 : RTFValue::Pointer_t pPicValue(new RTFValue(aPicAttributes));
749 8 : aGraphicDataSprms.set(NS_ooxml::LN_pic_pic, pPicValue);
750 : // graphicData sprm
751 8 : RTFSprms aGraphicAttributes;
752 8 : RTFSprms aGraphicSprms;
753 8 : RTFValue::Pointer_t pGraphicDataValue(new RTFValue(aGraphicDataAttributes, aGraphicDataSprms));
754 8 : aGraphicSprms.set(NS_ooxml::LN_CT_GraphicalObject_graphicData, pGraphicDataValue);
755 : // graphic sprm
756 8 : RTFValue::Pointer_t pGraphicValue(new RTFValue(aGraphicAttributes, aGraphicSprms));
757 : // extent sprm
758 8 : RTFSprms aExtentAttributes;
759 : int nXExt, nYExt;
760 8 : nXExt = (m_aStates.top().aPicture.nGoalWidth ? m_aStates.top().aPicture.nGoalWidth : m_aStates.top().aPicture.nWidth);
761 8 : nYExt = (m_aStates.top().aPicture.nGoalHeight ? m_aStates.top().aPicture.nGoalHeight : m_aStates.top().aPicture.nHeight);
762 8 : if (m_aStates.top().aPicture.nScaleX != 100)
763 3 : nXExt = (((long)m_aStates.top().aPicture.nScaleX) * ( nXExt - ( m_aStates.top().aPicture.nCropL + m_aStates.top().aPicture.nCropR ))) / 100L;
764 8 : if (m_aStates.top().aPicture.nScaleY != 100)
765 3 : nYExt = (((long)m_aStates.top().aPicture.nScaleY) * ( nYExt - ( m_aStates.top().aPicture.nCropT + m_aStates.top().aPicture.nCropB ))) / 100L;
766 8 : RTFValue::Pointer_t pXExtValue(new RTFValue(nXExt));
767 8 : RTFValue::Pointer_t pYExtValue(new RTFValue(nYExt));
768 8 : aExtentAttributes.set(NS_rtf::LN_XEXT, pXExtValue);
769 8 : aExtentAttributes.set(NS_rtf::LN_YEXT, pYExtValue);
770 8 : RTFValue::Pointer_t pExtentValue(new RTFValue(aExtentAttributes));
771 : // docpr sprm
772 8 : RTFSprms aDocprAttributes;
773 10 : for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin(); i != m_aStates.top().aCharacterAttributes.end(); ++i)
774 2 : if (i->first == NS_ooxml::LN_CT_NonVisualDrawingProps_name || i->first == NS_ooxml::LN_CT_NonVisualDrawingProps_descr)
775 0 : aDocprAttributes.set(i->first, i->second);
776 8 : RTFValue::Pointer_t pDocprValue(new RTFValue(aDocprAttributes));
777 8 : if (bInline)
778 : {
779 6 : RTFSprms aInlineAttributes;
780 6 : aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distT, RTFValue::Pointer_t(new RTFValue(0)));
781 6 : aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distB, RTFValue::Pointer_t(new RTFValue(0)));
782 6 : aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distL, RTFValue::Pointer_t(new RTFValue(0)));
783 6 : aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distR, RTFValue::Pointer_t(new RTFValue(0)));
784 6 : RTFSprms aInlineSprms;
785 6 : aInlineSprms.set(NS_ooxml::LN_CT_Inline_extent, pExtentValue);
786 6 : aInlineSprms.set(NS_ooxml::LN_CT_Inline_docPr, pDocprValue);
787 6 : aInlineSprms.set(NS_ooxml::LN_graphic_graphic, pGraphicValue);
788 : // inline sprm
789 6 : RTFValue::Pointer_t pValue(new RTFValue(aInlineAttributes, aInlineSprms));
790 6 : aSprms.set(NS_ooxml::LN_inline_inline, pValue);
791 : }
792 : else // anchored
793 : {
794 : // wrap sprm
795 2 : RTFSprms aAnchorWrapAttributes;
796 4 : for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin(); i != m_aStates.top().aCharacterAttributes.end(); ++i)
797 2 : if (i->first == NS_ooxml::LN_CT_WrapSquare_wrapText)
798 2 : aAnchorWrapAttributes.set(i->first, i->second);
799 2 : RTFValue::Pointer_t pAnchorWrapValue(new RTFValue(aAnchorWrapAttributes));
800 2 : RTFSprms aAnchorAttributes;
801 2 : RTFSprms aAnchorSprms;
802 2 : aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_extent, pExtentValue);
803 2 : if (aAnchorWrapAttributes.size())
804 2 : aAnchorSprms.set(NS_ooxml::LN_EG_WrapType_wrapSquare, pAnchorWrapValue);
805 2 : aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_docPr, pDocprValue);
806 2 : aAnchorSprms.set(NS_ooxml::LN_graphic_graphic, pGraphicValue);
807 : // anchor sprm
808 2 : RTFValue::Pointer_t pValue(new RTFValue(aAnchorAttributes, aAnchorSprms));
809 2 : aSprms.set(NS_ooxml::LN_anchor_anchor, pValue);
810 : }
811 8 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes, aSprms));
812 8 : checkFirstRun();
813 8 : if (!m_pCurrentBuffer)
814 6 : Mapper().props(pProperties);
815 : else
816 : {
817 2 : RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
818 2 : m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
819 : }
820 :
821 : // Make sure we don't loose these properties with a too early reset.
822 8 : m_bHadPicture = true;
823 8 : return 0;
824 : }
825 :
826 27894 : int RTFDocumentImpl::resolveChars(char ch)
827 : {
828 27894 : if (m_aStates.top().nInternalState == INTERNAL_BIN)
829 : {
830 1 : m_pBinaryData.reset(new SvMemoryStream());
831 1 : *m_pBinaryData << ch;
832 21996 : for (int i = 0; i < m_aStates.top().nBinaryToRead - 1; ++i)
833 : {
834 21995 : Strm() >> ch;
835 21995 : *m_pBinaryData << ch;
836 : }
837 1 : m_aStates.top().nInternalState = INTERNAL_NORMAL;
838 1 : return 0;
839 : }
840 :
841 27893 : if (m_aStates.top().nInternalState != INTERNAL_HEX)
842 4534 : checkUnicode(false, true);
843 :
844 27893 : OStringBuffer aBuf;
845 :
846 27893 : bool bUnicodeChecked = false;
847 27893 : bool bSkipped = false;
848 796924 : while(!Strm().IsEof() && ch != '{' && ch != '}' && ch != '\\')
849 : {
850 764496 : if (m_aStates.top().nInternalState == INTERNAL_HEX || (ch != 0x0d && ch != 0x0a))
851 : {
852 759019 : if (m_aStates.top().nCharsToSkip == 0)
853 : {
854 758922 : if (!bUnicodeChecked)
855 : {
856 27795 : checkUnicode(true, false);
857 27795 : bUnicodeChecked = true;
858 : }
859 758922 : aBuf.append(ch);
860 : }
861 : else
862 : {
863 97 : bSkipped = true;
864 97 : m_aStates.top().nCharsToSkip--;
865 : }
866 : }
867 : // read a single char if we're in hex mode
868 764496 : if (m_aStates.top().nInternalState == INTERNAL_HEX)
869 23358 : break;
870 741138 : Strm() >> ch;
871 : }
872 27893 : if (m_aStates.top().nInternalState != INTERNAL_HEX && !Strm().IsEof())
873 4534 : Strm().SeekRel(-1);
874 :
875 27893 : if (m_aStates.top().nInternalState == INTERNAL_HEX && m_aStates.top().nDestinationState != DESTINATION_LEVELNUMBERS)
876 : {
877 23344 : if (!bSkipped)
878 23271 : m_aHexBuffer.append(ch);
879 23344 : return 0;
880 : }
881 :
882 4549 : if (m_aStates.top().nDestinationState == DESTINATION_SKIP)
883 479 : return 0;
884 4070 : OString aStr = aBuf.makeStringAndClear();
885 4070 : if (m_aStates.top().nDestinationState == DESTINATION_LEVELNUMBERS)
886 : {
887 25 : if (aStr.toChar() != ';')
888 15 : m_aStates.top().aLevelNumbers.push_back(sal_Int32(ch));
889 25 : return 0;
890 : }
891 :
892 4045 : OUString aOUStr(OStringToOUString(aStr, m_aStates.top().nCurrentEncoding));
893 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": collected '" << aOUStr << "'");
894 :
895 4045 : if (m_aStates.top().nDestinationState == DESTINATION_COLORTABLE)
896 : {
897 : // we hit a ';' at the end of each color entry
898 324 : sal_uInt32 color = (m_aStates.top().aCurrentColor.nRed << 16) | ( m_aStates.top().aCurrentColor.nGreen << 8)
899 324 : | m_aStates.top().aCurrentColor.nBlue;
900 162 : m_aColorTable.push_back(color);
901 : // set components back to zero
902 162 : m_aStates.top().aCurrentColor = RTFColorTableEntry();
903 : }
904 3883 : else if (!aOUStr.isEmpty())
905 3859 : text(aOUStr);
906 :
907 4045 : return 0;
908 : }
909 :
910 5741 : bool RTFFrame::inFrame()
911 : {
912 : return nW > 0
913 : || nH > 0
914 : || nX > 0
915 5741 : || nY > 0;
916 : }
917 :
918 24 : void RTFDocumentImpl::singleChar(sal_uInt8 nValue, bool bRunProps)
919 : {
920 24 : sal_uInt8 sValue[] = { nValue };
921 24 : if (!m_pCurrentBuffer)
922 : {
923 24 : Mapper().startCharacterGroup();
924 : // Should we send run properties?
925 24 : if (bRunProps)
926 2 : runProps();
927 24 : Mapper().text(sValue, 1);
928 24 : Mapper().endCharacterGroup();
929 : }
930 : else
931 : {
932 0 : m_pCurrentBuffer->push_back(make_pair(BUFFER_STARTRUN, RTFValue::Pointer_t()));
933 0 : RTFValue::Pointer_t pValue(new RTFValue(*sValue));
934 0 : m_pCurrentBuffer->push_back(make_pair(BUFFER_TEXT, pValue));
935 0 : m_pCurrentBuffer->push_back(make_pair(BUFFER_ENDRUN, RTFValue::Pointer_t()));
936 : }
937 24 : }
938 :
939 6214 : void RTFDocumentImpl::text(OUString& rString)
940 : {
941 6214 : bool bRet = true;
942 6214 : switch (m_aStates.top().nDestinationState)
943 : {
944 : case DESTINATION_FONTTABLE:
945 : case DESTINATION_FONTENTRY:
946 : case DESTINATION_STYLESHEET:
947 : case DESTINATION_STYLEENTRY:
948 : case DESTINATION_REVISIONTABLE:
949 : case DESTINATION_REVISIONENTRY:
950 : {
951 : // ; is the end of the entry
952 858 : bool bEnd = false;
953 858 : if (rString.endsWithAsciiL(";", 1))
954 : {
955 750 : rString = rString.copy(0, rString.getLength() - 1);
956 750 : bEnd = true;
957 : }
958 858 : m_aStates.top().aDestinationText.append(rString);
959 858 : if (bEnd)
960 : {
961 750 : switch (m_aStates.top().nDestinationState)
962 : {
963 : case DESTINATION_FONTTABLE:
964 : case DESTINATION_FONTENTRY:
965 : {
966 467 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
967 467 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_XSZFFN, pValue);
968 :
969 : writerfilter::Reference<Properties>::Pointer_t const pProp(
970 1401 : new RTFReferenceProperties(m_aStates.top().aTableAttributes, m_aStates.top().aTableSprms)
971 1401 : );
972 :
973 : //See fdo#47347 initial invalid font entry properties are inserted first,
974 : //so when we attempt to insert the correct ones, there's already an
975 : //entry in the map for them, so the new ones aren't inserted.
976 467 : RTFReferenceTable::Entries_t::iterator lb = m_aFontTableEntries.lower_bound(m_nCurrentFontIndex);
977 467 : if (lb != m_aFontTableEntries.end() && !(m_aFontTableEntries.key_comp()(m_nCurrentFontIndex, lb->first)))
978 0 : lb->second = pProp;
979 : else
980 467 : m_aFontTableEntries.insert(lb, make_pair(m_nCurrentFontIndex, pProp));
981 : }
982 467 : break;
983 : case DESTINATION_STYLESHEET:
984 : case DESTINATION_STYLEENTRY:
985 : {
986 282 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
987 282 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_XSTZNAME1, pValue);
988 :
989 : writerfilter::Reference<Properties>::Pointer_t const pProp(
990 282 : new RTFReferenceProperties(mergeAttributes(), mergeSprms())
991 564 : );
992 282 : m_aStyleTableEntries.insert(make_pair(m_nCurrentStyleIndex, pProp));
993 : }
994 282 : break;
995 : case DESTINATION_REVISIONTABLE:
996 : case DESTINATION_REVISIONENTRY:
997 1 : m_aAuthors[m_aAuthors.size()] = m_aStates.top().aDestinationText.makeStringAndClear();
998 1 : break;
999 0 : default: break;
1000 : }
1001 750 : resetAttributes();
1002 750 : resetSprms();
1003 : }
1004 : }
1005 858 : break;
1006 : case DESTINATION_LEVELTEXT:
1007 : case DESTINATION_SHAPEPROPERTYNAME:
1008 : case DESTINATION_SHAPEPROPERTYVALUE:
1009 : case DESTINATION_BOOKMARKEND:
1010 : case DESTINATION_PICT:
1011 : case DESTINATION_SHAPEPROPERTYVALUEPICT:
1012 : case DESTINATION_FORMFIELDNAME:
1013 : case DESTINATION_FORMFIELDLIST:
1014 : case DESTINATION_DATAFIELD:
1015 : case DESTINATION_AUTHOR:
1016 : case DESTINATION_KEYWORDS:
1017 : case DESTINATION_OPERATOR:
1018 : case DESTINATION_COMPANY:
1019 : case DESTINATION_COMMENT:
1020 : case DESTINATION_OBJDATA:
1021 : case DESTINATION_ANNOTATIONDATE:
1022 : case DESTINATION_ANNOTATIONAUTHOR:
1023 : case DESTINATION_FALT:
1024 : case DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER:
1025 : case DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE:
1026 : case DESTINATION_TITLE:
1027 : case DESTINATION_SUBJECT:
1028 : case DESTINATION_DOCCOMM:
1029 : case DESTINATION_ATNID:
1030 : case DESTINATION_MR:
1031 : case DESTINATION_MCHR:
1032 : case DESTINATION_MPOS:
1033 : case DESTINATION_MVERTJC:
1034 : case DESTINATION_MSTRIKEH:
1035 : case DESTINATION_MDEGHIDE:
1036 : case DESTINATION_MBEGCHR:
1037 : case DESTINATION_MSEPCHR:
1038 : case DESTINATION_MENDCHR:
1039 : case DESTINATION_MSUBHIDE:
1040 : case DESTINATION_MSUPHIDE:
1041 : case DESTINATION_MTYPE:
1042 : case DESTINATION_MGROW:
1043 1244 : m_aStates.top().aDestinationText.append(rString);
1044 1244 : break;
1045 4112 : default: bRet = false; break;
1046 : }
1047 6214 : if (bRet)
1048 2102 : return;
1049 :
1050 4112 : if (!m_aIgnoreFirst.isEmpty() && m_aIgnoreFirst.equals(rString))
1051 : {
1052 0 : m_aIgnoreFirst = OUString();
1053 0 : return;
1054 : }
1055 :
1056 : // Are we in the middle of the table definition? (No cell defs yet, but we already have some cell props.)
1057 4113 : if (m_aStates.top().aTableCellSprms.find(NS_ooxml::LN_CT_TcPrBase_vAlign).get() &&
1058 1 : m_aStates.top().nCells == 0)
1059 : {
1060 1 : m_aTableBuffer.push_back(make_pair(BUFFER_UTEXT, RTFValue::Pointer_t(new RTFValue(rString))));
1061 1 : return;
1062 : }
1063 :
1064 4111 : checkFirstRun();
1065 4111 : checkNeedPap();
1066 :
1067 : // Don't return earlier, a bookmark start has to be in a paragraph group.
1068 4111 : if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKSTART)
1069 : {
1070 0 : m_aStates.top().aDestinationText.append(rString);
1071 0 : return;
1072 : }
1073 :
1074 4111 : if (!m_pCurrentBuffer && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
1075 3957 : Mapper().startCharacterGroup();
1076 154 : else if (m_pCurrentBuffer)
1077 : {
1078 154 : RTFValue::Pointer_t pValue;
1079 154 : m_pCurrentBuffer->push_back(make_pair(BUFFER_STARTRUN, pValue));
1080 : }
1081 4136 : if (m_aStates.top().nDestinationState == DESTINATION_NORMAL
1082 13 : || m_aStates.top().nDestinationState == DESTINATION_FIELDRESULT
1083 12 : || m_aStates.top().nDestinationState == DESTINATION_SHAPETEXT)
1084 4102 : runProps();
1085 4111 : if (!m_pCurrentBuffer)
1086 3957 : Mapper().utext(reinterpret_cast<sal_uInt8 const*>(rString.getStr()), rString.getLength());
1087 : else
1088 : {
1089 154 : RTFValue::Pointer_t pValue(new RTFValue(rString));
1090 154 : m_pCurrentBuffer->push_back(make_pair(BUFFER_UTEXT, pValue));
1091 : }
1092 4111 : m_bNeedCr = true;
1093 4111 : if (!m_pCurrentBuffer && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
1094 3957 : Mapper().endCharacterGroup();
1095 154 : else if(m_pCurrentBuffer)
1096 : {
1097 154 : RTFValue::Pointer_t pValue;
1098 154 : m_pCurrentBuffer->push_back(make_pair(BUFFER_ENDRUN, pValue));
1099 : }
1100 : }
1101 :
1102 174 : void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer)
1103 : {
1104 1096 : while (rBuffer.size())
1105 : {
1106 847 : std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = rBuffer.front();
1107 847 : rBuffer.pop_front();
1108 847 : if (aPair.first == BUFFER_PROPS)
1109 : {
1110 : writerfilter::Reference<Properties>::Pointer_t const pProp(
1111 843 : new RTFReferenceProperties(aPair.second->getAttributes(), aPair.second->getSprms())
1112 843 : );
1113 281 : Mapper().props(pProp);
1114 : }
1115 566 : else if (aPair.first == BUFFER_CELLEND)
1116 : {
1117 99 : RTFValue::Pointer_t pValue(new RTFValue(1));
1118 99 : m_aStates.top().aTableCellSprms.set(NS_sprm::LN_PCell, pValue);
1119 : writerfilter::Reference<Properties>::Pointer_t const pTableCellProperties(
1120 297 : new RTFReferenceProperties(m_aStates.top().aTableCellAttributes, m_aStates.top().aTableCellSprms)
1121 297 : );
1122 99 : Mapper().props(pTableCellProperties);
1123 99 : tableBreak();
1124 99 : break;
1125 : }
1126 467 : else if (aPair.first == BUFFER_STARTRUN)
1127 154 : Mapper().startCharacterGroup();
1128 313 : else if (aPair.first == BUFFER_TEXT)
1129 : {
1130 0 : sal_uInt8 nValue = aPair.second->getInt();
1131 0 : Mapper().text(&nValue, 1);
1132 : }
1133 313 : else if (aPair.first == BUFFER_UTEXT)
1134 : {
1135 155 : OUString aString(aPair.second->getString());
1136 155 : Mapper().utext(reinterpret_cast<sal_uInt8 const*>(aString.getStr()), aString.getLength());
1137 : }
1138 158 : else if (aPair.first == BUFFER_ENDRUN)
1139 154 : Mapper().endCharacterGroup();
1140 4 : else if (aPair.first == BUFFER_PAR)
1141 4 : parBreak();
1142 : else
1143 : SAL_WARN("writerfilter", "should not happen");
1144 847 : }
1145 :
1146 174 : }
1147 :
1148 2962 : int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
1149 : {
1150 2962 : checkUnicode();
1151 2962 : setNeedSect();
1152 2962 : RTFSkipDestination aSkip(*this);
1153 2962 : switch (nKeyword)
1154 : {
1155 : case RTF_RTF:
1156 128 : break;
1157 : case RTF_FONTTBL:
1158 55 : m_aStates.top().nDestinationState = DESTINATION_FONTTABLE;
1159 55 : break;
1160 : case RTF_COLORTBL:
1161 41 : m_aStates.top().nDestinationState = DESTINATION_COLORTABLE;
1162 41 : break;
1163 : case RTF_STYLESHEET:
1164 42 : m_aStates.top().nDestinationState = DESTINATION_STYLESHEET;
1165 42 : break;
1166 : case RTF_FIELD:
1167 6 : m_aStates.top().nDestinationState = DESTINATION_FIELD;
1168 6 : break;
1169 : case RTF_FLDINST:
1170 : {
1171 : // Look for the field type
1172 6 : sal_Int32 nPos = Strm().Tell();
1173 6 : OStringBuffer aBuf;
1174 6 : char ch = 0;
1175 6 : bool bFoundCode = false;
1176 6 : bool bInKeyword = false;
1177 61 : while (!bFoundCode && ch != '}')
1178 : {
1179 49 : Strm() >> ch;
1180 49 : if ('\\' == ch)
1181 3 : bInKeyword = true;
1182 49 : if (!bInKeyword && isalnum(ch))
1183 25 : aBuf.append(ch);
1184 24 : else if (bInKeyword && isspace(ch))
1185 1 : bInKeyword = false;
1186 49 : if (aBuf.getLength() > 0 && !isalnum(ch))
1187 6 : bFoundCode = true;
1188 : }
1189 6 : Strm().Seek(nPos);
1190 :
1191 : // Form data should be handled only for form fields if any
1192 6 : if (aBuf.toString().indexOf(OString("FORM")) != -1 )
1193 0 : m_bFormField = true;
1194 :
1195 6 : singleChar(0x13);
1196 6 : m_aStates.top().nDestinationState = DESTINATION_FIELDINSTRUCTION;
1197 : }
1198 6 : break;
1199 : case RTF_FLDRSLT:
1200 5 : m_aStates.top().nDestinationState = DESTINATION_FIELDRESULT;
1201 5 : break;
1202 : case RTF_LISTTABLE:
1203 5 : m_aStates.top().nDestinationState = DESTINATION_LISTTABLE;
1204 5 : break;
1205 : case RTF_LIST:
1206 5 : m_aStates.top().nDestinationState = DESTINATION_LISTENTRY;
1207 5 : break;
1208 : case RTF_LISTOVERRIDETABLE:
1209 5 : m_aStates.top().nDestinationState = DESTINATION_LISTOVERRIDETABLE;
1210 5 : break;
1211 : case RTF_LISTOVERRIDE:
1212 5 : m_aStates.top().nDestinationState = DESTINATION_LISTOVERRIDEENTRY;
1213 5 : break;
1214 : case RTF_LISTLEVEL:
1215 8 : m_aStates.top().nDestinationState = DESTINATION_LISTLEVEL;
1216 8 : break;
1217 : case RTF_LEVELTEXT:
1218 10 : m_aStates.top().nDestinationState = DESTINATION_LEVELTEXT;
1219 10 : break;
1220 : case RTF_LEVELNUMBERS:
1221 10 : m_aStates.top().nDestinationState = DESTINATION_LEVELNUMBERS;
1222 10 : break;
1223 : case RTF_SHPPICT:
1224 3 : m_aStates.top().resetFrame();
1225 3 : m_aStates.top().nDestinationState = DESTINATION_SHPPICT;
1226 3 : break;
1227 : case RTF_PICT:
1228 8 : if (m_aStates.top().nDestinationState != DESTINATION_SHAPEPROPERTYVALUE)
1229 6 : m_aStates.top().nDestinationState = DESTINATION_PICT; // as character
1230 : else
1231 2 : m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYVALUEPICT; // anchored inside a shape
1232 8 : break;
1233 : case RTF_PICPROP:
1234 0 : m_aStates.top().nDestinationState = DESTINATION_PICPROP;
1235 0 : break;
1236 : case RTF_SP:
1237 163 : m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTY;
1238 163 : break;
1239 : case RTF_SN:
1240 163 : m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYNAME;
1241 163 : break;
1242 : case RTF_SV:
1243 163 : m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYVALUE;
1244 163 : break;
1245 : case RTF_SHP:
1246 16 : m_aStates.top().nDestinationState = DESTINATION_SHAPE;
1247 16 : break;
1248 : case RTF_SHPINST:
1249 : // Don't try to support shapes inside tables for now.
1250 16 : if (m_pCurrentBuffer != &m_aTableBuffer)
1251 16 : m_aStates.top().nDestinationState = DESTINATION_SHAPEINSTRUCTION;
1252 : else
1253 0 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1254 16 : break;
1255 : case RTF_NESTTABLEPROPS:
1256 0 : m_aStates.top().nDestinationState = DESTINATION_NESTEDTABLEPROPERTIES;
1257 0 : break;
1258 : case RTF_HEADER:
1259 : case RTF_FOOTER:
1260 : case RTF_HEADERL:
1261 : case RTF_HEADERR:
1262 : case RTF_HEADERF:
1263 : case RTF_FOOTERL:
1264 : case RTF_FOOTERR:
1265 : case RTF_FOOTERF:
1266 8 : if (!m_pSuperstream)
1267 : {
1268 4 : Id nId = 0;
1269 4 : sal_uInt32 nPos = m_nGroupStartPos - 1;
1270 4 : switch (nKeyword)
1271 : {
1272 3 : case RTF_HEADER: nId = NS_rtf::LN_headerr; break;
1273 0 : case RTF_FOOTER: nId = NS_rtf::LN_footerr; break;
1274 0 : case RTF_HEADERL: nId = NS_rtf::LN_headerl; break;
1275 1 : case RTF_HEADERR: nId = NS_rtf::LN_headerr; break;
1276 0 : case RTF_HEADERF: nId = NS_rtf::LN_headerf; break;
1277 0 : case RTF_FOOTERL: nId = NS_rtf::LN_footerl; break;
1278 0 : case RTF_FOOTERR: nId = NS_rtf::LN_footerr; break;
1279 0 : case RTF_FOOTERF: nId = NS_rtf::LN_footerf; break;
1280 0 : default: break;
1281 : }
1282 4 : m_nHeaderFooterPositions.push(make_pair(nId, nPos));
1283 4 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1284 : }
1285 8 : break;
1286 : case RTF_FOOTNOTE:
1287 6 : if (!m_pSuperstream)
1288 : {
1289 3 : Id nId = NS_rtf::LN_footnote;
1290 :
1291 : // Check if this is an endnote.
1292 3 : OStringBuffer aBuf;
1293 : char ch;
1294 24 : for (int i = 0; i < 7; ++i)
1295 : {
1296 21 : Strm() >> ch;
1297 21 : aBuf.append(ch);
1298 : }
1299 3 : OString aKeyword = aBuf.makeStringAndClear();
1300 3 : if (aKeyword.equals("\\ftnalt"))
1301 0 : nId = NS_rtf::LN_endnote;
1302 :
1303 3 : m_bHasFootnote = true;
1304 3 : if (m_pCurrentBuffer == &m_aSuperBuffer)
1305 2 : m_pCurrentBuffer = 0;
1306 3 : bool bCustomMark = false;
1307 3 : OUString aCustomMark;
1308 6 : while (m_aSuperBuffer.size())
1309 : {
1310 0 : std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = m_aSuperBuffer.front();
1311 0 : m_aSuperBuffer.pop_front();
1312 0 : if (aPair.first == BUFFER_UTEXT)
1313 : {
1314 0 : aCustomMark = aPair.second->getString();
1315 0 : bCustomMark = true;
1316 : }
1317 0 : }
1318 3 : m_aStates.top().nDestinationState = DESTINATION_FOOTNOTE;
1319 3 : if (bCustomMark)
1320 0 : Mapper().startCharacterGroup();
1321 3 : resolveSubstream(m_nGroupStartPos - 1, nId, aCustomMark);
1322 3 : if (bCustomMark)
1323 : {
1324 0 : m_aStates.top().aCharacterAttributes.clear();
1325 0 : m_aStates.top().aCharacterSprms.clear();
1326 0 : RTFValue::Pointer_t pValue(new RTFValue(1));
1327 0 : m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows, pValue);
1328 0 : text(aCustomMark);
1329 0 : Mapper().endCharacterGroup();
1330 : }
1331 3 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1332 : }
1333 6 : break;
1334 : case RTF_BKMKSTART:
1335 0 : m_aStates.top().nDestinationState = DESTINATION_BOOKMARKSTART;
1336 0 : break;
1337 : case RTF_BKMKEND:
1338 0 : m_aStates.top().nDestinationState = DESTINATION_BOOKMARKEND;
1339 0 : break;
1340 : case RTF_REVTBL:
1341 1 : m_aStates.top().nDestinationState = DESTINATION_REVISIONTABLE;
1342 1 : break;
1343 : case RTF_ANNOTATION:
1344 4 : if (!m_pSuperstream)
1345 : {
1346 2 : resolveSubstream(m_nGroupStartPos - 1, NS_rtf::LN_annotation);
1347 2 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1348 : }
1349 : else
1350 : {
1351 : // If there is an author set, emit it now.
1352 2 : if (!m_aAuthor.isEmpty() || !m_aAuthorInitials.isEmpty())
1353 : {
1354 2 : RTFSprms aAttributes;
1355 2 : if (!m_aAuthor.isEmpty())
1356 : {
1357 2 : RTFValue::Pointer_t pValue(new RTFValue(m_aAuthor));
1358 2 : aAttributes.set(NS_ooxml::LN_CT_TrackChange_author, pValue);
1359 : }
1360 2 : if (!m_aAuthorInitials.isEmpty())
1361 : {
1362 2 : RTFValue::Pointer_t pValue(new RTFValue(m_aAuthorInitials));
1363 2 : aAttributes.set(NS_ooxml::LN_CT_Comment_initials, pValue);
1364 : }
1365 2 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
1366 2 : Mapper().props(pProperties);
1367 : }
1368 : }
1369 4 : break;
1370 : case RTF_SHPTXT:
1371 : case RTF_DPTXBXTEXT:
1372 3 : m_aStates.top().nDestinationState = DESTINATION_SHAPETEXT;
1373 3 : dispatchFlag(RTF_PARD);
1374 3 : m_bNeedPap = true;
1375 : OSL_ENSURE(!m_aShapetextBuffer.size(), "shapetext buffer is not empty");
1376 3 : m_pCurrentBuffer = &m_aShapetextBuffer;
1377 3 : break;
1378 : case RTF_FORMFIELD:
1379 0 : if (m_aStates.top().nDestinationState == DESTINATION_FIELDINSTRUCTION)
1380 0 : m_aStates.top().nDestinationState = DESTINATION_FORMFIELD;
1381 0 : break;
1382 : case RTF_FFNAME:
1383 0 : m_aStates.top().nDestinationState = DESTINATION_FORMFIELDNAME;
1384 0 : break;
1385 : case RTF_FFL:
1386 0 : m_aStates.top().nDestinationState = DESTINATION_FORMFIELDLIST;
1387 0 : break;
1388 : case RTF_DATAFIELD:
1389 0 : m_aStates.top().nDestinationState = DESTINATION_DATAFIELD;
1390 0 : break;
1391 : case RTF_INFO:
1392 41 : m_aStates.top().nDestinationState = DESTINATION_INFO;
1393 41 : break;
1394 : case RTF_CREATIM:
1395 32 : m_aStates.top().nDestinationState = DESTINATION_CREATIONTIME;
1396 32 : break;
1397 : case RTF_REVTIM:
1398 32 : m_aStates.top().nDestinationState = DESTINATION_REVISIONTIME;
1399 32 : break;
1400 : case RTF_PRINTIM:
1401 30 : m_aStates.top().nDestinationState = DESTINATION_PRINTTIME;
1402 30 : break;
1403 : case RTF_AUTHOR:
1404 5 : m_aStates.top().nDestinationState = DESTINATION_AUTHOR;
1405 5 : break;
1406 : case RTF_KEYWORDS:
1407 2 : m_aStates.top().nDestinationState = DESTINATION_KEYWORDS;
1408 2 : break;
1409 : case RTF_OPERATOR:
1410 3 : m_aStates.top().nDestinationState = DESTINATION_OPERATOR;
1411 3 : break;
1412 : case RTF_COMPANY:
1413 5 : m_aStates.top().nDestinationState = DESTINATION_COMPANY;
1414 5 : break;
1415 : case RTF_COMMENT:
1416 31 : m_aStates.top().nDestinationState = DESTINATION_COMMENT;
1417 31 : break;
1418 : case RTF_OBJECT:
1419 0 : m_aStates.top().nDestinationState = DESTINATION_OBJECT;
1420 0 : m_bObject = true;
1421 0 : break;
1422 : case RTF_OBJDATA:
1423 0 : m_aStates.top().nDestinationState = DESTINATION_OBJDATA;
1424 0 : break;
1425 : case RTF_RESULT:
1426 0 : m_aStates.top().nDestinationState = DESTINATION_RESULT;
1427 0 : break;
1428 : case RTF_ATNDATE:
1429 2 : m_aStates.top().nDestinationState = DESTINATION_ANNOTATIONDATE;
1430 2 : break;
1431 : case RTF_ATNAUTHOR:
1432 2 : m_aStates.top().nDestinationState = DESTINATION_ANNOTATIONAUTHOR;
1433 2 : break;
1434 : case RTF_FALT:
1435 104 : m_aStates.top().nDestinationState = DESTINATION_FALT;
1436 104 : break;
1437 : case RTF_FLYMAINCNT:
1438 3 : m_aStates.top().nDestinationState = DESTINATION_FLYMAINCONTENT;
1439 3 : break;
1440 : case RTF_LISTTEXT:
1441 : // Should be ignored by any reader that understands Word 97 through Word 2007 numbering.
1442 : case RTF_NONESTTABLES:
1443 : // This destination should be ignored by readers that support nested tables.
1444 5 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1445 5 : break;
1446 : case RTF_DO:
1447 10 : m_aStates.top().nDestinationState = DESTINATION_DRAWINGOBJECT;
1448 10 : break;
1449 : case RTF_PN:
1450 4 : m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING;
1451 4 : break;
1452 : case RTF_PNTEXT:
1453 : // This destination should be ignored by readers that support paragraph numbering.
1454 0 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1455 0 : break;
1456 : case RTF_PNTXTA:
1457 3 : m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER;
1458 3 : break;
1459 : case RTF_PNTXTB:
1460 3 : m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE;
1461 3 : break;
1462 : case RTF_TITLE:
1463 6 : m_aStates.top().nDestinationState = DESTINATION_TITLE;
1464 6 : break;
1465 : case RTF_SUBJECT:
1466 3 : m_aStates.top().nDestinationState = DESTINATION_SUBJECT;
1467 3 : break;
1468 : case RTF_DOCCOMM:
1469 4 : m_aStates.top().nDestinationState = DESTINATION_DOCCOMM;
1470 4 : break;
1471 : case RTF_ATRFSTART:
1472 : case RTF_ATRFEND:
1473 : {
1474 : // We could send the real value here, but that would make the
1475 : // tokenizer more complicated, and dmapper doesn't read the
1476 : // result anyway.
1477 4 : RTFValue::Pointer_t pValue(new RTFValue(0));
1478 4 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1479 :
1480 4 : RTFSprms aAttributes;
1481 4 : if (nKeyword == RTF_ATRFSTART)
1482 2 : aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart, pValue);
1483 : else
1484 2 : aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd, pValue);
1485 4 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
1486 4 : Mapper().props(pProperties);
1487 : }
1488 4 : break;
1489 : case RTF_ATNID:
1490 2 : m_aStates.top().nDestinationState = DESTINATION_ATNID;
1491 2 : break;
1492 : case RTF_MMATH:
1493 : case RTF_MOMATHPARA:
1494 : // Nothing to do here (just enter the destination) till RTF_MMATHPR is implemented.
1495 88 : break;
1496 490 : case RTF_MR: m_aStates.top().nDestinationState = DESTINATION_MR; break;
1497 38 : case RTF_MCHR: m_aStates.top().nDestinationState = DESTINATION_MCHR; break;
1498 4 : case RTF_MPOS: m_aStates.top().nDestinationState = DESTINATION_MPOS; break;
1499 3 : case RTF_MVERTJC: m_aStates.top().nDestinationState = DESTINATION_MVERTJC; break;
1500 2 : case RTF_MSTRIKEH: m_aStates.top().nDestinationState = DESTINATION_MSTRIKEH; break;
1501 4 : case RTF_MDEGHIDE: m_aStates.top().nDestinationState = DESTINATION_MDEGHIDE; break;
1502 6 : case RTF_MTYPE: m_aStates.top().nDestinationState = DESTINATION_MTYPE; break;
1503 2 : case RTF_MGROW: m_aStates.top().nDestinationState = DESTINATION_MGROW; break;
1504 : case RTF_MHIDETOP:
1505 : case RTF_MHIDEBOT:
1506 : case RTF_MHIDELEFT:
1507 : case RTF_MHIDERIGHT:
1508 : // SmOoxmlImport::handleBorderBox will ignore these anyway, so silently ignore for now.
1509 8 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1510 8 : break;
1511 2 : case RTF_MSUBHIDE: m_aStates.top().nDestinationState = DESTINATION_MSUBHIDE; break;
1512 2 : case RTF_MSUPHIDE: m_aStates.top().nDestinationState = DESTINATION_MSUPHIDE; break;
1513 32 : case RTF_MBEGCHR: m_aStates.top().nDestinationState = DESTINATION_MBEGCHR; break;
1514 3 : case RTF_MSEPCHR: m_aStates.top().nDestinationState = DESTINATION_MSEPCHR; break;
1515 32 : case RTF_MENDCHR: m_aStates.top().nDestinationState = DESTINATION_MENDCHR; break;
1516 59 : OPEN_M_TOKEN(OMATH, oMath);
1517 34 : OPEN_M_TOKEN(F, f);
1518 20 : OPEN_M_TOKEN(FPR, fPr);
1519 108 : OPEN_M_TOKEN(CTRLPR, ctrlPr);
1520 34 : OPEN_M_TOKEN(NUM, num);
1521 34 : OPEN_M_TOKEN(DEN, den);
1522 24 : OPEN_M_TOKEN(ACC, acc);
1523 24 : OPEN_M_TOKEN(ACCPR, accPr);
1524 2 : OPEN_M_TOKEN(BAR, bar);
1525 2 : OPEN_M_TOKEN(BARPR, barPr);
1526 197 : OPEN_M_TOKEN(E, e);
1527 45 : OPEN_M_TOKEN(D, d);
1528 45 : OPEN_M_TOKEN(DPR, dPr);
1529 12 : OPEN_M_TOKEN(FUNC, func);
1530 11 : OPEN_M_TOKEN(FUNCPR, funcPr);
1531 12 : OPEN_M_TOKEN(FNAME, fName);
1532 6 : OPEN_M_TOKEN(LIMLOW, limLow);
1533 3 : OPEN_M_TOKEN(LIMLOWPR, limLowPr);
1534 10 : OPEN_M_TOKEN(LIM, lim);
1535 2 : OPEN_M_TOKEN(M, m);
1536 1 : OPEN_M_TOKEN(MPR, mPr);
1537 4 : OPEN_M_TOKEN(MR, mr);
1538 13 : OPEN_M_TOKEN(NARY, nary);
1539 13 : OPEN_M_TOKEN(NARYPR, naryPr);
1540 29 : OPEN_M_TOKEN(SUB, sub);
1541 55 : OPEN_M_TOKEN(SUP, sup);
1542 4 : OPEN_M_TOKEN(LIMUPP, limUpp);
1543 2 : OPEN_M_TOKEN(LIMUPPPR, limUppPr);
1544 4 : OPEN_M_TOKEN(GROUPCHR, groupChr);
1545 4 : OPEN_M_TOKEN(GROUPCHRPR, groupChrPr);
1546 2 : OPEN_M_TOKEN(BORDERBOX, borderBox);
1547 2 : OPEN_M_TOKEN(BORDERBOXPR, borderBoxPr);
1548 6 : OPEN_M_TOKEN(RAD, rad);
1549 5 : OPEN_M_TOKEN(RADPR, radPr);
1550 6 : OPEN_M_TOKEN(DEG, deg);
1551 8 : OPEN_M_TOKEN(SSUB, sSub);
1552 4 : OPEN_M_TOKEN(SSUBPR, sSubPr);
1553 34 : OPEN_M_TOKEN(SSUP, sSup);
1554 17 : OPEN_M_TOKEN(SSUPPR, sSupPr);
1555 4 : OPEN_M_TOKEN(SSUBSUP, sSubSup);
1556 2 : OPEN_M_TOKEN(SSUBSUPPR, sSubSupPr);
1557 4 : OPEN_M_TOKEN(SPRE, sPre);
1558 2 : OPEN_M_TOKEN(SPREPR, sPrePr);
1559 1 : OPEN_M_TOKEN(BOX, box);
1560 6 : OPEN_M_TOKEN(EQARR, eqArr);
1561 : default:
1562 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle destination '" << lcl_RtfToString(nKeyword) << "'");
1563 : // Make sure we skip destinations (even without \*) till we don't handle them
1564 109 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
1565 109 : aSkip.setParsed(false);
1566 109 : break;
1567 : }
1568 :
1569 2962 : return 0;
1570 : }
1571 :
1572 24736 : int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
1573 : {
1574 24736 : if (nKeyword != RTF_HEXCHAR)
1575 1377 : checkUnicode();
1576 24736 : setNeedSect();
1577 24736 : RTFSkipDestination aSkip(*this);
1578 24736 : sal_uInt8 cCh = 0;
1579 :
1580 : // Trivial symbols
1581 24736 : switch (nKeyword)
1582 : {
1583 51 : case RTF_LINE: cCh = '\n'; break;
1584 41 : case RTF_TAB: cCh = '\t'; break;
1585 19 : case RTF_BACKSLASH: cCh = '\\'; break;
1586 23 : case RTF_LBRACE: cCh = '{'; break;
1587 20 : case RTF_RBRACE: cCh = '}'; break;
1588 9 : case RTF_EMDASH: cCh = 151; break;
1589 10 : case RTF_ENDASH: cCh = 150; break;
1590 15 : case RTF_BULLET: cCh = 149; break;
1591 16 : case RTF_LQUOTE: cCh = 145; break;
1592 13 : case RTF_RQUOTE: cCh = 146; break;
1593 22 : case RTF_LDBLQUOTE: cCh = 147; break;
1594 9 : case RTF_RDBLQUOTE: cCh = 148; break;
1595 24488 : default: break;
1596 : }
1597 24736 : if (cCh > 0)
1598 : {
1599 248 : OUString aStr(OStringToOUString(OString(cCh), RTL_TEXTENCODING_MS_1252));
1600 248 : text(aStr);
1601 248 : return 0;
1602 : }
1603 :
1604 24488 : switch (nKeyword)
1605 : {
1606 : case RTF_IGNORE:
1607 559 : m_bSkipUnknown = true;
1608 559 : aSkip.setReset(false);
1609 559 : return 0;
1610 : break;
1611 : case RTF_PAR:
1612 : {
1613 342 : checkFirstRun();
1614 342 : bool bNeedPap = m_bNeedPap;
1615 342 : checkNeedPap();
1616 342 : if (bNeedPap)
1617 133 : runProps();
1618 342 : if (!m_pCurrentBuffer)
1619 332 : parBreak();
1620 10 : else if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT)
1621 : {
1622 7 : RTFValue::Pointer_t pValue;
1623 7 : m_pCurrentBuffer->push_back(make_pair(BUFFER_PAR, pValue));
1624 : }
1625 : // but don't emit properties yet, since they may change till the first text token arrives
1626 342 : m_bNeedPap = true;
1627 342 : if (!m_aStates.top().aFrame.inFrame())
1628 325 : m_bNeedPar = false;
1629 342 : m_bNeedFinalPar = false;
1630 : }
1631 342 : break;
1632 : case RTF_SECT:
1633 : {
1634 5 : m_bHadSect = true;
1635 5 : if (m_bIgnoreNextContSectBreak)
1636 2 : m_bIgnoreNextContSectBreak = false;
1637 : else
1638 3 : sectBreak();
1639 : }
1640 5 : break;
1641 : case RTF_NOBREAK:
1642 : {
1643 19 : OUString aStr(SVT_HARD_SPACE);
1644 19 : text(aStr);
1645 : }
1646 19 : break;
1647 : case RTF_NOBRKHYPH:
1648 : {
1649 2 : OUString aStr(SVT_HARD_HYPHEN);
1650 2 : text(aStr);
1651 : }
1652 2 : break;
1653 : case RTF_OPTHYPH:
1654 : {
1655 13 : OUString aStr(SVT_SOFT_HYPHEN);
1656 13 : text(aStr);
1657 : }
1658 13 : break;
1659 : case RTF_HEXCHAR:
1660 23359 : m_aStates.top().nInternalState = INTERNAL_HEX;
1661 23359 : break;
1662 : case RTF_CELL:
1663 : case RTF_NESTCELL:
1664 : {
1665 99 : checkFirstRun();
1666 99 : if (m_bNeedPap)
1667 : {
1668 : // There were no runs in the cell, so we need to send paragraph and character properties here.
1669 16 : RTFValue::Pointer_t pPValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
1670 16 : m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pPValue));
1671 16 : RTFValue::Pointer_t pCValue(new RTFValue(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms));
1672 16 : m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pCValue));
1673 : }
1674 :
1675 99 : RTFValue::Pointer_t pValue;
1676 99 : m_aTableBuffer.push_back(make_pair(BUFFER_CELLEND, pValue));
1677 99 : m_bNeedPap = true;
1678 : }
1679 99 : break;
1680 : case RTF_ROW:
1681 : case RTF_NESTROW:
1682 : {
1683 24 : if (m_aStates.top().nCells)
1684 : {
1685 : // Make a backup before we start popping elements
1686 24 : m_aStates.top().aTableInheritingCellsSprms = m_aStates.top().aTableCellsSprms;
1687 24 : m_aStates.top().aTableInheritingCellsAttributes = m_aStates.top().aTableCellsAttributes;
1688 24 : m_aStates.top().nInheritingCells = m_aStates.top().nCells;
1689 : }
1690 : else
1691 : {
1692 : // No table definition? Then inherit from the previous row
1693 0 : m_aStates.top().aTableCellsSprms = m_aStates.top().aTableInheritingCellsSprms;
1694 0 : m_aStates.top().aTableCellsAttributes = m_aStates.top().aTableInheritingCellsAttributes;
1695 0 : m_aStates.top().nCells = m_aStates.top().nInheritingCells;
1696 : // This can't be the first row, and we need cell width only there
1697 0 : while(m_aStates.top().aTableRowSprms.erase(NS_ooxml::LN_CT_TblGridBase_gridCol)) ;
1698 : }
1699 188 : for (int i = 0; i < m_aStates.top().nCells; ++i)
1700 : {
1701 164 : m_aStates.top().aTableCellSprms = m_aStates.top().aTableCellsSprms.front();
1702 164 : m_aStates.top().aTableCellsSprms.pop_front();
1703 164 : m_aStates.top().aTableCellAttributes = m_aStates.top().aTableCellsAttributes.front();
1704 164 : m_aStates.top().aTableCellsAttributes.pop_front();
1705 164 : replayBuffer(m_aTableBuffer);
1706 : }
1707 24 : m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
1708 24 : m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
1709 :
1710 : writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
1711 48 : getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
1712 48 : );
1713 24 : Mapper().props(pParagraphProperties);
1714 :
1715 24 : if (m_aStates.top().aFrame.hasProperties())
1716 : {
1717 : writerfilter::Reference<Properties>::Pointer_t const pFrameProperties(
1718 0 : new RTFReferenceProperties(RTFSprms(), m_aStates.top().aFrame.getSprms()));
1719 0 : Mapper().props(pFrameProperties);
1720 : }
1721 :
1722 : // Table width.
1723 24 : RTFValue::Pointer_t pUnitValue(new RTFValue(3));
1724 24 : lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
1725 48 : NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pUnitValue);
1726 24 : RTFValue::Pointer_t pWValue(new RTFValue(m_aStates.top().nCellX));
1727 24 : lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
1728 48 : NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pWValue);
1729 :
1730 24 : RTFValue::Pointer_t pRowValue(new RTFValue(1));
1731 24 : if (m_aStates.top().nCells > 0)
1732 24 : m_aStates.top().aTableRowSprms.set(NS_sprm::LN_PRow, pRowValue);
1733 :
1734 24 : RTFValue::Pointer_t pCellMar = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblCellMar);
1735 24 : if (!pCellMar.get())
1736 : {
1737 : // If no cell margins are defined, the default left/right margin is 0 in Word, but not in Writer.
1738 24 : RTFSprms aAttributes;
1739 24 : aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, RTFValue::Pointer_t(new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)));
1740 24 : aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, RTFValue::Pointer_t(new RTFValue(0)));
1741 24 : lcl_putNestedSprm(m_aStates.top().aTableRowSprms,
1742 : NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left,
1743 48 : RTFValue::Pointer_t(new RTFValue(aAttributes)));
1744 24 : lcl_putNestedSprm(m_aStates.top().aTableRowSprms,
1745 : NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right,
1746 48 : RTFValue::Pointer_t(new RTFValue(aAttributes)));
1747 : }
1748 :
1749 : writerfilter::Reference<Properties>::Pointer_t const pTableRowProperties(
1750 72 : new RTFReferenceProperties(m_aStates.top().aTableRowAttributes, m_aStates.top().aTableRowSprms)
1751 72 : );
1752 24 : Mapper().props(pTableRowProperties);
1753 :
1754 24 : tableBreak();
1755 24 : m_bNeedPap = true;
1756 24 : m_bNeedFinalPar = true;
1757 24 : m_aTableBuffer.clear();
1758 24 : m_aStates.top().nCells = 0;
1759 24 : m_aStates.top().aTableCellsSprms.clear();
1760 24 : m_aStates.top().aTableCellsAttributes.clear();
1761 : }
1762 24 : break;
1763 : case RTF_COLUMN:
1764 : {
1765 1 : bool bColumns = false; // If we have multiple columns
1766 1 : RTFValue::Pointer_t pCols = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_cols);
1767 1 : if (pCols.get())
1768 : {
1769 0 : RTFValue::Pointer_t pNum = pCols->getAttributes().find(NS_ooxml::LN_CT_Columns_num);
1770 0 : if (pNum.get() && pNum->getInt() > 1)
1771 0 : bColumns = true;
1772 : }
1773 1 : if (bColumns)
1774 : {
1775 0 : sal_uInt8 sBreak[] = { 0xe };
1776 0 : Mapper().startCharacterGroup();
1777 0 : Mapper().text(sBreak, 1);
1778 0 : Mapper().endCharacterGroup();
1779 : }
1780 : else
1781 1 : dispatchSymbol(RTF_PAGE);
1782 : }
1783 1 : break;
1784 : case RTF_CHFTN:
1785 : // Nothing to do, dmapper assumes this is the default.
1786 6 : break;
1787 : case RTF_PAGE:
1788 : {
1789 : // If we're inside a continous section, we should send a section break, not a page one.
1790 55 : RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
1791 55 : if (pBreak.get() && !pBreak->getInt())
1792 : {
1793 2 : if (m_bWasInFrame)
1794 : {
1795 2 : dispatchSymbol(RTF_PAR);
1796 2 : m_bWasInFrame = false;
1797 : }
1798 2 : dispatchFlag(RTF_SBKPAGE);
1799 2 : sectBreak();
1800 2 : dispatchFlag(RTF_SBKNONE);
1801 2 : if (m_bNeedPar)
1802 2 : dispatchSymbol(RTF_PAR);
1803 2 : m_bIgnoreNextContSectBreak = true;
1804 : }
1805 : else
1806 : {
1807 53 : sal_uInt8 sBreak[] = { 0xc };
1808 53 : Mapper().text(sBreak, 1);
1809 53 : if (!m_bNeedPap)
1810 50 : parBreak();
1811 55 : }
1812 : }
1813 55 : break;
1814 : case RTF_CHPGN:
1815 : {
1816 2 : OUString aStr("PAGE");
1817 2 : singleChar(0x13);
1818 2 : text(aStr);
1819 2 : singleChar(0x14, true);
1820 2 : singleChar(0x15);
1821 : }
1822 2 : break;
1823 : default:
1824 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle symbol '" << lcl_RtfToString(nKeyword) << "'");
1825 2 : aSkip.setParsed(false);
1826 2 : break;
1827 : }
1828 23929 : return 0;
1829 : }
1830 :
1831 8592 : int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
1832 : {
1833 8592 : checkUnicode();
1834 8592 : setNeedSect();
1835 8592 : RTFSkipDestination aSkip(*this);
1836 8592 : int nParam = -1;
1837 8592 : int nSprm = -1;
1838 :
1839 : // Map all underline flags to a single sprm.
1840 8592 : switch (nKeyword)
1841 : {
1842 0 : case RTF_ULD: nSprm = 4; break;
1843 0 : case RTF_ULW: nSprm = 2; break;
1844 8592 : default: break;
1845 : }
1846 8592 : if (nSprm >= 0)
1847 : {
1848 0 : RTFValue::Pointer_t pValue(new RTFValue(nSprm));
1849 0 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
1850 0 : return 0;
1851 : }
1852 :
1853 : // Indentation
1854 8592 : switch (nKeyword)
1855 : {
1856 10 : case RTF_QC: nParam = 1; break;
1857 3 : case RTF_QJ: nParam = 3; break;
1858 75 : case RTF_QL: nParam = 0; break;
1859 13 : case RTF_QR: nParam = 2; break;
1860 0 : case RTF_QD: nParam = 4; break;
1861 8491 : default: break;
1862 : }
1863 8592 : if (nParam >= 0)
1864 : {
1865 101 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1866 101 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PJc, pValue);
1867 101 : return 0;
1868 : }
1869 :
1870 : // Font Alignment
1871 8491 : switch (nKeyword)
1872 : {
1873 : case RTF_FAFIXED:
1874 84 : case RTF_FAAUTO: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_auto; break;
1875 0 : case RTF_FAHANG: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_top; break;
1876 0 : case RTF_FACENTER: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_center; break;
1877 0 : case RTF_FAROMAN: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_baseline; break;
1878 0 : case RTF_FAVAR: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_bottom; break;
1879 8407 : default: break;
1880 : }
1881 8491 : if (nParam >= 0)
1882 : {
1883 84 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1884 84 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PWAlignFont, pValue);
1885 84 : return 0;
1886 : }
1887 :
1888 : // Tab kind.
1889 8407 : switch (nKeyword)
1890 : {
1891 2 : case RTF_TQR: nParam = 2; break;
1892 0 : case RTF_TQC: nParam = 1; break;
1893 0 : case RTF_TQDEC: nParam = 3; break;
1894 8405 : default: break;
1895 : }
1896 8407 : if (nParam >= 0)
1897 : {
1898 2 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1899 2 : m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_val, pValue);
1900 2 : return 0;
1901 : }
1902 :
1903 : // Tab lead.
1904 8405 : switch (nKeyword)
1905 : {
1906 0 : case RTF_TLDOT: nParam = 1; break;
1907 0 : case RTF_TLMDOT: nParam = NS_ooxml::LN_Value_ST_TabTlc_middleDot; break;
1908 0 : case RTF_TLHYPH: nParam = 2; break;
1909 0 : case RTF_TLUL: nParam = 3; break;
1910 0 : case RTF_TLTH: nParam = 2; break; // thick line is not supported by dmapper, this is just a hack
1911 0 : case RTF_TLEQ: nParam = 0; break; // equal sign isn't, either
1912 8405 : default: break;
1913 : }
1914 8405 : if (nParam >= 0)
1915 : {
1916 0 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1917 0 : m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_leader, pValue);
1918 0 : return 0;
1919 : }
1920 :
1921 : // Border types
1922 : {
1923 8405 : switch (nKeyword)
1924 : {
1925 : // brdrhair and brdrs are the same, brdrw will make a difference
1926 : // map to values in ooxml/model.xml resource ST_Border
1927 3 : case RTF_BRDRHAIR: nParam = 5; break;
1928 21 : case RTF_BRDRS: nParam = 1; break;
1929 0 : case RTF_BRDRDOT: nParam = 6; break;
1930 0 : case RTF_BRDRDASH: nParam = 7; break;
1931 17 : case RTF_BRDRDB: nParam = 3; break;
1932 0 : case RTF_BRDRTNTHSG: nParam = 11; break;
1933 0 : case RTF_BRDRTNTHMG: nParam = 14; break;
1934 0 : case RTF_BRDRTNTHLG: nParam = 17; break;
1935 10 : case RTF_BRDRTHTNSG: nParam = 12; break;
1936 20 : case RTF_BRDRTHTNMG: nParam = 15; break;
1937 18 : case RTF_BRDRTHTNLG: nParam = 18; break;
1938 12 : case RTF_BRDREMBOSS: nParam = 24; break;
1939 12 : case RTF_BRDRENGRAVE: nParam = 25; break;
1940 22 : case RTF_BRDROUTSET: nParam = 18; break;
1941 20 : case RTF_BRDRINSET: nParam = 17; break;
1942 48 : case RTF_BRDRNONE: nParam = 0; break;
1943 8202 : default: break;
1944 : }
1945 8405 : if (nParam >= 0)
1946 : {
1947 203 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1948 203 : lcl_putBorderProperty(m_aStates, NS_rtf::LN_BRCTYPE, pValue);
1949 203 : return 0;
1950 : }
1951 : }
1952 :
1953 : // Section breaks
1954 8202 : switch (nKeyword)
1955 : {
1956 41 : case RTF_SBKNONE: nParam = 0; break;
1957 0 : case RTF_SBKCOL: nParam = 1; break;
1958 3 : case RTF_SBKPAGE: nParam = 2; break;
1959 0 : case RTF_SBKEVEN: nParam = 3; break;
1960 0 : case RTF_SBKODD: nParam = 4; break;
1961 8158 : default: break;
1962 : }
1963 8202 : if (nParam >= 0)
1964 : {
1965 44 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1966 44 : m_aStates.top().aSectionSprms.set(NS_sprm::LN_SBkc, pValue);
1967 44 : return 0;
1968 : }
1969 :
1970 : // Footnote numbering
1971 8158 : switch (nKeyword)
1972 : {
1973 33 : case RTF_FTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break;
1974 0 : case RTF_FTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break;
1975 0 : case RTF_FTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break;
1976 0 : case RTF_FTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break;
1977 0 : case RTF_FTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break;
1978 0 : case RTF_FTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break;
1979 8125 : default: break;
1980 : }
1981 8158 : if (nParam >= 0)
1982 : {
1983 33 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1984 33 : lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt, pValue);
1985 33 : return 0;
1986 : }
1987 :
1988 : // Footnote restart type
1989 8125 : switch (nKeyword)
1990 : {
1991 0 : case RTF_FTNRSTPG: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage; break;
1992 0 : case RTF_FTNRESTART: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect; break;
1993 31 : case RTF_FTNRSTCONT: nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous; break;
1994 8094 : default: break;
1995 : }
1996 8125 : if (nParam >= 0)
1997 : {
1998 31 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
1999 31 : lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
2000 31 : return 0;
2001 : }
2002 :
2003 : // Endnote numbering
2004 8094 : switch (nKeyword)
2005 : {
2006 3 : case RTF_AFTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break;
2007 0 : case RTF_AFTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break;
2008 0 : case RTF_AFTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break;
2009 31 : case RTF_AFTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break;
2010 0 : case RTF_AFTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break;
2011 0 : case RTF_AFTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break;
2012 8060 : default: break;
2013 : }
2014 8094 : if (nParam >= 0)
2015 : {
2016 34 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
2017 34 : lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_CT_EdnProps_numFmt, pValue);
2018 34 : return 0;
2019 : }
2020 :
2021 : // Cell Text Flow
2022 8060 : switch (nKeyword)
2023 : {
2024 118 : case RTF_CLTXLRTB: nParam = 0; break;
2025 0 : case RTF_CLTXTBRL: nParam = 1; break;
2026 0 : case RTF_CLTXBTLR: nParam = 3; break;
2027 0 : case RTF_CLTXLRTBV: nParam = 4; break;
2028 0 : case RTF_CLTXTBRLV: nParam = 5; break;
2029 7942 : default: break;
2030 : }
2031 8060 : if (nParam >= 0)
2032 : {
2033 118 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
2034 118 : m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_textDirection, pValue);
2035 : }
2036 :
2037 : // Trivial paragraph flags
2038 8060 : switch (nKeyword)
2039 : {
2040 0 : case RTF_KEEP: if (m_pCurrentBuffer != &m_aTableBuffer) nParam = NS_sprm::LN_PFKeep; break;
2041 39 : case RTF_KEEPN: if (m_pCurrentBuffer != &m_aTableBuffer) nParam = NS_sprm::LN_PFKeepFollow; break;
2042 223 : case RTF_INTBL: m_pCurrentBuffer = &m_aTableBuffer; nParam = NS_sprm::LN_PFInTable; break;
2043 2 : case RTF_PAGEBB: nParam = NS_sprm::LN_PFPageBreakBefore; break;
2044 7796 : default: break;
2045 : }
2046 8060 : if (nParam >= 0)
2047 : {
2048 373 : RTFValue::Pointer_t pValue(new RTFValue(1));
2049 373 : m_aStates.top().aParagraphSprms.erase(NS_sprm::LN_PFInTable);
2050 373 : m_aStates.top().aParagraphSprms.set(nParam, pValue);
2051 373 : return 0;
2052 : }
2053 :
2054 7687 : switch (nKeyword)
2055 : {
2056 : case RTF_FNIL:
2057 : case RTF_FROMAN:
2058 : case RTF_FSWISS:
2059 : case RTF_FMODERN:
2060 : case RTF_FSCRIPT:
2061 : case RTF_FDECOR:
2062 : case RTF_FTECH:
2063 : case RTF_FBIDI:
2064 : // TODO ooxml:CT_Font_family seems to be ignored by the domain mapper
2065 578 : break;
2066 : case RTF_ANSI:
2067 57 : m_aStates.top().nCurrentEncoding = RTL_TEXTENCODING_MS_1252;
2068 57 : break;
2069 : case RTF_PLAIN:
2070 : {
2071 159 : m_aStates.top().aCharacterSprms = getDefaultState().aCharacterSprms;
2072 159 : RTFValue::Pointer_t pValue = m_aStates.top().aCharacterSprms.find(NS_sprm::LN_CRgFtc0);
2073 159 : if (pValue.get())
2074 137 : m_aStates.top().nCurrentEncoding = getEncoding(pValue->getInt());
2075 159 : m_aStates.top().aCharacterAttributes = getDefaultState().aCharacterAttributes;
2076 : }
2077 159 : break;
2078 : case RTF_PARD:
2079 219 : if (m_bHadPicture)
2080 3 : dispatchSymbol(RTF_PAR);
2081 219 : m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms;
2082 219 : m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes;
2083 219 : m_aStates.top().resetFrame();
2084 219 : if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT)
2085 215 : m_pCurrentBuffer = 0;
2086 219 : break;
2087 : case RTF_SECTD:
2088 46 : m_aStates.top().aSectionSprms = m_aDefaultState.aSectionSprms;
2089 46 : m_aStates.top().aSectionAttributes = m_aDefaultState.aSectionAttributes;
2090 46 : break;
2091 : case RTF_TROWD:
2092 35 : m_aStates.top().aTableRowSprms = m_aDefaultState.aTableRowSprms;
2093 35 : m_aStates.top().aTableRowAttributes = m_aDefaultState.aTableRowAttributes;
2094 35 : m_aStates.top().nCellX = 0;
2095 : // In case the table definition is in the middle of the row
2096 : // (invalid), make sure table definition is emitted.
2097 35 : m_bNeedPap = true;
2098 35 : break;
2099 : case RTF_WIDCTLPAR:
2100 : case RTF_NOWIDCTLPAR:
2101 : {
2102 212 : RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_WIDCTLPAR));
2103 212 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFWidowControl, pValue);
2104 : }
2105 212 : break;
2106 : case RTF_BOX:
2107 : {
2108 4 : RTFSprms aAttributes;
2109 4 : RTFValue::Pointer_t pValue(new RTFValue(aAttributes));
2110 20 : for (int i = 0; i < 4; i++)
2111 16 : m_aStates.top().aParagraphSprms.set(lcl_getParagraphBorder(i), pValue);
2112 4 : m_aStates.top().nBorderState = BORDER_PARAGRAPH_BOX;
2113 : }
2114 4 : break;
2115 : case RTF_LTRSECT:
2116 : case RTF_RTLSECT:
2117 : {
2118 8 : RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRSECT ? 0 : 1));
2119 8 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_STextFlow, pValue);
2120 : }
2121 8 : break;
2122 : case RTF_LTRPAR:
2123 : case RTF_RTLPAR:
2124 : {
2125 84 : RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRPAR ? 0 : 1));
2126 84 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFrameTextFlow, pValue);
2127 : }
2128 84 : break;
2129 : case RTF_LTRROW:
2130 : case RTF_RTLROW:
2131 : {
2132 37 : RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRROW ? 0 : 1));
2133 37 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_TTextFlow, pValue);
2134 : }
2135 37 : break;
2136 : case RTF_LTRCH:
2137 : // dmapper does not support this.
2138 762 : break;
2139 : case RTF_RTLCH:
2140 756 : if (m_aDefaultState.nCurrentEncoding == RTL_TEXTENCODING_MS_1255)
2141 1 : m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
2142 756 : break;
2143 : case RTF_ULNONE:
2144 : {
2145 0 : RTFValue::Pointer_t pValue(new RTFValue(0));
2146 0 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
2147 : }
2148 0 : break;
2149 : case RTF_NONSHPPICT:
2150 : case RTF_MMATHPICT: // Picture group used by readers not understanding \moMath group
2151 0 : m_aStates.top().nDestinationState = DESTINATION_SKIP;
2152 0 : break;
2153 : case RTF_CLBRDRT:
2154 : case RTF_CLBRDRL:
2155 : case RTF_CLBRDRB:
2156 : case RTF_CLBRDRR:
2157 : {
2158 476 : RTFSprms aAttributes;
2159 476 : RTFSprms aSprms;
2160 476 : RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
2161 476 : switch (nKeyword)
2162 : {
2163 119 : case RTF_CLBRDRT: nParam = NS_ooxml::LN_CT_TcBorders_top; break;
2164 119 : case RTF_CLBRDRL: nParam = NS_ooxml::LN_CT_TcBorders_left; break;
2165 119 : case RTF_CLBRDRB: nParam = NS_ooxml::LN_CT_TcBorders_bottom; break;
2166 119 : case RTF_CLBRDRR: nParam = NS_ooxml::LN_CT_TcBorders_right; break;
2167 0 : default: break;
2168 : }
2169 476 : lcl_putNestedSprm(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders, nParam, pValue);
2170 476 : m_aStates.top().nBorderState = BORDER_CELL;
2171 : }
2172 476 : break;
2173 : case RTF_PGBRDRT:
2174 : case RTF_PGBRDRL:
2175 : case RTF_PGBRDRB:
2176 : case RTF_PGBRDRR:
2177 : {
2178 0 : RTFSprms aAttributes;
2179 0 : RTFSprms aSprms;
2180 0 : RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
2181 0 : switch (nKeyword)
2182 : {
2183 0 : case RTF_PGBRDRT: nParam = NS_ooxml::LN_CT_PageBorders_top; break;
2184 0 : case RTF_PGBRDRL: nParam = NS_ooxml::LN_CT_PageBorders_left; break;
2185 0 : case RTF_PGBRDRB: nParam = NS_ooxml::LN_CT_PageBorders_bottom; break;
2186 0 : case RTF_PGBRDRR: nParam = NS_ooxml::LN_CT_PageBorders_right; break;
2187 0 : default: break;
2188 : }
2189 0 : lcl_putNestedSprm(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders, nParam, pValue);
2190 0 : m_aStates.top().nBorderState = BORDER_PAGE;
2191 : }
2192 0 : break;
2193 : case RTF_BRDRT:
2194 : case RTF_BRDRL:
2195 : case RTF_BRDRB:
2196 : case RTF_BRDRR:
2197 : {
2198 1 : RTFSprms aAttributes;
2199 1 : RTFSprms aSprms;
2200 1 : RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
2201 1 : switch (nKeyword)
2202 : {
2203 0 : case RTF_BRDRT: nParam = lcl_getParagraphBorder(0); break;
2204 0 : case RTF_BRDRL: nParam = lcl_getParagraphBorder(1); break;
2205 1 : case RTF_BRDRB: nParam = lcl_getParagraphBorder(2); break;
2206 0 : case RTF_BRDRR: nParam = lcl_getParagraphBorder(3); break;
2207 0 : default: break;
2208 : }
2209 1 : lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr, nParam, pValue);
2210 1 : m_aStates.top().nBorderState = BORDER_PARAGRAPH;
2211 : }
2212 1 : break;
2213 : case RTF_CLVMGF:
2214 : {
2215 0 : RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));
2216 0 : m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
2217 : }
2218 0 : break;
2219 : case RTF_CLVMRG:
2220 : {
2221 0 : RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue));
2222 0 : m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
2223 : }
2224 0 : break;
2225 : case RTF_CLVERTALT:
2226 : case RTF_CLVERTALC:
2227 : case RTF_CLVERTALB:
2228 : {
2229 151 : switch (nKeyword)
2230 : {
2231 151 : case RTF_CLVERTALT: nParam = 0; break;
2232 0 : case RTF_CLVERTALC: nParam = 1; break;
2233 0 : case RTF_CLVERTALB: nParam = 3; break;
2234 0 : default: break;
2235 : }
2236 151 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
2237 151 : m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue);
2238 : }
2239 151 : break;
2240 : case RTF_TRKEEP:
2241 : {
2242 0 : RTFValue::Pointer_t pValue(new RTFValue(1));
2243 0 : m_aStates.top().aTableRowSprms.set(NS_sprm::LN_TCantSplit, pValue);
2244 : }
2245 : case RTF_SECTUNLOCKED:
2246 : {
2247 31 : RTFValue::Pointer_t pValue(new RTFValue(!nParam));
2248 31 : m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue);
2249 : }
2250 : case RTF_PGNDEC:
2251 : case RTF_PGNUCRM:
2252 : case RTF_PGNLCRM:
2253 : case RTF_PGNUCLTR:
2254 : case RTF_PGNLCLTR:
2255 : case RTF_PGNBIDIA:
2256 : case RTF_PGNBIDIB:
2257 : // These should be mapped to NS_ooxml::LN_EG_SectPrContents_pgNumType, but dmapper has no API for that at the moment.
2258 92 : break;
2259 : case RTF_LOCH:
2260 : // Noop, dmapper detects this automatically.
2261 1050 : break;
2262 : case RTF_HICH:
2263 744 : m_aStates.top().bIsCjk = true;
2264 744 : break;
2265 : case RTF_DBCH:
2266 1132 : m_aStates.top().bIsCjk = false;
2267 1132 : break;
2268 : case RTF_TITLEPG:
2269 : {
2270 6 : RTFValue::Pointer_t pValue(new RTFValue(1));
2271 6 : m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue);
2272 : }
2273 6 : break;
2274 : case RTF_SUPER:
2275 : {
2276 9 : if (!m_pCurrentBuffer)
2277 9 : m_pCurrentBuffer = &m_aSuperBuffer;
2278 9 : RTFValue::Pointer_t pValue(new RTFValue("superscript"));
2279 9 : m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
2280 : }
2281 9 : break;
2282 : case RTF_SUB:
2283 : {
2284 0 : RTFValue::Pointer_t pValue(new RTFValue("subscript"));
2285 0 : m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
2286 : }
2287 0 : break;
2288 : case RTF_NOSUPERSUB:
2289 1 : if (m_pCurrentBuffer == &m_aSuperBuffer)
2290 : {
2291 1 : replayBuffer(m_aSuperBuffer);
2292 1 : m_pCurrentBuffer = 0;
2293 : }
2294 1 : m_aStates.top().aCharacterSprms.erase(NS_ooxml::LN_EG_RPrBase_vertAlign);
2295 1 : break;
2296 : case RTF_LINEPPAGE:
2297 : case RTF_LINECONT:
2298 : {
2299 0 : RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LINEPPAGE ? 0 : 2));
2300 0 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
2301 0 : NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_restart, pValue);
2302 : }
2303 0 : break;
2304 : case RTF_AENDDOC:
2305 : // Noop, this is the default in Writer.
2306 38 : break;
2307 : case RTF_AENDNOTES:
2308 : // Noop, Writer does not support having endnotes at the end of section.
2309 0 : break;
2310 : case RTF_AFTNRSTCONT:
2311 : // Noop, this is the default in Writer.
2312 31 : break;
2313 : case RTF_AFTNRESTART:
2314 : // Noop, Writer does not support restarting endnotes at each section.
2315 0 : break;
2316 : case RTF_FTNBJ:
2317 : // Noop, this is the default in Writer.
2318 42 : break;
2319 : case RTF_ENDDOC:
2320 : {
2321 0 : RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_RestartNumber_eachSect));
2322 0 : lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
2323 : }
2324 0 : break;
2325 : case RTF_NOLINE:
2326 64 : lcl_eraseNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance);
2327 64 : break;
2328 : case RTF_FORMSHADE:
2329 : // Noop, this is the default in Writer.
2330 33 : break;
2331 : case RTF_PNGBLIP:
2332 5 : m_aStates.top().aPicture.nStyle = BMPSTYLE_PNG;
2333 5 : break;
2334 : case RTF_JPEGBLIP:
2335 1 : m_aStates.top().aPicture.nStyle = BMPSTYLE_JPEG;
2336 1 : break;
2337 2 : case RTF_POSYT: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_top); break;
2338 0 : case RTF_POSYB: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_bottom); break;
2339 0 : case RTF_POSYC: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_center); break;
2340 0 : case RTF_POSYIN: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inside); break;
2341 0 : case RTF_POSYOUT: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_outside); break;
2342 0 : case RTF_POSYIL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inline); break;
2343 :
2344 1 : case RTF_PHMRG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_margin); break;
2345 0 : case RTF_PVMRG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_margin); break;
2346 8 : case RTF_PHPG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_page); break;
2347 10 : case RTF_PVPG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_page); break;
2348 3 : case RTF_PHCOL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_text); break;
2349 3 : case RTF_PVPARA: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_text); break;
2350 :
2351 2 : case RTF_POSXC: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_center); break;
2352 0 : case RTF_POSXI: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_inside); break;
2353 0 : case RTF_POSXO: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_outside); break;
2354 0 : case RTF_POSXL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_left); break;
2355 0 : case RTF_POSXR: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_right); break;
2356 :
2357 : case RTF_DPLINE:
2358 : case RTF_DPRECT:
2359 : case RTF_DPELLIPSE:
2360 : case RTF_DPTXBX:
2361 : case RTF_DPPOLYLINE:
2362 : {
2363 10 : sal_Int32 nType = 0;
2364 10 : switch (nKeyword)
2365 : {
2366 : case RTF_DPLINE:
2367 1 : m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.LineShape"), uno::UNO_QUERY);
2368 1 : break;
2369 : case RTF_DPPOLYLINE:
2370 : // The reason this is not a simple CustomShape is that in the old syntax we have no ViewBox info.
2371 4 : m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.PolyLineShape"), uno::UNO_QUERY);
2372 4 : break;
2373 : case RTF_DPRECT:
2374 3 : m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
2375 3 : break;
2376 : case RTF_DPELLIPSE:
2377 0 : nType = ESCHER_ShpInst_Ellipse;
2378 0 : break;
2379 : case RTF_DPTXBX:
2380 : {
2381 2 : m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.text.TextFrame"), uno::UNO_QUERY);
2382 : // These are the default in Word, but not in Writer
2383 2 : beans::PropertyValue aPropertyValue;
2384 2 : aPropertyValue.Name = "HoriOrient";
2385 2 : aPropertyValue.Value <<= text::HoriOrientation::NONE;
2386 2 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2387 2 : aPropertyValue.Name = "VertOrient";
2388 2 : aPropertyValue.Value <<= text::VertOrientation::NONE;
2389 2 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2390 2 : aPropertyValue.Name = "BackColorTransparency";
2391 2 : aPropertyValue.Value <<= sal_Int32(100);
2392 2 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2393 2 : aPropertyValue.Name = "LeftBorderDistance";
2394 2 : aPropertyValue.Value <<= sal_Int32(0);
2395 2 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2396 2 : aPropertyValue.Name = "RightBorderDistance";
2397 2 : aPropertyValue.Value <<= sal_Int32(0);
2398 2 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2399 2 : aPropertyValue.Name = "TopBorderDistance";
2400 2 : aPropertyValue.Value <<= sal_Int32(0);
2401 2 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2402 2 : aPropertyValue.Name = "BottomBorderDistance";
2403 2 : aPropertyValue.Value <<= sal_Int32(0);
2404 2 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2405 : }
2406 2 : break;
2407 : default:
2408 0 : break;
2409 : }
2410 10 : if (nType)
2411 0 : m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.CustomShape"), uno::UNO_QUERY);
2412 10 : uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier( m_xDstDoc, uno::UNO_QUERY);
2413 10 : if (xDrawSupplier.is())
2414 : {
2415 10 : uno::Reference<drawing::XShapes> xShapes(xDrawSupplier->getDrawPage(), uno::UNO_QUERY);
2416 10 : if (xShapes.is() && nKeyword != RTF_DPTXBX)
2417 8 : xShapes->add(m_aStates.top().aDrawingObject.xShape);
2418 : }
2419 10 : if (nType)
2420 : {
2421 0 : uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
2422 0 : xDefaulter->createCustomShapeDefaults(OUString::valueOf(nType));
2423 : }
2424 10 : m_aStates.top().aDrawingObject.xPropertySet.set(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
2425 10 : std::vector<beans::PropertyValue>& rPendingProperties = m_aStates.top().aDrawingObject.aPendingProperties;
2426 41 : for (std::vector<beans::PropertyValue>::iterator i = rPendingProperties.begin(); i != rPendingProperties.end(); ++i)
2427 31 : m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue(i->Name, i->Value);
2428 10 : m_pSdrImport->resolveDhgt(m_aStates.top().aDrawingObject.xPropertySet, m_aStates.top().aDrawingObject.nDhgt);
2429 : }
2430 10 : break;
2431 : case RTF_DOBXMARGIN:
2432 : case RTF_DOBYMARGIN:
2433 : {
2434 1 : beans::PropertyValue aPropertyValue;
2435 1 : aPropertyValue.Name = (nKeyword == RTF_DOBXMARGIN ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
2436 1 : aPropertyValue.Value <<= text::RelOrientation::PAGE_PRINT_AREA;
2437 1 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2438 : }
2439 1 : break;
2440 : case RTF_DOBXPAGE:
2441 : case RTF_DOBYPAGE:
2442 : {
2443 7 : beans::PropertyValue aPropertyValue;
2444 7 : aPropertyValue.Name = (nKeyword == RTF_DOBXPAGE ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
2445 7 : aPropertyValue.Value <<= text::RelOrientation::PAGE_FRAME;
2446 7 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2447 : }
2448 7 : break;
2449 : case RTF_DOBYPARA:
2450 : {
2451 9 : beans::PropertyValue aPropertyValue;
2452 9 : aPropertyValue.Name = OUString("VertOrientRelation");
2453 9 : aPropertyValue.Value <<= text::RelOrientation::FRAME;
2454 9 : m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
2455 : }
2456 9 : break;
2457 : case RTF_CONTEXTUALSPACE:
2458 : {
2459 2 : RTFValue::Pointer_t pValue(new RTFValue(1));
2460 2 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PContextualSpacing, pValue);
2461 : }
2462 2 : break;
2463 : case RTF_LINKSTYLES:
2464 : {
2465 1 : RTFValue::Pointer_t pValue(new RTFValue(1));
2466 1 : m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue);
2467 : }
2468 1 : break;
2469 : case RTF_PNLVLBODY:
2470 : {
2471 3 : RTFValue::Pointer_t pValue(new RTFValue(2));
2472 3 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, pValue);
2473 : }
2474 3 : break;
2475 : case RTF_PNDEC:
2476 : {
2477 3 : RTFValue::Pointer_t pValue(new RTFValue(0)); // decimal, same as \levelnfc0
2478 3 : m_aStates.top().aTableSprms.set(NS_rtf::LN_NFC, pValue);
2479 : }
2480 3 : break;
2481 : case RTF_PNLVLBLT:
2482 : {
2483 1 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, RTFValue::Pointer_t(new RTFValue(1)));
2484 1 : m_aStates.top().aTableSprms.set(NS_rtf::LN_NFC, RTFValue::Pointer_t(new RTFValue(23))); // bullets, same as \levelnfc23
2485 : }
2486 1 : break;
2487 : case RTF_LANDSCAPE:
2488 3 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, RTFValue::Pointer_t(new RTFValue(1)));
2489 3 : break;
2490 : case RTF_FACINGP:
2491 2 : m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_evenAndOddHeaders, RTFValue::Pointer_t(new RTFValue(1)));
2492 2 : break;
2493 : case RTF_SHPBXPAGE:
2494 7 : m_aStates.top().aShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
2495 7 : break;
2496 : case RTF_SHPBYPAGE:
2497 6 : m_aStates.top().aShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
2498 6 : break;
2499 : case RTF_DPLINEHOLLOW:
2500 2 : m_aStates.top().aDrawingObject.nFLine = 0;
2501 2 : break;
2502 : case RTF_DPROUNDR:
2503 0 : if (m_aStates.top().aDrawingObject.xPropertySet.is())
2504 : // Seems this old syntax has no way to specify a custom radius, and this is the default
2505 0 : m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue("CornerRadius", uno::makeAny(sal_Int32(83)));
2506 0 : break;
2507 : default:
2508 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle flag '" << lcl_RtfToString(nKeyword) << "'");
2509 768 : aSkip.setParsed(false);
2510 768 : break;
2511 : }
2512 7687 : return 0;
2513 : }
2514 :
2515 14421 : int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
2516 : {
2517 14421 : checkUnicode(nKeyword != RTF_U, true);
2518 14421 : setNeedSect();
2519 14421 : RTFSkipDestination aSkip(*this);
2520 14421 : int nSprm = 0;
2521 14421 : RTFValue::Pointer_t pIntValue(new RTFValue(nParam));
2522 : // Trivial table sprms.
2523 14421 : switch (nKeyword)
2524 : {
2525 453 : case RTF_FPRQ: nSprm = NS_rtf::LN_PRQ; break;
2526 6 : case RTF_LEVELJC: nSprm = NS_ooxml::LN_CT_Lvl_lvlJc; break;
2527 10 : case RTF_LEVELNFC: nSprm = NS_rtf::LN_NFC; break;
2528 10 : case RTF_LEVELSTARTAT: nSprm = NS_rtf::LN_ISTARTAT; break;
2529 13942 : default: break;
2530 : }
2531 14421 : if (nSprm > 0)
2532 : {
2533 479 : m_aStates.top().aTableSprms.set(nSprm, pIntValue);
2534 479 : return 0;
2535 : }
2536 : // Trivial character sprms.
2537 13942 : switch (nKeyword)
2538 : {
2539 2854 : case RTF_AF: nSprm = (m_aStates.top().bIsCjk ? NS_sprm::LN_CRgFtc1 : NS_sprm::LN_CRgFtc2); break;
2540 312 : case RTF_FS: nSprm = NS_sprm::LN_CHps; break;
2541 256 : case RTF_AFS: nSprm = NS_sprm::LN_CHpsBi; break;
2542 0 : case RTF_ANIMTEXT: nSprm = NS_sprm::LN_CSfxText; break;
2543 0 : case RTF_EXPNDTW: nSprm = NS_sprm::LN_CDxaSpace; break;
2544 129 : case RTF_KERNING: nSprm = NS_sprm::LN_CHpsKern; break;
2545 0 : case RTF_CHARSCALEX: nSprm = NS_sprm::LN_CCharScale; break;
2546 236 : case RTF_LANG: nSprm = NS_sprm::LN_CRgLid0; break;
2547 221 : case RTF_LANGFE: nSprm = NS_sprm::LN_CRgLid1; break;
2548 182 : case RTF_ALANG: nSprm = NS_sprm::LN_CLidBi; break;
2549 9752 : default: break;
2550 : }
2551 13942 : if (nSprm > 0)
2552 : {
2553 4190 : m_aStates.top().aCharacterSprms.set(nSprm, pIntValue);
2554 : // Language is a character property, but we should store it at a paragraph level as well for fields.
2555 4190 : if (nKeyword == RTF_LANG && m_bNeedPap)
2556 234 : m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
2557 4190 : return 0;
2558 : }
2559 : // Trivial paragraph sprms.
2560 9752 : switch (nKeyword)
2561 : {
2562 103 : case RTF_FI: nSprm = NS_sprm::LN_PDxaLeft1; break;
2563 93 : case RTF_LIN: nSprm = 0x845e; break;
2564 89 : case RTF_RI: nSprm = NS_sprm::LN_PDxaRight; break;
2565 88 : case RTF_RIN: nSprm = 0x845d; break;
2566 31 : case RTF_ITAP: nSprm = NS_sprm::LN_PTableDepth; break;
2567 9348 : default: break;
2568 : }
2569 9752 : if (nSprm > 0)
2570 : {
2571 404 : m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
2572 404 : if (nKeyword == RTF_ITAP && nParam > 0)
2573 : // Invalid tables may omit INTBL after ITAP
2574 0 : dispatchFlag(RTF_INTBL);
2575 404 : return 0;
2576 : }
2577 :
2578 : // Trivial table attributes.
2579 9348 : switch (nKeyword)
2580 : {
2581 201 : case RTF_SBASEDON: nSprm = NS_rtf::LN_ISTDBASE; break;
2582 227 : case RTF_SNEXT: nSprm = NS_rtf::LN_ISTDNEXT; break;
2583 8920 : default: break;
2584 : }
2585 9348 : if (nSprm > 0)
2586 : {
2587 428 : m_aStates.top().aTableAttributes.set(nSprm, pIntValue);
2588 428 : return 0;
2589 : }
2590 :
2591 : // Info group.
2592 8920 : switch (nKeyword)
2593 : {
2594 94 : case RTF_YR: m_aStates.top().nYear = nParam; nSprm = 1; break;
2595 94 : case RTF_MO: m_aStates.top().nMonth = nParam; nSprm = 1; break;
2596 94 : case RTF_DY: m_aStates.top().nDay = nParam; nSprm = 1; break;
2597 94 : case RTF_HR: m_aStates.top().nHour = nParam; nSprm = 1; break;
2598 94 : case RTF_MIN: m_aStates.top().nMinute = nParam; nSprm = 1; break;
2599 8450 : default: break;
2600 : }
2601 8920 : if (nSprm > 0)
2602 470 : return 0;
2603 :
2604 : // Frame size / position.
2605 8450 : Id nId = 0;
2606 8450 : switch (nKeyword)
2607 : {
2608 14 : case RTF_ABSW: nId = NS_sprm::LN_PDxaWidth; break;
2609 14 : case RTF_ABSH: nId = NS_sprm::LN_PWHeightAbs; break;
2610 12 : case RTF_POSX: nId = NS_ooxml::LN_CT_FramePr_x; m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, 0); break;
2611 12 : case RTF_POSY: nId = NS_ooxml::LN_CT_FramePr_y; m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, 0); break;
2612 8398 : default: break;
2613 : }
2614 8450 : if (nId > 0)
2615 : {
2616 52 : m_bNeedPap = true;
2617 : // Don't try to support text frames inside tables for now.
2618 52 : if (m_pCurrentBuffer != &m_aTableBuffer)
2619 52 : m_aStates.top().aFrame.setSprm(nId, nParam);
2620 52 : return 0;
2621 : }
2622 :
2623 : // Then check for the more complex ones.
2624 8398 : switch (nKeyword)
2625 : {
2626 : case RTF_F:
2627 1466 : if (m_aStates.top().nDestinationState == DESTINATION_FONTTABLE || m_aStates.top().nDestinationState == DESTINATION_FONTENTRY)
2628 : {
2629 467 : m_aFontIndexes.push_back(nParam);
2630 467 : m_nCurrentFontIndex = getFontIndex(nParam);
2631 : }
2632 : else
2633 : {
2634 999 : int nFontIndex = getFontIndex(nParam);
2635 999 : RTFValue::Pointer_t pValue(new RTFValue(nFontIndex));
2636 999 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CRgFtc0, pValue);
2637 999 : m_aStates.top().nCurrentEncoding = getEncoding(nFontIndex);
2638 : }
2639 1466 : break;
2640 : case RTF_RED:
2641 124 : m_aStates.top().aCurrentColor.nRed = nParam;
2642 124 : break;
2643 : case RTF_GREEN:
2644 124 : m_aStates.top().aCurrentColor.nGreen = nParam;
2645 124 : break;
2646 : case RTF_BLUE:
2647 124 : m_aStates.top().aCurrentColor.nBlue = nParam;
2648 124 : break;
2649 : case RTF_FCHARSET:
2650 : {
2651 : // we always send text to the domain mapper in OUString, so no
2652 : // need to send encoding info
2653 : int i;
2654 4215 : for (i = 0; i < nRTFEncodings; i++)
2655 : {
2656 4215 : if (aRTFEncodings[i].charset == nParam)
2657 462 : break;
2658 : }
2659 462 : if (i == nRTFEncodings)
2660 : // not found
2661 0 : return 0;
2662 462 : m_aFontEncodings[m_nCurrentFontIndex] = rtl_getTextEncodingFromWindowsCodePage(aRTFEncodings[i].codepage);
2663 : }
2664 462 : break;
2665 : case RTF_ANSICPG:
2666 15 : m_aDefaultState.nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
2667 15 : m_aStates.top().nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
2668 15 : break;
2669 : case RTF_CPG:
2670 1 : m_aFontEncodings[m_nCurrentFontIndex] = rtl_getTextEncodingFromWindowsCodePage(nParam);
2671 1 : break;
2672 : case RTF_CF:
2673 : {
2674 : // NS_sprm::LN_CIco won't work, that would be an index in a static table
2675 146 : RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
2676 146 : m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_Color_val, pValue);
2677 : }
2678 146 : break;
2679 : case RTF_S:
2680 377 : m_aStates.top().nCurrentStyleIndex = nParam;
2681 377 : if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
2682 : {
2683 256 : m_nCurrentStyleIndex = nParam;
2684 256 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_ISTD, pIntValue);
2685 256 : RTFValue::Pointer_t pValue(new RTFValue(1));
2686 256 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_SGC, pValue); // paragraph style
2687 : }
2688 : else
2689 121 : m_aStates.top().aParagraphAttributes.set(NS_rtf::LN_ISTD, pIntValue);
2690 377 : break;
2691 : case RTF_CS:
2692 25 : if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
2693 : {
2694 22 : m_nCurrentStyleIndex = nParam;
2695 22 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_ISTD, pIntValue);
2696 22 : RTFValue::Pointer_t pValue(new RTFValue(2));
2697 22 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_SGC, pValue); // character style
2698 : }
2699 : else
2700 3 : m_aStates.top().aCharacterAttributes.set(NS_rtf::LN_ISTD, pIntValue);
2701 25 : break;
2702 : case RTF_DEFF:
2703 53 : m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CRgFtc0, pIntValue);
2704 53 : break;
2705 : case RTF_DEFLANG:
2706 11 : m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CRgLid0, pIntValue);
2707 11 : break;
2708 : case RTF_ADEFLANG:
2709 37 : m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CLidBi, pIntValue);
2710 37 : break;
2711 : case RTF_CHCBPAT:
2712 : {
2713 3 : RTFValue::Pointer_t pValue(new RTFValue(nParam ? getColorTable(nParam) : COL_AUTO));
2714 3 : lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_sprm::LN_CShd, NS_ooxml::LN_CT_Shd_fill, pValue);
2715 : }
2716 3 : break;
2717 : case RTF_CLCBPAT:
2718 : {
2719 1 : RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
2720 1 : lcl_putNestedAttribute(m_aStates.top().aTableCellSprms,
2721 2 : NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
2722 : }
2723 1 : break;
2724 : case RTF_CBPAT:
2725 2 : if (nParam)
2726 : {
2727 1 : RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
2728 1 : lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_sprm::LN_PShd, NS_ooxml::LN_CT_Shd_fill, pValue);
2729 : }
2730 2 : break;
2731 : case RTF_ULC:
2732 : {
2733 0 : RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
2734 0 : m_aStates.top().aCharacterSprms.set(0x6877, pValue);
2735 : }
2736 0 : break;
2737 : case RTF_HIGHLIGHT:
2738 : {
2739 0 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
2740 0 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CHighlight, pValue);
2741 : }
2742 0 : break;
2743 : case RTF_UP:
2744 : case RTF_DN:
2745 : {
2746 5 : RTFValue::Pointer_t pValue(new RTFValue(nParam * (nKeyword == RTF_UP ? 1 : -1)));
2747 5 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CHpsPos, pValue);
2748 : }
2749 5 : break;
2750 : case RTF_HORZVERT:
2751 : {
2752 0 : RTFValue::Pointer_t pValue(new RTFValue(true));
2753 0 : m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vert, pValue);
2754 0 : if (nParam)
2755 : // rotate fits to a single line
2756 0 : m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vertCompress, pValue);
2757 : }
2758 0 : break;
2759 : case RTF_EXPND:
2760 : {
2761 0 : RTFValue::Pointer_t pValue(new RTFValue(nParam/5));
2762 0 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CDxaSpace, pValue);
2763 : }
2764 0 : break;
2765 : case RTF_TWOINONE:
2766 : {
2767 0 : RTFValue::Pointer_t pValue(new RTFValue(true));
2768 0 : m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combine, pValue);
2769 0 : if (nParam > 0)
2770 0 : m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combineBrackets, pIntValue);
2771 : }
2772 0 : break;
2773 : case RTF_SL:
2774 : {
2775 : // This is similar to RTF_ABSH, negative value means 'exact', positive means 'at least'.
2776 15 : RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_atLeast));
2777 15 : if (nParam < 0)
2778 : {
2779 1 : pValue.reset(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_exact));
2780 1 : pIntValue.reset(new RTFValue(-nParam));
2781 : }
2782 15 : m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
2783 15 : m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_line, pIntValue);
2784 : }
2785 15 : break;
2786 : case RTF_SLMULT:
2787 14 : if (nParam > 0)
2788 : {
2789 13 : RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_auto));
2790 13 : m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
2791 : }
2792 14 : break;
2793 : case RTF_BRDRW:
2794 : {
2795 : // dmapper expects it in 1/8 pt, we have it in twip - but avoid rounding 1 to 0
2796 154 : if (nParam > 1)
2797 151 : nParam = nParam * 2 / 5;
2798 154 : RTFValue::Pointer_t pValue(new RTFValue(nParam));
2799 154 : lcl_putBorderProperty(m_aStates, NS_rtf::LN_DPTLINEWIDTH, pValue);
2800 : }
2801 154 : break;
2802 : case RTF_BRDRCF:
2803 : {
2804 19 : RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
2805 19 : lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_color, pValue);
2806 : }
2807 19 : break;
2808 : case RTF_BRSP:
2809 : {
2810 : // dmapper expects it in points, we have it in twip
2811 4 : RTFValue::Pointer_t pValue(new RTFValue(nParam / 20));
2812 4 : lcl_putBorderProperty(m_aStates, NS_rtf::LN_DPTSPACE, pValue);
2813 : }
2814 4 : break;
2815 : case RTF_TX:
2816 : {
2817 89 : m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_pos, pIntValue);
2818 89 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aTabAttributes));
2819 89 : lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_Tabs_tab, pValue);
2820 89 : m_aStates.top().aTabAttributes.clear();
2821 : }
2822 89 : break;
2823 : case RTF_ILVL:
2824 6 : lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_sprm::LN_PIlvl, pIntValue);
2825 6 : break;
2826 : case RTF_LISTTEMPLATEID:
2827 : // This one is not referenced anywhere, so it's pointless to store it at the moment.
2828 5 : break;
2829 : case RTF_LISTID:
2830 : {
2831 10 : if (m_aStates.top().nDestinationState == DESTINATION_LISTENTRY)
2832 5 : m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIntValue);
2833 5 : else if (m_aStates.top().nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
2834 5 : m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIntValue);
2835 : }
2836 10 : break;
2837 : case RTF_LS:
2838 : {
2839 14 : if (m_aStates.top().nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
2840 5 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, pIntValue);
2841 : else
2842 9 : lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_sprm::LN_PIlfo, pIntValue);
2843 : }
2844 14 : break;
2845 : case RTF_UC:
2846 12 : if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_INT16))
2847 12 : m_aStates.top().nUc = nParam;
2848 12 : break;
2849 : case RTF_U:
2850 96 : if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_INT16))
2851 : {
2852 96 : m_aUnicodeBuffer.append(static_cast<sal_Unicode>(nParam));
2853 96 : m_aStates.top().nCharsToSkip = m_aStates.top().nUc;
2854 : }
2855 96 : break;
2856 : case RTF_LEVELFOLLOW:
2857 10 : m_aStates.top().aTableAttributes.set(NS_rtf::LN_IXCHFOLLOW, pIntValue);
2858 10 : break;
2859 : case RTF_LISTOVERRIDECOUNT:
2860 : // Ignore this for now, the exporter always emits it with a zero parameter.
2861 5 : break;
2862 : case RTF_PICSCALEX:
2863 5 : m_aStates.top().aPicture.nScaleX = nParam;
2864 5 : break;
2865 : case RTF_PICSCALEY:
2866 5 : m_aStates.top().aPicture.nScaleY = nParam;
2867 5 : break;
2868 : case RTF_PICW:
2869 6 : m_aStates.top().aPicture.nWidth = nParam;
2870 6 : break;
2871 : case RTF_PICH:
2872 6 : m_aStates.top().aPicture.nHeight = nParam;
2873 6 : break;
2874 : case RTF_PICWGOAL:
2875 6 : m_aStates.top().aPicture.nGoalWidth = TWIP_TO_MM100(nParam);
2876 6 : break;
2877 : case RTF_PICHGOAL:
2878 6 : m_aStates.top().aPicture.nGoalHeight = TWIP_TO_MM100(nParam);
2879 6 : break;
2880 3 : case RTF_PICCROPL: m_aStates.top().aPicture.nCropL = TWIP_TO_MM100(nParam); break;
2881 3 : case RTF_PICCROPR: m_aStates.top().aPicture.nCropR = TWIP_TO_MM100(nParam); break;
2882 3 : case RTF_PICCROPT: m_aStates.top().aPicture.nCropT = TWIP_TO_MM100(nParam); break;
2883 3 : case RTF_PICCROPB: m_aStates.top().aPicture.nCropB = TWIP_TO_MM100(nParam); break;
2884 : case RTF_SHPWRK:
2885 : {
2886 11 : int nValue = 0;
2887 11 : switch (nParam)
2888 : {
2889 11 : case 0: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides; break;
2890 0 : case 1: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left; break;
2891 0 : case 2: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right; break;
2892 0 : case 3: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest; break;
2893 0 : default: break;
2894 : }
2895 11 : RTFValue::Pointer_t pValue(new RTFValue(nValue));
2896 11 : m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_WrapSquare_wrapText, pValue);
2897 : }
2898 11 : break;
2899 : case RTF_SHPWR:
2900 : {
2901 12 : switch (nParam)
2902 : {
2903 : case 1:
2904 0 : m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_NONE; break;
2905 : case 2:
2906 0 : m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_PARALLEL; break;
2907 : case 3:
2908 12 : m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_THROUGHT; break;
2909 : case 4:
2910 0 : m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_PARALLEL; break;
2911 : case 5:
2912 0 : m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_THROUGHT; break;
2913 : }
2914 : }
2915 12 : break;
2916 : case RTF_CELLX:
2917 : {
2918 164 : int nCellX = nParam - m_aStates.top().nCellX;
2919 :
2920 : // If there is a negative left margin, then the first cellx is relateve to that.
2921 164 : RTFValue::Pointer_t pTblInd = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblInd);
2922 164 : if (m_aStates.top().nCellX == 0 && pTblInd.get())
2923 : {
2924 29 : RTFValue::Pointer_t pWidth = pTblInd->getAttributes().find(NS_ooxml::LN_CT_TblWidth_w);
2925 29 : if (pWidth.get() && pWidth->getInt() < 0)
2926 29 : nCellX = -1 * (pWidth->getInt() - nParam);
2927 : }
2928 :
2929 164 : m_aStates.top().nCellX = nParam;
2930 164 : RTFValue::Pointer_t pXValue(new RTFValue(nCellX));
2931 164 : m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, false);
2932 164 : m_aStates.top().nCells++;
2933 :
2934 : // Push cell properties.
2935 164 : m_aStates.top().aTableCellsSprms.push_back(m_aStates.top().aTableCellSprms);
2936 164 : m_aStates.top().aTableCellsAttributes.push_back(m_aStates.top().aTableCellAttributes);
2937 164 : m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
2938 164 : m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
2939 : // We assume text after a row definition always belongs to the table, to handle text before the real INTBL token
2940 164 : dispatchFlag(RTF_INTBL);
2941 : }
2942 164 : break;
2943 : case RTF_TRRH:
2944 : {
2945 3 : rtl::OUString hRule = rtl::OUString::createFromAscii("auto");
2946 3 : if ( nParam < 0 )
2947 : {
2948 0 : RTFValue::Pointer_t pAbsValue(new RTFValue(-nParam));
2949 0 : pIntValue.swap( pAbsValue );
2950 :
2951 0 : hRule = rtl::OUString::createFromAscii("exact");
2952 : }
2953 3 : else if ( nParam > 0 )
2954 3 : hRule = rtl::OUString::createFromAscii("atLeast");
2955 :
2956 3 : lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
2957 6 : NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_val, pIntValue);
2958 :
2959 3 : RTFValue::Pointer_t pHRule(new RTFValue(hRule));
2960 3 : lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
2961 6 : NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_hRule, pHRule);
2962 : }
2963 3 : break;
2964 : case RTF_TRLEFT:
2965 : {
2966 : // the value is in twips
2967 29 : lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
2968 : NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_type,
2969 58 : RTFValue::Pointer_t(new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)));
2970 29 : lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
2971 : NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_w,
2972 58 : RTFValue::Pointer_t(new RTFValue(nParam)));
2973 : }
2974 29 : break;
2975 : case RTF_COLS:
2976 0 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
2977 0 : NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_num, pIntValue);
2978 0 : break;
2979 : case RTF_COLSX:
2980 4 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
2981 8 : NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_space, pIntValue);
2982 4 : break;
2983 : case RTF_COLNO:
2984 0 : lcl_putNestedSprm(m_aStates.top().aSectionSprms,
2985 0 : NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_col, pIntValue);
2986 0 : break;
2987 : case RTF_COLW:
2988 : case RTF_COLSR:
2989 : {
2990 0 : RTFSprms& rAttributes = lcl_getLastAttributes(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols);
2991 0 : rAttributes.set((nKeyword == RTF_COLW ? NS_ooxml::LN_CT_Column_w : NS_ooxml::LN_CT_Column_space), pIntValue);
2992 : }
2993 0 : break;
2994 : case RTF_PAPERH: // fall through: set the default + current value
2995 : lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
2996 47 : NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue, true);
2997 : case RTF_PGHSXN:
2998 81 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
2999 162 : NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue, true);
3000 81 : break;
3001 : case RTF_PAPERW: // fall through: set the default + current value
3002 : lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
3003 47 : NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue, true);
3004 : case RTF_PGWSXN:
3005 81 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3006 162 : NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue, true);
3007 81 : break;
3008 : case RTF_MARGL: // fall through: set the default + current value
3009 : lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
3010 47 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue, true);
3011 : case RTF_MARGLSXN:
3012 83 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3013 166 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue, true);
3014 83 : break;
3015 : case RTF_MARGR: // fall through: set the default + current value
3016 : lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
3017 47 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue, true);
3018 : case RTF_MARGRSXN:
3019 83 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3020 166 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue, true);
3021 83 : break;
3022 : case RTF_MARGT: // fall through: set the default + current value
3023 : lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
3024 46 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue, true);
3025 : case RTF_MARGTSXN:
3026 81 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3027 162 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue, true);
3028 81 : break;
3029 : case RTF_MARGB: // fall through: set the default + current value
3030 : lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
3031 45 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue, true);
3032 : case RTF_MARGBSXN:
3033 80 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3034 160 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue, true);
3035 80 : break;
3036 : case RTF_HEADERY:
3037 4 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3038 8 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_header, pIntValue, true);
3039 4 : break;
3040 : case RTF_FOOTERY:
3041 3 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3042 6 : NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_footer, pIntValue, true);
3043 3 : break;
3044 : case RTF_DEFTAB:
3045 35 : m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_defaultTabStop, pIntValue);
3046 35 : break;
3047 : case RTF_LINEMOD:
3048 0 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3049 0 : NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_countBy, pIntValue);
3050 0 : break;
3051 : case RTF_LINEX:
3052 7 : if (nParam)
3053 0 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3054 0 : NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance, pIntValue);
3055 7 : break;
3056 : case RTF_LINESTARTS:
3057 0 : lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
3058 0 : NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_start, pIntValue);
3059 0 : break;
3060 : case RTF_REVAUTH:
3061 : case RTF_REVAUTHDEL:
3062 : {
3063 0 : RTFValue::Pointer_t pValue(new RTFValue(m_aAuthors[nParam]));
3064 0 : lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
3065 0 : NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_author, pValue);
3066 : }
3067 0 : break;
3068 : case RTF_REVDTTM:
3069 : case RTF_REVDTTMDEL:
3070 : {
3071 0 : OUString aStr(OStringToOUString(lcl_DTTM22OString(nParam), m_aStates.top().nCurrentEncoding));
3072 0 : RTFValue::Pointer_t pValue(new RTFValue(aStr));
3073 0 : lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
3074 0 : NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_date, pValue);
3075 : }
3076 0 : break;
3077 : case RTF_SHPLEFT:
3078 15 : m_aStates.top().aShape.nLeft = TWIP_TO_MM100(nParam);
3079 15 : break;
3080 : case RTF_SHPTOP:
3081 15 : m_aStates.top().aShape.nTop = TWIP_TO_MM100(nParam);
3082 15 : break;
3083 : case RTF_SHPRIGHT:
3084 15 : m_aStates.top().aShape.nRight = TWIP_TO_MM100(nParam);
3085 15 : break;
3086 : case RTF_SHPBOTTOM:
3087 15 : m_aStates.top().aShape.nBottom = TWIP_TO_MM100(nParam);
3088 15 : break;
3089 : case RTF_FFTYPE:
3090 0 : switch (nParam)
3091 : {
3092 0 : case 0: m_nFormFieldType = FORMFIELD_TEXT; break;
3093 0 : case 1: m_nFormFieldType = FORMFIELD_CHECKBOX; break;
3094 0 : case 2: m_nFormFieldType = FORMFIELD_LIST; break;
3095 0 : default: m_nFormFieldType = FORMFIELD_NONE; break;
3096 : }
3097 0 : break;
3098 : case RTF_FFDEFRES:
3099 0 : if (m_nFormFieldType == FORMFIELD_CHECKBOX)
3100 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_default, pIntValue);
3101 0 : else if (m_nFormFieldType == FORMFIELD_LIST)
3102 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_default, pIntValue);
3103 0 : break;
3104 : case RTF_FFRES:
3105 0 : if (m_nFormFieldType == FORMFIELD_CHECKBOX)
3106 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_checked, pIntValue);
3107 0 : else if (m_nFormFieldType == FORMFIELD_LIST)
3108 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_result, pIntValue);
3109 0 : break;
3110 : case RTF_EDMINS:
3111 3 : if (m_xDocumentProperties.is())
3112 1 : m_xDocumentProperties->setEditingDuration(nParam);
3113 3 : break;
3114 : case RTF_NOFPAGES:
3115 : case RTF_NOFWORDS:
3116 : case RTF_NOFCHARS:
3117 : case RTF_NOFCHARSWS:
3118 12 : if (m_xDocumentProperties.is())
3119 : {
3120 4 : uno::Sequence<beans::NamedValue> aSet = m_xDocumentProperties->getDocumentStatistics();
3121 4 : OUString aName;
3122 4 : switch (nKeyword)
3123 : {
3124 1 : case RTF_NOFPAGES: aName = "PageCount"; nParam = 99; break;
3125 1 : case RTF_NOFWORDS: aName = "WordCount"; break;
3126 1 : case RTF_NOFCHARS: aName = "CharacterCount"; break;
3127 1 : case RTF_NOFCHARSWS: aName = "NonWhitespaceCharacterCount"; break;
3128 0 : default: break;
3129 : }
3130 4 : if (!aName.isEmpty())
3131 : {
3132 4 : bool bFound = false;
3133 4 : int nLen = aSet.getLength();
3134 10 : for (int i = 0; i < nLen; ++i)
3135 6 : if (aSet[i].Name.equals(aName))
3136 0 : aSet[i].Value = uno::makeAny(sal_Int32(nParam));
3137 4 : if (!bFound)
3138 : {
3139 4 : aSet.realloc(nLen + 1);
3140 4 : aSet[nLen].Name = aName;
3141 4 : aSet[nLen].Value = uno::makeAny(sal_Int32(nParam));
3142 : }
3143 4 : m_xDocumentProperties->setDocumentStatistics(aSet);
3144 4 : }
3145 : }
3146 12 : break;
3147 : case RTF_VERSION:
3148 3 : if (m_xDocumentProperties.is())
3149 1 : m_xDocumentProperties->setEditingCycles(nParam);
3150 3 : break;
3151 : case RTF_VERN:
3152 : // Ignore this for now, later the RTF writer version could be used to add hacks for older buggy writers.
3153 34 : break;
3154 : case RTF_FTNSTART:
3155 35 : lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
3156 35 : break;
3157 : case RTF_AFTNSTART:
3158 33 : lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
3159 33 : break;
3160 : case RTF_DFRMTXTX:
3161 3 : m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDxaFromText, nParam);
3162 3 : break;
3163 : case RTF_DFRMTXTY:
3164 3 : m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDyaFromText, nParam);
3165 3 : break;
3166 : case RTF_DXFRTEXT:
3167 0 : m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDxaFromText, nParam);
3168 0 : m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDyaFromText, nParam);
3169 0 : break;
3170 : case RTF_FLYVERT:
3171 : {
3172 3 : RTFVertOrient aVertOrient(nParam);
3173 3 : m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, aVertOrient.GetAlign());
3174 3 : m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, aVertOrient.GetAnchor());
3175 : }
3176 3 : break;
3177 : case RTF_FLYHORZ:
3178 : {
3179 3 : RTFHoriOrient aHoriOrient(nParam);
3180 3 : m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, aHoriOrient.GetAlign());
3181 3 : m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, aHoriOrient.GetAnchor());
3182 : }
3183 3 : break;
3184 : case RTF_FLYANCHOR:
3185 3 : m_aStates.top().aFrame.nAnchorType = nParam;
3186 3 : break;
3187 : case RTF_WMETAFILE:
3188 1 : m_aStates.top().aPicture.eWMetafile = nParam;
3189 1 : break;
3190 : case RTF_SB:
3191 172 : lcl_putNestedAttribute(m_aStates.top().aParagraphSprms,
3192 344 : NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before, pIntValue, true);
3193 172 : break;
3194 : case RTF_SA:
3195 176 : lcl_putNestedAttribute(m_aStates.top().aParagraphSprms,
3196 352 : NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after, pIntValue, true);
3197 176 : break;
3198 : case RTF_DPX:
3199 10 : m_aStates.top().aDrawingObject.nLeft = TWIP_TO_MM100(nParam);
3200 10 : break;
3201 : case RTF_DPY:
3202 10 : m_aStates.top().aDrawingObject.nTop = TWIP_TO_MM100(nParam);
3203 10 : break;
3204 : case RTF_DPXSIZE:
3205 10 : m_aStates.top().aDrawingObject.nRight = TWIP_TO_MM100(nParam);
3206 10 : break;
3207 : case RTF_DPYSIZE:
3208 10 : m_aStates.top().aDrawingObject.nBottom = TWIP_TO_MM100(nParam);
3209 10 : break;
3210 : case RTF_PNSTART:
3211 4 : m_aStates.top().aTableSprms.set(NS_rtf::LN_ISTARTAT, pIntValue);
3212 4 : break;
3213 : case RTF_PNF:
3214 : {
3215 1 : int nFontIndex = getFontIndex(nParam);
3216 1 : RTFValue::Pointer_t pValue(new RTFValue(nFontIndex));
3217 1 : lcl_putNestedSprm(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_Lvl_rPr, NS_sprm::LN_CRgFtc0, pValue);
3218 : }
3219 1 : break;
3220 : case RTF_VIEWSCALE:
3221 39 : m_aSettingsTableAttributes.set(NS_ooxml::LN_CT_Zoom_percent, pIntValue);
3222 39 : break;
3223 : case RTF_BIN:
3224 1 : m_aStates.top().nInternalState = INTERNAL_BIN;
3225 1 : m_aStates.top().nBinaryToRead = nParam;
3226 1 : break;
3227 : case RTF_DPLINECOR:
3228 4 : m_aStates.top().aDrawingObject.nLineColorR = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
3229 4 : break;
3230 : case RTF_DPLINECOG:
3231 4 : m_aStates.top().aDrawingObject.nLineColorG = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
3232 4 : break;
3233 : case RTF_DPLINECOB:
3234 4 : m_aStates.top().aDrawingObject.nLineColorB = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
3235 4 : break;
3236 : case RTF_DPFILLBGCR:
3237 3 : m_aStates.top().aDrawingObject.nFillColorR = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
3238 3 : break;
3239 : case RTF_DPFILLBGCG:
3240 3 : m_aStates.top().aDrawingObject.nFillColorG = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
3241 3 : break;
3242 : case RTF_DPFILLBGCB:
3243 3 : m_aStates.top().aDrawingObject.nFillColorB = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
3244 3 : break;
3245 : case RTF_LI:
3246 147 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft, pIntValue);
3247 : // It turns out \li should reset the \fi inherited from the stylesheet.
3248 : // So set the direct formatting to zero, if we don't have such direct formatting yet.
3249 147 : if (!m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PDxaLeft1).get())
3250 88 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft1, RTFValue::Pointer_t(new RTFValue(0)));
3251 147 : break;
3252 : case RTF_CLSHDNG:
3253 : {
3254 0 : int nValue = -1;
3255 0 : switch (nParam)
3256 : {
3257 0 : case 500: nValue = 2; break;
3258 0 : case 1000: nValue = 3; break;
3259 0 : case 1200: nValue = 27; break;
3260 0 : case 1500: nValue = 28; break;
3261 0 : case 2000: nValue = 4; break;
3262 0 : case 2500: nValue = 5; break;
3263 0 : case 3000: nValue = 6; break;
3264 0 : case 3500: nValue = 43; break;
3265 0 : case 3700: nValue = 44; break;
3266 0 : case 4000: nValue = 7; break;
3267 0 : case 4500: nValue = 46; break;
3268 0 : case 5000: nValue = 8; break;
3269 0 : case 5500: nValue = 49; break;
3270 0 : case 6000: nValue = 9; break;
3271 0 : case 6200: nValue = 51; break;
3272 0 : case 6500: nValue = 52; break;
3273 0 : case 7000: nValue = 10; break;
3274 0 : case 7500: nValue = 11; break;
3275 0 : case 8000: nValue = 12; break;
3276 0 : case 8500: nValue = 57; break;
3277 0 : case 8700: nValue = 58; break;
3278 0 : case 9000: nValue = 13; break;
3279 0 : case 9500: nValue = 60; break;
3280 0 : default: break;
3281 : }
3282 0 : if (nValue != -1)
3283 0 : lcl_putNestedAttribute(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_val, RTFValue::Pointer_t(new RTFValue(nValue)));
3284 : }
3285 0 : break;
3286 : case RTF_DODHGT:
3287 10 : m_aStates.top().aDrawingObject.nDhgt = nParam;
3288 10 : break;
3289 : case RTF_DPPOLYCOUNT:
3290 4 : if (nParam >= 0)
3291 : {
3292 4 : m_aStates.top().aDrawingObject.nPolyLineCount = nParam;
3293 4 : m_aStates.top().aDrawingObject.aPolyLinePoints.realloc(nParam);
3294 : }
3295 4 : break;
3296 : case RTF_DPPTX:
3297 : {
3298 8 : RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
3299 8 : rDrawingObject.aPolyLinePoints[rDrawingObject.aPolyLinePoints.getLength() - rDrawingObject.nPolyLineCount].X = TWIP_TO_MM100(nParam);
3300 : }
3301 8 : break;
3302 : case RTF_DPPTY:
3303 : {
3304 8 : RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
3305 8 : rDrawingObject.aPolyLinePoints[rDrawingObject.aPolyLinePoints.getLength() - rDrawingObject.nPolyLineCount].Y = TWIP_TO_MM100(nParam);
3306 8 : rDrawingObject.nPolyLineCount--;
3307 8 : if (rDrawingObject.nPolyLineCount == 0)
3308 : {
3309 4 : uno::Sequence< uno::Sequence<awt::Point> >aPointSequenceSequence(1);
3310 4 : aPointSequenceSequence[0] = rDrawingObject.aPolyLinePoints;
3311 4 : rDrawingObject.xPropertySet->setPropertyValue("PolyPolygon", uno::Any(aPointSequenceSequence));
3312 : }
3313 : }
3314 8 : break;
3315 : default:
3316 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle value '" << lcl_RtfToString(nKeyword) << "'");
3317 3335 : aSkip.setParsed(false);
3318 3335 : break;
3319 : }
3320 8398 : return 0;
3321 : }
3322 :
3323 484 : int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam)
3324 : {
3325 484 : checkUnicode();
3326 484 : setNeedSect();
3327 484 : RTFSkipDestination aSkip(*this);
3328 484 : int nSprm = -1;
3329 484 : RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0));
3330 :
3331 : // Map all underline toggles to a single sprm.
3332 484 : switch (nKeyword)
3333 : {
3334 6 : case RTF_UL: nSprm = 1; break;
3335 0 : case RTF_ULDASH: nSprm = 7; break;
3336 0 : case RTF_ULDASHD: nSprm = 9; break;
3337 0 : case RTF_ULDASHDD: nSprm = 10; break;
3338 0 : case RTF_ULDB: nSprm = 3; break;
3339 0 : case RTF_ULHWAVE: nSprm = 27; break;
3340 0 : case RTF_ULLDASH: nSprm = 39; break;
3341 0 : case RTF_ULTH: nSprm = 6; break;
3342 0 : case RTF_ULTHD: nSprm = 20; break;
3343 0 : case RTF_ULTHDASH: nSprm = 23; break;
3344 0 : case RTF_ULTHDASHD: nSprm = 25; break;
3345 0 : case RTF_ULTHDASHDD: nSprm = 26; break;
3346 0 : case RTF_ULTHLDASH: nSprm = 55; break;
3347 0 : case RTF_ULULDBWAVE: nSprm = 43; break;
3348 0 : case RTF_ULWAVE: nSprm = 11; break;
3349 478 : default: break;
3350 : }
3351 484 : if (nSprm >= 0)
3352 : {
3353 6 : RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0));
3354 6 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
3355 6 : return 0;
3356 : }
3357 :
3358 : // Accent characters (over dot / over coma).
3359 478 : switch (nKeyword)
3360 : {
3361 0 : case RTF_ACCNONE: nSprm = 0; break;
3362 0 : case RTF_ACCDOT: nSprm = 1; break;
3363 0 : case RTF_ACCCOMMA: nSprm = 2; break;
3364 0 : case RTF_ACCCIRCLE: nSprm = 3; break;
3365 0 : case RTF_ACCUNDERDOT: nSprm = 4; break;
3366 478 : default: break;
3367 : }
3368 478 : if (nSprm >= 0)
3369 : {
3370 0 : RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0));
3371 0 : m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKcd, pValue);
3372 0 : return 0;
3373 : }
3374 :
3375 : // Trivial character sprms.
3376 478 : switch (nKeyword)
3377 : {
3378 29 : case RTF_B: nSprm = NS_sprm::LN_CFBold; break;
3379 13 : case RTF_AB: nSprm = NS_sprm::LN_CFBoldBi; break;
3380 263 : case RTF_I: nSprm = NS_sprm::LN_CFItalic; break;
3381 30 : case RTF_AI: nSprm = NS_sprm::LN_CFItalicBi; break;
3382 0 : case RTF_UL: nSprm = NS_sprm::LN_CKul; break;
3383 0 : case RTF_OUTL: nSprm = NS_sprm::LN_CFOutline; break;
3384 0 : case RTF_SHAD: nSprm = NS_sprm::LN_CFShadow; break;
3385 0 : case RTF_V: nSprm = NS_sprm::LN_CFVanish; break;
3386 4 : case RTF_STRIKE: nSprm = NS_sprm::LN_CFStrike; break;
3387 0 : case RTF_STRIKED: nSprm = NS_sprm::LN_CFDStrike; break;
3388 5 : case RTF_SCAPS: nSprm = NS_sprm::LN_CFSmallCaps; break;
3389 0 : case RTF_IMPR: nSprm = NS_sprm::LN_CFImprint; break;
3390 1 : case RTF_CAPS: nSprm = NS_sprm::LN_CFCaps; break;
3391 133 : default: break;
3392 : }
3393 478 : if (nSprm >= 0)
3394 : {
3395 345 : m_aStates.top().aCharacterSprms.set(nSprm, pBoolValue);
3396 345 : return 0;
3397 : }
3398 :
3399 133 : switch (nKeyword)
3400 : {
3401 : case RTF_ASPALPHA:
3402 72 : m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFAutoSpaceDE, pBoolValue);
3403 72 : break;
3404 : case RTF_DELETED:
3405 : case RTF_REVISED:
3406 : {
3407 0 : RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_DELETED ? ooxml::OOXML_del : ooxml::OOXML_ins));
3408 0 : lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
3409 0 : NS_ooxml::LN_trackchange, NS_ooxml::LN_token, pValue);
3410 : }
3411 0 : break;
3412 : default:
3413 : SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle toggle '" << lcl_RtfToString(nKeyword) << "'");
3414 61 : aSkip.setParsed(false);
3415 61 : break;
3416 : }
3417 133 : return 0;
3418 : }
3419 :
3420 5386 : int RTFDocumentImpl::pushState()
3421 : {
3422 : //SAL_INFO("writerfilter", OSL_THIS_FUNC << " before push: " << m_pTokenizer->getGroup());
3423 :
3424 5386 : checkUnicode();
3425 5386 : m_nGroupStartPos = Strm().Tell();
3426 :
3427 5386 : if (m_aStates.empty())
3428 138 : m_aStates.push(m_aDefaultState);
3429 : else
3430 : {
3431 5248 : if (m_aStates.top().nDestinationState == DESTINATION_MR)
3432 231 : lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer);
3433 5248 : m_aStates.push(m_aStates.top());
3434 : }
3435 5386 : m_aStates.top().aDestinationText.setLength(0);
3436 :
3437 5386 : m_pTokenizer->pushGroup();
3438 :
3439 5386 : switch (m_aStates.top().nDestinationState)
3440 : {
3441 465 : case DESTINATION_FONTTABLE: m_aStates.top().nDestinationState = DESTINATION_FONTENTRY; break;
3442 286 : case DESTINATION_STYLESHEET: m_aStates.top().nDestinationState = DESTINATION_STYLEENTRY; break;
3443 : case DESTINATION_FIELDRESULT:
3444 : case DESTINATION_SHAPETEXT:
3445 : case DESTINATION_FORMFIELD:
3446 3 : m_aStates.top().nDestinationState = DESTINATION_NORMAL;
3447 3 : break;
3448 : case DESTINATION_MNUM:
3449 : case DESTINATION_MDEN:
3450 : case DESTINATION_ME:
3451 : case DESTINATION_MFNAME:
3452 : case DESTINATION_MLIM:
3453 : case DESTINATION_MSUB:
3454 : case DESTINATION_MSUP:
3455 : case DESTINATION_MDEG:
3456 704 : m_aStates.top().nDestinationState = DESTINATION_MR;
3457 704 : break;
3458 : case DESTINATION_FIELDINSTRUCTION:
3459 2 : m_aStates.top().nDestinationState = DESTINATION_NORMAL;
3460 2 : break;
3461 1 : case DESTINATION_REVISIONTABLE: m_aStates.top().nDestinationState = DESTINATION_REVISIONENTRY; break;
3462 309 : case DESTINATION_MOMATH: m_aStates.top().nDestinationState = DESTINATION_MR; break;
3463 3616 : default: break;
3464 : }
3465 :
3466 5386 : return 0;
3467 : }
3468 :
3469 282 : RTFSprms RTFDocumentImpl::mergeSprms()
3470 : {
3471 282 : RTFSprms aSprms;
3472 846 : for (RTFSprms::Iterator_t i = m_aStates.top().aTableSprms.begin();
3473 564 : i != m_aStates.top().aTableSprms.end(); ++i)
3474 0 : aSprms.set(i->first, i->second);
3475 3048 : for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterSprms.begin();
3476 2032 : i != m_aStates.top().aCharacterSprms.end(); ++i)
3477 734 : aSprms.set(i->first, i->second);
3478 2094 : for (RTFSprms::Iterator_t i = m_aStates.top().aParagraphSprms.begin();
3479 1396 : i != m_aStates.top().aParagraphSprms.end(); ++i)
3480 416 : aSprms.set(i->first, i->second);
3481 282 : return aSprms;
3482 : }
3483 :
3484 750 : void RTFDocumentImpl::resetSprms()
3485 : {
3486 750 : m_aStates.top().aTableSprms.clear();
3487 750 : m_aStates.top().aCharacterSprms.clear();
3488 750 : m_aStates.top().aParagraphSprms.clear();
3489 750 : }
3490 :
3491 282 : RTFSprms RTFDocumentImpl::mergeAttributes()
3492 : {
3493 282 : RTFSprms aAttributes;
3494 4644 : for (RTFSprms::Iterator_t i = m_aStates.top().aTableAttributes.begin();
3495 3096 : i != m_aStates.top().aTableAttributes.end(); ++i)
3496 1266 : aAttributes.set(i->first, i->second);
3497 936 : for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin();
3498 624 : i != m_aStates.top().aCharacterAttributes.end(); ++i)
3499 30 : aAttributes.set(i->first, i->second);
3500 852 : for (RTFSprms::Iterator_t i = m_aStates.top().aParagraphAttributes.begin();
3501 568 : i != m_aStates.top().aParagraphAttributes.end(); ++i)
3502 2 : aAttributes.set(i->first, i->second);
3503 282 : return aAttributes;
3504 : }
3505 :
3506 750 : void RTFDocumentImpl::resetAttributes()
3507 : {
3508 750 : m_aStates.top().aTableAttributes.clear();
3509 750 : m_aStates.top().aCharacterAttributes.clear();
3510 750 : m_aStates.top().aParagraphAttributes.clear();
3511 750 : }
3512 :
3513 5383 : int RTFDocumentImpl::popState()
3514 : {
3515 : //SAL_INFO("writerfilter", OSL_THIS_FUNC << " before pop: m_pTokenizer->getGroup() " << m_pTokenizer->getGroup() <<
3516 : // ", dest state: " << m_aStates.top().nDestinationState);
3517 :
3518 5383 : checkUnicode();
3519 5383 : RTFParserState aState(m_aStates.top());
3520 5383 : m_bWasInFrame = aState.aFrame.inFrame();
3521 5383 : sal_Int32 nMathToken = 0;
3522 :
3523 5383 : switch (m_aStates.top().nDestinationState)
3524 : {
3525 : case DESTINATION_FONTTABLE:
3526 : {
3527 55 : writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(m_aFontTableEntries));
3528 55 : Mapper().table(NS_rtf::LN_FONTTABLE, pTable);
3529 : }
3530 55 : break;
3531 : case DESTINATION_STYLESHEET:
3532 : {
3533 42 : writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(m_aStyleTableEntries));
3534 42 : Mapper().table(NS_rtf::LN_STYLESHEET, pTable);
3535 : }
3536 42 : break;
3537 : case DESTINATION_LISTOVERRIDETABLE:
3538 : {
3539 5 : RTFSprms aListTableAttributes;
3540 5 : writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(aListTableAttributes, m_aListTableSprms));
3541 5 : RTFReferenceTable::Entries_t aListTableEntries;
3542 5 : aListTableEntries.insert(make_pair(0, pProp));
3543 5 : writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aListTableEntries));
3544 5 : Mapper().table(NS_rtf::LN_LISTTABLE, pTable);
3545 : }
3546 5 : break;
3547 : case DESTINATION_LISTENTRY:
3548 13 : for (RTFSprms::Iterator_t i = aState.aListLevelEntries.begin(); i != aState.aListLevelEntries.end(); ++i)
3549 8 : aState.aTableSprms.set(i->first, i->second, false);
3550 5 : break;
3551 : case DESTINATION_FIELDINSTRUCTION:
3552 : {
3553 6 : RTFValue::Pointer_t pValue(new RTFValue(m_aFormfieldAttributes, m_aFormfieldSprms));
3554 6 : RTFSprms aFFAttributes;
3555 6 : RTFSprms aFFSprms;
3556 6 : aFFSprms.set(NS_ooxml::LN_ffdata, pValue);
3557 6 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aFFAttributes, aFFSprms));
3558 6 : Mapper().props(pProperties);
3559 6 : m_aFormfieldAttributes.clear();
3560 6 : m_aFormfieldSprms.clear();
3561 : }
3562 6 : singleChar(0x14);
3563 6 : break;
3564 : case DESTINATION_FIELDRESULT:
3565 5 : singleChar(0x15);
3566 5 : break;
3567 : case DESTINATION_LEVELTEXT:
3568 : {
3569 10 : OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
3570 :
3571 : // The first character is the length of the string (the rest should be ignored).
3572 10 : sal_Int32 nLength(aStr.toChar());
3573 10 : OUString aValue;
3574 10 : if (nLength <= aStr.getLength())
3575 10 : aValue = aStr.copy(1, nLength);
3576 : else
3577 0 : aValue = aStr;
3578 10 : RTFValue::Pointer_t pValue(new RTFValue(aValue, true));
3579 10 : aState.aTableAttributes.set(NS_ooxml::LN_CT_LevelText_val, pValue);
3580 : }
3581 10 : break;
3582 : case DESTINATION_LEVELNUMBERS:
3583 : {
3584 10 : RTFSprms& rAttributes = aState.aTableSprms.find(NS_ooxml::LN_CT_Lvl_lvlText)->getAttributes();
3585 10 : RTFValue::Pointer_t pValue = rAttributes.find(NS_ooxml::LN_CT_LevelText_val);
3586 10 : OUString aOrig = pValue->getString();
3587 :
3588 10 : OUStringBuffer aBuf;
3589 10 : sal_Int32 nReplaces = 1;
3590 36 : for (int i = 0; i < aOrig.getLength(); i++)
3591 : {
3592 104 : if (std::find(m_aStates.top().aLevelNumbers.begin(), m_aStates.top().aLevelNumbers.end(), i+1)
3593 104 : != m_aStates.top().aLevelNumbers.end())
3594 : {
3595 15 : aBuf.append(sal_Unicode('%'));
3596 : // '1.1.1' -> '%1.%2.%3', but '1.' (with '2.' prefix omitted) is %2.
3597 15 : aBuf.append(sal_Int32(nReplaces++ + m_aStates.top().nListLevelNum + 1 - m_aStates.top().aLevelNumbers.size()));
3598 : }
3599 : else
3600 11 : aBuf.append(aOrig.copy(i, 1));
3601 : }
3602 10 : pValue->setString(aBuf.makeStringAndClear());
3603 : }
3604 10 : break;
3605 : case DESTINATION_SHAPEPROPERTYNAME:
3606 : case DESTINATION_SHAPEPROPERTYVALUE:
3607 : case DESTINATION_SHAPEPROPERTY:
3608 : {
3609 489 : if (m_aStates.top().nDestinationState == DESTINATION_SHAPEPROPERTYNAME)
3610 163 : aState.aShape.aProperties.push_back(make_pair(m_aStates.top().aDestinationText.makeStringAndClear(), OUString()));
3611 326 : else if (m_aStates.top().nDestinationState == DESTINATION_SHAPEPROPERTYVALUE && aState.aShape.aProperties.size())
3612 162 : aState.aShape.aProperties.back().second = m_aStates.top().aDestinationText.makeStringAndClear();
3613 : }
3614 489 : break;
3615 : case DESTINATION_PICPROP:
3616 : case DESTINATION_SHAPEINSTRUCTION:
3617 16 : if (!m_bObject)
3618 16 : m_pSdrImport->resolve(m_aStates.top().aShape);
3619 16 : break;
3620 : case DESTINATION_BOOKMARKSTART:
3621 : {
3622 0 : OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
3623 0 : int nPos = m_aBookmarks.size();
3624 0 : m_aBookmarks[aStr] = nPos;
3625 0 : Mapper().props(lcl_getBookmarkProperties(nPos, aStr));
3626 : }
3627 0 : break;
3628 : case DESTINATION_BOOKMARKEND:
3629 0 : Mapper().props(lcl_getBookmarkProperties(m_aBookmarks[m_aStates.top().aDestinationText.makeStringAndClear()]));
3630 0 : break;
3631 : case DESTINATION_PICT:
3632 7 : resolvePict(true);
3633 7 : break;
3634 : case DESTINATION_SHAPETEXT:
3635 3 : m_pCurrentBuffer = 0; // Just disable buffering, don't empty it yet.
3636 3 : break;
3637 : case DESTINATION_FORMFIELDNAME:
3638 : {
3639 0 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
3640 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFData_name, pValue);
3641 : }
3642 0 : break;
3643 : case DESTINATION_FORMFIELDLIST:
3644 : {
3645 0 : RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
3646 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_listEntry, pValue);
3647 : }
3648 0 : break;
3649 : case DESTINATION_DATAFIELD:
3650 : {
3651 0 : OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), m_aStates.top().nCurrentEncoding);
3652 : // decode hex dump
3653 0 : OStringBuffer aBuf;
3654 0 : const char *str = aStr.getStr();
3655 0 : int b = 0, count = 2;
3656 0 : for (int i = 0; i < aStr.getLength(); ++i)
3657 : {
3658 0 : char ch = str[i];
3659 0 : if (ch != 0x0d && ch != 0x0a)
3660 : {
3661 0 : b = b << 4;
3662 0 : sal_Int8 parsed = m_pTokenizer->asHex(ch);
3663 0 : if (parsed == -1)
3664 0 : return ERROR_HEX_INVALID;
3665 0 : b += parsed;
3666 0 : count--;
3667 0 : if (!count)
3668 : {
3669 0 : aBuf.append((char)b);
3670 0 : count = 2;
3671 0 : b = 0;
3672 : }
3673 : }
3674 : }
3675 0 : aStr = aBuf.makeStringAndClear();
3676 : // ignore the first bytes
3677 0 : if (aStr.getLength() > 8)
3678 0 : aStr = aStr.copy(8);
3679 : // extract name
3680 0 : int nLength = aStr.toChar();
3681 0 : aStr = aStr.copy(1);
3682 0 : OString aName = aStr.copy(0, nLength);
3683 0 : aStr = aStr.copy(nLength+1); // zero-terminated string
3684 : // extract default text
3685 0 : nLength = aStr.toChar();
3686 0 : aStr = aStr.copy(1);
3687 0 : OString aDefaultText = aStr.copy(0, nLength);
3688 0 : RTFValue::Pointer_t pNValue(new RTFValue(OStringToOUString(aName, m_aStates.top().nCurrentEncoding)));
3689 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFData_name, pNValue);
3690 0 : RTFValue::Pointer_t pDValue(new RTFValue(OStringToOUString(aDefaultText, m_aStates.top().nCurrentEncoding)));
3691 0 : m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFTextInput_default, pDValue);
3692 :
3693 0 : m_bFormField = false;
3694 : }
3695 0 : break;
3696 : case DESTINATION_CREATIONTIME:
3697 32 : if (m_xDocumentProperties.is())
3698 30 : m_xDocumentProperties->setCreationDate(lcl_getDateTime(m_aStates));
3699 32 : break;
3700 : case DESTINATION_REVISIONTIME:
3701 32 : if (m_xDocumentProperties.is())
3702 30 : m_xDocumentProperties->setModificationDate(lcl_getDateTime(m_aStates));
3703 32 : break;
3704 : case DESTINATION_PRINTTIME:
3705 30 : if (m_xDocumentProperties.is())
3706 29 : m_xDocumentProperties->setPrintDate(lcl_getDateTime(m_aStates));
3707 30 : break;
3708 : case DESTINATION_AUTHOR:
3709 5 : if (m_xDocumentProperties.is())
3710 3 : m_xDocumentProperties->setAuthor(m_aStates.top().aDestinationText.makeStringAndClear());
3711 5 : break;
3712 : case DESTINATION_KEYWORDS:
3713 2 : if (m_xDocumentProperties.is())
3714 2 : m_xDocumentProperties->setKeywords(comphelper::string::convertCommaSeparated(m_aStates.top().aDestinationText.makeStringAndClear()));
3715 2 : break;
3716 : case DESTINATION_COMMENT:
3717 60 : if (m_xDocumentProperties.is())
3718 58 : m_xDocumentProperties->setGenerator(m_aStates.top().aDestinationText.makeStringAndClear());
3719 60 : break;
3720 : case DESTINATION_TITLE:
3721 6 : if (m_xDocumentProperties.is())
3722 4 : m_xDocumentProperties->setTitle(m_aStates.top().aDestinationText.makeStringAndClear());
3723 6 : break;
3724 : case DESTINATION_SUBJECT:
3725 3 : if (m_xDocumentProperties.is())
3726 3 : m_xDocumentProperties->setSubject(m_aStates.top().aDestinationText.makeStringAndClear());
3727 3 : break;
3728 : case DESTINATION_DOCCOMM:
3729 4 : if (m_xDocumentProperties.is())
3730 4 : m_xDocumentProperties->setDescription(m_aStates.top().aDestinationText.makeStringAndClear());
3731 4 : break;
3732 : case DESTINATION_OPERATOR:
3733 : case DESTINATION_COMPANY:
3734 : {
3735 8 : OUString aName = m_aStates.top().nDestinationState == DESTINATION_OPERATOR ? OUString("Operator") : OUString("Company");
3736 8 : if (m_xDocumentProperties.is())
3737 : {
3738 4 : uno::Reference<beans::XPropertyContainer> xUserDefinedProperties = m_xDocumentProperties->getUserDefinedProperties();
3739 4 : xUserDefinedProperties->addProperty(aName, beans::PropertyAttribute::REMOVEABLE,
3740 4 : uno::makeAny(m_aStates.top().aDestinationText.makeStringAndClear()));
3741 8 : }
3742 : }
3743 8 : break;
3744 : case DESTINATION_OBJDATA:
3745 : {
3746 0 : m_pObjectData.reset(new SvMemoryStream());
3747 0 : int b = 0, count = 2;
3748 :
3749 : // Feed the destination text to a stream.
3750 0 : OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
3751 0 : const char *str = aStr.getStr();
3752 0 : for (int i = 0; i < aStr.getLength(); ++i)
3753 : {
3754 0 : char ch = str[i];
3755 0 : if (ch != 0x0d && ch != 0x0a)
3756 : {
3757 0 : b = b << 4;
3758 0 : sal_Int8 parsed = m_pTokenizer->asHex(ch);
3759 0 : if (parsed == -1)
3760 0 : return ERROR_HEX_INVALID;
3761 0 : b += parsed;
3762 0 : count--;
3763 0 : if (!count)
3764 : {
3765 0 : *m_pObjectData << (char)b;
3766 0 : count = 2;
3767 0 : b = 0;
3768 : }
3769 : }
3770 : }
3771 :
3772 0 : if (m_pObjectData->Tell())
3773 : {
3774 0 : m_pObjectData->Seek(0);
3775 :
3776 : // Skip ObjectHeader
3777 : sal_uInt32 nData;
3778 0 : *m_pObjectData >> nData; // OLEVersion
3779 0 : *m_pObjectData >> nData; // FormatID
3780 0 : *m_pObjectData >> nData; // ClassName
3781 0 : m_pObjectData->SeekRel(nData);
3782 0 : *m_pObjectData >> nData; // TopicName
3783 0 : m_pObjectData->SeekRel(nData);
3784 0 : *m_pObjectData >> nData; // ItemName
3785 0 : m_pObjectData->SeekRel(nData);
3786 0 : *m_pObjectData >> nData; // NativeDataSize
3787 : }
3788 :
3789 0 : uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(m_pObjectData.get()));
3790 0 : RTFValue::Pointer_t pStreamValue(new RTFValue(xInputStream));
3791 :
3792 0 : RTFSprms aOLEAttributes;
3793 0 : aOLEAttributes.set(NS_ooxml::LN_inputstream, pStreamValue);
3794 0 : RTFValue::Pointer_t pValue(new RTFValue(aOLEAttributes));
3795 0 : m_aObjectSprms.set(NS_ooxml::LN_OLEObject_OLEObject, pValue);
3796 : }
3797 0 : break;
3798 : case DESTINATION_OBJECT:
3799 : {
3800 0 : RTFSprms aObjAttributes;
3801 0 : RTFSprms aObjSprms;
3802 0 : RTFValue::Pointer_t pValue(new RTFValue(m_aObjectAttributes, m_aObjectSprms));
3803 0 : aObjSprms.set(NS_ooxml::LN_object, pValue);
3804 0 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aObjAttributes, aObjSprms));
3805 0 : uno::Reference<drawing::XShape> xShape;
3806 0 : RTFValue::Pointer_t pShape = m_aObjectAttributes.find(NS_ooxml::LN_shape);
3807 : OSL_ASSERT(pShape.get());
3808 0 : if (pShape.get())
3809 0 : pShape->getAny() >>= xShape;
3810 0 : Mapper().startShape(xShape);
3811 0 : Mapper().props(pProperties);
3812 0 : Mapper().endShape();
3813 0 : m_aObjectAttributes.clear();
3814 0 : m_aObjectSprms.clear();
3815 0 : m_bObject = false;
3816 : }
3817 0 : break;
3818 : case DESTINATION_ANNOTATIONDATE:
3819 : {
3820 2 : OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aStates.top().aDestinationText.makeStringAndClear().toInt32()),
3821 4 : m_aStates.top().nCurrentEncoding));
3822 2 : RTFValue::Pointer_t pValue(new RTFValue(aStr));
3823 2 : RTFSprms aAnnAttributes;
3824 2 : aAnnAttributes.set(NS_ooxml::LN_CT_TrackChange_date, pValue);
3825 2 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAnnAttributes));
3826 2 : Mapper().props(pProperties);
3827 : }
3828 2 : break;
3829 : case DESTINATION_ANNOTATIONAUTHOR:
3830 2 : m_aAuthor = m_aStates.top().aDestinationText.makeStringAndClear();
3831 2 : break;
3832 : case DESTINATION_ATNID:
3833 2 : m_aAuthorInitials = m_aStates.top().aDestinationText.makeStringAndClear();
3834 2 : break;
3835 : case DESTINATION_FALT:
3836 : {
3837 104 : OUString aStr(m_aStates.top().aDestinationText.makeStringAndClear());
3838 104 : RTFValue::Pointer_t pValue(new RTFValue(aStr));
3839 104 : aState.aTableSprms.set(NS_ooxml::LN_CT_Font_altName, pValue);
3840 : }
3841 104 : break;
3842 : case DESTINATION_DRAWINGOBJECT:
3843 10 : if (m_aStates.top().aDrawingObject.xShape.is())
3844 : {
3845 10 : RTFDrawingObject& rDrawing = m_aStates.top().aDrawingObject;
3846 10 : uno::Reference<drawing::XShape> xShape(rDrawing.xShape);
3847 10 : uno::Reference<beans::XPropertySet> xPropertySet(rDrawing.xPropertySet);
3848 :
3849 10 : uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY);
3850 10 : bool bTextFrame = xServiceInfo->supportsService("com.sun.star.text.TextFrame");
3851 :
3852 10 : if (bTextFrame)
3853 : {
3854 2 : xPropertySet->setPropertyValue("HoriOrientPosition", uno::makeAny((sal_Int32)rDrawing.nLeft));
3855 2 : xPropertySet->setPropertyValue("VertOrientPosition", uno::makeAny((sal_Int32)rDrawing.nTop));
3856 : }
3857 : else
3858 : {
3859 8 : xShape->setPosition(awt::Point(rDrawing.nLeft, rDrawing.nTop));
3860 : }
3861 10 : xShape->setSize(awt::Size(rDrawing.nRight, rDrawing.nBottom));
3862 :
3863 10 : if (rDrawing.bHasLineColor)
3864 4 : xPropertySet->setPropertyValue("LineColor", uno::makeAny(sal_uInt32((rDrawing.nLineColorR<<16) + (rDrawing.nLineColorG<<8) + rDrawing.nLineColorB)));
3865 10 : if (rDrawing.bHasFillColor)
3866 3 : xPropertySet->setPropertyValue("FillColor", uno::makeAny(sal_uInt32((rDrawing.nFillColorR<<16) + (rDrawing.nFillColorG<<8) + rDrawing.nFillColorB)));
3867 7 : else if (!bTextFrame)
3868 : // If there is no fill, the Word default is 100% transparency.
3869 5 : xPropertySet->setPropertyValue("FillTransparence", uno::makeAny(sal_Int32(100)));
3870 :
3871 10 : m_pSdrImport->resolveFLine(xPropertySet, rDrawing.nFLine);
3872 :
3873 10 : Mapper().startShape(xShape);
3874 10 : replayShapetext();
3875 10 : Mapper().endShape();
3876 : }
3877 10 : break;
3878 : case DESTINATION_SHAPE:
3879 16 : if (m_aStates.top().aFrame.inFrame())
3880 : {
3881 2 : m_aStates.top().resetFrame();
3882 2 : parBreak();
3883 : // Save this state for later use, so we only reset frame status only for the first shape inside a frame.
3884 2 : aState = m_aStates.top();
3885 2 : m_bNeedPap = true;
3886 : }
3887 16 : break;
3888 : case DESTINATION_MOMATH:
3889 : {
3890 59 : m_aMathBuffer.appendClosingTag(M_TOKEN(oMath));
3891 :
3892 59 : SvGlobalName aGlobalName(SO3_SM_CLASSID);
3893 59 : comphelper::EmbeddedObjectContainer aContainer;
3894 59 : OUString aName;
3895 59 : uno::Reference<embed::XEmbeddedObject> xObject = aContainer.CreateEmbeddedObject(aGlobalName.GetByteSequence(), aName);
3896 59 : uno::Reference<util::XCloseable> xComponent(xObject->getComponent(), uno::UNO_QUERY);
3897 : // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
3898 : // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
3899 : // to RTLD_GLOBAL, so most probably a gcc bug.
3900 59 : oox::FormulaImportBase* pImport = dynamic_cast<oox::FormulaImportBase*>(dynamic_cast<SfxBaseModel*>(xComponent.get()));
3901 : assert( pImport != NULL );
3902 59 : pImport->readFormulaOoxml(m_aMathBuffer);
3903 59 : RTFValue::Pointer_t pValue(new RTFValue(xObject));
3904 59 : RTFSprms aMathAttributes;
3905 59 : aMathAttributes.set(NS_ooxml::LN_starmath, pValue);
3906 59 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aMathAttributes));
3907 59 : Mapper().props(pProperties);
3908 59 : m_aMathBuffer = oox::formulaimport::XmlStreamBuilder();
3909 : }
3910 59 : break;
3911 1033 : case DESTINATION_MR: lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer); break;
3912 34 : case DESTINATION_MF: m_aMathBuffer.appendClosingTag(M_TOKEN(f)); break;
3913 20 : case DESTINATION_MFPR: m_aMathBuffer.appendClosingTag(M_TOKEN(fPr)); break;
3914 108 : case DESTINATION_MCTRLPR: m_aMathBuffer.appendClosingTag(M_TOKEN(ctrlPr)); break;
3915 34 : case DESTINATION_MNUM: m_aMathBuffer.appendClosingTag(M_TOKEN(num)); break;
3916 34 : case DESTINATION_MDEN: m_aMathBuffer.appendClosingTag(M_TOKEN(den)); break;
3917 24 : case DESTINATION_MACC: m_aMathBuffer.appendClosingTag(M_TOKEN(acc)); break;
3918 24 : case DESTINATION_MACCPR: m_aMathBuffer.appendClosingTag(M_TOKEN(accPr)); break;
3919 38 : case DESTINATION_MCHR: if (!nMathToken) nMathToken = M_TOKEN(chr);
3920 42 : case DESTINATION_MPOS: if (!nMathToken) nMathToken = M_TOKEN(pos);
3921 45 : case DESTINATION_MVERTJC: if (!nMathToken) nMathToken = M_TOKEN(vertJc);
3922 47 : case DESTINATION_MSTRIKEH: if (!nMathToken) nMathToken = M_TOKEN(strikeH);
3923 51 : case DESTINATION_MDEGHIDE: if (!nMathToken) nMathToken = M_TOKEN(degHide);
3924 83 : case DESTINATION_MBEGCHR: if (!nMathToken) nMathToken = M_TOKEN(begChr);
3925 86 : case DESTINATION_MSEPCHR: if (!nMathToken) nMathToken = M_TOKEN(sepChr);
3926 118 : case DESTINATION_MENDCHR: if (!nMathToken) nMathToken = M_TOKEN(endChr);
3927 120 : case DESTINATION_MSUBHIDE: if (!nMathToken) nMathToken = M_TOKEN(subHide);
3928 122 : case DESTINATION_MSUPHIDE: if (!nMathToken) nMathToken = M_TOKEN(supHide);
3929 128 : case DESTINATION_MTYPE: if (!nMathToken) nMathToken = M_TOKEN(type);
3930 130 : case DESTINATION_MGROW: if (!nMathToken) nMathToken = M_TOKEN(grow);
3931 : {
3932 130 : oox::formulaimport::XmlStream::AttributeList aAttribs;
3933 130 : aAttribs[M_TOKEN(val)] = m_aStates.top().aDestinationText.makeStringAndClear();
3934 130 : m_aMathBuffer.appendOpeningTag(nMathToken, aAttribs);
3935 130 : m_aMathBuffer.appendClosingTag(nMathToken);
3936 : }
3937 130 : break;
3938 197 : case DESTINATION_ME: m_aMathBuffer.appendClosingTag(M_TOKEN(e)); break;
3939 2 : case DESTINATION_MBAR: m_aMathBuffer.appendClosingTag(M_TOKEN(bar)); break;
3940 2 : case DESTINATION_MBARPR: m_aMathBuffer.appendClosingTag(M_TOKEN(barPr)); break;
3941 45 : case DESTINATION_MD: m_aMathBuffer.appendClosingTag(M_TOKEN(d)); break;
3942 45 : case DESTINATION_MDPR: m_aMathBuffer.appendClosingTag(M_TOKEN(dPr)); break;
3943 12 : case DESTINATION_MFUNC: m_aMathBuffer.appendClosingTag(M_TOKEN(func)); break;
3944 11 : case DESTINATION_MFUNCPR: m_aMathBuffer.appendClosingTag(M_TOKEN(funcPr)); break;
3945 12 : case DESTINATION_MFNAME: m_aMathBuffer.appendClosingTag(M_TOKEN(fName)); break;
3946 6 : case DESTINATION_MLIMLOW: m_aMathBuffer.appendClosingTag(M_TOKEN(limLow)); break;
3947 3 : case DESTINATION_MLIMLOWPR: m_aMathBuffer.appendClosingTag(M_TOKEN(limLowPr)); break;
3948 10 : case DESTINATION_MLIM: m_aMathBuffer.appendClosingTag(M_TOKEN(lim)); break;
3949 2 : case DESTINATION_MM: m_aMathBuffer.appendClosingTag(M_TOKEN(m)); break;
3950 1 : case DESTINATION_MMPR: m_aMathBuffer.appendClosingTag(M_TOKEN(mPr)); break;
3951 4 : case DESTINATION_MMR: m_aMathBuffer.appendClosingTag(M_TOKEN(mr)); break;
3952 13 : case DESTINATION_MNARY: m_aMathBuffer.appendClosingTag(M_TOKEN(nary)); break;
3953 13 : case DESTINATION_MNARYPR: m_aMathBuffer.appendClosingTag(M_TOKEN(naryPr)); break;
3954 29 : case DESTINATION_MSUB: m_aMathBuffer.appendClosingTag(M_TOKEN(sub)); break;
3955 55 : case DESTINATION_MSUP: m_aMathBuffer.appendClosingTag(M_TOKEN(sup)); break;
3956 4 : case DESTINATION_MLIMUPP: m_aMathBuffer.appendClosingTag(M_TOKEN(limUpp)); break;
3957 2 : case DESTINATION_MLIMUPPPR: m_aMathBuffer.appendClosingTag(M_TOKEN(limUppPr)); break;
3958 4 : case DESTINATION_MGROUPCHR: m_aMathBuffer.appendClosingTag(M_TOKEN(groupChr)); break;
3959 4 : case DESTINATION_MGROUPCHRPR: m_aMathBuffer.appendClosingTag(M_TOKEN(groupChrPr)); break;
3960 2 : case DESTINATION_MBORDERBOX: m_aMathBuffer.appendClosingTag(M_TOKEN(borderBox)); break;
3961 2 : case DESTINATION_MBORDERBOXPR: m_aMathBuffer.appendClosingTag(M_TOKEN(borderBoxPr)); break;
3962 6 : case DESTINATION_MRAD: m_aMathBuffer.appendClosingTag(M_TOKEN(rad)); break;
3963 5 : case DESTINATION_MRADPR: m_aMathBuffer.appendClosingTag(M_TOKEN(radPr)); break;
3964 6 : case DESTINATION_MDEG: m_aMathBuffer.appendClosingTag(M_TOKEN(deg)); break;
3965 8 : case DESTINATION_MSSUB: m_aMathBuffer.appendClosingTag(M_TOKEN(sSub)); break;
3966 4 : case DESTINATION_MSSUBPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sSubPr)); break;
3967 34 : case DESTINATION_MSSUP: m_aMathBuffer.appendClosingTag(M_TOKEN(sSup)); break;
3968 17 : case DESTINATION_MSSUPPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sSupPr)); break;
3969 4 : case DESTINATION_MSSUBSUP: m_aMathBuffer.appendClosingTag(M_TOKEN(sSubSup)); break;
3970 2 : case DESTINATION_MSSUBSUPPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sSubSupPr)); break;
3971 4 : case DESTINATION_MSPRE: m_aMathBuffer.appendClosingTag(M_TOKEN(sPre)); break;
3972 2 : case DESTINATION_MSPREPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sPrePr)); break;
3973 1 : case DESTINATION_MBOX: m_aMathBuffer.appendClosingTag(M_TOKEN(box)); break;
3974 6 : case DESTINATION_MEQARR: m_aMathBuffer.appendClosingTag(M_TOKEN(eqArr)); break;
3975 2333 : default: break;
3976 : }
3977 :
3978 : // See if we need to end a track change
3979 5383 : RTFValue::Pointer_t pTrackchange = m_aStates.top().aCharacterSprms.find(NS_ooxml::LN_trackchange);
3980 5383 : if (pTrackchange.get())
3981 : {
3982 0 : RTFSprms aTCAttributes;
3983 0 : RTFValue::Pointer_t pValue(new RTFValue(0));
3984 0 : aTCAttributes.set(NS_ooxml::LN_endtrackchange, pValue);
3985 0 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aTCAttributes));
3986 0 : Mapper().props(pProperties);
3987 : }
3988 :
3989 : // This is the end of the doc, see if we need to close the last section.
3990 5383 : if (m_pTokenizer->getGroup() == 1 && !m_bFirstRun)
3991 : {
3992 132 : if (m_bNeedCr)
3993 8 : dispatchSymbol(RTF_PAR);
3994 132 : sectBreak(true);
3995 : }
3996 :
3997 5383 : m_aStates.pop();
3998 :
3999 5383 : m_pTokenizer->popGroup();
4000 :
4001 : // list table
4002 5383 : if (aState.nDestinationState == DESTINATION_LISTENTRY)
4003 : {
4004 5 : RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
4005 5 : m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_abstractNum, pValue, false);
4006 : }
4007 5378 : else if (aState.nDestinationState == DESTINATION_PARAGRAPHNUMBERING)
4008 : {
4009 4 : RTFValue::Pointer_t pIdValue = aState.aTableAttributes.find(NS_rtf::LN_LSID);
4010 4 : if (pIdValue.get())
4011 : {
4012 : // Abstract numbering
4013 4 : RTFSprms aLeveltextAttributes;
4014 4 : OUString aTextValue;
4015 4 : RTFValue::Pointer_t pTextBefore = aState.aTableAttributes.find(NS_ooxml::LN_CT_LevelText_val);
4016 4 : if (pTextBefore.get())
4017 3 : aTextValue += pTextBefore->getString();
4018 4 : aTextValue += "%1";
4019 4 : RTFValue::Pointer_t pTextAfter = aState.aTableAttributes.find(NS_ooxml::LN_CT_LevelSuffix_val);
4020 4 : if (pTextAfter.get())
4021 3 : aTextValue += pTextAfter->getString();
4022 4 : RTFValue::Pointer_t pTextValue(new RTFValue(aTextValue));
4023 4 : aLeveltextAttributes.set(NS_ooxml::LN_CT_LevelText_val, pTextValue);
4024 :
4025 4 : RTFSprms aLevelAttributes;
4026 4 : RTFSprms aLevelSprms;
4027 4 : RTFValue::Pointer_t pIlvlValue(new RTFValue(0));
4028 4 : aLevelAttributes.set(NS_ooxml::LN_CT_Lvl_ilvl, pIlvlValue);
4029 :
4030 4 : RTFValue::Pointer_t pNfcValue = aState.aTableSprms.find(NS_rtf::LN_NFC);
4031 4 : if (pNfcValue.get())
4032 4 : aLevelSprms.set(NS_rtf::LN_NFC, pNfcValue);
4033 :
4034 4 : RTFValue::Pointer_t pStartatValue = aState.aTableSprms.find(NS_rtf::LN_ISTARTAT);
4035 4 : if (pStartatValue.get())
4036 4 : aLevelSprms.set(NS_rtf::LN_ISTARTAT, pStartatValue);
4037 :
4038 4 : RTFValue::Pointer_t pLeveltextValue(new RTFValue(aLeveltextAttributes));
4039 4 : aLevelSprms.set(NS_ooxml::LN_CT_Lvl_lvlText, pLeveltextValue);
4040 4 : RTFValue::Pointer_t pRunProps = aState.aTableSprms.find(NS_ooxml::LN_CT_Lvl_rPr);
4041 4 : if (pRunProps.get())
4042 1 : aLevelSprms.set(NS_ooxml::LN_CT_Lvl_rPr, pRunProps);
4043 :
4044 4 : RTFSprms aAbstractAttributes;
4045 4 : RTFSprms aAbstractSprms;
4046 4 : aAbstractAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIdValue);
4047 4 : RTFValue::Pointer_t pLevelValue(new RTFValue(aLevelAttributes, aLevelSprms));
4048 4 : aAbstractSprms.set(NS_ooxml::LN_CT_AbstractNum_lvl, pLevelValue, false);
4049 :
4050 4 : RTFSprms aListTableSprms;
4051 4 : RTFValue::Pointer_t pAbstractValue(new RTFValue(aAbstractAttributes, aAbstractSprms));
4052 : // It's important that Numbering_abstractNum and Numbering_num never overwrites previous values.
4053 4 : aListTableSprms.set(NS_ooxml::LN_CT_Numbering_abstractNum, pAbstractValue, false);
4054 :
4055 : // Numbering
4056 4 : RTFSprms aNumberingAttributes;
4057 4 : RTFSprms aNumberingSprms;
4058 4 : aNumberingAttributes.set(NS_rtf::LN_LSID, pIdValue);
4059 4 : aNumberingSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIdValue);
4060 4 : RTFValue::Pointer_t pNumberingValue(new RTFValue(aNumberingAttributes, aNumberingSprms));
4061 4 : aListTableSprms.set(NS_ooxml::LN_CT_Numbering_num, pNumberingValue, false);
4062 :
4063 : // Table
4064 4 : RTFSprms aListTableAttributes;
4065 4 : writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(aListTableAttributes, aListTableSprms));
4066 :
4067 4 : RTFReferenceTable::Entries_t aListTableEntries;
4068 4 : aListTableEntries.insert(make_pair(0, pProp));
4069 4 : writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aListTableEntries));
4070 4 : Mapper().table(NS_rtf::LN_LISTTABLE, pTable);
4071 :
4072 : // Use it
4073 4 : lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_sprm::LN_PIlvl, pIlvlValue);
4074 4 : lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_sprm::LN_PIlfo, pIdValue);
4075 4 : }
4076 : }
4077 5374 : else if (aState.nDestinationState == DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER)
4078 : {
4079 3 : RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
4080 3 : m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelSuffix_val, pValue);
4081 : }
4082 5371 : else if (aState.nDestinationState == DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE)
4083 : {
4084 3 : RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
4085 3 : m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelText_val, pValue);
4086 : }
4087 5368 : else if (aState.nDestinationState == DESTINATION_LISTLEVEL)
4088 : {
4089 8 : RTFValue::Pointer_t pInnerValue(new RTFValue(m_aStates.top().nListLevelNum++));
4090 8 : aState.aTableAttributes.set(NS_ooxml::LN_CT_Lvl_ilvl, pInnerValue);
4091 :
4092 8 : RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
4093 8 : m_aStates.top().aListLevelEntries.set(NS_ooxml::LN_CT_AbstractNum_lvl, pValue, false);
4094 : }
4095 : // list override table
4096 5360 : else if (aState.nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
4097 : {
4098 5 : RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
4099 5 : m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_num, pValue, false);
4100 : }
4101 5355 : else if (aState.nDestinationState == DESTINATION_LEVELTEXT)
4102 : {
4103 10 : RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes));
4104 10 : m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_lvlText, pValue);
4105 : }
4106 5345 : else if (aState.nDestinationState == DESTINATION_LEVELNUMBERS)
4107 10 : m_aStates.top().aTableSprms = aState.aTableSprms;
4108 5335 : else if (aState.nDestinationState == DESTINATION_FIELDINSTRUCTION)
4109 6 : m_aStates.top().nFieldStatus = FIELD_INSTRUCTION;
4110 5329 : else if (aState.nDestinationState == DESTINATION_FIELDRESULT)
4111 5 : m_aStates.top().nFieldStatus = FIELD_RESULT;
4112 5324 : else if (aState.nDestinationState == DESTINATION_FIELD)
4113 : {
4114 6 : if (aState.nFieldStatus == FIELD_INSTRUCTION)
4115 1 : singleChar(0x15);
4116 : }
4117 5318 : else if (aState.nDestinationState == DESTINATION_SHAPEPROPERTYVALUEPICT)
4118 : {
4119 2 : m_aStates.top().aPicture = aState.aPicture;
4120 2 : m_aStates.top().aDestinationText = aState.aDestinationText;
4121 : }
4122 5316 : else if (aState.nDestinationState == DESTINATION_FALT)
4123 104 : m_aStates.top().aTableSprms = aState.aTableSprms;
4124 5212 : else if (m_aStates.size() && m_aStates.top().nDestinationState == DESTINATION_PICT)
4125 2 : m_aStates.top().aPicture = aState.aPicture;
4126 5210 : else if (aState.nDestinationState == DESTINATION_SHAPEPROPERTYNAME ||
4127 : aState.nDestinationState == DESTINATION_SHAPEPROPERTYVALUE ||
4128 : aState.nDestinationState == DESTINATION_SHAPEPROPERTY)
4129 : {
4130 489 : m_aStates.top().aShape = aState.aShape;
4131 489 : m_aStates.top().aPicture = aState.aPicture;
4132 489 : m_aStates.top().aCharacterAttributes = aState.aCharacterAttributes;
4133 : }
4134 4721 : else if (aState.nDestinationState == DESTINATION_FLYMAINCONTENT ||
4135 : aState.nDestinationState == DESTINATION_SHPPICT ||
4136 : aState.nDestinationState == DESTINATION_SHAPE)
4137 22 : m_aStates.top().aFrame = aState.aFrame;
4138 5383 : if (m_pCurrentBuffer == &m_aSuperBuffer)
4139 : {
4140 6 : if (!m_bHasFootnote)
4141 6 : replayBuffer(m_aSuperBuffer);
4142 6 : m_pCurrentBuffer = 0;
4143 6 : m_bHasFootnote = false;
4144 : }
4145 5383 : if (m_aStates.size())
4146 : {
4147 5248 : m_aStates.top().nCells = aState.nCells;
4148 5248 : m_aStates.top().aTableCellsSprms = aState.aTableCellsSprms;
4149 5248 : m_aStates.top().aTableCellsAttributes = aState.aTableCellsAttributes;
4150 : }
4151 :
4152 5383 : return 0;
4153 : }
4154 :
4155 0 : ::std::string RTFDocumentImpl::getType() const
4156 : {
4157 0 : return "RTFDocumentImpl";
4158 : }
4159 :
4160 45 : uno::Reference<lang::XMultiServiceFactory> RTFDocumentImpl::getModelFactory()
4161 : {
4162 45 : return m_xModelFactory;
4163 : }
4164 :
4165 253804 : RTFParserState& RTFDocumentImpl::getState()
4166 : {
4167 253804 : return m_aStates.top();
4168 : }
4169 :
4170 2 : void RTFDocumentImpl::setDestinationText(OUString& rString)
4171 : {
4172 2 : m_aStates.top().aDestinationText.setLength(0);
4173 2 : m_aStates.top().aDestinationText.append(rString);
4174 2 : }
4175 :
4176 24 : void RTFDocumentImpl::replayShapetext()
4177 : {
4178 24 : Mapper().startParagraphGroup();
4179 24 : if (!m_aShapetextBuffer.empty())
4180 : {
4181 3 : replayBuffer(m_aShapetextBuffer);
4182 3 : Mapper().startCharacterGroup();
4183 3 : runBreak();
4184 3 : Mapper().endCharacterGroup();
4185 : }
4186 24 : Mapper().endParagraphGroup();
4187 24 : }
4188 :
4189 51405 : bool RTFDocumentImpl::getSkipUnknown()
4190 : {
4191 51405 : return m_bSkipUnknown;
4192 : }
4193 :
4194 559 : void RTFDocumentImpl::setSkipUnknown(bool bSkipUnknown)
4195 : {
4196 559 : m_bSkipUnknown = bSkipUnknown;
4197 559 : }
4198 :
4199 70943 : void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex)
4200 : {
4201 70943 : if (bUnicode && m_aUnicodeBuffer.getLength() > 0)
4202 : {
4203 96 : OUString aString = m_aUnicodeBuffer.makeStringAndClear();
4204 96 : text(aString);
4205 : }
4206 70943 : if (bHex && m_aHexBuffer.getLength() > 0)
4207 : {
4208 1975 : OUString aString = OStringToOUString(m_aHexBuffer.makeStringAndClear(), m_aStates.top().nCurrentEncoding);
4209 1975 : text(aString);
4210 : }
4211 70943 : }
4212 :
4213 138 : RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
4214 : : m_pDocumentImpl(pDocumentImpl),
4215 : nInternalState(INTERNAL_NORMAL),
4216 : nDestinationState(DESTINATION_NORMAL),
4217 : nFieldStatus(FIELD_NONE),
4218 : nBorderState(BORDER_NONE),
4219 : aTableSprms(),
4220 : aTableAttributes(),
4221 : aCharacterSprms(),
4222 : aCharacterAttributes(),
4223 : aParagraphSprms(),
4224 : aParagraphAttributes(),
4225 : aSectionSprms(),
4226 : aSectionAttributes(),
4227 : aTableRowSprms(),
4228 : aTableRowAttributes(),
4229 : aTableCellSprms(),
4230 : aTableCellAttributes(),
4231 : aTableCellsSprms(),
4232 : aTableCellsAttributes(),
4233 : aTabAttributes(),
4234 : aCurrentColor(),
4235 : nCurrentEncoding(0),
4236 : nUc(1),
4237 : nCharsToSkip(0),
4238 : nBinaryToRead(0),
4239 : nListLevelNum(0),
4240 : aListLevelEntries(),
4241 : aLevelNumbers(),
4242 : aPicture(),
4243 : aShape(),
4244 : aDrawingObject(),
4245 : aFrame(this),
4246 : nCellX(0),
4247 : nCells(0),
4248 : nInheritingCells(0),
4249 : bIsCjk(false),
4250 : nYear(0),
4251 : nMonth(0),
4252 : nDay(0),
4253 : nHour(0),
4254 : nMinute(0),
4255 138 : nCurrentStyleIndex(-1)
4256 : {
4257 138 : }
4258 :
4259 224 : void RTFParserState::resetFrame()
4260 : {
4261 224 : aFrame = RTFFrame(this);
4262 224 : }
4263 :
4264 300 : RTFColorTableEntry::RTFColorTableEntry()
4265 : : nRed(0),
4266 : nGreen(0),
4267 300 : nBlue(0)
4268 : {
4269 300 : }
4270 :
4271 138 : RTFPicture::RTFPicture()
4272 : : nWidth(0),
4273 : nHeight(0),
4274 : nGoalWidth(0),
4275 : nGoalHeight(0),
4276 : nScaleX(100),
4277 : nScaleY(100),
4278 : nCropT(0),
4279 : nCropB(0),
4280 : nCropL(0),
4281 : nCropR(0),
4282 : eWMetafile(0),
4283 138 : nStyle(BMPSTYLE_NONE)
4284 : {
4285 138 : }
4286 :
4287 276 : RTFShape::RTFShape()
4288 : : nLeft(0),
4289 : nTop(0),
4290 : nRight(0),
4291 : nBottom(0),
4292 : nHoriOrientRelation(0),
4293 : nVertOrientRelation(0),
4294 276 : nWrap(-1)
4295 : {
4296 276 : }
4297 :
4298 138 : RTFDrawingObject::RTFDrawingObject()
4299 : : nLineColorR(0),
4300 : nLineColorG(0),
4301 : nLineColorB(0),
4302 : bHasLineColor(false),
4303 : nFillColorR(0),
4304 : nFillColorG(0),
4305 : nFillColorB(0),
4306 : bHasFillColor(false),
4307 : nDhgt(0),
4308 : nFLine(-1),
4309 138 : nPolyLineCount(0)
4310 : {
4311 138 : }
4312 :
4313 362 : RTFFrame::RTFFrame(RTFParserState* pParserState)
4314 : : m_pParserState(pParserState),
4315 : nX(0),
4316 : nY(0),
4317 : nW(0),
4318 : nH(0),
4319 : nHoriPadding(0),
4320 : nVertPadding(0),
4321 : nHoriAlign(0),
4322 : nHoriAnchor(0),
4323 : nVertAlign(0),
4324 : nVertAnchor(0),
4325 : nHRule(NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_auto),
4326 362 : nAnchorType(0)
4327 : {
4328 362 : }
4329 :
4330 123 : void RTFFrame::setSprm(Id nId, Id nValue)
4331 : {
4332 123 : if (m_pParserState->m_pDocumentImpl->getFirstRun())
4333 : {
4334 6 : m_pParserState->m_pDocumentImpl->checkFirstRun();
4335 6 : m_pParserState->m_pDocumentImpl->setNeedPar(false);
4336 : }
4337 123 : switch (nId)
4338 : {
4339 : case NS_sprm::LN_PDxaWidth:
4340 14 : nW = nValue;
4341 14 : break;
4342 : case NS_sprm::LN_PWHeightAbs:
4343 14 : nH = nValue;
4344 14 : break;
4345 : case NS_ooxml::LN_CT_FramePr_x:
4346 12 : nX = nValue;
4347 12 : break;
4348 : case NS_ooxml::LN_CT_FramePr_y:
4349 12 : nY = nValue;
4350 12 : break;
4351 : case NS_sprm::LN_PDxaFromText:
4352 3 : nHoriPadding = nValue;
4353 3 : break;
4354 : case NS_sprm::LN_PDyaFromText:
4355 3 : nVertPadding = nValue;
4356 3 : break;
4357 : case NS_ooxml::LN_CT_FramePr_xAlign:
4358 17 : nHoriAlign = nValue;
4359 17 : break;
4360 : case NS_ooxml::LN_CT_FramePr_hAnchor:
4361 15 : nHoriAnchor = nValue;
4362 15 : break;
4363 : case NS_ooxml::LN_CT_FramePr_yAlign:
4364 17 : nVertAlign = nValue;
4365 17 : break;
4366 : case NS_ooxml::LN_CT_FramePr_vAnchor:
4367 16 : nVertAnchor = nValue;
4368 16 : break;
4369 : default:
4370 0 : break;
4371 : }
4372 123 : }
4373 :
4374 17 : RTFSprms RTFFrame::getSprms()
4375 : {
4376 17 : RTFSprms sprms;
4377 :
4378 : static Id pNames[] =
4379 : {
4380 : NS_ooxml::LN_CT_FramePr_x,
4381 : NS_ooxml::LN_CT_FramePr_y,
4382 : NS_ooxml::LN_CT_FramePr_hRule, // Make sure nHRule is processed before nH
4383 : NS_sprm::LN_PWHeightAbs,
4384 : NS_sprm::LN_PDxaWidth,
4385 : NS_sprm::LN_PDxaFromText,
4386 : NS_sprm::LN_PDyaFromText,
4387 : NS_ooxml::LN_CT_FramePr_hAnchor,
4388 : NS_ooxml::LN_CT_FramePr_vAnchor,
4389 : NS_ooxml::LN_CT_FramePr_xAlign,
4390 : NS_ooxml::LN_CT_FramePr_yAlign,
4391 : NS_sprm::LN_PWr,
4392 : NS_ooxml::LN_CT_FramePr_dropCap,
4393 : NS_ooxml::LN_CT_FramePr_lines
4394 : };
4395 :
4396 255 : for ( int i = 0, len = SAL_N_ELEMENTS(pNames); i < len; ++i )
4397 : {
4398 238 : Id nId = pNames[i];
4399 238 : RTFValue::Pointer_t pValue;
4400 :
4401 238 : switch ( nId )
4402 : {
4403 : case NS_ooxml::LN_CT_FramePr_x:
4404 17 : if ( nX != 0 )
4405 14 : pValue.reset(new RTFValue(nX));
4406 17 : break;
4407 : case NS_ooxml::LN_CT_FramePr_y:
4408 17 : if ( nY != 0 )
4409 14 : pValue.reset(new RTFValue(nY));
4410 17 : break;
4411 : case NS_sprm::LN_PWHeightAbs:
4412 17 : if ( nH != 0 )
4413 : {
4414 17 : if (nHRule == NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_exact)
4415 12 : pValue.reset(new RTFValue(-nH)); // The negative value just sets nHRule
4416 : else
4417 5 : pValue.reset(new RTFValue(nH));
4418 : }
4419 17 : break;
4420 : case NS_sprm::LN_PDxaWidth:
4421 17 : if ( nW != 0 )
4422 17 : pValue.reset(new RTFValue(nW));
4423 17 : break;
4424 : case NS_sprm::LN_PDxaFromText:
4425 17 : if ( nHoriPadding != 0 )
4426 4 : pValue.reset(new RTFValue(nHoriPadding));
4427 17 : break;
4428 : case NS_sprm::LN_PDyaFromText:
4429 17 : if ( nVertPadding != 0 )
4430 4 : pValue.reset(new RTFValue(nVertPadding));
4431 17 : break;
4432 : case NS_ooxml::LN_CT_FramePr_hAnchor:
4433 17 : if ( nHoriAnchor == 0 )
4434 3 : nHoriAnchor = NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_margin;
4435 17 : pValue.reset(new RTFValue(nHoriAnchor));
4436 17 : break;
4437 : case NS_ooxml::LN_CT_FramePr_vAnchor:
4438 17 : if ( nVertAnchor == 0 )
4439 4 : nVertAnchor = NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_margin;
4440 17 : pValue.reset(new RTFValue(nVertAnchor));
4441 17 : break;
4442 : case NS_ooxml::LN_CT_FramePr_xAlign:
4443 17 : pValue.reset(new RTFValue(nHoriAlign));
4444 17 : break;
4445 : case NS_ooxml::LN_CT_FramePr_yAlign:
4446 17 : pValue.reset(new RTFValue(nVertAlign));
4447 17 : break;
4448 : case NS_ooxml::LN_CT_FramePr_hRule:
4449 : {
4450 17 : if ( nH < 0 )
4451 12 : nHRule = NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_exact;
4452 5 : else if ( nH > 0 )
4453 5 : nHRule = NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_atLeast;
4454 17 : pValue.reset(new RTFValue(nHRule));
4455 17 : break;
4456 : }
4457 : default:
4458 51 : break;
4459 : }
4460 :
4461 238 : if (pValue.get())
4462 155 : sprms.set(nId, pValue);
4463 238 : }
4464 :
4465 17 : RTFSprms frameprSprms;
4466 17 : RTFValue::Pointer_t pFrameprValue(new RTFValue(sprms));
4467 17 : frameprSprms.set(NS_ooxml::LN_CT_PPrBase_framePr, pFrameprValue);
4468 :
4469 17 : return frameprSprms;
4470 : }
4471 :
4472 692 : bool RTFFrame::hasProperties()
4473 : {
4474 : return nX != 0 || nY != 0 || nW != 0 || nH != 0 ||
4475 : nHoriPadding != 0 || nVertPadding != 0 ||
4476 : nHoriAlign != 0 || nHoriAnchor != 0 || nVertAlign != 0 || nVertAnchor != 0 ||
4477 692 : nAnchorType != 0;
4478 : }
4479 :
4480 : } // namespace rtftok
4481 15 : } // namespace writerfilter
4482 :
4483 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|