1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_STARMATH_INC_NODE_HXX
21 #define INCLUDED_STARMATH_INC_NODE_HXX
29 #include <o3tl/typed_flags_set.hxx>
36 enum class FontAttribute
{
44 template<> struct typed_flags
<FontAttribute
> : is_typed_flags
<FontAttribute
, 0x0003> {};
48 enum class FontSizeType
{
56 // flags to interdict respective status changes
57 enum class FontChangeMask
{
70 template<> struct typed_flags
<FontChangeMask
> : is_typed_flags
<FontChangeMask
, 0x007f> {};
77 class SmStructureNode
;
79 typedef std::deque
<std::unique_ptr
<SmNode
>> SmNodeStack
;
80 typedef std::vector
< SmNode
* > SmNodeArray
;
82 template < typename T
>
83 T
* popOrZero(std::deque
<std::unique_ptr
<T
>> & rStack
)
87 std::unique_ptr
<T
> pTmp(std::move(rStack
.front()));
89 return pTmp
.release();
92 enum SmScaleMode
{ SCALE_NONE
, SCALE_WIDTH
, SCALE_HEIGHT
};
96 /* 0*/ NTABLE
, NBRACE
, NBRACEBODY
, NOPER
, NALIGN
,
97 /* 5*/ NATTRIBUT
, NFONT
, NUNHOR
, NBINHOR
, NBINVER
,
98 /*10*/ NBINDIAGONAL
, NSUBSUP
, NMATRIX
, NPLACE
, NTEXT
,
99 /*15*/ NSPECIAL
, NGLYPH_SPECIAL
, NMATH
, NBLANK
, NERROR
,
100 /*20*/ NLINE
, NEXPRESSION
, NPOLYLINE
, NROOT
, NROOTSYMBOL
,
101 /*25*/ NRECTANGLE
, NVERTICAL_BRACE
, NMATHIDENT
105 class SmNode
: public SmRect
111 SmScaleMode meScaleMode
;
112 RectHorAlign meRectHorAlign
;
113 FontChangeMask mnFlags
;
114 FontAttribute mnAttributes
;
117 // index in accessible text; -1 if not (yet) applicable
118 sal_Int32 mnAccIndex
;
121 SmNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
);
124 SmNode(const SmNode
&) = delete;
125 SmNode
& operator=(const SmNode
&) = delete;
130 * Returns true if this is a instance of SmVisibleNode's subclass, false otherwise.
132 virtual bool IsVisible() const = 0;
134 virtual sal_uInt16
GetNumSubNodes() const = 0;
135 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
) = 0;
136 const SmNode
* GetSubNode(sal_uInt16 nIndex
) const
138 return const_cast<SmNode
*>(this)->GetSubNode(nIndex
);
141 virtual const SmNode
* GetLeftMost() const;
143 FontChangeMask
&Flags() { return mnFlags
; }
144 FontAttribute
&Attributes() { return mnAttributes
; }
146 bool IsPhantom() const { return mbIsPhantom
; }
147 void SetPhantom(bool bIsPhantom
);
148 void SetColor(const Color
&rColor
);
150 void SetAttribut(FontAttribute nAttrib
);
151 void ClearAttribut(FontAttribute nAttrib
);
153 const SmFace
& GetFont() const { return maFace
; };
154 SmFace
& GetFont() { return maFace
; };
156 void SetFont(const SmFace
&rFace
);
157 void SetFontSize(const Fraction
&rRelSize
, FontSizeType nType
);
158 void SetSize(const Fraction
&rScale
);
160 /** Prepare preliminary settings about font and text
161 * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
163 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
);
164 void PrepareAttributes();
166 void SetRectHorAlign(RectHorAlign eHorAlign
, bool bApplyToSubTree
= true );
167 RectHorAlign
GetRectHorAlign() const { return meRectHorAlign
; }
169 const SmRect
& GetRect() const { return *this; }
171 void Move(const Point
&rPosition
);
172 void MoveTo(const Point
&rPosition
) { Move(rPosition
- GetTopLeft()); }
173 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) = 0;
174 virtual void CreateTextFromNode(OUString
&rText
);
176 virtual void GetAccessibleText( OUStringBuffer
&rText
) const = 0;
177 sal_Int32
GetAccessibleIndex() const { return mnAccIndex
; }
178 void SetAccessibleIndex(sal_Int32 nAccIndex
) { mnAccIndex
= nAccIndex
; }
179 const SmNode
* FindNodeWithAccessibleIndex(sal_Int32 nAccIndex
) const;
181 sal_uInt16
GetRow() const { return sal::static_int_cast
<sal_uInt16
>(maNodeToken
.nRow
); }
182 sal_uInt16
GetColumn() const { return sal::static_int_cast
<sal_uInt16
>(maNodeToken
.nCol
); }
184 SmScaleMode
GetScaleMode() const { return meScaleMode
; }
185 void SetScaleMode(SmScaleMode eMode
) { meScaleMode
= eMode
; }
187 virtual void AdaptToX(OutputDevice
&rDev
, sal_uLong nWidth
);
188 virtual void AdaptToY(OutputDevice
&rDev
, sal_uLong nHeight
);
190 SmNodeType
GetType() const { return meType
; }
191 const SmToken
& GetToken() const { return maNodeToken
; }
193 const SmNode
* FindTokenAt(sal_uInt16 nRow
, sal_uInt16 nCol
) const;
194 const SmNode
* FindRectClosestTo(const Point
&rPoint
) const;
197 * Calls the method for this class on the visitor
199 virtual void Accept(SmVisitor
* pVisitor
) = 0;
201 /** True if this node is selected */
202 bool IsSelected() const {return mbIsSelected
;}
203 void SetSelected(bool Selected
) {mbIsSelected
= Selected
;}
205 /** Get the parent node of this node */
206 SmStructureNode
* GetParent(){ return mpParentNode
; }
207 const SmStructureNode
* GetParent() const { return mpParentNode
; }
208 /** Set the parent node */
209 void SetParent(SmStructureNode
* parent
){
210 mpParentNode
= parent
;
213 /** Set the token for this node */
214 void SetToken(SmToken
& token
){
219 SmStructureNode
* mpParentNode
;
223 /** Abstract baseclass for all composite node
225 * Subclasses of this class can have subnodes. Nodes that doesn't derivate from
226 * this class does not have subnodes.
228 class SmStructureNode
: public SmNode
230 SmNodeArray aSubNodes
;
233 SmStructureNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
, size_t nSize
= 0)
234 : SmNode(eNodeType
, rNodeToken
)
239 virtual ~SmStructureNode() override
;
241 virtual bool IsVisible() const override
;
243 virtual sal_uInt16
GetNumSubNodes() const override
;
245 using SmNode::GetSubNode
;
246 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
) override
;
247 void SetSubNodes(SmNode
*pFirst
, SmNode
*pSecond
, SmNode
*pThird
= nullptr);
248 void SetSubNodes(const SmNodeArray
&rNodeArray
);
250 virtual void GetAccessibleText( OUStringBuffer
&rText
) const override
;
252 SmNodeArray::iterator
begin() {return aSubNodes
.begin();}
253 SmNodeArray::iterator
end() {return aSubNodes
.end();}
254 SmNodeArray::reverse_iterator
rbegin() {return aSubNodes
.rbegin();}
255 SmNodeArray::reverse_iterator
rend() {return aSubNodes
.rend();}
257 /** Get the index of a child node
259 * Returns -1, if pSubNode isn't a subnode of this.
261 int IndexOfSubNode(SmNode
* pSubNode
)
263 sal_uInt16 nSize
= GetNumSubNodes();
264 for(sal_uInt16 i
= 0; i
< nSize
; i
++)
265 if(pSubNode
== GetSubNode(i
))
270 void SetSubNode(size_t nIndex
, SmNode
* pNode
)
272 size_t size
= aSubNodes
.size();
275 //Resize subnodes array
276 aSubNodes
.resize(nIndex
+ 1);
277 //Set new slots to NULL
278 for (size_t i
= size
; i
< nIndex
+1; i
++)
279 aSubNodes
[i
] = nullptr;
281 aSubNodes
[nIndex
] = pNode
;
286 /** Sets parent on children of this node */
287 void ClaimPaternity();
291 /** Abstract base class for all visible node
293 * Nodes that doesn't derivate from this class doesn't draw anything, but their
296 class SmVisibleNode
: public SmNode
299 SmVisibleNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
300 : SmNode(eNodeType
, rNodeToken
)
305 virtual bool IsVisible() const override
;
306 virtual sal_uInt16
GetNumSubNodes() const override
;
307 using SmNode::GetSubNode
;
308 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
) override
;
312 class SmGraphicNode
: public SmVisibleNode
315 SmGraphicNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
316 : SmVisibleNode(eNodeType
, rNodeToken
)
321 virtual void GetAccessibleText( OUStringBuffer
&rText
) const override
;
325 /** Draws a rectangle
327 * Used for drawing the line in the OVER and OVERSTRIKE commands.
329 class SmRectangleNode
: public SmGraphicNode
334 explicit SmRectangleNode(const SmToken
&rNodeToken
)
335 : SmGraphicNode(NRECTANGLE
, rNodeToken
)
338 virtual void AdaptToX(OutputDevice
&rDev
, sal_uLong nWidth
) override
;
339 virtual void AdaptToY(OutputDevice
&rDev
, sal_uLong nHeight
) override
;
341 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
343 void CreateTextFromNode(OUString
&rText
) override
;
344 void Accept(SmVisitor
* pVisitor
) override
;
348 /** Polygon line node
350 * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
352 class SmPolyLineNode
: public SmGraphicNode
354 tools::Polygon aPoly
;
359 explicit SmPolyLineNode(const SmToken
&rNodeToken
);
361 long GetWidth() const { return nWidth
; }
362 tools::Polygon
&GetPolygon() { return aPoly
; }
364 virtual void AdaptToX(OutputDevice
&rDev
, sal_uLong nWidth
) override
;
365 virtual void AdaptToY(OutputDevice
&rDev
, sal_uLong nHeight
) override
;
367 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
369 void Accept(SmVisitor
* pVisitor
) override
;
375 * @remarks This class also serves as baseclass for all nodes that contains text.
377 class SmTextNode
: public SmVisibleNode
380 sal_uInt16 nFontDesc
;
381 /** Index within text where the selection starts
382 * @remarks Only valid if SmNode::IsSelected() is true
384 sal_Int32 nSelectionStart
;
385 /** Index within text where the selection ends
386 * @remarks Only valid if SmNode::IsSelected() is true
388 sal_Int32 nSelectionEnd
;
391 SmTextNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
, sal_uInt16 nFontDescP
);
394 SmTextNode(const SmToken
&rNodeToken
, sal_uInt16 nFontDescP
);
396 sal_uInt16
GetFontDesc() const { return nFontDesc
; }
397 void SetText(const OUString
&rText
) { aText
= rText
; }
398 const OUString
& GetText() const { return aText
; }
399 /** Change the text of this node, including the underlying token */
400 void ChangeText(const OUString
&rText
) {
402 SmToken token
= GetToken();
404 SetToken(token
); //TODO: Merge this with AdjustFontDesc for better performance
407 /** Try to guess the correct FontDesc, used during visual editing */
408 void AdjustFontDesc();
409 /** Index within GetText() where the selection starts
410 * @remarks Only valid of SmNode::IsSelected() is true
412 sal_Int32
GetSelectionStart() const {return nSelectionStart
;}
413 /** Index within GetText() where the selection end
414 * @remarks Only valid of SmNode::IsSelected() is true
416 sal_Int32
GetSelectionEnd() const {return nSelectionEnd
;}
417 /** Set the index within GetText() where the selection starts */
418 void SetSelectionStart(sal_Int32 index
) {nSelectionStart
= index
;}
419 /** Set the index within GetText() where the selection end */
420 void SetSelectionEnd(sal_Int32 index
) {nSelectionEnd
= index
;}
422 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
423 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
424 virtual void CreateTextFromNode(OUString
&rText
) override
;
426 virtual void GetAccessibleText( OUStringBuffer
&rText
) const override
;
427 void Accept(SmVisitor
* pVisitor
) override
;
429 Converts the character from StarMath's private area symbols to a matching Unicode
430 character, if necessary. To be used when converting GetText() to a normal text.
432 static sal_Unicode
ConvertSymbolToUnicode(sal_Unicode nIn
);
436 /** Special node for user defined characters
438 * Node used for pre- and user-defined characters from:
439 * officecfg/registry/data/org/openoffice/Office/Math.xcu
441 * This is just single characters, I think.
443 class SmSpecialNode
: public SmTextNode
445 bool bIsFromGreekSymbolSet
;
448 SmSpecialNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
, sal_uInt16 _nFontDesc
);
451 explicit SmSpecialNode(const SmToken
&rNodeToken
);
453 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
454 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
456 void Accept(SmVisitor
* pVisitor
) override
;
460 /** Glyph node for custom operators
462 * This node is used with commands: oper, uoper and boper.
463 * E.g. in "A boper op B", "op" will be an instance of SmGlyphSpecialNode.
464 * "boper" simply interprets "op", the following token, as an binary operator.
465 * The command "uoper" interprets the following token as unary operator.
466 * For these commands an instance of SmGlyphSpecialNode is used for the
467 * operator token, following the command.
469 class SmGlyphSpecialNode
: public SmSpecialNode
472 explicit SmGlyphSpecialNode(const SmToken
&rNodeToken
)
473 : SmSpecialNode(NGLYPH_SPECIAL
, rNodeToken
, FNT_MATH
)
476 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
477 void Accept(SmVisitor
* pVisitor
) override
;
483 * Use for math symbols such as plus, minus and integral in the INT command.
485 class SmMathSymbolNode
: public SmSpecialNode
488 SmMathSymbolNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
489 : SmSpecialNode(eNodeType
, rNodeToken
, FNT_MATH
)
491 sal_Unicode cChar
= GetToken().cMathChar
;
492 if (sal_Unicode('\0') != cChar
)
493 SetText(OUString(cChar
));
497 explicit SmMathSymbolNode(const SmToken
&rNodeToken
);
499 virtual void AdaptToX(OutputDevice
&rDev
, sal_uLong nWidth
) override
;
500 virtual void AdaptToY(OutputDevice
&rDev
, sal_uLong nHeight
) override
;
502 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
503 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
504 void CreateTextFromNode(OUString
&rText
) override
;
505 void Accept(SmVisitor
* pVisitor
) override
;
511 * This behaves essentially the same as SmMathSymbolNode and is only used to
512 * represent math symbols that should be exported as <mi> elements rather than
515 class SmMathIdentifierNode
: public SmMathSymbolNode
518 explicit SmMathIdentifierNode(const SmToken
&rNodeToken
)
519 : SmMathSymbolNode(NMATHIDENT
, rNodeToken
) {}
525 * Root symbol node used by SmRootNode to create the root symbol, in front of
526 * the line with the line above. I don't think this node should be used for
529 class SmRootSymbolNode
: public SmMathSymbolNode
531 sal_uLong nBodyWidth
; // width of body (argument) of root sign
534 explicit SmRootSymbolNode(const SmToken
&rNodeToken
)
535 : SmMathSymbolNode(NROOTSYMBOL
, rNodeToken
)
540 sal_uLong
GetBodyWidth() const {return nBodyWidth
;};
541 virtual void AdaptToX(OutputDevice
&rDev
, sal_uLong nHeight
) override
;
542 virtual void AdaptToY(OutputDevice
&rDev
, sal_uLong nHeight
) override
;
544 void Accept(SmVisitor
* pVisitor
) override
;
550 * Used to create the <?> command, that denotes place where something can be
552 * It is drawn as a square with a shadow.
554 class SmPlaceNode
: public SmMathSymbolNode
557 explicit SmPlaceNode(const SmToken
&rNodeToken
)
558 : SmMathSymbolNode(NPLACE
, rNodeToken
)
561 SmPlaceNode() : SmMathSymbolNode(NPLACE
, SmToken(TPLACE
, MS_PLACE
, "<?>")) {};
563 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
564 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
565 void Accept(SmVisitor
* pVisitor
) override
;
569 /** Error node, for parsing errors
571 * This node is used for parsing errors and draws an questionmark turned upside
572 * down (inverted question mark).
574 class SmErrorNode
: public SmMathSymbolNode
577 explicit SmErrorNode(const SmToken
&rNodeToken
)
578 : SmMathSymbolNode(NERROR
, rNodeToken
)
580 SetText(OUString(MS_ERROR
));
583 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
584 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
585 void Accept(SmVisitor
* pVisitor
) override
;
591 * This is the root node for the formula tree. This node is also used for the
592 * STACK and BINOM commands. When used for root node, its
593 * children are instances of SmLineNode, and in some obscure cases the a child
594 * can be an instance of SmExpressionNode, mainly when errors occur.
596 class SmTableNode
: public SmStructureNode
598 long nFormulaBaseline
;
600 explicit SmTableNode(const SmToken
&rNodeToken
)
601 : SmStructureNode(NTABLE
, rNodeToken
)
602 , nFormulaBaseline(0)
606 virtual const SmNode
* GetLeftMost() const override
;
608 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
609 long GetFormulaBaseline() const;
611 void Accept(SmVisitor
* pVisitor
) override
;
617 * Used as child of SmTableNode when the SmTableNode is the root node of the
620 class SmLineNode
: public SmStructureNode
622 bool bUseExtraSpaces
;
625 SmLineNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
626 : SmStructureNode(eNodeType
, rNodeToken
)
628 bUseExtraSpaces
= true;
632 explicit SmLineNode(const SmToken
&rNodeToken
)
633 : SmStructureNode(NLINE
, rNodeToken
)
635 bUseExtraSpaces
= true;
638 void SetUseExtraSpaces(bool bVal
) { bUseExtraSpaces
= bVal
; }
639 bool IsUseExtraSpaces() const { return bUseExtraSpaces
; };
641 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
642 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
643 void Accept(SmVisitor
* pVisitor
) override
;
649 * Used whenever you have an expression such as "A OVER {B + C}", here there is
650 * an expression node that allows "B + C" to be the denominator of the
651 * SmBinVerNode, that the OVER command creates.
653 class SmExpressionNode
: public SmLineNode
656 explicit SmExpressionNode(const SmToken
&rNodeToken
)
657 : SmLineNode(NEXPRESSION
, rNodeToken
)
660 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
661 void CreateTextFromNode(OUString
&rText
) override
;
662 void Accept(SmVisitor
* pVisitor
) override
;
666 /** Unary horizontal node
668 * The same as SmBinHorNode except this is for unary operators.
670 class SmUnHorNode
: public SmStructureNode
673 explicit SmUnHorNode(const SmToken
&rNodeToken
)
674 : SmStructureNode(NUNHOR
, rNodeToken
, 2)
678 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
679 void Accept(SmVisitor
* pVisitor
) override
;
685 * Used for create square roots and other roots, example:
686 * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
689 * 0: Argument (optional)<BR>
690 * 1: Symbol (instance of SmRootSymbolNode)<BR>
692 * Where argument is optional and may be NULL.
694 class SmRootNode
: public SmStructureNode
697 static void GetHeightVerOffset(const SmRect
&rRect
,
698 long &rHeight
, long &rVerOffset
);
699 static Point
GetExtraPos(const SmRect
&rRootSymbol
, const SmRect
&rExtra
);
702 explicit SmRootNode(const SmToken
&rNodeToken
)
703 : SmStructureNode(NROOT
, rNodeToken
, 3)
707 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
708 void CreateTextFromNode(OUString
&rText
) override
;
709 void Accept(SmVisitor
* pVisitor
) override
;
712 const SmNode
* Argument() const;
713 SmRootSymbolNode
* Symbol();
714 const SmRootSymbolNode
* Symbol() const;
716 const SmNode
* Body() const;
720 /** Binary horizontal node
722 * This node is used for binary operators. In a formula such as "A + B".
725 * 0: Left operand<BR>
726 * 1: Binary operator<BR>
727 * 2: Right operand<BR>
729 * None of the children may be NULL.
731 class SmBinHorNode
: public SmStructureNode
734 explicit SmBinHorNode(const SmToken
&rNodeToken
)
735 : SmStructureNode(NBINHOR
, rNodeToken
, 3)
739 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
740 void Accept(SmVisitor
* pVisitor
) override
;
743 const SmNode
* Symbol() const;
744 SmNode
* LeftOperand();
745 const SmNode
* LeftOperand() const;
746 SmNode
* RightOperand();
747 const SmNode
* RightOperand() const;
751 /** Binary horizontal node
753 * This node is used for creating the OVER command, consider the formula:
754 * "numerator OVER denominator", which looks like
755 * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
759 * 1: Line (instance of SmRectangleNode)<BR>
761 * None of the children may be NULL.
763 class SmBinVerNode
: public SmStructureNode
766 explicit SmBinVerNode(const SmToken
&rNodeToken
)
767 : SmStructureNode(NBINVER
, rNodeToken
, 3)
771 virtual const SmNode
* GetLeftMost() const override
;
773 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
774 void CreateTextFromNode(OUString
&rText
) override
;
775 void Accept(SmVisitor
* pVisitor
) override
;
779 /** Binary diagonal node
781 * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
784 * 0: Left operand<BR>
785 * 1: right operand<BR>
786 * 2: Line (instance of SmPolyLineNode).<BR>
787 * None of the children may be NULL.
789 class SmBinDiagonalNode
: public SmStructureNode
793 void GetOperPosSize(Point
&rPos
, Size
&rSize
,
794 const Point
&rDiagPoint
, double fAngleDeg
) const;
797 explicit SmBinDiagonalNode(const SmToken
&rNodeToken
);
799 bool IsAscending() const { return bAscending
; }
800 void SetAscending(bool bVal
) { bAscending
= bVal
; }
802 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
803 void Accept(SmVisitor
* pVisitor
) override
;
807 /** Enum used to index sub-/supscripts in the 'aSubNodes' array
810 * See graphic for positions at char:
825 { CSUB
, CSUP
, RSUB
, RSUP
, LSUB
, LSUP
828 /** numbers of entries in the above enum (that is: the number of possible
831 #define SUBSUP_NUM_ENTRIES 6
833 /** Super- and subscript node
835 * Used for creating super- and subscripts for commands such as:
836 * "^", "_", "lsup", "lsub", "csup" and "csub".
837 * Example: "A^2" which looks like: \f$ A^2 \f$
839 * This node is also used for creating limits on SmOperNode, when
840 * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
842 * Children of this node can be enumerated using the SmSubSup enum.
843 * Please note that children may be NULL, except for the body.
844 * It is recommended that you access children using GetBody() and
847 class SmSubSupNode
: public SmStructureNode
852 explicit SmSubSupNode(const SmToken
&rNodeToken
)
853 : SmStructureNode(NSUBSUP
, rNodeToken
, 1 + SUBSUP_NUM_ENTRIES
)
858 /** Get body (Not NULL) */
859 SmNode
* GetBody() { return GetSubNode(0); }
860 /** Get body (Not NULL) */
861 const SmNode
* GetBody() const
863 return const_cast<SmSubSupNode
*>(this)->GetBody();
866 void SetUseLimits(bool bVal
) { bUseLimits
= bVal
; }
867 bool IsUseLimits() const { return bUseLimits
; };
869 /** Get super- or subscript
870 * @remarks this method may return NULL.
872 SmNode
* GetSubSup(SmSubSup eSubSup
) { return GetSubNode( sal::static_int_cast
< sal_uInt16
>(1 + eSubSup
) ); };
873 const SmNode
* GetSubSup(SmSubSup eSubSup
) const { return const_cast< SmSubSupNode
* >( this )->GetSubSup( eSubSup
); }
876 void SetBody(SmNode
* pBody
) { SetSubNode(0, pBody
); }
877 void SetSubSup(SmSubSup eSubSup
, SmNode
* pScript
) { SetSubNode( 1 + eSubSup
, pScript
); }
879 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
880 void CreateTextFromNode(OUString
&rText
) override
;
881 void Accept(SmVisitor
* pVisitor
) override
;
886 /** Node for brace construction
888 * Used for "lbrace [body] rbrace" and similar constructions.
889 * Should look like \f$ \{\mbox{[body]}\} \f$
892 * 0: Opening brace<BR>
893 * 1: Body (usually SmBracebodyNode)<BR>
894 * 2: Closing brace<BR>
895 * None of the children can be NULL.
897 * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
899 class SmBraceNode
: public SmStructureNode
902 explicit SmBraceNode(const SmToken
&rNodeToken
)
903 : SmStructureNode(NBRACE
, rNodeToken
, 3)
907 SmMathSymbolNode
* OpeningBrace();
908 const SmMathSymbolNode
* OpeningBrace() const;
910 const SmNode
* Body() const;
911 SmMathSymbolNode
* ClosingBrace();
912 const SmMathSymbolNode
* ClosingBrace() const;
914 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
915 void CreateTextFromNode(OUString
&rText
) override
;
916 void Accept(SmVisitor
* pVisitor
) override
;
920 /** Body of an SmBraceNode
922 * This usually only has one child an SmExpressionNode, however, it can also
923 * have other children.
924 * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
925 * \f$ \{\mbox{[body1] | [body2]}\} \f$.
926 * In this case SmBracebodyNode will have three children, "[body1]", "|" and
929 class SmBracebodyNode
: public SmStructureNode
934 explicit inline SmBracebodyNode(const SmToken
&rNodeToken
);
936 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
937 long GetBodyHeight() const { return nBodyHeight
; }
938 void Accept(SmVisitor
* pVisitor
) override
;
942 inline SmBracebodyNode::SmBracebodyNode(const SmToken
&rNodeToken
) :
943 SmStructureNode(NBRACEBODY
, rNodeToken
)
949 /** Node for vertical brace construction
951 * Used to implement commands "[body] underbrace [script]" and
952 * "[body] overbrace [script]".
953 * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
959 * (None of these children are optional, e.g. they must all be not NULL).
961 class SmVerticalBraceNode
: public SmStructureNode
964 explicit inline SmVerticalBraceNode(const SmToken
&rNodeToken
);
967 const SmNode
* Body() const;
968 SmMathSymbolNode
* Brace();
969 const SmMathSymbolNode
* Brace() const;
971 const SmNode
* Script() const;
973 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
974 void Accept(SmVisitor
* pVisitor
) override
;
978 inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken
&rNodeToken
)
979 : SmStructureNode(NVERTICAL_BRACE
, rNodeToken
, 3)
986 * Used for commands like SUM, INT and similar.
989 * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
991 * None of the children may be NULL.
994 class SmOperNode
: public SmStructureNode
997 explicit SmOperNode(const SmToken
&rNodeToken
)
998 : SmStructureNode(NOPER
, rNodeToken
, 2)
1002 SmNode
* GetSymbol();
1003 const SmNode
* GetSymbol() const
1005 return const_cast<SmOperNode
*>(this)->GetSymbol();
1008 long CalcSymbolHeight(const SmNode
&rSymbol
, const SmFormat
&rFormat
) const;
1010 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
1011 void Accept(SmVisitor
* pVisitor
) override
;
1015 /** Node used for alignment
1017 * This node has exactly one child at index 0.
1019 class SmAlignNode
: public SmStructureNode
1022 explicit SmAlignNode(const SmToken
&rNodeToken
)
1023 : SmStructureNode(NALIGN
, rNodeToken
)
1026 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
1027 void Accept(SmVisitor
* pVisitor
) override
;
1033 * Used to give an attribute to another node. Used for commands such as:
1034 * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHAT and WIDETILDE.
1039 * None of these may be NULL.
1041 class SmAttributNode
: public SmStructureNode
1044 explicit SmAttributNode(const SmToken
&rNodeToken
)
1045 : SmStructureNode(NATTRIBUT
, rNodeToken
, 2)
1048 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
1049 void CreateTextFromNode(OUString
&rText
) override
;
1050 void Accept(SmVisitor
* pVisitor
) override
;
1052 SmNode
* Attribute();
1053 const SmNode
* Attribute() const;
1055 const SmNode
* Body() const;
1061 * Used to change the font of its children.
1063 class SmFontNode
: public SmStructureNode
1065 FontSizeType nSizeType
;
1069 explicit SmFontNode(const SmToken
&rNodeToken
)
1070 : SmStructureNode(NFONT
, rNodeToken
)
1072 nSizeType
= FontSizeType::MULTIPLY
;
1073 aFontSize
= Fraction(1L);
1076 void SetSizeParameter(const Fraction
&rValue
, FontSizeType nType
);
1077 const Fraction
& GetSizeParameter() const {return aFontSize
;}
1078 const FontSizeType
& GetSizeType() const {return nSizeType
;}
1080 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
1081 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
1082 void CreateTextFromNode(OUString
&rText
) override
;
1083 void Accept(SmVisitor
* pVisitor
) override
;
1089 * Used to implement the MATRIX command, example:
1090 * "matrix{ 1 # 2 ## 3 # 4}".
1092 class SmMatrixNode
: public SmStructureNode
1094 sal_uInt16 mnNumRows
,
1098 explicit SmMatrixNode(const SmToken
&rNodeToken
)
1099 : SmStructureNode(NMATRIX
, rNodeToken
)
1105 sal_uInt16
GetNumRows() const {return mnNumRows
;}
1106 sal_uInt16
GetNumCols() const {return mnNumCols
;}
1107 void SetRowCol(sal_uInt16 nMatrixRows
, sal_uInt16 nMatrixCols
);
1109 virtual const SmNode
* GetLeftMost() const override
;
1111 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
1112 void CreateTextFromNode(OUString
&rText
) override
;
1113 void Accept(SmVisitor
* pVisitor
) override
;
1117 /** Node for whitespace
1119 * Used to implement the commands "~" and "`". This node is just a blank space.
1121 class SmBlankNode
: public SmGraphicNode
1126 explicit SmBlankNode(const SmToken
&rNodeToken
)
1127 : SmGraphicNode(NBLANK
, rNodeToken
)
1132 void IncreaseBy(const SmToken
&rToken
);
1133 void Clear() { mnNum
= 0; }
1134 sal_uInt16
GetBlankNum() const { return mnNum
; }
1135 void SetBlankNum(sal_uInt16 nNumber
) { mnNum
= nNumber
; }
1137 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) override
;
1138 virtual void Arrange(OutputDevice
&rDev
, const SmFormat
&rFormat
) override
;
1139 void Accept(SmVisitor
* pVisitor
) override
;
1140 virtual void CreateTextFromNode(OUString
&rText
) override
;
1144 inline SmNode
* SmRootNode::Argument()
1146 assert( GetNumSubNodes() == 3 );
1147 return GetSubNode( 0 );
1149 inline const SmNode
* SmRootNode::Argument() const
1151 return const_cast< SmRootNode
* >( this )->Argument();
1153 inline SmRootSymbolNode
* SmRootNode::Symbol()
1155 assert( GetNumSubNodes() == 3 );
1156 assert( GetSubNode( 1 )->GetType() == NROOTSYMBOL
);
1157 return static_cast< SmRootSymbolNode
* >( GetSubNode( 1 ));
1159 inline const SmRootSymbolNode
* SmRootNode::Symbol() const
1161 return const_cast< SmRootNode
* >( this )->Symbol();
1163 inline SmNode
* SmRootNode::Body()
1165 assert( GetNumSubNodes() == 3 );
1166 return GetSubNode( 2 );
1168 inline const SmNode
* SmRootNode::Body() const
1170 return const_cast< SmRootNode
* >( this )->Body();
1174 inline SmNode
* SmBinHorNode::Symbol()
1176 assert( GetNumSubNodes() == 3 );
1177 return GetSubNode( 1 );
1179 inline const SmNode
* SmBinHorNode::Symbol() const
1181 return const_cast< SmBinHorNode
* >( this )->Symbol();
1183 inline SmNode
* SmBinHorNode::LeftOperand()
1185 assert( GetNumSubNodes() == 3 );
1186 return GetSubNode( 0 );
1188 inline const SmNode
* SmBinHorNode::LeftOperand() const
1190 return const_cast< SmBinHorNode
* >( this )->LeftOperand();
1192 inline SmNode
* SmBinHorNode::RightOperand()
1194 assert( GetNumSubNodes() == 3 );
1195 return GetSubNode( 2 );
1197 inline const SmNode
* SmBinHorNode::RightOperand() const
1199 return const_cast< SmBinHorNode
* >( this )->RightOperand();
1202 inline SmNode
* SmAttributNode::Attribute()
1204 assert( GetNumSubNodes() == 2 );
1205 return GetSubNode( 0 );
1207 inline const SmNode
* SmAttributNode::Attribute() const
1209 return const_cast< SmAttributNode
* >( this )->Attribute();
1211 inline SmNode
* SmAttributNode::Body()
1213 assert( GetNumSubNodes() == 2 );
1214 return GetSubNode( 1 );
1216 inline const SmNode
* SmAttributNode::Body() const
1218 return const_cast< SmAttributNode
* >( this )->Body();
1221 inline SmMathSymbolNode
* SmBraceNode::OpeningBrace()
1223 assert( GetNumSubNodes() == 3 );
1224 assert( GetSubNode( 0 )->GetType() == NMATH
);
1225 return static_cast< SmMathSymbolNode
* >( GetSubNode( 0 ));
1227 inline const SmMathSymbolNode
* SmBraceNode::OpeningBrace() const
1229 return const_cast< SmBraceNode
* >( this )->OpeningBrace();
1231 inline SmNode
* SmBraceNode::Body()
1233 assert( GetNumSubNodes() == 3 );
1234 return GetSubNode( 1 );
1236 inline const SmNode
* SmBraceNode::Body() const
1238 return const_cast< SmBraceNode
* >( this )->Body();
1240 inline SmMathSymbolNode
* SmBraceNode::ClosingBrace()
1242 assert( GetNumSubNodes() == 3 );
1243 assert( GetSubNode( 2 )->GetType() == NMATH
);
1244 return static_cast< SmMathSymbolNode
* >( GetSubNode( 2 ));
1246 inline const SmMathSymbolNode
* SmBraceNode::ClosingBrace() const
1248 return const_cast< SmBraceNode
* >( this )->ClosingBrace();
1251 inline SmNode
* SmVerticalBraceNode::Body()
1253 assert( GetNumSubNodes() == 3 );
1254 return GetSubNode( 0 );
1256 inline const SmNode
* SmVerticalBraceNode::Body() const
1258 return const_cast< SmVerticalBraceNode
* >( this )->Body();
1260 inline SmMathSymbolNode
* SmVerticalBraceNode::Brace()
1262 assert( GetNumSubNodes() == 3 );
1263 assert( GetSubNode( 1 )->GetType() == NMATH
);
1264 return static_cast< SmMathSymbolNode
* >( GetSubNode( 1 ));
1266 inline const SmMathSymbolNode
* SmVerticalBraceNode::Brace() const
1268 return const_cast< SmVerticalBraceNode
* >( this )->Brace();
1270 inline SmNode
* SmVerticalBraceNode::Script()
1272 assert( GetNumSubNodes() == 3 );
1273 return GetSubNode( 2 );
1275 inline const SmNode
* SmVerticalBraceNode::Script() const
1277 return const_cast< SmVerticalBraceNode
* >( this )->Script();
1283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */