LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / writerfilter / source / rtftok / rtfdocumentimpl.hxx
blob14ffc2f630a454630bc289098430dc1e91f40536
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #pragma once
12 #include <memory>
13 #include <queue>
14 #include <tuple>
15 #include <vector>
16 #include <optional>
18 #include <com/sun/star/text/WrapTextMode.hpp>
19 #include <com/sun/star/io/WrongFormatException.hpp>
20 #include <oox/mathml/importutils.hxx>
21 #include <rtl/strbuf.hxx>
22 #include <rtl/ustrbuf.hxx>
23 #include <tools/color.hxx>
24 #include <tools/long.hxx>
26 #include <rtftok/RTFDocument.hxx>
27 #include "rtfreferencetable.hxx"
28 #include "rtfsprm.hxx"
29 #include "rtflistener.hxx"
31 class SvStream;
32 namespace oox
34 class GraphicHelper;
36 namespace com::sun::star
38 namespace beans
40 class XPropertySet;
42 namespace document
44 class XDocumentProperties;
46 namespace lang
48 class XMultiServiceFactory;
52 namespace writerfilter::rtftok
54 class RTFParserState;
55 class RTFDocumentImpl;
56 class RTFTokenizer;
57 class RTFSdrImport;
58 class TableRowBuffer;
60 enum class RTFBorderState
62 NONE,
63 PARAGRAPH,
64 PARAGRAPH_BOX,
65 CELL,
66 PAGE,
67 CHARACTER
70 /// Different kind of buffers for table cell contents.
71 enum RTFBufferTypes
73 BUFFER_SETSTYLE,
74 /// Stores properties, should be created only in bufferProperties().
75 BUFFER_PROPS,
76 BUFFER_NESTROW,
77 BUFFER_CELLEND,
78 BUFFER_STARTRUN,
79 BUFFER_TEXT,
80 BUFFER_UTEXT,
81 BUFFER_ENDRUN,
82 BUFFER_PAR,
83 BUFFER_STARTSHAPE,
84 /// Imports a shape.
85 BUFFER_RESOLVESHAPE,
86 BUFFER_ENDSHAPE,
87 BUFFER_RESOLVESUBSTREAM,
88 /// Restores RTFParserState::aPicture.
89 BUFFER_PICTURE
92 /// Form field types
93 enum class RTFFormFieldType
95 NONE,
96 TEXT,
97 CHECKBOX,
98 LIST
101 enum class RTFBmpStyle
103 NONE,
104 PNG,
105 JPEG,
106 DIBITMAP
109 enum class RTFFieldStatus
111 NONE,
112 INSTRUCTION,
113 RESULT
116 /// A buffer storing dmapper calls.
117 using Buf_t = std::tuple<RTFBufferTypes, RTFValue::Pointer_t, tools::SvRef<TableRowBuffer>>;
118 using RTFBuffer_t = std::deque<Buf_t>;
120 /// holds one nested table row
121 class TableRowBuffer : public virtual SvRefBase
123 RTFBuffer_t m_aBuffer;
124 ::std::deque<RTFSprms> m_aCellsSprms;
125 ::std::deque<RTFSprms> m_aCellsAttributes;
126 int m_nCells;
127 writerfilter::Reference<Properties>::Pointer_t m_pParaProperties;
128 writerfilter::Reference<Properties>::Pointer_t m_pFrameProperties;
129 writerfilter::Reference<Properties>::Pointer_t m_pRowProperties;
131 public:
132 TableRowBuffer(RTFBuffer_t aBuffer, std::deque<RTFSprms> aSprms,
133 std::deque<RTFSprms> aAttributes, int const nCells)
134 : m_aBuffer(std::move(aBuffer))
135 , m_aCellsSprms(std::move(aSprms))
136 , m_aCellsAttributes(std::move(aAttributes))
137 , m_nCells(nCells)
141 RTFBuffer_t& GetBuffer() { return m_aBuffer; }
142 std::deque<RTFSprms>& GetCellsSprms() { return m_aCellsSprms; }
143 std::deque<RTFSprms>& GetCellsAttributes() { return m_aCellsAttributes; }
144 int GetCells() const { return m_nCells; }
145 writerfilter::Reference<Properties>::Pointer_t& GetParaProperties()
147 return m_pParaProperties;
149 writerfilter::Reference<Properties>::Pointer_t& GetFrameProperties()
151 return m_pFrameProperties;
153 writerfilter::Reference<Properties>::Pointer_t& GetRowProperties() { return m_pRowProperties; }
156 /// An entry in the color table.
157 class RTFColorTableEntry
159 public:
160 void SetRed(sal_uInt8 nRed)
162 m_bAuto = false;
163 m_nR = nRed;
165 void SetGreen(sal_uInt8 nGreen)
167 m_bAuto = false;
168 m_nG = nGreen;
170 void SetBlue(sal_uInt8 nBlue)
172 m_bAuto = false;
173 m_nB = nBlue;
175 Color GetColor() const { return m_bAuto ? COL_AUTO : Color(m_nR, m_nG, m_nB); }
177 private:
178 bool m_bAuto = true;
179 sal_uInt8 m_nR = 0;
180 sal_uInt8 m_nG = 0;
181 sal_uInt8 m_nB = 0;
184 /// Stores the properties of a shape.
185 class RTFShape : public virtual SvRefBase
187 public:
188 RTFShape();
190 std::vector<std::pair<OUString, OUString>>& getProperties() { return m_aProperties; }
192 const std::vector<std::pair<OUString, OUString>>& getProperties() const
194 return m_aProperties;
197 std::vector<std::pair<OUString, OUString>>& getGroupProperties() { return m_aGroupProperties; }
199 void setLeft(sal_Int32 nLeft) { m_nLeft = nLeft; }
201 sal_Int32 getLeft() const { return m_nLeft; }
203 void setTop(sal_Int32 nTop) { m_nTop = nTop; }
205 sal_Int32 getTop() const { return m_nTop; }
207 void setRight(sal_Int32 nRight) { m_nRight = nRight; }
209 sal_Int32 getRight() const { return m_nRight; }
211 void setBottom(sal_Int32 nBottom) { m_nBottom = nBottom; }
213 sal_Int32 getBottom() const { return m_nBottom; }
215 void setZ(sal_Int32 nZ) { m_oZ = nZ; }
217 bool hasZ() const { return bool(m_oZ); }
219 sal_Int32 getZ() const { return *m_oZ; }
221 void setHoriOrientRelation(sal_Int16 nHoriOrientRelation)
223 m_nHoriOrientRelation = nHoriOrientRelation;
226 sal_Int16 getHoriOrientRelation() const { return m_nHoriOrientRelation; }
228 void setVertOrientRelation(sal_Int16 nVertOrientRelation)
230 m_nVertOrientRelation = nVertOrientRelation;
233 sal_Int16 getVertOrientRelation() const { return m_nVertOrientRelation; }
235 void setHoriOrientRelationToken(sal_uInt32 nHoriOrientRelationToken)
237 m_nHoriOrientRelationToken = nHoriOrientRelationToken;
240 sal_uInt32 getHoriOrientRelationToken() const { return m_nHoriOrientRelationToken; }
242 void setVertOrientRelationToken(sal_uInt32 nVertOrientRelationToken)
244 m_nVertOrientRelationToken = nVertOrientRelationToken;
247 sal_uInt32 getVertOrientRelationToken() const { return m_nVertOrientRelationToken; }
249 void setWrap(css::text::WrapTextMode nWrap) { m_nWrap = nWrap; }
251 css::text::WrapTextMode getWrap() const { return m_nWrap; }
253 void setInBackground(bool bInBackground) { m_bInBackground = bInBackground; }
255 bool getInBackground() const { return m_bInBackground; }
257 RTFSprms& getWrapPolygonSprms() { return m_aWrapPolygonSprms; }
259 RTFSprms& getAnchorAttributes() { return m_aAnchorAttributes; }
261 std::pair<Id, RTFValue::Pointer_t>& getWrapSprm() { return m_aWrapSprm; }
263 private:
264 std::vector<std::pair<OUString, OUString>> m_aProperties; ///< Properties of a single shape.
265 std::vector<std::pair<OUString, OUString>>
266 m_aGroupProperties; ///< Properties applied on the groupshape.
267 sal_Int32 m_nLeft = 0;
268 sal_Int32 m_nTop = 0;
269 sal_Int32 m_nRight = 0;
270 sal_Int32 m_nBottom = 0;
271 std::optional<sal_Int32> m_oZ; ///< Z-Order of the shape.
272 sal_Int16 m_nHoriOrientRelation
273 = 0; ///< Horizontal text::RelOrientation for drawinglayer shapes.
274 sal_Int16 m_nVertOrientRelation = 0; ///< Vertical text::RelOrientation for drawinglayer shapes.
275 sal_uInt32 m_nHoriOrientRelationToken = 0; ///< Horizontal dmapper token for Writer pictures.
276 sal_uInt32 m_nVertOrientRelationToken = 0; ///< Vertical dmapper token for Writer pictures.
277 css::text::WrapTextMode m_nWrap = css::text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE;
278 /// If shape is below text (true) or text is below shape (false).
279 bool m_bInBackground = false;
280 /// Wrap polygon, written by RTFSdrImport::resolve(), read by RTFDocumentImpl::resolvePict().
281 RTFSprms m_aWrapPolygonSprms;
282 /// Anchor attributes like wrap distance, written by RTFSdrImport::resolve(), read by RTFDocumentImpl::resolvePict().
283 RTFSprms m_aAnchorAttributes;
284 /// Wrap type, written by RTFDocumentImpl::popState(), read by RTFDocumentImpl::resolvePict().
285 std::pair<Id, RTFValue::Pointer_t> m_aWrapSprm{ 0, nullptr };
288 /// Stores the properties of a drawing object.
289 class RTFDrawingObject : public RTFShape
291 public:
292 RTFDrawingObject();
294 void setShape(const css::uno::Reference<css::drawing::XShape>& xShape) { m_xShape = xShape; }
295 const css::uno::Reference<css::drawing::XShape>& getShape() const { return m_xShape; }
296 void setPropertySet(const css::uno::Reference<css::beans::XPropertySet>& xPropertySet)
298 m_xPropertySet = xPropertySet;
300 const css::uno::Reference<css::beans::XPropertySet>& getPropertySet() const
302 return m_xPropertySet;
304 std::vector<css::beans::PropertyValue>& getPendingProperties() { return m_aPendingProperties; }
305 void setLineColorR(sal_uInt8 nLineColorR) { m_nLineColorR = nLineColorR; }
306 sal_uInt8 getLineColorR() const { return m_nLineColorR; }
307 void setLineColorG(sal_uInt8 nLineColorG) { m_nLineColorG = nLineColorG; }
308 sal_uInt8 getLineColorG() const { return m_nLineColorG; }
309 void setLineColorB(sal_uInt8 nLineColorB) { m_nLineColorB = nLineColorB; }
310 sal_uInt8 getLineColorB() const { return m_nLineColorB; }
311 void setHasLineColor(bool bHasLineColor) { m_bHasLineColor = bHasLineColor; }
312 bool getHasLineColor() const { return m_bHasLineColor; }
313 void setFillColorR(sal_uInt8 nFillColorR) { m_nFillColorR = nFillColorR; }
314 sal_uInt8 getFillColorR() const { return m_nFillColorR; }
315 void setFillColorG(sal_uInt8 nFillColorG) { m_nFillColorG = nFillColorG; }
316 sal_uInt8 getFillColorG() const { return m_nFillColorG; }
317 void setFillColorB(sal_uInt8 nFillColorB) { m_nFillColorB = nFillColorB; }
318 sal_uInt8 getFillColorB() const { return m_nFillColorB; }
319 void setHasFillColor(bool bHasFillColor) { m_bHasFillColor = bHasFillColor; }
320 bool getHasFillColor() const { return m_bHasFillColor; }
321 void setDhgt(sal_Int32 nDhgt) { m_nDhgt = nDhgt; }
322 sal_Int32 getDhgt() const { return m_nDhgt; }
323 void setFLine(sal_Int32 nFLine) { m_nFLine = nFLine; }
324 sal_Int32 getFLine() const { return m_nFLine; }
325 void setPolyLineCount(sal_Int32 nPolyLineCount) { m_nPolyLineCount = nPolyLineCount; }
326 sal_Int32 getPolyLineCount() const { return m_nPolyLineCount; }
327 std::vector<css::awt::Point>& getPolyLinePoints() { return m_aPolyLinePoints; }
328 void setHadShapeText(bool bHadShapeText) { m_bHadShapeText = bHadShapeText; }
329 bool getHadShapeText() const { return m_bHadShapeText; }
331 private:
332 css::uno::Reference<css::drawing::XShape> m_xShape;
333 css::uno::Reference<css::beans::XPropertySet> m_xPropertySet;
334 std::vector<css::beans::PropertyValue> m_aPendingProperties;
335 sal_uInt8 m_nLineColorR = 0;
336 sal_uInt8 m_nLineColorG = 0;
337 sal_uInt8 m_nLineColorB = 0;
338 bool m_bHasLineColor = false;
339 sal_uInt8 m_nFillColorR = 0;
340 sal_uInt8 m_nFillColorG = 0;
341 sal_uInt8 m_nFillColorB = 0;
342 bool m_bHasFillColor = false;
343 sal_Int32 m_nDhgt = 0;
344 sal_Int32 m_nFLine = -1;
345 sal_Int32 m_nPolyLineCount = 0;
346 std::vector<css::awt::Point> m_aPolyLinePoints;
347 bool m_bHadShapeText = false;
350 /// Stores the properties of a picture.
351 class RTFPicture : public virtual SvRefBase
353 public:
354 sal_Int32 nWidth = 0;
355 sal_Int32 nHeight = 0;
356 sal_Int32 nGoalWidth = 0;
357 sal_Int32 nGoalHeight = 0;
358 sal_uInt16 nScaleX = 100;
359 sal_uInt16 nScaleY = 100;
360 short nCropT = 0;
361 short nCropB = 0;
362 short nCropL = 0;
363 short nCropR = 0;
364 sal_uInt16 eWMetafile = 0;
365 RTFBmpStyle eStyle = RTFBmpStyle::NONE;
368 /// Stores the properties of a frame
369 class RTFFrame
371 private:
372 RTFDocumentImpl* m_pDocumentImpl;
373 sal_Int32 m_nX, m_nY, m_nW, m_nH;
374 sal_Int32 m_nHoriPadding, m_nVertPadding;
375 sal_Int32 m_nHoriAlign, m_nHoriAnchor, m_nVertAlign, m_nVertAnchor;
376 Id m_nHRule;
377 std::optional<Id> m_oWrap;
379 public:
380 explicit RTFFrame(RTFParserState* pParserState);
382 /// Convert the stored properties to Sprms
383 RTFSprms getSprms();
384 /// Store a property
385 void setSprm(Id nId, Id nValue);
386 bool hasProperties() const;
387 /// If we got tokens indicating we're in a frame.
388 bool inFrame() const;
391 /// State of the parser, which gets saved / restored when changing groups.
392 class RTFParserState
394 public:
395 /// Maps to OOXML's ascii, cs or eastAsia.
396 enum class RunType
398 NONE,
399 LOCH,
400 HICH,
401 DBCH,
402 LTRCH_RTLCH_1,
403 LTRCH_RTLCH_2,
404 RTLCH_LTRCH_1,
405 RTLCH_LTRCH_2
408 explicit RTFParserState(RTFDocumentImpl* pDocumentImpl);
410 void appendDestinationText(std::u16string_view rString)
412 if (m_pCurrentDestinationText)
413 m_pCurrentDestinationText->append(rString);
416 void setPropName(const OUString& rPropName) { m_aPropName = rPropName; }
417 OUString const& getPropName() const { return m_aPropName; }
418 void setPropType(const css::uno::Type& rPropType) { m_aPropType = rPropType; }
419 css::uno::Type const& getPropType() const { return m_aPropType; }
420 void setTableRowWidthAfter(int nTableRowWidthAfter)
422 m_nTableRowWidthAfter = nTableRowWidthAfter;
424 int getTableRowWidthAfter() const { return m_nTableRowWidthAfter; }
425 void setStartedTrackchange(bool bStartedTrackchange)
427 m_bStartedTrackchange = bStartedTrackchange;
429 bool getStartedTrackchange() const { return m_bStartedTrackchange; }
430 void setCreatedShapeGroup(bool bCreatedShapeGroup)
432 m_bCreatedShapeGroup = bCreatedShapeGroup;
434 bool getCreatedShapeGroup() const { return m_bCreatedShapeGroup; }
435 void setInShape(bool bInShape) { m_bInShape = bInShape; }
436 bool getInShape() const { return m_bInShape; }
437 void setInShapeGroup(bool bInShapeGroup) { m_bInShapeGroup = bInShapeGroup; }
438 bool getInShapeGroup() const { return m_bInShapeGroup; }
439 void setHadShapeText(bool bHadShapeText) { m_bHadShapeText = bHadShapeText; }
440 bool getHadShapeText() const { return m_bHadShapeText; }
441 void setInBackground(bool bInBackground) { m_bInBackground = bInBackground; }
442 bool getInBackground() const { return m_bInBackground; }
443 void setInListpicture(bool bInListpicture) { m_bInListpicture = bInListpicture; }
444 bool getInListpicture() const { return m_bInListpicture; }
445 void setCurrentBuffer(RTFBuffer_t* pCurrentBuffer) { m_pCurrentBuffer = pCurrentBuffer; }
446 RTFBuffer_t* getCurrentBuffer() const { return m_pCurrentBuffer; }
447 void setCurrentListOverrideIndex(int nCurrentListOverrideIndex)
449 m_nCurrentListOverrideIndex = nCurrentListOverrideIndex;
451 int getCurrentListOverrideIndex() const { return m_nCurrentListOverrideIndex; }
452 void setCurrentListIndex(int nCurrentListIndex) { m_nCurrentListIndex = nCurrentListIndex; }
453 int getCurrentListIndex() const { return m_nCurrentListIndex; }
454 void setCurrentCharacterStyleIndex(int nCurrentCharacterStyleIndex)
456 m_nCurrentCharacterStyleIndex = nCurrentCharacterStyleIndex;
458 int getCurrentCharacterStyleIndex() const { return m_nCurrentCharacterStyleIndex; }
459 void setCurrentStyleIndex(int nCurrentStyleIndex) { m_nCurrentStyleIndex = nCurrentStyleIndex; }
460 int getCurrentStyleIndex() const { return m_nCurrentStyleIndex; }
461 void setCurrentDestinationText(OUStringBuffer* pDestinationText)
463 m_pCurrentDestinationText = pDestinationText;
465 OUStringBuffer* getCurrentDestinationText() const { return m_pCurrentDestinationText; }
466 OUStringBuffer& getDestinationText() { return m_aDestinationText; }
467 void setMinute(sal_uInt16 nMinute) { m_nMinute = nMinute; }
468 sal_uInt16 getMinute() const { return m_nMinute; }
469 void setHour(sal_uInt16 nHour) { m_nHour = nHour; }
470 sal_uInt16 getHour() const { return m_nHour; }
471 void setDay(sal_uInt16 nDay) { m_nDay = nDay; }
472 sal_uInt16 getDay() const { return m_nDay; }
473 void setMonth(sal_uInt16 nMonth) { m_nMonth = nMonth; }
474 sal_uInt16 getMonth() const { return m_nMonth; }
475 void setYear(sal_uInt16 nYear) { m_nYear = nYear; }
476 sal_uInt16 getYear() const { return m_nYear; }
477 void setRunType(RunType eRunType) { m_eRunType = eRunType; }
478 RunType getRunType() const { return m_eRunType; }
479 RTFFrame& getFrame() { return m_aFrame; }
480 RTFDrawingObject& getDrawingObject() { return m_aDrawingObject; }
481 RTFShape& getShape() { return m_aShape; }
482 RTFPicture& getPicture() { return m_aPicture; }
483 void setLevelNumbersValid(bool bLevelNumbersValid)
485 m_bLevelNumbersValid = bLevelNumbersValid;
487 bool getLevelNumbersValid() const { return m_bLevelNumbersValid; }
488 std::vector<sal_Int32>& getLevelNumbers() { return m_aLevelNumbers; }
489 RTFSprms& getListLevelEntries() { return m_aListLevelEntries; }
490 int& getListLevelNum() { return m_nListLevelNum; }
491 void setBinaryToRead(int nBinaryToRead) { m_nBinaryToRead = nBinaryToRead; }
492 int getBinaryToRead() const { return m_nBinaryToRead; }
493 int& getCharsToSkip() { return m_nCharsToSkip; }
494 void setUc(int nUc) { m_nUc = nUc; }
495 int getUc() const { return m_nUc; }
496 void setCurrentEncoding(rtl_TextEncoding nCurrentEncoding)
498 m_nCurrentEncoding = nCurrentEncoding;
500 rtl_TextEncoding getCurrentEncoding() const { return m_nCurrentEncoding; }
501 RTFColorTableEntry& getCurrentColor() { return m_aCurrentColor; }
502 RTFSprms& getTabAttributes() { return m_aTabAttributes; }
503 RTFSprms& getTableCellAttributes() { return m_aTableCellAttributes; }
504 RTFSprms& getTableCellSprms() { return m_aTableCellSprms; }
505 RTFSprms& getTableRowAttributes() { return m_aTableRowAttributes; }
506 RTFSprms& getTableRowSprms() { return m_aTableRowSprms; }
507 RTFSprms& getSectionAttributes() { return m_aSectionAttributes; }
508 RTFSprms& getSectionSprms() { return m_aSectionSprms; }
509 RTFSprms& getParagraphAttributes() { return m_aParagraphAttributes; }
510 RTFSprms& getParagraphSprms() { return m_aParagraphSprms; }
511 RTFSprms& getCharacterAttributes() { return m_aCharacterAttributes; }
512 RTFSprms& getCharacterSprms() { return m_aCharacterSprms; }
513 RTFSprms& getTableAttributes() { return m_aTableAttributes; }
514 RTFSprms& getTableSprms() { return m_aTableSprms; }
515 void setBorderState(RTFBorderState nBorderState) { m_nBorderState = nBorderState; }
516 RTFBorderState getBorderState() const { return m_nBorderState; }
517 void setFieldStatus(RTFFieldStatus eFieldStatus) { m_eFieldStatus = eFieldStatus; }
518 RTFFieldStatus getFieldStatus() const { return m_eFieldStatus; }
519 void setFieldLocked(bool bSet) { m_bFieldLocked = bSet; }
520 bool isFieldLocked() const { return m_bFieldLocked; }
521 void setDestination(Destination eDestination) { m_eDestination = eDestination; }
522 Destination getDestination() const { return m_eDestination; }
523 void setInternalState(RTFInternalState nInternalState) { m_nInternalState = nInternalState; }
524 RTFInternalState getInternalState() const { return m_nInternalState; }
525 RTFDocumentImpl* getDocumentImpl() { return m_pDocumentImpl; }
527 private:
528 RTFDocumentImpl* m_pDocumentImpl;
529 RTFInternalState m_nInternalState;
530 Destination m_eDestination;
531 RTFFieldStatus m_eFieldStatus;
532 bool m_bFieldLocked;
533 RTFBorderState m_nBorderState;
534 // font table, stylesheet table
535 RTFSprms m_aTableSprms;
536 RTFSprms m_aTableAttributes;
537 // reset by plain
538 RTFSprms m_aCharacterSprms;
539 RTFSprms m_aCharacterAttributes;
540 // reset by pard
541 RTFSprms m_aParagraphSprms;
542 RTFSprms m_aParagraphAttributes;
543 // reset by sectd
544 RTFSprms m_aSectionSprms;
545 RTFSprms m_aSectionAttributes;
546 // reset by trowd
547 RTFSprms m_aTableRowSprms;
548 RTFSprms m_aTableRowAttributes;
549 // reset by cellx
550 RTFSprms m_aTableCellSprms;
551 RTFSprms m_aTableCellAttributes;
552 // reset by tx
553 RTFSprms m_aTabAttributes;
555 RTFColorTableEntry m_aCurrentColor;
557 rtl_TextEncoding m_nCurrentEncoding;
559 /// Current \uc value.
560 int m_nUc;
561 /// Characters to skip, set to nUc by \u.
562 int m_nCharsToSkip;
563 /// Characters to read, once in binary mode.
564 int m_nBinaryToRead;
566 /// Next list level index to use when parsing list table.
567 int m_nListLevelNum;
568 /// List level entries, which will form a list entry later.
569 RTFSprms m_aListLevelEntries;
570 /// List of character positions in leveltext to replace.
571 std::vector<sal_Int32> m_aLevelNumbers;
572 /// If aLevelNumbers should be read at all.
573 bool m_bLevelNumbersValid;
575 RTFPicture m_aPicture;
576 RTFShape m_aShape;
577 RTFDrawingObject m_aDrawingObject;
578 RTFFrame m_aFrame;
580 RunType m_eRunType;
582 // Info group.
583 sal_Int16 m_nYear;
584 sal_uInt16 m_nMonth;
585 sal_uInt16 m_nDay;
586 sal_uInt16 m_nHour;
587 sal_uInt16 m_nMinute;
589 /// Text from special destinations.
590 OUStringBuffer m_aDestinationText{ 512 };
591 /// point to the buffer of the current destination
592 OUStringBuffer* m_pCurrentDestinationText;
594 /// Index of the current style.
595 int m_nCurrentStyleIndex;
596 /// Index of the current character style.
597 int m_nCurrentCharacterStyleIndex;
598 /// Current listid, points to a listtable entry.
599 int m_nCurrentListIndex = -1;
600 /// Current ls, points to a listoverridetable entry.
601 int m_nCurrentListOverrideIndex = -1;
603 /// Points to the active buffer, if there is one.
604 RTFBuffer_t* m_pCurrentBuffer;
606 /// If we're inside a \listpicture group.
607 bool m_bInListpicture;
609 /// If we're inside a \background group.
610 bool m_bInBackground;
612 bool m_bHadShapeText;
613 bool m_bInShapeGroup; ///< If we're inside a \shpgrp group.
614 bool m_bInShape; ///< If we're inside a \shp group.
615 bool m_bCreatedShapeGroup; ///< A GroupShape was created and pushed to the parent stack.
616 bool m_bStartedTrackchange; ///< Track change is started, need to end it before popping.
618 /// User-defined property: key name.
619 OUString m_aPropName;
620 /// User-defined property: value type.
621 css::uno::Type m_aPropType;
623 /// Width of invisible cell at the end of the row.
624 int m_nTableRowWidthAfter;
627 /// An RTF stack is similar to std::stack, except that it has an operator[].
628 struct RTFStack
630 private:
631 std::deque<RTFParserState> m_Impl;
633 public:
634 RTFParserState& top()
636 if (m_Impl.empty())
637 throw css::io::WrongFormatException(
638 "Parser state is empty! Invalid usage of destination braces in RTF?", nullptr);
639 return m_Impl.back();
641 void pop()
643 if (m_Impl.empty())
644 throw css::io::WrongFormatException(
645 "Parser state is empty! Invalid usage of destination braces in RTF?", nullptr);
646 return m_Impl.pop_back();
648 void push(RTFParserState const& rState) { return m_Impl.push_back(rState); }
649 bool empty() const { return m_Impl.empty(); }
650 size_t size() const { return m_Impl.size(); }
651 const RTFParserState& operator[](size_t nIndex) const { return m_Impl[nIndex]; }
652 RTFParserState& operator[](size_t nIndex) { return m_Impl[nIndex]; }
655 void putBorderProperty(RTFStack& aStates, Id nId, const RTFValue::Pointer_t& pValue);
656 void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue,
657 RTFOverwrite eOverwrite = RTFOverwrite::NO_APPEND);
658 Id getParagraphBorder(sal_uInt32 nIndex);
659 void putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue,
660 RTFOverwrite eOverwrite = RTFOverwrite::YES, bool bAttribute = true);
661 bool eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId);
663 /// Looks up the nParent then the nested nId attribute in rSprms.
664 RTFValue::Pointer_t getNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId);
666 /// Looks up the nParent then the nested nId sprm in rSprms.
667 RTFValue::Pointer_t getNestedSprm(RTFSprms& rSprms, Id nParent, Id nId);
669 /// Checks if rName is contained at least once in rProperties as a key.
670 bool findPropertyName(const std::vector<css::beans::PropertyValue>& rProperties,
671 const OUString& rName);
672 RTFSprms& getLastAttributes(RTFSprms& rSprms, Id nId);
673 OString DTTM22OString(tools::Long nDTTM);
675 /// Implementation of the RTFDocument interface.
676 class RTFDocumentImpl : public RTFDocument, public RTFListener
678 public:
679 using Pointer_t = tools::SvRef<RTFDocumentImpl>;
680 RTFDocumentImpl(css::uno::Reference<css::uno::XComponentContext> const& xContext,
681 css::uno::Reference<css::io::XInputStream> const& xInputStream,
682 css::uno::Reference<css::lang::XComponent> const& xDstDoc,
683 css::uno::Reference<css::frame::XFrame> const& xFrame,
684 css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator,
685 const utl::MediaDescriptor& rMediaDescriptor);
686 ~RTFDocumentImpl() override;
688 // RTFDocument
689 void resolve(Stream& rMapper) override;
691 // RTFListener
692 RTFError dispatchDestination(RTFKeyword nKeyword) override;
693 RTFError dispatchFlag(RTFKeyword nKeyword) override;
694 RTFError dispatchSymbol(RTFKeyword nKeyword) override;
695 RTFError dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam) override;
696 RTFError dispatchValue(RTFKeyword nKeyword, int nParam) override;
697 bool dispatchTableSprmValue(RTFKeyword nKeyword, int nParam);
698 bool dispatchCharacterSprmValue(RTFKeyword nKeyword, int nParam);
699 bool dispatchCharacterAttributeValue(RTFKeyword nKeyword, int nParam);
700 bool dispatchParagraphSprmValue(RTFKeyword nKeyword, int nParam);
701 bool dispatchInfoValue(RTFKeyword nKeyword, int nParam);
702 bool dispatchFrameValue(RTFKeyword nKeyword, int nParam);
703 bool dispatchTableValue(RTFKeyword nKeyword, int nParam);
704 RTFError resolveChars(char ch) override;
705 RTFError pushState() override;
706 RTFError beforePopState(RTFParserState& rState);
707 RTFError popState() override;
708 void afterPopState(RTFParserState& rState);
709 Destination getDestination() override;
710 void setDestination(Destination eDestination) override;
711 RTFInternalState getInternalState() override;
712 void setInternalState(RTFInternalState nInternalState) override;
713 bool getSkipUnknown() override;
714 void setSkipUnknown(bool bSkipUnknown) override;
715 void finishSubstream() override;
716 bool isSubstream() const override;
718 Stream& Mapper() { return *m_pMapperStream; }
719 void setSuperstream(RTFDocumentImpl* pSuperstream);
720 const css::uno::Reference<css::lang::XMultiServiceFactory>& getModelFactory() const
722 return m_xModelFactory;
724 bool isInBackground();
725 void setDestinationText(std::u16string_view rString);
726 /// Resolve a picture: If not inline, then anchored.
727 void resolvePict(bool bInline, css::uno::Reference<css::drawing::XShape> const& rShape);
729 /// If this is the first run of the document, starts the initial paragraph.
730 void checkFirstRun();
731 /// Send NS_ooxml::LN_settings_settings to dmapper.
732 void outputSettingsTable();
733 /// If the initial paragraph is started.
734 bool getFirstRun() const { return m_bFirstRun; }
735 /// If we need to add a dummy paragraph before a section break.
736 void setNeedPar(bool bNeedPar);
737 /// Return the dmapper index of an RTF index for fonts.
738 int getFontIndex(int nIndex);
739 /// Return the name of the font, based on a dmapper index.
740 OUString getFontName(int nIndex);
741 /// Return the style name of an RTF style index.
742 OUString getStyleName(int nIndex);
743 /// Return the style type of an RTF style index.
744 Id getStyleType(int nIndex);
745 /// Return the encoding associated with a font index.
746 rtl_TextEncoding getEncoding(int nFontIndex);
747 /// Get the default parser state.
748 RTFParserState& getDefaultState();
749 oox::GraphicHelper& getGraphicHelper();
750 /// Are we inside the stylesheet table?
751 bool isStyleSheetImport();
752 /// Resets m_aStates.top().aFrame.
753 void resetFrame();
754 /// Buffers properties to be sent later.
755 void bufferProperties(RTFBuffer_t& rBuffer, const RTFValue::Pointer_t& pValue,
756 const tools::SvRef<TableRowBuffer>& pTableProperties);
757 /// implement non-obvious RTF specific style inheritance
758 RTFReferenceTable::Entries_t deduplicateStyleTable();
760 private:
761 SvStream& Strm();
762 Color getColorTable(sal_uInt32 nIndex);
763 writerfilter::Reference<Properties>::Pointer_t createStyleProperties();
764 void resetSprms();
765 void resetAttributes();
766 void resolveSubstream(std::size_t nPos, Id nId);
767 void resolveSubstream(std::size_t nPos, Id nId, OUString const& rIgnoreFirst);
769 void text(OUString& rString);
770 // Sends a single character to dmapper, taking care of buffering.
771 void singleChar(sal_uInt8 nValue, bool bRunProps = false);
772 // Sends run properties to dmapper, taking care of buffering.
773 void runProps();
774 void runBreak();
775 void parBreak();
776 void tableBreak();
777 writerfilter::Reference<Properties>::Pointer_t
778 getProperties(const RTFSprms& rAttributes, RTFSprms const& rSprms, Id nStyleType);
779 void checkNeedPap();
780 void handleFontTableEntry();
781 void sectBreak(bool bFinal = false);
782 void prepareProperties(RTFParserState& rState,
783 writerfilter::Reference<Properties>::Pointer_t& o_rpParagraphProperties,
784 writerfilter::Reference<Properties>::Pointer_t& o_rpFrameProperties,
785 writerfilter::Reference<Properties>::Pointer_t& o_rpTableRowProperties,
786 int nCells, int nCurrentCellX);
787 /// Send the passed properties to dmapper.
788 void sendProperties(writerfilter::Reference<Properties>::Pointer_t const& pParagraphProperties,
789 writerfilter::Reference<Properties>::Pointer_t const& pFrameProperties,
790 writerfilter::Reference<Properties>::Pointer_t const& pTableRowProperties);
791 void replayRowBuffer(RTFBuffer_t& rBuffer, ::std::deque<RTFSprms>& rCellsSrpms,
792 ::std::deque<RTFSprms>& rCellsAttributes, int nCells);
793 void replayBuffer(RTFBuffer_t& rBuffer, RTFSprms* pSprms, RTFSprms const* pAttributes);
794 /// If we have some unicode or hex characters to send.
795 void checkUnicode(bool bUnicode, bool bHex);
796 /// If we need a final section break at the end of the document.
797 void setNeedSect(bool bNeedSect);
798 void resetTableRowProperties();
799 void backupTableRowProperties();
800 void restoreTableRowProperties();
801 /// Turns the destination text into an input stream of the current OLE attributes.
802 RTFError handleEmbeddedObject();
804 css::uno::Reference<css::uno::XComponentContext> const& m_xContext;
805 css::uno::Reference<css::io::XInputStream> const& m_xInputStream;
806 css::uno::Reference<css::lang::XComponent> const& m_xDstDoc;
807 css::uno::Reference<css::frame::XFrame> const& m_xFrame;
808 css::uno::Reference<css::task::XStatusIndicator> const& m_xStatusIndicator;
809 css::uno::Reference<css::lang::XMultiServiceFactory> m_xModelFactory;
810 css::uno::Reference<css::document::XDocumentProperties> m_xDocumentProperties;
811 std::unique_ptr<SvStream> m_pInStream;
812 Stream* m_pMapperStream;
813 tools::SvRef<RTFSdrImport> m_pSdrImport;
814 tools::SvRef<RTFTokenizer> m_pTokenizer;
815 RTFStack m_aStates;
816 /// Read by RTF_PARD.
817 RTFParserState m_aDefaultState;
818 bool m_bSkipUnknown;
819 /// Font index <-> encoding map, *not* part of the parser state
820 std::map<int, rtl_TextEncoding> m_aFontEncodings;
821 /// Font index <-> name map.
822 std::map<int, OUString> m_aFontNames;
823 /// Maps the non-continuous font indexes to the continuous dmapper indexes.
824 std::vector<int> m_aFontIndexes;
825 /// Maps style indexes to style names.
826 std::map<int, OUString> m_aStyleNames;
827 /// Maps style indexes to style types.
828 std::map<int, Id> m_aStyleTypes;
829 /// Color index <-> RGB color value map
830 std::vector<Color> m_aColorTable;
831 /// to start initial paragraph / section after font/style tables
832 bool m_bFirstRun;
833 /// except in the case of tables in initial multicolumn section (global for assertion)
834 bool m_bFirstRunException;
835 /// If paragraph properties should be emitted on next run.
836 bool m_bNeedPap;
837 /// If we need to emit a CR at the end of substream.
838 bool m_bNeedCr;
839 /// Original value of m_bNeedCr -- saved/restored before/after textframes.
840 bool m_bNeedCrOrig;
841 bool m_bNeedPar;
842 /// If set, an empty paragraph will be added at the end of the document.
843 bool m_bNeedFinalPar;
844 /// The list table and list override table combined.
845 RTFSprms m_aListTableSprms;
846 /// Maps between listoverridetable and listtable indexes.
847 std::map<int, int> m_aListOverrideTable;
848 /// Maps listtable indexes to listtable entries.
849 std::map<int, RTFValue::Pointer_t> m_aListTable;
850 /// Index of the current list level in a list table entry.
851 int m_nListLevel = -1;
852 /// Maps List level indexes to removed values in the current list entry.
853 std::map<int, int> m_aInvalidListLevelFirstIndents;
854 /// Maps list table indexes to levels (and their removed values).
855 std::map<int, std::map<int, int>> m_aInvalidListTableFirstIndents;
856 /// The settings table attributes.
857 RTFSprms m_aSettingsTableAttributes;
858 /// The settings table sprms.
859 RTFSprms m_aSettingsTableSprms;
861 std::shared_ptr<oox::GraphicHelper> m_pGraphicHelper;
863 /// cell props buffer for nested tables, reset by \nestrow
864 /// the \nesttableprops is a destination and must follow the
865 /// nested cells, so it should be sufficient to store the
866 /// currently active one, no need for a stack of them
867 int m_nNestedCells;
868 std::deque<RTFSprms> m_aNestedTableCellsSprms;
869 std::deque<RTFSprms> m_aNestedTableCellsAttributes;
870 /// cell props buffer for top-level table, reset by \row
871 int m_nTopLevelCells;
872 std::deque<RTFSprms> m_aTopLevelTableCellsSprms;
873 std::deque<RTFSprms> m_aTopLevelTableCellsAttributes;
874 /// backup of top-level props, to support inheriting cell props
875 int m_nInheritingCells;
876 std::deque<RTFSprms> m_aTableInheritingCellsSprms;
877 std::deque<RTFSprms> m_aTableInheritingCellsAttributes;
879 // Left row margin (for nested and top-level rows)
880 int m_nNestedTRLeft;
881 int m_nTopLevelTRLeft;
883 /// Current cellx value (nested table)
884 int m_nNestedCurrentCellX;
885 /// Current cellx value (top-level table)
886 int m_nTopLevelCurrentCellX;
888 // Backup of what \trowd clears, to work around invalid input.
889 RTFSprms m_aBackupTableRowSprms;
890 RTFSprms m_aBackupTableRowAttributes;
891 int m_nBackupTopLevelCurrentCellX;
893 /// Buffered table cells, till cell definitions are not reached.
894 /// for nested table, one buffer per table level
895 std::deque<RTFBuffer_t> m_aTableBufferStack;
896 /// Buffered superscript, till footnote is reached (or not).
897 RTFBuffer_t m_aSuperBuffer;
899 /// Superstream of this substream.
900 RTFDocumentImpl* m_pSuperstream;
901 /// Type of the stream: header, footer, footnote, etc.
902 Id m_nStreamType;
903 std::queue<std::pair<Id, std::size_t>> m_nHeaderFooterPositions;
904 std::size_t m_nGroupStartPos;
905 /// Ignore the first occurrence of this text.
906 OUString m_aIgnoreFirst;
907 /// Bookmark name <-> index map.
908 std::map<OUString, int> m_aBookmarks;
909 /// Revision index <-> author map.
910 std::map<int, OUString> m_aAuthors;
911 /// Annotation author of the next annotation.
912 OUString m_aAuthor;
913 /// Initials of author of the next annotation.
914 OUString m_aAuthorInitials;
916 RTFSprms m_aFormfieldSprms;
917 RTFSprms m_aFormfieldAttributes;
918 RTFFormFieldType m_nFormFieldType;
920 /// OLE attributes are attributes of the ooxml:OLEObject_OLEObject sprm.
921 RTFSprms m_aOLEAttributes;
922 RTFSprms m_aObjectAttributes;
923 /** If we are in an object group and if the we use its
924 * \objdata element.
925 * (if we don't use the \objdata we use the \result element)*/
926 bool m_bObject;
927 /// If the data for a picture is a binary one, it's stored here.
928 std::shared_ptr<SvStream> m_pBinaryData;
930 RTFReferenceTable::Entries_t m_aFontTableEntries;
931 int m_nCurrentFontIndex;
932 /// Used only during font table parsing till we don't know the font name.
933 int m_nCurrentEncoding;
934 /// Raw default font index, use getFont() on it to get a real one.
935 int m_nDefaultFontIndex;
937 /// To avoid copying entries between DomainMapper instances it is stored as pointer
938 std::shared_ptr<RTFReferenceTable::Entries_t> m_pStyleTableEntries;
939 int m_nCurrentStyleIndex;
940 bool m_bFormField;
941 /// For the INCLUDEPICTURE field's argument.
942 OUString m_aPicturePath;
943 // Unicode characters are collected here so we don't have to send them one by one.
944 OUStringBuffer m_aUnicodeBuffer{ 512 };
945 /// Same for hex characters.
946 OStringBuffer m_aHexBuffer{ 512 };
947 /// Formula import.
948 oox::formulaimport::XmlStreamBuilder m_aMathBuffer;
949 /// Normal text property, that is math italic and math spacing are not applied to the current run.
950 bool m_bMathNor;
951 /// If the next continuous section break should be ignored.
952 bool m_bIgnoreNextContSectBreak;
953 /// clean up a synthetic page break, see RTF_PAGE
954 /// if inactive value is -1, otherwise the RTF_SKB* to restore
955 RTFKeyword m_nResetBreakOnSectBreak;
956 /// If a section break is needed before the end of the doc (false right after a section break).
957 bool m_bNeedSect;
958 /// If aFrame.inFrame() was true in the previous state.
959 bool m_bWasInFrame;
960 /// A picture was seen in the current paragraph.
961 bool m_bHadPicture;
962 /// The document has multiple sections.
963 bool m_bHadSect;
964 /// Max width of the rows in the current table.
965 int m_nCellxMax;
966 /// ID of the next \listlevel picture.
967 int m_nListPictureId;
969 /// New document means not pasting into an existing one.
970 bool m_bIsNewDoc;
971 /// The media descriptor contains e.g. the base URL of the document.
972 const utl::MediaDescriptor& m_rMediaDescriptor;
974 /// Flags for ensuring that only one header and footer is added per section
975 bool m_hasRHeader;
976 bool m_hasFHeader;
977 bool m_hasRFooter;
978 bool m_hasFFooter;
980 /// Are we after a \cell, but before a \row?
981 bool m_bAfterCellBeforeRow;
983 } // namespace writerfilter::rtftok
985 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */