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
31 #include <boost/ptr_container/ptr_deque.hpp>
34 #define ATTR_BOLD 0x0001
35 #define ATTR_ITALIC 0x0002
38 enum class FontSizeType
{
46 // flags to interdict respective status changes
47 #define FLG_FONT 0x0001
48 #define FLG_SIZE 0x0002
49 #define FLG_BOLD 0x0004
50 #define FLG_ITALIC 0x0008
51 #define FLG_COLOR 0x0010
52 #define FLG_VISIBLE 0x0020
53 #define FLG_HORALIGN 0x0040
56 extern SmFormat
*pActiveFormat
;
61 class SmStructureNode
;
63 typedef std::shared_ptr
<SmNode
> SmNodePointer
;
64 typedef boost::ptr_deque
<SmNode
> SmNodeStack
;
65 typedef std::vector
< SmNode
* > SmNodeArray
;
66 typedef std::vector
< SmStructureNode
* > SmStructureNodeArray
;
68 template < typename T
>
69 T
* popOrZero( boost::ptr_deque
<T
> & rStack
)
73 auto pTmp
= rStack
.pop_front();
74 return pTmp
.release();
77 enum SmScaleMode
{ SCALE_NONE
, SCALE_WIDTH
, SCALE_HEIGHT
};
81 /* 0*/ NTABLE
, NBRACE
, NBRACEBODY
, NOPER
, NALIGN
,
82 /* 5*/ NATTRIBUT
, NFONT
, NUNHOR
, NBINHOR
, NBINVER
,
83 /*10*/ NBINDIAGONAL
, NSUBSUP
, NMATRIX
, NPLACE
, NTEXT
,
84 /*15*/ NSPECIAL
, NGLYPH_SPECIAL
, NMATH
, NBLANK
, NERROR
,
85 /*20*/ NLINE
, NEXPRESSION
, NPOLYLINE
, NROOT
, NROOTSYMBOL
,
86 /*25*/ NRECTANGLE
, NVERTICAL_BRACE
, NMATHIDENT
, NDYNINT
, NDYNINTSYMBOL
93 class SmNode
: public SmRect
99 SmScaleMode eScaleMode
;
100 RectHorAlign eRectHorAlign
;
109 SmNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
);
111 // index in accessible text -1 if not (yet) applicable
117 virtual bool IsVisible() const;
119 virtual sal_uInt16
GetNumSubNodes() const;
120 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
);
121 const SmNode
* GetSubNode(sal_uInt16 nIndex
) const
123 return const_cast<SmNode
*>(this)->GetSubNode(nIndex
);
126 virtual SmNode
* GetLeftMost();
127 const SmNode
* GetLeftMost() const
129 return const_cast<SmNode
*>(this)->GetLeftMost();
132 sal_uInt16
& Flags() { return nFlags
; }
133 sal_uInt16
& Attributes() { return nAttributes
; }
135 bool IsDebug() const { return bIsDebug
; }
136 bool IsPhantom() const { return bIsPhantom
; }
137 void SetPhantom(bool bIsPhantom
);
138 void SetColor(const Color
&rColor
);
140 void SetAttribut(sal_uInt16 nAttrib
);
141 void ClearAttribut(sal_uInt16 nAttrib
);
143 const SmFace
& GetFont() const { return aFace
; };
144 SmFace
& GetFont() { return aFace
; };
146 void SetFont(const SmFace
&rFace
);
147 void SetFontSize(const Fraction
&rRelSize
, FontSizeType nType
);
148 void SetSize(const Fraction
&rScale
);
150 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
);
151 void PrepareAttributes();
153 sal_uInt16
FindIndex() const;
156 void ToggleDebug() const;
159 void SetRectHorAlign(RectHorAlign eHorAlign
, bool bApplyToSubTree
= true );
160 RectHorAlign
GetRectHorAlign() const { return eRectHorAlign
; }
162 const SmRect
& GetRect() const { return *this; }
163 SmRect
& GetRect() { return *this; }
165 void Move(const Point
&rPosition
);
166 void MoveTo(const Point
&rPosition
) { Move(rPosition
- GetTopLeft()); }
167 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
);
168 virtual void CreateTextFromNode(OUString
&rText
);
170 virtual void GetAccessibleText( OUStringBuffer
&rText
) const;
171 sal_Int32
GetAccessibleIndex() const { return nAccIndex
; }
172 const SmNode
* FindNodeWithAccessibleIndex(sal_Int32 nAccIndex
) const;
174 sal_uInt16
GetRow() const { return (sal_uInt16
)aNodeToken
.nRow
; }
175 sal_uInt16
GetColumn() const { return (sal_uInt16
)aNodeToken
.nCol
; }
177 SmScaleMode
GetScaleMode() const { return eScaleMode
; }
178 void SetScaleMode(SmScaleMode eMode
) { eScaleMode
= eMode
; }
180 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
);
181 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
);
183 SmNodeType
GetType() const { return eType
; }
184 const SmToken
& GetToken() const { return aNodeToken
; }
186 const SmNode
* FindTokenAt(sal_uInt16 nRow
, sal_uInt16 nCol
) const;
187 const SmNode
* FindRectClosestTo(const Point
&rPoint
) const;
189 virtual long GetFormulaBaseline() const;
192 * Calls the method for this class on the visitor
194 virtual void Accept(SmVisitor
* pVisitor
);
196 /** True if this node is selected */
197 bool IsSelected() const {return bIsSelected
;}
198 void SetSelected(bool Selected
= true) {bIsSelected
= Selected
;}
200 #ifdef DEBUG_ENABLE_DUMPASDOT
201 /** The tree as dot graph for graphviz, usable for debugging
202 * Convert the output to a image using $ dot graph.gv -Tpng > graph.png
204 inline void DumpAsDot(std::ostream
&out
, OUString
* label
= NULL
) const{
206 DumpAsDot(out
, label
, -1, id
, -1);
208 #endif /* DEBUG_ENABLE_DUMPASDOT */
210 /** Get the parent node of this node */
211 SmStructureNode
* GetParent(){ return aParentNode
; }
212 const SmStructureNode
* GetParent() const { return aParentNode
; }
213 /** Set the parent node */
214 void SetParent(SmStructureNode
* parent
){
215 aParentNode
= parent
;
218 /** Get the index of a child node
220 * Returns -1, if pSubNode isn't a subnode of this.
222 int IndexOfSubNode(SmNode
* pSubNode
){
223 sal_uInt16 nSize
= GetNumSubNodes();
224 for(sal_uInt16 i
= 0; i
< nSize
; i
++)
225 if(pSubNode
== GetSubNode(i
))
229 /** Set the token for this node */
230 void SetToken(SmToken
& token
){
234 /** Sets parent on children of this node */
235 inline void ClaimPaternity();
237 SmStructureNode
* aParentNode
;
238 void DumpAsDot(std::ostream
&out
, OUString
* label
, int number
, int& id
, int parent
) const;
243 /** A simple auxiliary iterator class for SmNode
245 * Example of iteration over children of pMyNode:
247 * //Node to iterate over:
248 * SmNode* pMyNode = 0;// A pointer from somewhere
250 * SmNodeIterator it(pMyNode);
253 * it->SetSelected(true);
257 class SmNodeIterator
{
259 SmNodeIterator(SmNode
* node
, bool bReverse
= false){
261 nSize
= pNode
->GetNumSubNodes();
264 bIsReverse
= bReverse
;
266 /** Get the subnode or NULL if none */
268 while(!bIsReverse
&& nIndex
< nSize
){
269 if(NULL
!= (pChildNode
= pNode
->GetSubNode(nIndex
++)))
272 while(bIsReverse
&& nSize
> 0){
273 if(NULL
!= (pChildNode
= pNode
->GetSubNode((nSize
--)-1)))
279 /** Get the current child node, NULL if none */
283 /** Get the current child node, NULL if none */
284 SmNode
* operator->(){
290 /** Node whos children we're iterating over */
292 /** Size of the node */
294 /** Current index in the node */
302 /** Abstract baseclass for all composite node
304 * Subclasses of this class can have subnodes. Nodes that doesn't derivate from
305 * this class does not have subnodes.
307 class SmStructureNode
: public SmNode
309 SmNodeArray aSubNodes
;
312 SmStructureNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
313 : SmNode(eNodeType
, rNodeToken
)
317 SmStructureNode( const SmStructureNode
&rNode
);
318 virtual ~SmStructureNode();
320 virtual bool IsVisible() const SAL_OVERRIDE
;
322 virtual sal_uInt16
GetNumSubNodes() const SAL_OVERRIDE
;
323 void SetNumSubNodes(sal_uInt16 nSize
) { aSubNodes
.resize(nSize
); }
325 using SmNode::GetSubNode
;
326 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
) SAL_OVERRIDE
;
327 void SetSubNodes(SmNode
*pFirst
, SmNode
*pSecond
, SmNode
*pThird
= NULL
);
328 void SetSubNodes(const SmNodeArray
&rNodeArray
);
330 SmStructureNode
& operator = ( const SmStructureNode
&rNode
);
332 virtual void GetAccessibleText( OUStringBuffer
&rText
) const SAL_OVERRIDE
;
334 void SetSubNode(size_t nIndex
, SmNode
* pNode
)
336 size_t size
= aSubNodes
.size();
339 //Resize subnodes array
340 aSubNodes
.resize(nIndex
+ 1);
341 //Set new slots to NULL
342 for (size_t i
= size
; i
< nIndex
+1; i
++)
345 aSubNodes
[nIndex
] = pNode
;
350 inline void SmNode::ClaimPaternity() {
352 sal_uInt16 nSize
= GetNumSubNodes();
353 for (sal_uInt16 i
= 0; i
< nSize
; i
++)
354 if (NULL
!= (pNode
= GetSubNode(i
)))
355 pNode
->SetParent(static_cast<SmStructureNode
*>(this)); //Cast is valid if we have children
358 /** Abstract base class for all visible node
360 * Nodes that doesn't derivate from this class doesn't draw anything, but their
363 class SmVisibleNode
: public SmNode
366 SmVisibleNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
367 : SmNode(eNodeType
, rNodeToken
)
372 virtual bool IsVisible() const SAL_OVERRIDE
;
373 virtual sal_uInt16
GetNumSubNodes() const SAL_OVERRIDE
;
374 using SmNode::GetSubNode
;
375 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
) SAL_OVERRIDE
;
382 class SmGraphicNode
: public SmVisibleNode
385 SmGraphicNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
386 : SmVisibleNode(eNodeType
, rNodeToken
)
391 virtual void GetAccessibleText( OUStringBuffer
&rText
) const SAL_OVERRIDE
;
397 /** Draws a rectangle
399 * Used for drawing the line in the OVER and OVERSTRIKE commands.
401 class SmRectangleNode
: public SmGraphicNode
406 SmRectangleNode(const SmToken
&rNodeToken
)
407 : SmGraphicNode(NRECTANGLE
, rNodeToken
)
410 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
) SAL_OVERRIDE
;
411 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
413 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
415 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
416 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
422 /** Polygon line node
424 * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
426 class SmPolyLineNode
: public SmGraphicNode
433 SmPolyLineNode(const SmToken
&rNodeToken
);
435 long GetWidth() const { return nWidth
; }
436 Size
GetToSize() const { return aToSize
; }
437 Polygon
&GetPolygon() { return aPoly
; }
439 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
) SAL_OVERRIDE
;
440 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
442 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
444 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
452 * @remarks This class also serves as baseclass for all nodes that contains text.
454 class SmTextNode
: public SmVisibleNode
457 sal_uInt16 nFontDesc
;
458 /** Index within text where the selection starts
459 * @remarks Only valid if SmNode::IsSelected() is true
461 sal_Int32 nSelectionStart
;
462 /** Index within text where the selection ends
463 * @remarks Only valid if SmNode::IsSelected() is true
465 sal_Int32 nSelectionEnd
;
468 SmTextNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
, sal_uInt16 nFontDescP
);
471 SmTextNode(const SmToken
&rNodeToken
, sal_uInt16 nFontDescP
);
473 sal_uInt16
GetFontDesc() const { return nFontDesc
; }
474 void SetText(const OUString
&rText
) { aText
= rText
; }
475 const OUString
& GetText() const { return aText
; }
476 /** Change the text of this node, including the underlying token */
477 void ChangeText(const OUString
&rText
) {
479 SmToken token
= GetToken();
481 SetToken(token
); //TODO: Merge this with AdjustFontDesc for better performance
484 /** Try to guess the correct FontDesc, used during visual editing */
485 void AdjustFontDesc();
486 /** Index within GetText() where the selection starts
487 * @remarks Only valid of SmNode::IsSelected() is true
489 sal_Int32
GetSelectionStart() const {return nSelectionStart
;}
490 /** Index within GetText() where the selection end
491 * @remarks Only valid of SmNode::IsSelected() is true
493 sal_Int32
GetSelectionEnd() const {return nSelectionEnd
;}
494 /** Set the index within GetText() where the selection starts */
495 void SetSelectionStart(sal_Int32 index
) {nSelectionStart
= index
;}
496 /** Set the index within GetText() where the selection end */
497 void SetSelectionEnd(sal_Int32 index
) {nSelectionEnd
= index
;}
499 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
500 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
501 virtual void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
503 virtual void GetAccessibleText( OUStringBuffer
&rText
) const SAL_OVERRIDE
;
504 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
506 Converts the character from StarMath's private area symbols to a matching Unicode
507 character, if necessary. To be used when converting GetText() to a normal text.
509 static sal_Unicode
ConvertSymbolToUnicode(sal_Unicode nIn
);
515 /** Special node for user defined characters
517 * Node used for pre- and user-defined characters from:
518 * officecfg/registry/data/org/openoffice/Office/Math.xcu
520 * This is just single characters, I think.
522 class SmSpecialNode
: public SmTextNode
524 bool bIsFromGreekSymbolSet
;
527 SmSpecialNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
, sal_uInt16 _nFontDesc
);
530 SmSpecialNode(const SmToken
&rNodeToken
);
532 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
533 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
535 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
541 /** Glyph node for custom operators
543 * This node is used with commands: oper, uoper and boper.
544 * E.g. in "A boper op B", "op" will be an instance of SmGlyphSpecialNode.
545 * "boper" simply inteprets "op", the following token, as an binary operator.
546 * The command "uoper" interprets the following token as unary operator.
547 * For these commands an instance of SmGlyphSpecialNode is used for the
548 * operator token, following the command.
550 class SmGlyphSpecialNode
: public SmSpecialNode
553 SmGlyphSpecialNode(const SmToken
&rNodeToken
)
554 : SmSpecialNode(NGLYPH_SPECIAL
, rNodeToken
, FNT_MATH
)
557 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
558 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
566 * Use for math symbols such as plus, minus and integrale in the INT command.
568 class SmMathSymbolNode
: public SmSpecialNode
571 SmMathSymbolNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
572 : SmSpecialNode(eNodeType
, rNodeToken
, FNT_MATH
)
574 sal_Unicode cChar
= GetToken().cMathChar
;
575 if ((sal_Unicode
) '\0' != cChar
)
576 SetText(OUString(cChar
));
580 SmMathSymbolNode(const SmToken
&rNodeToken
);
582 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
) SAL_OVERRIDE
;
583 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
585 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
586 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
587 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
588 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
595 * This behaves essentially the same as SmMathSymbolNode and is only used to
596 * represent math symbols that should be exported as <mi> elements rather than
599 class SmMathIdentifierNode
: public SmMathSymbolNode
602 SmMathIdentifierNode(const SmToken
&rNodeToken
)
603 : SmMathSymbolNode(NMATHIDENT
, rNodeToken
) {}
610 * Root symbol node used by SmRootNode to create the root symbol, in front of
611 * the line with the line above. I don't think this node should be used for
614 class SmRootSymbolNode
: public SmMathSymbolNode
616 sal_uLong nBodyWidth
; // width of body (argument) of root sign
619 SmRootSymbolNode(const SmToken
&rNodeToken
)
620 : SmMathSymbolNode(NROOTSYMBOL
, rNodeToken
)
625 sal_uLong
GetBodyWidth() const {return nBodyWidth
;};
626 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
627 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
629 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
633 /** Dynamic Integral symbol node
635 * Node for drawing dynamically sized integral symbols.
637 * TODO: It might be created a parent class SmDynamicSizedNode
638 (for both dynamic integrals, roots and other dynamic symbols)
641 class SmDynIntegralSymbolNode
: public SmMathSymbolNode
646 SmDynIntegralSymbolNode(const SmToken
&rNodeToken
)
647 : SmMathSymbolNode(NDYNINTSYMBOL
, rNodeToken
)
650 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
652 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
660 * Used to create the <?> command, that denotes place where something can be
662 * It is drawn as a square with a shadow.
664 class SmPlaceNode
: public SmMathSymbolNode
667 SmPlaceNode(const SmToken
&rNodeToken
)
668 : SmMathSymbolNode(NPLACE
, rNodeToken
)
671 SmPlaceNode() : SmMathSymbolNode(NPLACE
, SmToken(TPLACE
, MS_PLACE
, "<?>")) {};
673 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
674 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
675 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
681 /** Error node, for parsing errors
683 * This node is used for parsing errors and draws an questionmark turned upside
684 * down (inverted question mark).
686 class SmErrorNode
: public SmMathSymbolNode
689 SmErrorNode(SmParseError
/*eError*/, const SmToken
&rNodeToken
)
690 : SmMathSymbolNode(NERROR
, rNodeToken
)
692 SetText(OUString(MS_ERROR
));
695 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
696 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
697 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
705 * This is the root node for the formula tree. This node is also used for the
706 * STACK and BINOM commands. When used for root node, its
707 * children are instances of SmLineNode, and in some obscure cases the a child
708 * can be an instance of SmExpressionNode, mainly when errors occur.
710 class SmTableNode
: public SmStructureNode
712 long nFormulaBaseline
;
714 SmTableNode(const SmToken
&rNodeToken
)
715 : SmStructureNode(NTABLE
, rNodeToken
)
716 , nFormulaBaseline(0)
720 using SmNode::GetLeftMost
;
721 virtual SmNode
* GetLeftMost() SAL_OVERRIDE
;
723 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
724 virtual long GetFormulaBaseline() const SAL_OVERRIDE
;
726 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
734 * Used as child of SmTableNode when the SmTableNode is the root node of the
737 class SmLineNode
: public SmStructureNode
739 bool bUseExtraSpaces
;
742 SmLineNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
743 : SmStructureNode(eNodeType
, rNodeToken
)
745 bUseExtraSpaces
= true;
749 SmLineNode(const SmToken
&rNodeToken
)
750 : SmStructureNode(NLINE
, rNodeToken
)
752 bUseExtraSpaces
= true;
755 void SetUseExtraSpaces(bool bVal
) { bUseExtraSpaces
= bVal
; }
756 bool IsUseExtraSpaces() const { return bUseExtraSpaces
; };
758 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
759 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
760 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
768 * Used whenever you have an expression such as "A OVER {B + C}", here there is
769 * an expression node that allows "B + C" to be the denominator of the
770 * SmBinVerNode, that the OVER command creates.
772 class SmExpressionNode
: public SmLineNode
775 SmExpressionNode(const SmToken
&rNodeToken
)
776 : SmLineNode(NEXPRESSION
, rNodeToken
)
779 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
780 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
781 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
787 /** Unary horizontal node
789 * The same as SmBinHorNode except this is for unary operators.
791 class SmUnHorNode
: public SmStructureNode
794 SmUnHorNode(const SmToken
&rNodeToken
)
795 : SmStructureNode(NUNHOR
, rNodeToken
)
800 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
801 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
809 * Used for create square roots and other roots, example:
810 * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
813 * 0: Argument (optional)<BR>
814 * 1: Symbol (instance of SmRootSymbolNode)<BR>
816 * Where argument is optional and may be NULL.
818 class SmRootNode
: public SmStructureNode
821 static void GetHeightVerOffset(const SmRect
&rRect
,
822 long &rHeight
, long &rVerOffset
);
823 static Point
GetExtraPos(const SmRect
&rRootSymbol
, const SmRect
&rExtra
);
826 SmRootNode(const SmToken
&rNodeToken
)
827 : SmStructureNode(NROOT
, rNodeToken
)
832 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
833 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
834 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
837 const SmNode
* Argument() const;
838 SmRootSymbolNode
* Symbol();
839 const SmRootSymbolNode
* Symbol() const;
841 const SmNode
* Body() const;
845 /** Dynamic Integral node
847 * Used to create Dynamically sized integrals
850 * 0: Symbol (instance of DynIntegralSymbolNode)<BR>
853 class SmDynIntegralNode
: public SmStructureNode
856 void GetHeightVerOffset(const SmRect
&rRect
,
857 long &rHeight
, long &rVerOffset
) const;
860 SmDynIntegralNode(const SmToken
&rNodeToken
)
861 : SmStructureNode(NDYNINT
, rNodeToken
)
866 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
867 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
868 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
870 SmDynIntegralSymbolNode
* Symbol();
871 const SmDynIntegralSymbolNode
* Symbol() const;
873 const SmNode
* Body() const;
879 /** Binary horizontal node
881 * This node is used for binary operators. In a formula such as "A + B".
884 * 0: Left operand<BR>
885 * 1: Binary operator<BR>
886 * 2: Right operand<BR>
888 * None of the children may be NULL.
890 class SmBinHorNode
: public SmStructureNode
893 SmBinHorNode(const SmToken
&rNodeToken
)
894 : SmStructureNode(NBINHOR
, rNodeToken
)
899 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
900 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
902 SmMathSymbolNode
* Symbol();
903 const SmMathSymbolNode
* Symbol() const;
904 SmNode
* LeftOperand();
905 const SmNode
* LeftOperand() const;
906 SmNode
* RightOperand();
907 const SmNode
* RightOperand() const;
913 /** Binary horizontal node
915 * This node is used for creating the OVER command, consider the formula:
916 * "numerator OVER denominator", which looks like
917 * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
921 * 1: Line (instance of SmRectangleNode)<BR>
923 * None of the children may be NULL.
925 class SmBinVerNode
: public SmStructureNode
928 SmBinVerNode(const SmToken
&rNodeToken
)
929 : SmStructureNode(NBINVER
, rNodeToken
)
934 using SmNode::GetLeftMost
;
935 virtual SmNode
* GetLeftMost() SAL_OVERRIDE
;
937 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
938 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
939 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
945 /** Binary diagonal node
947 * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
950 * 0: Left operand<BR>
951 * 1: right operand<BR>
952 * 2: Line (instance of SmPolyLineNode).<BR>
953 * None of the children may be NULL.
955 class SmBinDiagonalNode
: public SmStructureNode
959 void GetOperPosSize(Point
&rPos
, Size
&rSize
,
960 const Point
&rDiagPoint
, double fAngleDeg
) const;
963 SmBinDiagonalNode(const SmToken
&rNodeToken
);
965 bool IsAscending() const { return bAscending
; }
966 void SetAscending(bool bVal
) { bAscending
= bVal
; }
968 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
969 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
976 /** Enum used to index sub-/supscripts in the 'aSubNodes' array
979 * See graphic for positions at char:
994 { CSUB
, CSUP
, RSUB
, RSUP
, LSUB
, LSUP
997 /** numbers of entries in the above enum (that is: the number of possible
1000 #define SUBSUP_NUM_ENTRIES 6
1002 /** Super- and subscript node
1004 * Used for creating super- and subscripts for commands such as:
1005 * "^", "_", "lsup", "lsub", "csup" and "csub".
1006 * Example: "A^2" which looks like: \f$ A^2 \f$
1008 * This node is also used for creating limits on SmOperNode, when
1009 * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
1011 * Children of this node can be enumerated using the SmSubSup enum.
1012 * Please note that children may be NULL, except for the body.
1013 * It is recommended that you access children using GetBody() and
1016 class SmSubSupNode
: public SmStructureNode
1021 SmSubSupNode(const SmToken
&rNodeToken
)
1022 : SmStructureNode(NSUBSUP
, rNodeToken
)
1024 SetNumSubNodes(1 + SUBSUP_NUM_ENTRIES
);
1028 /** Get body (Not NULL) */
1029 SmNode
* GetBody() { return GetSubNode(0); }
1030 /** Get body (Not NULL) */
1031 const SmNode
* GetBody() const
1033 return const_cast<SmSubSupNode
*>(this)->GetBody();
1036 void SetUseLimits(bool bVal
) { bUseLimits
= bVal
; }
1037 bool IsUseLimits() const { return bUseLimits
; };
1039 /** Get super- or subscript
1040 * @remarks this method may return NULL.
1042 SmNode
* GetSubSup(SmSubSup eSubSup
) { return GetSubNode( sal::static_int_cast
< sal_uInt16
>(1 + eSubSup
) ); };
1043 const SmNode
* GetSubSup(SmSubSup eSubSup
) const { return const_cast< SmSubSupNode
* >( this )->GetSubSup( eSubSup
); }
1046 void SetBody(SmNode
* pBody
) { SetSubNode(0, pBody
); }
1047 void SetSubSup(SmSubSup eSubSup
, SmNode
* pScript
) { SetSubNode( 1 + eSubSup
, pScript
); }
1049 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1050 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1051 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1058 /** Node for brace construction
1060 * Used for "lbrace [body] rbrace" and similar constructions.
1061 * Should look like \f$ \{\mbox{[body]}\} \f$
1064 * 0: Opening brace<BR>
1065 * 1: Body (usually SmBracebodyNode)<BR>
1066 * 2: Closing brace<BR>
1067 * None of the children can be NULL.
1069 * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
1071 class SmBraceNode
: public SmStructureNode
1074 SmBraceNode(const SmToken
&rNodeToken
)
1075 : SmStructureNode(NBRACE
, rNodeToken
)
1080 SmMathSymbolNode
* OpeningBrace();
1081 const SmMathSymbolNode
* OpeningBrace() const;
1083 const SmNode
* Body() const;
1084 SmMathSymbolNode
* ClosingBrace();
1085 const SmMathSymbolNode
* ClosingBrace() const;
1087 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1088 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1089 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1095 /** Body of an SmBraceNode
1097 * This usually only has one child an SmExpressionNode, however, it can also
1098 * have other children.
1099 * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
1100 * \f$ \{\mbox{[body1] | [body2]}\} \f$.
1101 * In this case SmBracebodyNode will have three children, "[body1]", "|" and
1104 class SmBracebodyNode
: public SmStructureNode
1109 inline SmBracebodyNode(const SmToken
&rNodeToken
);
1111 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1112 long GetBodyHeight() const { return nBodyHeight
; }
1113 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1117 inline SmBracebodyNode::SmBracebodyNode(const SmToken
&rNodeToken
) :
1118 SmStructureNode(NBRACEBODY
, rNodeToken
)
1126 /** Node for vertical brace construction
1128 * Used to implement commands "[body] underbrace [script]" and
1129 * "[body] overbrace [script]".
1130 * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
1136 * (None of these children are optional, e.g. they must all be not NULL).
1138 class SmVerticalBraceNode
: public SmStructureNode
1141 inline SmVerticalBraceNode(const SmToken
&rNodeToken
);
1144 const SmNode
* Body() const;
1145 SmMathSymbolNode
* Brace();
1146 const SmMathSymbolNode
* Brace() const;
1148 const SmNode
* Script() const;
1150 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1151 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1155 inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken
&rNodeToken
) :
1156 SmStructureNode(NVERTICAL_BRACE
, rNodeToken
)
1167 * Used for commands like SUM, INT and similar.
1170 * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
1172 * None of the children may be NULL.
1175 class SmOperNode
: public SmStructureNode
1178 SmOperNode(const SmToken
&rNodeToken
)
1179 : SmStructureNode(NOPER
, rNodeToken
)
1184 SmNode
* GetSymbol();
1185 const SmNode
* GetSymbol() const
1187 return const_cast<SmOperNode
*>(this)->GetSymbol();
1190 long CalcSymbolHeight(const SmNode
&rSymbol
, const SmFormat
&rFormat
) const;
1192 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1193 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1199 /** Node used for alignment
1201 class SmAlignNode
: public SmStructureNode
1204 SmAlignNode(const SmToken
&rNodeToken
)
1205 : SmStructureNode(NALIGN
, rNodeToken
)
1208 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1209 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1217 * Used to give an attribute to another node. Used for commands such as:
1218 * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHAT and WIDETILDE.
1223 * None of these may be NULL.
1225 class SmAttributNode
: public SmStructureNode
1228 SmAttributNode(const SmToken
&rNodeToken
)
1229 : SmStructureNode(NATTRIBUT
, rNodeToken
)
1232 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1233 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1234 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1236 SmNode
* Attribute();
1237 const SmNode
* Attribute() const;
1239 const SmNode
* Body() const;
1247 * Used to change the font of its children.
1249 class SmFontNode
: public SmStructureNode
1251 FontSizeType nSizeType
;
1255 SmFontNode(const SmToken
&rNodeToken
)
1256 : SmStructureNode(NFONT
, rNodeToken
)
1258 nSizeType
= FontSizeType::MULTIPLY
;
1259 aFontSize
= Fraction(1L);
1262 void SetSizeParameter(const Fraction
&rValue
, FontSizeType nType
);
1263 const Fraction
& GetSizeParameter() const {return aFontSize
;}
1264 const FontSizeType
& GetSizeType() const {return nSizeType
;}
1266 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
1267 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1268 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1269 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1277 * Used to implement the MATRIX command, example:
1278 * "matrix{ 1 # 2 ## 3 # 4}".
1280 class SmMatrixNode
: public SmStructureNode
1282 sal_uInt16 nNumRows
,
1286 SmMatrixNode(const SmToken
&rNodeToken
)
1287 : SmStructureNode(NMATRIX
, rNodeToken
)
1289 nNumRows
= nNumCols
= 0;
1292 sal_uInt16
GetNumRows() const {return nNumRows
;}
1293 sal_uInt16
GetNumCols() const {return nNumCols
;}
1294 void SetRowCol(sal_uInt16 nMatrixRows
, sal_uInt16 nMatrixCols
);
1296 using SmNode::GetLeftMost
;
1297 virtual SmNode
* GetLeftMost() SAL_OVERRIDE
;
1299 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1300 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1301 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1307 /** Node for whitespace
1309 * Used to implement the "~" command. This node is just a blank space.
1311 class SmBlankNode
: public SmGraphicNode
1316 SmBlankNode(const SmToken
&rNodeToken
)
1317 : SmGraphicNode(NBLANK
, rNodeToken
)
1322 void IncreaseBy(const SmToken
&rToken
);
1323 void Clear() { nNum
= 0; }
1324 sal_uInt16
GetBlankNum() const { return nNum
; }
1325 void SetBlankNum(sal_uInt16 nNumber
) { nNum
= nNumber
; }
1327 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
1328 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1329 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1336 inline SmNode
* SmRootNode::Argument()
1338 OSL_ASSERT( GetNumSubNodes() > 0 );
1339 return GetSubNode( 0 );
1341 inline const SmNode
* SmRootNode::Argument() const
1343 return const_cast< SmRootNode
* >( this )->Argument();
1345 inline SmRootSymbolNode
* SmRootNode::Symbol()
1347 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NROOTSYMBOL
);
1348 return static_cast< SmRootSymbolNode
* >( GetSubNode( 1 ));
1350 inline const SmRootSymbolNode
* SmRootNode::Symbol() const
1352 return const_cast< SmRootNode
* >( this )->Symbol();
1354 inline SmNode
* SmRootNode::Body()
1356 OSL_ASSERT( GetNumSubNodes() > 2 );
1357 return GetSubNode( 2 );
1359 inline const SmNode
* SmRootNode::Body() const
1361 return const_cast< SmRootNode
* >( this )->Body();
1366 inline SmDynIntegralSymbolNode
* SmDynIntegralNode::Symbol()
1368 OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NDYNINTSYMBOL
);
1369 return static_cast< SmDynIntegralSymbolNode
* >( GetSubNode( 0 ));
1371 inline const SmDynIntegralSymbolNode
* SmDynIntegralNode::Symbol() const
1373 return const_cast< SmDynIntegralNode
* >( this )->Symbol();
1375 inline SmNode
* SmDynIntegralNode::Body()
1377 OSL_ASSERT( GetNumSubNodes() > 1 );
1378 return GetSubNode( 1 );
1380 inline const SmNode
* SmDynIntegralNode::Body() const
1382 return const_cast< SmDynIntegralNode
* >( this )->Body();
1386 inline SmMathSymbolNode
* SmBinHorNode::Symbol()
1388 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH
);
1389 return static_cast< SmMathSymbolNode
* >( GetSubNode( 1 ));
1391 inline const SmMathSymbolNode
* SmBinHorNode::Symbol() const
1393 return const_cast< SmBinHorNode
* >( this )->Symbol();
1395 inline SmNode
* SmBinHorNode::LeftOperand()
1397 OSL_ASSERT( GetNumSubNodes() > 0 );
1398 return GetSubNode( 0 );
1400 inline const SmNode
* SmBinHorNode::LeftOperand() const
1402 return const_cast< SmBinHorNode
* >( this )->LeftOperand();
1404 inline SmNode
* SmBinHorNode::RightOperand()
1406 OSL_ASSERT( GetNumSubNodes() > 2 );
1407 return GetSubNode( 2 );
1409 inline const SmNode
* SmBinHorNode::RightOperand() const
1411 return const_cast< SmBinHorNode
* >( this )->RightOperand();
1414 inline SmNode
* SmAttributNode::Attribute()
1416 OSL_ASSERT( GetNumSubNodes() > 0 );
1417 return GetSubNode( 0 );
1419 inline const SmNode
* SmAttributNode::Attribute() const
1421 return const_cast< SmAttributNode
* >( this )->Attribute();
1423 inline SmNode
* SmAttributNode::Body()
1425 OSL_ASSERT( GetNumSubNodes() > 1 );
1426 return GetSubNode( 1 );
1428 inline const SmNode
* SmAttributNode::Body() const
1430 return const_cast< SmAttributNode
* >( this )->Body();
1433 inline SmMathSymbolNode
* SmBraceNode::OpeningBrace()
1435 OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NMATH
);
1436 return static_cast< SmMathSymbolNode
* >( GetSubNode( 0 ));
1438 inline const SmMathSymbolNode
* SmBraceNode::OpeningBrace() const
1440 return const_cast< SmBraceNode
* >( this )->OpeningBrace();
1442 inline SmNode
* SmBraceNode::Body()
1444 OSL_ASSERT( GetNumSubNodes() > 1 );
1445 return GetSubNode( 1 );
1447 inline const SmNode
* SmBraceNode::Body() const
1449 return const_cast< SmBraceNode
* >( this )->Body();
1451 inline SmMathSymbolNode
* SmBraceNode::ClosingBrace()
1453 OSL_ASSERT( GetNumSubNodes() > 2 && GetSubNode( 2 )->GetType() == NMATH
);
1454 return static_cast< SmMathSymbolNode
* >( GetSubNode( 2 ));
1456 inline const SmMathSymbolNode
* SmBraceNode::ClosingBrace() const
1458 return const_cast< SmBraceNode
* >( this )->ClosingBrace();
1461 inline SmNode
* SmVerticalBraceNode::Body()
1463 OSL_ASSERT( GetNumSubNodes() > 0 );
1464 return GetSubNode( 0 );
1466 inline const SmNode
* SmVerticalBraceNode::Body() const
1468 return const_cast< SmVerticalBraceNode
* >( this )->Body();
1470 inline SmMathSymbolNode
* SmVerticalBraceNode::Brace()
1472 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH
);
1473 return static_cast< SmMathSymbolNode
* >( GetSubNode( 1 ));
1475 inline const SmMathSymbolNode
* SmVerticalBraceNode::Brace() const
1477 return const_cast< SmVerticalBraceNode
* >( this )->Brace();
1479 inline SmNode
* SmVerticalBraceNode::Script()
1481 OSL_ASSERT( GetNumSubNodes() > 2 );
1482 return GetSubNode( 2 );
1484 inline const SmNode
* SmVerticalBraceNode::Script() const
1486 return const_cast< SmVerticalBraceNode
* >( this )->Script();
1492 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */