Avoid potential negative array index access to cached text.
[LibreOffice.git] / writerfilter / source / rtftok / rtfdocumentimpl.hxx
blobf05f7d321cdda088a09a88703847d9a037d94255
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_PROPS_CHAR,
77 BUFFER_NESTROW,
78 BUFFER_CELLEND,
79 BUFFER_STARTRUN,
80 BUFFER_TEXT,
81 BUFFER_UTEXT,
82 BUFFER_ENDRUN,
83 BUFFER_PAR,
84 BUFFER_STARTSHAPE,
85 /// Imports a shape.
86 BUFFER_RESOLVESHAPE,
87 BUFFER_ENDSHAPE,
88 BUFFER_RESOLVESUBSTREAM,
89 /// Restores RTFParserState::aPicture.
90 BUFFER_PICTURE
93 /// Form field types
94 enum class RTFFormFieldType
96 NONE,
97 TEXT,
98 CHECKBOX,
99 LIST
102 enum class RTFBmpStyle
104 NONE,
105 PNG,
106 JPEG,
107 DIBITMAP
110 enum class RTFFieldStatus
112 NONE,
113 INSTRUCTION,
114 RESULT
117 /// A buffer storing dmapper calls.
118 using Buf_t = std::tuple<RTFBufferTypes, RTFValue::Pointer_t, tools::SvRef<TableRowBuffer>>;
119 using RTFBuffer_t = std::deque<Buf_t>;
121 /// holds one nested table row
122 class TableRowBuffer : public virtual SvRefBase
124 RTFBuffer_t m_aBuffer;
125 ::std::deque<RTFSprms> m_aCellsSprms;
126 ::std::deque<RTFSprms> m_aCellsAttributes;
127 int m_nCells;
128 writerfilter::Reference<Properties>::Pointer_t m_pParaProperties;
129 writerfilter::Reference<Properties>::Pointer_t m_pFrameProperties;
130 writerfilter::Reference<Properties>::Pointer_t m_pRowProperties;
132 public:
133 TableRowBuffer(RTFBuffer_t aBuffer, std::deque<RTFSprms> aSprms,
134 std::deque<RTFSprms> aAttributes, int const nCells)
135 : m_aBuffer(std::move(aBuffer))
136 , m_aCellsSprms(std::move(aSprms))
137 , m_aCellsAttributes(std::move(aAttributes))
138 , m_nCells(nCells)
142 RTFBuffer_t& GetBuffer() { return m_aBuffer; }
143 std::deque<RTFSprms>& GetCellsSprms() { return m_aCellsSprms; }
144 std::deque<RTFSprms>& GetCellsAttributes() { return m_aCellsAttributes; }
145 int GetCells() const { return m_nCells; }
146 writerfilter::Reference<Properties>::Pointer_t& GetParaProperties()
148 return m_pParaProperties;
150 writerfilter::Reference<Properties>::Pointer_t& GetFrameProperties()
152 return m_pFrameProperties;
154 writerfilter::Reference<Properties>::Pointer_t& GetRowProperties() { return m_pRowProperties; }
157 /// An entry in the color table.
158 class RTFColorTableEntry
160 public:
161 void SetRed(sal_uInt8 nRed)
163 m_bAuto = false;
164 m_nR = nRed;
166 void SetGreen(sal_uInt8 nGreen)
168 m_bAuto = false;
169 m_nG = nGreen;
171 void SetBlue(sal_uInt8 nBlue)
173 m_bAuto = false;
174 m_nB = nBlue;
176 Color GetColor() const { return m_bAuto ? COL_AUTO : Color(m_nR, m_nG, m_nB); }
178 private:
179 bool m_bAuto = true;
180 sal_uInt8 m_nR = 0;
181 sal_uInt8 m_nG = 0;
182 sal_uInt8 m_nB = 0;
185 /// Stores the properties of a shape.
186 class RTFShape : public virtual SvRefBase
188 public:
189 RTFShape();
191 std::vector<std::pair<OUString, OUString>>& getProperties() { return m_aProperties; }
193 const std::vector<std::pair<OUString, OUString>>& getProperties() const
195 return m_aProperties;
198 std::vector<std::pair<OUString, OUString>>& getGroupProperties() { return m_aGroupProperties; }
200 void setLeft(sal_Int32 nLeft) { m_nLeft = nLeft; }
202 sal_Int32 getLeft() const { return m_nLeft; }
204 void setTop(sal_Int32 nTop) { m_nTop = nTop; }
206 sal_Int32 getTop() const { return m_nTop; }
208 void setRight(sal_Int32 nRight) { m_nRight = nRight; }
210 sal_Int32 getRight() const { return m_nRight; }
212 void setBottom(sal_Int32 nBottom) { m_nBottom = nBottom; }
214 sal_Int32 getBottom() const { return m_nBottom; }
216 void setZ(sal_Int32 nZ) { m_oZ = nZ; }
218 bool hasZ() const { return bool(m_oZ); }
220 sal_Int32 getZ() const { return *m_oZ; }
222 void setHoriOrientRelation(sal_Int16 nHoriOrientRelation)
224 m_nHoriOrientRelation = nHoriOrientRelation;
227 sal_Int16 getHoriOrientRelation() const { return m_nHoriOrientRelation; }
229 void setVertOrientRelation(sal_Int16 nVertOrientRelation)
231 m_nVertOrientRelation = nVertOrientRelation;
234 sal_Int16 getVertOrientRelation() const { return m_nVertOrientRelation; }
236 void setHoriOrientRelationToken(sal_uInt32 nHoriOrientRelationToken)
238 m_nHoriOrientRelationToken = nHoriOrientRelationToken;
241 sal_uInt32 getHoriOrientRelationToken() const { return m_nHoriOrientRelationToken; }
243 void setVertOrientRelationToken(sal_uInt32 nVertOrientRelationToken)
245 m_nVertOrientRelationToken = nVertOrientRelationToken;
248 sal_uInt32 getVertOrientRelationToken() const { return m_nVertOrientRelationToken; }
250 void setWrap(css::text::WrapTextMode nWrap) { m_nWrap = nWrap; }
252 css::text::WrapTextMode getWrap() const { return m_nWrap; }
254 void setInBackground(bool bInBackground) { m_bInBackground = bInBackground; }
256 bool getInBackground() const { return m_bInBackground; }
258 RTFSprms& getWrapPolygonSprms() { return m_aWrapPolygonSprms; }
260 RTFSprms& getAnchorAttributes() { return m_aAnchorAttributes; }
262 std::pair<Id, RTFValue::Pointer_t>& getWrapSprm() { return m_aWrapSprm; }
264 private:
265 std::vector<std::pair<OUString, OUString>> m_aProperties; ///< Properties of a single shape.
266 std::vector<std::pair<OUString, OUString>>
267 m_aGroupProperties; ///< Properties applied on the groupshape.
268 sal_Int32 m_nLeft = 0;
269 sal_Int32 m_nTop = 0;
270 sal_Int32 m_nRight = 0;
271 sal_Int32 m_nBottom = 0;
272 std::optional<sal_Int32> m_oZ; ///< Z-Order of the shape.
273 sal_Int16 m_nHoriOrientRelation
274 = 0; ///< Horizontal text::RelOrientation for drawinglayer shapes.
275 sal_Int16 m_nVertOrientRelation = 0; ///< Vertical text::RelOrientation for drawinglayer shapes.
276 sal_uInt32 m_nHoriOrientRelationToken = 0; ///< Horizontal dmapper token for Writer pictures.
277 sal_uInt32 m_nVertOrientRelationToken = 0; ///< Vertical dmapper token for Writer pictures.
278 css::text::WrapTextMode m_nWrap = css::text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE;
279 /// If shape is below text (true) or text is below shape (false).
280 bool m_bInBackground = false;
281 /// Wrap polygon, written by RTFSdrImport::resolve(), read by RTFDocumentImpl::resolvePict().
282 RTFSprms m_aWrapPolygonSprms;
283 /// Anchor attributes like wrap distance, written by RTFSdrImport::resolve(), read by RTFDocumentImpl::resolvePict().
284 RTFSprms m_aAnchorAttributes;
285 /// Wrap type, written by RTFDocumentImpl::popState(), read by RTFDocumentImpl::resolvePict().
286 std::pair<Id, RTFValue::Pointer_t> m_aWrapSprm{ 0, nullptr };
289 /// Stores the properties of a drawing object.
290 class RTFDrawingObject : public RTFShape
292 public:
293 RTFDrawingObject();
295 void setShape(const css::uno::Reference<css::drawing::XShape>& xShape) { m_xShape = xShape; }
296 const css::uno::Reference<css::drawing::XShape>& getShape() const { return m_xShape; }
297 void setPropertySet(const css::uno::Reference<css::beans::XPropertySet>& xPropertySet)
299 m_xPropertySet = xPropertySet;
301 const css::uno::Reference<css::beans::XPropertySet>& getPropertySet() const
303 return m_xPropertySet;
305 std::vector<css::beans::PropertyValue>& getPendingProperties() { return m_aPendingProperties; }
306 void setLineColorR(sal_uInt8 nLineColorR) { m_nLineColorR = nLineColorR; }
307 sal_uInt8 getLineColorR() const { return m_nLineColorR; }
308 void setLineColorG(sal_uInt8 nLineColorG) { m_nLineColorG = nLineColorG; }
309 sal_uInt8 getLineColorG() const { return m_nLineColorG; }
310 void setLineColorB(sal_uInt8 nLineColorB) { m_nLineColorB = nLineColorB; }
311 sal_uInt8 getLineColorB() const { return m_nLineColorB; }
312 void setHasLineColor(bool bHasLineColor) { m_bHasLineColor = bHasLineColor; }
313 bool getHasLineColor() const { return m_bHasLineColor; }
314 void setFillColorR(sal_uInt8 nFillColorR) { m_nFillColorR = nFillColorR; }
315 sal_uInt8 getFillColorR() const { return m_nFillColorR; }
316 void setFillColorG(sal_uInt8 nFillColorG) { m_nFillColorG = nFillColorG; }
317 sal_uInt8 getFillColorG() const { return m_nFillColorG; }
318 void setFillColorB(sal_uInt8 nFillColorB) { m_nFillColorB = nFillColorB; }
319 sal_uInt8 getFillColorB() const { return m_nFillColorB; }
320 void setHasFillColor(bool bHasFillColor) { m_bHasFillColor = bHasFillColor; }
321 bool getHasFillColor() const { return m_bHasFillColor; }
322 void setDhgt(sal_Int32 nDhgt) { m_nDhgt = nDhgt; }
323 sal_Int32 getDhgt() const { return m_nDhgt; }
324 void setFLine(sal_Int32 nFLine) { m_nFLine = nFLine; }
325 sal_Int32 getFLine() const { return m_nFLine; }
326 void setPolyLineCount(sal_Int32 nPolyLineCount) { m_nPolyLineCount = nPolyLineCount; }
327 sal_Int32 getPolyLineCount() const { return m_nPolyLineCount; }
328 std::vector<css::awt::Point>& getPolyLinePoints() { return m_aPolyLinePoints; }
329 void setHadShapeText(bool bHadShapeText) { m_bHadShapeText = bHadShapeText; }
330 bool getHadShapeText() const { return m_bHadShapeText; }
332 private:
333 css::uno::Reference<css::drawing::XShape> m_xShape;
334 css::uno::Reference<css::beans::XPropertySet> m_xPropertySet;
335 std::vector<css::beans::PropertyValue> m_aPendingProperties;
336 sal_uInt8 m_nLineColorR = 0;
337 sal_uInt8 m_nLineColorG = 0;
338 sal_uInt8 m_nLineColorB = 0;
339 bool m_bHasLineColor = false;
340 sal_uInt8 m_nFillColorR = 0;
341 sal_uInt8 m_nFillColorG = 0;
342 sal_uInt8 m_nFillColorB = 0;
343 bool m_bHasFillColor = false;
344 sal_Int32 m_nDhgt = 0;
345 sal_Int32 m_nFLine = -1;
346 sal_Int32 m_nPolyLineCount = 0;
347 std::vector<css::awt::Point> m_aPolyLinePoints;
348 bool m_bHadShapeText = false;
351 /// Stores the properties of a picture.
352 class RTFPicture : public virtual SvRefBase
354 public:
355 sal_Int32 nWidth = 0;
356 sal_Int32 nHeight = 0;
357 sal_Int32 nGoalWidth = 0;
358 sal_Int32 nGoalHeight = 0;
359 sal_uInt16 nScaleX = 100;
360 sal_uInt16 nScaleY = 100;
361 short nCropT = 0;
362 short nCropB = 0;
363 short nCropL = 0;
364 short nCropR = 0;
365 sal_uInt16 eWMetafile = 0;
366 RTFBmpStyle eStyle = RTFBmpStyle::NONE;
369 /// Stores the properties of a frame
370 class RTFFrame
372 private:
373 RTFDocumentImpl* m_pDocumentImpl;
374 sal_Int32 m_nX, m_nY, m_nW, m_nH;
375 sal_Int32 m_nHoriPadding, m_nVertPadding;
376 sal_Int32 m_nHoriAlign, m_nHoriAnchor, m_nVertAlign, m_nVertAnchor;
377 Id m_nHRule;
378 std::optional<Id> m_oWrap;
380 public:
381 explicit RTFFrame(RTFParserState* pParserState);
383 /// Convert the stored properties to Sprms
384 RTFSprms getSprms();
385 /// Store a property
386 void setSprm(Id nId, Id nValue);
387 /// If we got tokens indicating we're in a frame.
388 bool hasProperties() 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; }
526 OUString getDocVar() { return m_aDocVar; }
527 void appendDocVar(OUString& aDocVar) { m_aDocVar += aDocVar; };
528 OUString getDocVarName() { return m_aDocVarName; }
529 void setDocVarName(OUString& aDocVarName) { m_aDocVarName = aDocVarName; }
530 void clearDocVarName() { m_aDocVarName = ""; }
532 private:
533 RTFDocumentImpl* m_pDocumentImpl;
534 RTFInternalState m_nInternalState;
535 Destination m_eDestination;
536 RTFFieldStatus m_eFieldStatus;
537 bool m_bFieldLocked;
538 RTFBorderState m_nBorderState;
539 // font table, stylesheet table
540 RTFSprms m_aTableSprms;
541 RTFSprms m_aTableAttributes;
542 // reset by plain
543 RTFSprms m_aCharacterSprms;
544 RTFSprms m_aCharacterAttributes;
545 // reset by pard
546 RTFSprms m_aParagraphSprms;
547 RTFSprms m_aParagraphAttributes;
548 // reset by sectd
549 RTFSprms m_aSectionSprms;
550 RTFSprms m_aSectionAttributes;
551 // reset by trowd
552 RTFSprms m_aTableRowSprms;
553 RTFSprms m_aTableRowAttributes;
554 // reset by cellx
555 RTFSprms m_aTableCellSprms;
556 RTFSprms m_aTableCellAttributes;
557 // reset by tx
558 RTFSprms m_aTabAttributes;
560 RTFColorTableEntry m_aCurrentColor;
562 rtl_TextEncoding m_nCurrentEncoding;
564 /// Current \uc value.
565 int m_nUc;
566 /// Characters to skip, set to nUc by \u.
567 int m_nCharsToSkip;
568 /// Characters to read, once in binary mode.
569 int m_nBinaryToRead;
571 /// Next list level index to use when parsing list table.
572 int m_nListLevelNum;
573 /// List level entries, which will form a list entry later.
574 RTFSprms m_aListLevelEntries;
575 /// List of character positions in leveltext to replace.
576 std::vector<sal_Int32> m_aLevelNumbers;
577 /// If aLevelNumbers should be read at all.
578 bool m_bLevelNumbersValid;
580 RTFPicture m_aPicture;
581 RTFShape m_aShape;
582 RTFDrawingObject m_aDrawingObject;
583 RTFFrame m_aFrame;
585 RunType m_eRunType;
587 // Info group.
588 sal_Int16 m_nYear;
589 sal_uInt16 m_nMonth;
590 sal_uInt16 m_nDay;
591 sal_uInt16 m_nHour;
592 sal_uInt16 m_nMinute;
594 /// Text from special destinations.
595 OUStringBuffer m_aDestinationText{ 512 };
596 /// point to the buffer of the current destination
597 OUStringBuffer* m_pCurrentDestinationText;
599 /// Index of the current style.
600 int m_nCurrentStyleIndex;
601 /// Index of the current character style.
602 int m_nCurrentCharacterStyleIndex;
603 /// Current listid, points to a listtable entry.
604 int m_nCurrentListIndex = -1;
605 /// Current ls, points to a listoverridetable entry.
606 int m_nCurrentListOverrideIndex = -1;
608 /// Points to the active buffer, if there is one.
609 RTFBuffer_t* m_pCurrentBuffer;
611 /// If we're inside a \listpicture group.
612 bool m_bInListpicture;
614 /// If we're inside a \background group.
615 bool m_bInBackground;
617 bool m_bHadShapeText;
618 bool m_bInShapeGroup; ///< If we're inside a \shpgrp group.
619 bool m_bInShape; ///< If we're inside a \shp group.
620 bool m_bCreatedShapeGroup; ///< A GroupShape was created and pushed to the parent stack.
621 bool m_bStartedTrackchange; ///< Track change is started, need to end it before popping.
623 /// User-defined property: key name.
624 OUString m_aPropName;
625 /// User-defined property: value type.
626 css::uno::Type m_aPropType;
628 /// Width of invisible cell at the end of the row.
629 int m_nTableRowWidthAfter;
631 /// For importing document variables which are not referenced in the document
632 OUString m_aDocVar;
633 OUString m_aDocVarName;
636 /// An RTF stack is similar to std::stack, except that it has an operator[].
637 struct RTFStack
639 private:
640 std::deque<RTFParserState> m_Impl;
642 public:
643 RTFParserState& top()
645 if (m_Impl.empty())
646 throw css::io::WrongFormatException(
647 "Parser state is empty! Invalid usage of destination braces in RTF?", nullptr);
648 return m_Impl.back();
650 void pop()
652 if (m_Impl.empty())
653 throw css::io::WrongFormatException(
654 "Parser state is empty! Invalid usage of destination braces in RTF?", nullptr);
655 return m_Impl.pop_back();
657 void push(RTFParserState const& rState) { return m_Impl.push_back(rState); }
658 bool empty() const { return m_Impl.empty(); }
659 size_t size() const { return m_Impl.size(); }
660 const RTFParserState& operator[](size_t nIndex) const { return m_Impl[nIndex]; }
661 RTFParserState& operator[](size_t nIndex) { return m_Impl[nIndex]; }
664 void putBorderProperty(RTFStack& aStates, Id nId, const RTFValue::Pointer_t& pValue);
665 void putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue,
666 RTFOverwrite eOverwrite = RTFOverwrite::NO_APPEND);
667 Id getParagraphBorder(sal_uInt32 nIndex);
668 void putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Pointer_t& pValue,
669 RTFOverwrite eOverwrite = RTFOverwrite::YES, bool bAttribute = true);
670 bool eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId);
672 /// Looks up the nParent then the nested nId attribute in rSprms.
673 RTFValue::Pointer_t getNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId);
675 /// Looks up the nParent then the nested nId sprm in rSprms.
676 RTFValue::Pointer_t getNestedSprm(RTFSprms& rSprms, Id nParent, Id nId);
678 /// Checks if rName is contained at least once in rProperties as a key.
679 bool findPropertyName(const std::vector<css::beans::PropertyValue>& rProperties,
680 const OUString& rName);
681 RTFSprms& getLastAttributes(RTFSprms& rSprms, Id nId);
682 OString DTTM22OString(tools::Long nDTTM);
684 /// Implementation of the RTFDocument interface.
685 class RTFDocumentImpl : public RTFDocument, public RTFListener
687 public:
688 using Pointer_t = tools::SvRef<RTFDocumentImpl>;
689 RTFDocumentImpl(css::uno::Reference<css::uno::XComponentContext> const& xContext,
690 css::uno::Reference<css::io::XInputStream> const& xInputStream,
691 css::uno::Reference<css::lang::XComponent> const& xDstDoc,
692 css::uno::Reference<css::frame::XFrame> const& xFrame,
693 css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator,
694 const utl::MediaDescriptor& rMediaDescriptor);
695 ~RTFDocumentImpl() override;
697 // RTFDocument
698 void resolve(Stream& rMapper) override;
700 // RTFListener
701 RTFError dispatchDestination(RTFKeyword nKeyword) override;
702 RTFError dispatchFlag(RTFKeyword nKeyword) override;
703 /// Dispatches flags related to Positioned Wrapped Tables.
704 bool dispatchFloatingTableFlag(RTFKeyword nKeyword);
705 RTFError dispatchSymbol(RTFKeyword nKeyword) override;
706 RTFError dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam) override;
707 RTFError dispatchValue(RTFKeyword nKeyword, int nParam) override;
708 bool dispatchTableSprmValue(RTFKeyword nKeyword, int nParam);
709 bool dispatchCharacterSprmValue(RTFKeyword nKeyword, int nParam);
710 bool dispatchCharacterAttributeValue(RTFKeyword nKeyword, int nParam);
711 bool dispatchParagraphSprmValue(RTFKeyword nKeyword, int nParam);
712 bool dispatchInfoValue(RTFKeyword nKeyword, int nParam);
713 bool dispatchFrameValue(RTFKeyword nKeyword, int nParam);
714 bool dispatchTableValue(RTFKeyword nKeyword, int nParam);
715 RTFError resolveChars(char ch) override;
716 RTFError pushState() override;
717 RTFError beforePopState(RTFParserState& rState);
718 RTFError popState() override;
719 void afterPopState(RTFParserState& rState);
720 Destination getDestination() override;
721 void setDestination(Destination eDestination) override;
722 RTFInternalState getInternalState() override;
723 void setInternalState(RTFInternalState nInternalState) override;
724 bool getSkipUnknown() override;
725 void setSkipUnknown(bool bSkipUnknown) override;
726 void finishSubstream() override;
727 bool isSubstream() const override;
729 Stream& Mapper() { return *m_pMapperStream; }
730 void setSuperstream(RTFDocumentImpl* pSuperstream);
731 const css::uno::Reference<css::lang::XMultiServiceFactory>& getModelFactory() const
733 return m_xModelFactory;
735 bool isInBackground();
736 void setDestinationText(std::u16string_view rString);
737 /// Resolve a picture: If not inline, then anchored.
738 void resolvePict(bool bInline, css::uno::Reference<css::drawing::XShape> const& rShape);
740 /// If this is the first run of the document, starts the initial paragraph.
741 void checkFirstRun();
742 /// Send NS_ooxml::LN_settings_settings to dmapper.
743 void outputSettingsTable();
744 /// If the initial paragraph is started.
745 bool getFirstRun() const { return m_bFirstRun; }
746 /// If we need to add a dummy paragraph before a section break.
747 void setNeedPar(bool bNeedPar);
748 /// Return the dmapper index of an RTF index for fonts.
749 int getFontIndex(int nIndex);
750 /// Return the name of the font, based on a dmapper index.
751 OUString getFontName(int nIndex);
752 /// Return the style name of an RTF style index.
753 OUString getStyleName(int nIndex);
754 /// Return the style type of an RTF style index.
755 Id getStyleType(int nIndex);
756 /// Return the encoding associated with a font index.
757 rtl_TextEncoding getEncoding(int nFontIndex);
758 /// Get the default parser state.
759 RTFParserState& getDefaultState();
760 oox::GraphicHelper& getGraphicHelper();
761 /// Are we inside the stylesheet table?
762 bool isStyleSheetImport();
763 /// Resets m_aStates.top().aFrame.
764 void resetFrame();
765 /// Buffers properties to be sent later.
766 void bufferProperties(RTFBuffer_t& rBuffer, const RTFValue::Pointer_t& pValue,
767 const tools::SvRef<TableRowBuffer>& pTableProperties, Id nStyleType = 0);
768 /// implement non-obvious RTF specific style inheritance
769 RTFReferenceTable::Entries_t deduplicateStyleTable();
771 private:
772 SvStream& Strm();
773 Color getColorTable(sal_uInt32 nIndex);
774 writerfilter::Reference<Properties>::Pointer_t createStyleProperties();
775 void resetSprms();
776 void resetAttributes();
777 void resolveSubstream(std::size_t nPos, Id nId);
778 void resolveSubstream(std::size_t nPos, Id nId, OUString const& rIgnoreFirst);
780 void text(OUString& rString);
781 // Sends a single character to dmapper, taking care of buffering.
782 void singleChar(sal_uInt8 nValue, bool bRunProps = false);
783 // Sends run properties to dmapper, taking care of buffering.
784 void runProps();
785 void runBreak();
786 void parBreak();
787 void tableBreak();
788 writerfilter::Reference<Properties>::Pointer_t
789 getProperties(const RTFSprms& rAttributes, RTFSprms const& rSprms, Id nStyleType);
790 void checkNeedPap();
791 void handleFontTableEntry();
792 void sectBreak(bool bFinal = false);
793 void prepareProperties(RTFParserState& rState,
794 writerfilter::Reference<Properties>::Pointer_t& o_rpParagraphProperties,
795 writerfilter::Reference<Properties>::Pointer_t& o_rpFrameProperties,
796 writerfilter::Reference<Properties>::Pointer_t& o_rpTableRowProperties,
797 int nCells, int nCurrentCellX);
798 /// Send the passed properties to dmapper.
799 void sendProperties(writerfilter::Reference<Properties>::Pointer_t const& pParagraphProperties,
800 writerfilter::Reference<Properties>::Pointer_t const& pFrameProperties,
801 writerfilter::Reference<Properties>::Pointer_t const& pTableRowProperties);
802 void replayRowBuffer(RTFBuffer_t& rBuffer, ::std::deque<RTFSprms>& rCellsSprms,
803 ::std::deque<RTFSprms>& rCellsAttributes, int nCells);
804 void replayBuffer(RTFBuffer_t& rBuffer, RTFSprms* pSprms, RTFSprms const* pAttributes);
805 /// If we have some unicode or hex characters to send.
806 void checkUnicode(bool bUnicode, bool bHex);
807 /// If we need a final section break at the end of the document.
808 void setNeedSect(bool bNeedSect);
809 void resetTableRowProperties();
810 void backupTableRowProperties();
811 void restoreTableRowProperties();
812 /// Turns the destination text into an input stream of the current OLE attributes.
813 RTFError handleEmbeddedObject();
815 css::uno::Reference<css::uno::XComponentContext> const& m_xContext;
816 css::uno::Reference<css::io::XInputStream> const& m_xInputStream;
817 css::uno::Reference<css::lang::XComponent> const& m_xDstDoc;
818 css::uno::Reference<css::frame::XFrame> const& m_xFrame;
819 css::uno::Reference<css::task::XStatusIndicator> const& m_xStatusIndicator;
820 css::uno::Reference<css::lang::XMultiServiceFactory> m_xModelFactory;
821 css::uno::Reference<css::document::XDocumentProperties> m_xDocumentProperties;
822 std::unique_ptr<SvStream> m_pInStream;
823 Stream* m_pMapperStream;
824 tools::SvRef<RTFSdrImport> m_pSdrImport;
825 tools::SvRef<RTFTokenizer> m_pTokenizer;
826 RTFStack m_aStates;
827 /// Read by RTF_PARD.
828 RTFParserState m_aDefaultState;
829 bool m_bSkipUnknown;
830 /// Font index <-> encoding map, *not* part of the parser state
831 std::map<int, rtl_TextEncoding> m_aFontEncodings;
832 /// Font index <-> name map.
833 std::map<int, OUString> m_aFontNames;
834 /// Maps the non-continuous font indexes to the continuous dmapper indexes.
835 std::vector<int> m_aFontIndexes;
836 /// Maps style indexes to style names.
837 std::map<int, OUString> m_aStyleNames;
838 /// Maps style indexes to style types.
839 std::map<int, Id> m_aStyleTypes;
840 /// Color index <-> RGB color value map
841 std::vector<Color> m_aColorTable;
842 /// to start initial paragraph / section after font/style tables
843 bool m_bFirstRun;
844 /// except in the case of tables in initial multicolumn section (global for assertion)
845 bool m_bFirstRunException;
846 /// If paragraph properties should be emitted on next run.
847 bool m_bNeedPap;
848 /// If we need to emit a CR at the end of substream.
849 bool m_bNeedCr;
850 /// Original value of m_bNeedCr -- saved/restored before/after textframes.
851 bool m_bNeedCrOrig;
852 bool m_bNeedPar;
853 /// If set, an empty paragraph will be added at the end of the document.
854 bool m_bNeedFinalPar;
855 /// a synthetic \par was dispatched at the end of the current section
856 bool m_bParAtEndOfSection = false;
857 /// The list table and list override table combined.
858 RTFSprms m_aListTableSprms;
859 /// Maps between listoverridetable and listtable indexes.
860 std::map<int, int> m_aListOverrideTable;
861 /// Maps listtable indexes to listtable entries.
862 std::map<int, RTFValue::Pointer_t> m_aListTable;
863 /// Index of the current list level in a list table entry.
864 int m_nListLevel = -1;
865 /// Maps List level indexes to removed values in the current list entry.
866 std::map<int, int> m_aInvalidListLevelFirstIndents;
867 /// Maps list table indexes to levels (and their removed values).
868 std::map<int, std::map<int, int>> m_aInvalidListTableFirstIndents;
869 /// The settings table attributes.
870 RTFSprms m_aSettingsTableAttributes;
871 /// The settings table sprms.
872 RTFSprms m_aSettingsTableSprms;
874 std::shared_ptr<oox::GraphicHelper> m_pGraphicHelper;
876 /// cell props buffer for nested tables, reset by \nestrow
877 /// the \nesttableprops is a destination and must follow the
878 /// nested cells, so it should be sufficient to store the
879 /// currently active one, no need for a stack of them
880 int m_nNestedCells;
881 std::deque<RTFSprms> m_aNestedTableCellsSprms;
882 std::deque<RTFSprms> m_aNestedTableCellsAttributes;
883 /// cell props buffer for top-level table, reset by \row
884 int m_nTopLevelCells;
885 std::deque<RTFSprms> m_aTopLevelTableCellsSprms;
886 std::deque<RTFSprms> m_aTopLevelTableCellsAttributes;
887 /// backup of top-level props, to support inheriting cell props
888 int m_nInheritingCells;
889 std::deque<RTFSprms> m_aTableInheritingCellsSprms;
890 std::deque<RTFSprms> m_aTableInheritingCellsAttributes;
892 // Left row margin (for nested and top-level rows)
893 int m_nNestedTRLeft;
894 int m_nTopLevelTRLeft;
896 /// Current cellx value (nested table)
897 int m_nNestedCurrentCellX;
898 /// Current cellx value (top-level table)
899 int m_nTopLevelCurrentCellX;
901 // Backup of what \trowd clears, to work around invalid input.
902 RTFSprms m_aBackupTableRowSprms;
903 RTFSprms m_aBackupTableRowAttributes;
904 int m_nBackupTopLevelCurrentCellX;
906 /// Buffered table cells, till cell definitions are not reached.
907 /// for nested table, one buffer per table level
908 std::deque<RTFBuffer_t> m_aTableBufferStack;
909 /// Buffered superscript, till footnote is reached (or not).
910 RTFBuffer_t m_aSuperBuffer;
912 /// Superstream of this substream.
913 RTFDocumentImpl* m_pSuperstream;
914 /// Type of the stream: header, footer, footnote, etc.
915 Id m_nStreamType;
916 std::queue<std::pair<Id, std::size_t>> m_nHeaderFooterPositions;
917 std::size_t m_nGroupStartPos;
918 /// Ignore the first occurrence of this text.
919 OUString m_aIgnoreFirst;
920 /// Bookmark name <-> index map.
921 std::map<OUString, int> m_aBookmarks;
922 /// Revision index <-> author map.
923 std::map<int, OUString> m_aAuthors;
924 /// Annotation author of the next annotation.
925 OUString m_aAuthor;
926 /// Initials of author of the next annotation.
927 OUString m_aAuthorInitials;
929 RTFSprms m_aFormfieldSprms;
930 RTFSprms m_aFormfieldAttributes;
931 RTFFormFieldType m_nFormFieldType;
933 /// OLE attributes are attributes of the ooxml:OLEObject_OLEObject sprm.
934 RTFSprms m_aOLEAttributes;
935 RTFSprms m_aObjectAttributes;
936 /** If we are in an object group and if the we use its
937 * \objdata element.
938 * (if we don't use the \objdata we use the \result element)*/
939 bool m_bObject;
940 /// If the data for a picture is a binary one, it's stored here.
941 std::shared_ptr<SvStream> m_pBinaryData;
943 RTFReferenceTable::Entries_t m_aFontTableEntries;
944 int m_nCurrentFontIndex;
945 /// Used only during font table parsing till we don't know the font name.
946 int m_nCurrentEncoding;
947 /// Raw default font index, use getFont() on it to get a real one.
948 int m_nDefaultFontIndex;
950 /// To avoid copying entries between DomainMapper instances it is stored as pointer
951 std::shared_ptr<RTFReferenceTable::Entries_t> m_pStyleTableEntries;
952 int m_nCurrentStyleIndex;
953 bool m_bFormField;
954 /// For the INCLUDEPICTURE field's argument.
955 OUString m_aPicturePath;
956 // Unicode characters are collected here so we don't have to send them one by one.
957 OUStringBuffer m_aUnicodeBuffer{ 512 };
958 /// Same for hex characters.
959 OStringBuffer m_aHexBuffer{ 512 };
960 /// Formula import.
961 oox::formulaimport::XmlStreamBuilder m_aMathBuffer;
962 /// Normal text property, that is math italic and math spacing are not applied to the current run.
963 bool m_bMathNor;
964 /// If the next continuous section break should be ignored.
965 bool m_bIgnoreNextContSectBreak;
966 /// clean up a synthetic page break, see RTF_PAGE
967 /// if inactive value is -1, otherwise the RTF_SKB* to restore
968 RTFKeyword m_nResetBreakOnSectBreak;
969 /// If a section break is needed before the end of the doc (false right after a section break).
970 bool m_bNeedSect;
971 /// If aFrame.hasProperties() was true in the previous state.
972 bool m_bWasInFrame;
973 /// A picture was seen in the current paragraph.
974 bool m_bHadPicture;
975 /// The document has multiple sections.
976 bool m_bHadSect;
977 /// Max width of the rows in the current table.
978 int m_nCellxMax;
979 /// ID of the next \listlevel picture.
980 int m_nListPictureId;
982 /// New document means not pasting into an existing one.
983 bool m_bIsNewDoc;
984 /// The media descriptor contains e.g. the base URL of the document.
985 const utl::MediaDescriptor& m_rMediaDescriptor;
987 /// Flags for ensuring that only one header and footer is added per section
988 bool m_hasRHeader;
989 bool m_hasFHeader;
990 bool m_hasRFooter;
991 bool m_hasFFooter;
993 } // namespace writerfilter::rtftok
995 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */