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
33 #define ATTR_BOLD 0x0001
34 #define ATTR_ITALIC 0x0002
37 #define FNTSIZ_ABSOLUT 1
39 #define FNTSIZ_MINUS 3
40 #define FNTSIZ_MULTIPLY 4
41 #define FNTSIZ_DIVIDE 5
43 // flags to interdict respective status changes
44 #define FLG_FONT 0x0001
45 #define FLG_SIZE 0x0002
46 #define FLG_BOLD 0x0004
47 #define FLG_ITALIC 0x0008
48 #define FLG_COLOR 0x0010
49 #define FLG_VISIBLE 0x0020
50 #define FLG_HORALIGN 0x0040
53 extern SmFormat
*pActiveFormat
;
58 class SmStructureNode
;
60 typedef boost::shared_ptr
<SmNode
> SmNodePointer
;
61 typedef std::vector
< SmNode
* > SmNodeArray
;
62 typedef std::vector
< SmStructureNode
* > SmStructureNodeArray
;
67 enum SmScaleMode
{ SCALE_NONE
, SCALE_WIDTH
, SCALE_HEIGHT
};
71 /* 0*/ NTABLE
, NBRACE
, NBRACEBODY
, NOPER
, NALIGN
,
72 /* 5*/ NATTRIBUT
, NFONT
, NUNHOR
, NBINHOR
, NBINVER
,
73 /*10*/ NBINDIAGONAL
, NSUBSUP
, NMATRIX
, NPLACE
, NTEXT
,
74 /*15*/ NSPECIAL
, NGLYPH_SPECIAL
, NMATH
, NBLANK
, NERROR
,
75 /*20*/ NLINE
, NEXPRESSION
, NPOLYLINE
, NROOT
, NROOTSYMBOL
,
76 /*25*/ NRECTANGLE
, NVERTICAL_BRACE
, NMATHIDENT
, NDYNINT
, NDYNINTSYMBOL
83 class SmNode
: public SmRect
89 SmScaleMode eScaleMode
;
90 RectHorAlign eRectHorAlign
;
99 SmNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
);
101 // index in accessible text -1 if not (yet) applicable
107 virtual bool IsVisible() const;
109 virtual sal_uInt16
GetNumSubNodes() const;
110 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
);
111 const SmNode
* GetSubNode(sal_uInt16 nIndex
) const
113 return const_cast<SmNode
*>(this)->GetSubNode(nIndex
);
116 virtual SmNode
* GetLeftMost();
117 const SmNode
* GetLeftMost() const
119 return const_cast<SmNode
*>(this)->GetLeftMost();
122 sal_uInt16
& Flags() { return nFlags
; }
123 sal_uInt16
& Attributes() { return nAttributes
; }
125 bool IsDebug() const { return bIsDebug
; }
126 bool IsPhantom() const { return bIsPhantom
; }
127 void SetPhantom(bool bIsPhantom
);
128 void SetColor(const Color
&rColor
);
130 void SetAttribut(sal_uInt16 nAttrib
);
131 void ClearAttribut(sal_uInt16 nAttrib
);
133 const SmFace
& GetFont() const { return aFace
; };
134 SmFace
& GetFont() { return aFace
; };
136 void SetFont(const SmFace
&rFace
);
137 void SetFontSize(const Fraction
&rRelSize
, sal_uInt16 nType
);
138 void SetSize(const Fraction
&rScale
);
140 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
);
141 virtual void PrepareAttributes();
143 sal_uInt16
FindIndex() const;
146 void ToggleDebug() const;
149 void SetRectHorAlign(RectHorAlign eHorAlign
, bool bApplyToSubTree
= true );
150 RectHorAlign
GetRectHorAlign() const { return eRectHorAlign
; }
152 const SmRect
& GetRect() const { return *this; }
153 SmRect
& GetRect() { return *this; }
155 virtual void Move(const Point
&rPosition
);
156 void MoveTo(const Point
&rPosition
) { Move(rPosition
- GetTopLeft()); }
157 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
);
158 virtual void CreateTextFromNode(OUString
&rText
);
160 virtual void GetAccessibleText( OUStringBuffer
&rText
) const;
161 sal_Int32
GetAccessibleIndex() const { return nAccIndex
; }
162 const SmNode
* FindNodeWithAccessibleIndex(sal_Int32 nAccIndex
) const;
164 sal_uInt16
GetRow() const { return (sal_uInt16
)aNodeToken
.nRow
; }
165 sal_uInt16
GetColumn() const { return (sal_uInt16
)aNodeToken
.nCol
; }
167 SmScaleMode
GetScaleMode() const { return eScaleMode
; }
168 void SetScaleMode(SmScaleMode eMode
) { eScaleMode
= eMode
; }
170 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
);
171 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
);
173 SmNodeType
GetType() const { return eType
; }
174 const SmToken
& GetToken() const { return aNodeToken
; }
176 const SmNode
* FindTokenAt(sal_uInt16 nRow
, sal_uInt16 nCol
) const;
177 const SmNode
* FindRectClosestTo(const Point
&rPoint
) const;
179 virtual long GetFormulaBaseline() const;
182 * Calls the method for this class on the visitor
184 virtual void Accept(SmVisitor
* pVisitor
);
186 /** True if this node is selected */
187 bool IsSelected() const {return bIsSelected
;}
188 void SetSelected(bool Selected
= true) {bIsSelected
= Selected
;}
190 #ifdef DEBUG_ENABLE_DUMPASDOT
191 /** The tree as dot graph for graphviz, usable for debugging
192 * Convert the output to a image using $ dot graph.gv -Tpng > graph.png
194 inline void DumpAsDot(std::ostream
&out
, OUString
* label
= NULL
) const{
196 DumpAsDot(out
, label
, -1, id
, -1);
198 #endif /* DEBUG_ENABLE_DUMPASDOT */
200 /** Get the parent node of this node */
201 SmStructureNode
* GetParent(){ return aParentNode
; }
202 const SmStructureNode
* GetParent() const { return aParentNode
; }
203 /** Set the parent node */
204 void SetParent(SmStructureNode
* parent
){
205 aParentNode
= parent
;
208 /** Get the index of a child node
210 * Returns -1, if pSubNode isn't a subnode of this.
212 int IndexOfSubNode(SmNode
* pSubNode
){
213 sal_uInt16 nSize
= GetNumSubNodes();
214 for(sal_uInt16 i
= 0; i
< nSize
; i
++)
215 if(pSubNode
== GetSubNode(i
))
219 /** Set the token for this node */
220 void SetToken(SmToken
& token
){
224 /** Sets parent on children of this node */
225 void ClaimPaternity(){
227 sal_uInt16 nSize
= GetNumSubNodes();
228 for (sal_uInt16 i
= 0; i
< nSize
; i
++)
229 if (NULL
!= (pNode
= GetSubNode(i
)))
230 pNode
->SetParent((SmStructureNode
*)this); //Cast is valid if we have children
233 SmStructureNode
* aParentNode
;
234 void DumpAsDot(std::ostream
&out
, OUString
* label
, int number
, int& id
, int parent
) const;
239 /** A simple auxiliary iterator class for SmNode
241 * Example of iteration over children of pMyNode:
243 * //Node to iterate over:
244 * SmNode* pMyNode = 0;// A pointer from somewhere
246 * SmNodeIterator it(pMyNode);
249 * it->SetSelected(true);
253 class SmNodeIterator
{
255 SmNodeIterator(SmNode
* node
, bool bReverse
= false){
257 nSize
= pNode
->GetNumSubNodes();
260 bIsReverse
= bReverse
;
262 /** Get the subnode or NULL if none */
264 while(!bIsReverse
&& nIndex
< nSize
){
265 if(NULL
!= (pChildNode
= pNode
->GetSubNode(nIndex
++)))
268 while(bIsReverse
&& nSize
> 0){
269 if(NULL
!= (pChildNode
= pNode
->GetSubNode((nSize
--)-1)))
275 /** Get the current child node, NULL if none */
279 /** Get the current child node, NULL if none */
280 SmNode
* operator->(){
286 /** Node whos children we're iterating over */
288 /** Size of the node */
290 /** Current index in the node */
298 /** Abstract baseclass for all composite node
300 * Subclasses of this class can have subnodes. Nodes that doesn't derivate from
301 * this class does not have subnodes.
303 class SmStructureNode
: public SmNode
305 SmNodeArray aSubNodes
;
308 SmStructureNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
309 : SmNode(eNodeType
, rNodeToken
)
313 SmStructureNode( const SmStructureNode
&rNode
);
314 virtual ~SmStructureNode();
316 virtual bool IsVisible() const SAL_OVERRIDE
;
318 virtual sal_uInt16
GetNumSubNodes() const SAL_OVERRIDE
;
319 void SetNumSubNodes(sal_uInt16 nSize
) { aSubNodes
.resize(nSize
); }
321 using SmNode::GetSubNode
;
322 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
) SAL_OVERRIDE
;
323 void SetSubNodes(SmNode
*pFirst
, SmNode
*pSecond
, SmNode
*pThird
= NULL
);
324 void SetSubNodes(const SmNodeArray
&rNodeArray
);
326 SmStructureNode
& operator = ( const SmStructureNode
&rNode
);
328 virtual void GetAccessibleText( OUStringBuffer
&rText
) const SAL_OVERRIDE
;
330 void SetSubNode(size_t nIndex
, SmNode
* pNode
)
332 size_t size
= aSubNodes
.size();
335 //Resize subnodes array
336 aSubNodes
.resize(nIndex
+ 1);
337 //Set new slots to NULL
338 for (size_t i
= size
; i
< nIndex
+1; i
++)
341 aSubNodes
[nIndex
] = pNode
;
349 /** Abstract base class for all visible node
351 * Nodes that doesn't derivate from this class doesn't draw anything, but their
354 class SmVisibleNode
: public SmNode
357 SmVisibleNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
358 : SmNode(eNodeType
, rNodeToken
)
363 virtual bool IsVisible() const SAL_OVERRIDE
;
364 virtual sal_uInt16
GetNumSubNodes() const SAL_OVERRIDE
;
365 using SmNode::GetSubNode
;
366 virtual SmNode
* GetSubNode(sal_uInt16 nIndex
) SAL_OVERRIDE
;
373 class SmGraphicNode
: public SmVisibleNode
376 SmGraphicNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
377 : SmVisibleNode(eNodeType
, rNodeToken
)
382 virtual void GetAccessibleText( OUStringBuffer
&rText
) const SAL_OVERRIDE
;
388 /** Draws a rectangle
390 * Used for drawing the line in the OVER and OVERSTRIKE commands.
392 class SmRectangleNode
: public SmGraphicNode
397 SmRectangleNode(const SmToken
&rNodeToken
)
398 : SmGraphicNode(NRECTANGLE
, rNodeToken
)
401 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
) SAL_OVERRIDE
;
402 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
404 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
406 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
407 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
413 /** Polygon line node
415 * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
417 class SmPolyLineNode
: public SmGraphicNode
424 SmPolyLineNode(const SmToken
&rNodeToken
);
426 long GetWidth() const { return nWidth
; }
427 Size
GetToSize() const { return aToSize
; }
428 Polygon
&GetPolygon() { return aPoly
; }
430 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
) SAL_OVERRIDE
;
431 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
433 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
435 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
443 * @remarks This class also serves as baseclass for all nodes that contains text.
445 class SmTextNode
: public SmVisibleNode
448 sal_uInt16 nFontDesc
;
449 /** Index within text where the selection starts
450 * @remarks Only valid if SmNode::IsSelected() is true
452 sal_Int32 nSelectionStart
;
453 /** Index within text where the selection ends
454 * @remarks Only valid if SmNode::IsSelected() is true
456 sal_Int32 nSelectionEnd
;
459 SmTextNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
, sal_uInt16 nFontDescP
);
462 SmTextNode(const SmToken
&rNodeToken
, sal_uInt16 nFontDescP
);
464 sal_uInt16
GetFontDesc() const { return nFontDesc
; }
465 void SetText(const OUString
&rText
) { aText
= rText
; }
466 const OUString
& GetText() const { return aText
; }
467 /** Change the text of this node, including the underlying token */
468 void ChangeText(const OUString
&rText
) {
470 SmToken token
= GetToken();
472 SetToken(token
); //TODO: Merge this with AdjustFontDesc for better performance
475 /** Try to guess the correct FontDesc, used during visual editing */
476 void AdjustFontDesc();
477 /** Index within GetText() where the selection starts
478 * @remarks Only valid of SmNode::IsSelected() is true
480 sal_Int32
GetSelectionStart() const {return nSelectionStart
;}
481 /** Index within GetText() where the selection end
482 * @remarks Only valid of SmNode::IsSelected() is true
484 sal_Int32
GetSelectionEnd() const {return nSelectionEnd
;}
485 /** Set the index within GetText() where the selection starts */
486 void SetSelectionStart(sal_Int32 index
) {nSelectionStart
= index
;}
487 /** Set the index within GetText() where the selection end */
488 void SetSelectionEnd(sal_Int32 index
) {nSelectionEnd
= index
;}
490 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
491 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
492 virtual void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
494 virtual void GetAccessibleText( OUStringBuffer
&rText
) const SAL_OVERRIDE
;
495 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
497 Converts the character from StarMath's private area symbols to a matching Unicode
498 character, if necessary. To be used when converting GetText() to a normal text.
500 static sal_Unicode
ConvertSymbolToUnicode(sal_Unicode nIn
);
506 /** Special node for user defined characters
508 * Node used for pre- and user-defined characters from:
509 * officecfg/registry/data/org/openoffice/Office/Math.xcu
511 * This is just single characters, I think.
513 class SmSpecialNode
: public SmTextNode
515 bool bIsFromGreekSymbolSet
;
518 SmSpecialNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
, sal_uInt16 _nFontDesc
);
521 SmSpecialNode(const SmToken
&rNodeToken
);
523 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
524 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
526 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
532 /** Glyph node for custom operators
534 * This node is used with commands: oper, uoper and boper.
535 * E.g. in "A boper op B", "op" will be an instance of SmGlyphSpecialNode.
536 * "boper" simply inteprets "op", the following token, as an binary operator.
537 * The command "uoper" interprets the following token as unary operator.
538 * For these commands an instance of SmGlyphSpecialNode is used for the
539 * operator token, following the command.
541 class SmGlyphSpecialNode
: public SmSpecialNode
544 SmGlyphSpecialNode(const SmToken
&rNodeToken
)
545 : SmSpecialNode(NGLYPH_SPECIAL
, rNodeToken
, FNT_MATH
)
548 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
549 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
557 * Use for math symbols such as plus, minus and integrale in the INT command.
559 class SmMathSymbolNode
: public SmSpecialNode
562 SmMathSymbolNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
563 : SmSpecialNode(eNodeType
, rNodeToken
, FNT_MATH
)
565 sal_Unicode cChar
= GetToken().cMathChar
;
566 if ((sal_Unicode
) '\0' != cChar
)
567 SetText(OUString(cChar
));
571 SmMathSymbolNode(const SmToken
&rNodeToken
);
573 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nWidth
) SAL_OVERRIDE
;
574 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
576 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
577 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
578 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
579 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
586 * This behaves essentially the same as SmMathSymbolNode and is only used to
587 * represent math symbols that should be exported as <mi> elements rather than
590 class SmMathIdentifierNode
: public SmMathSymbolNode
593 SmMathIdentifierNode(const SmToken
&rNodeToken
)
594 : SmMathSymbolNode(NMATHIDENT
, rNodeToken
) {}
601 * Root symbol node used by SmRootNode to create the root symbol, in front of
602 * the line with the line above. I don't think this node should be used for
605 class SmRootSymbolNode
: public SmMathSymbolNode
607 sal_uLong nBodyWidth
; // width of body (argument) of root sign
610 SmRootSymbolNode(const SmToken
&rNodeToken
)
611 : SmMathSymbolNode(NROOTSYMBOL
, rNodeToken
)
616 sal_uLong
GetBodyWidth() const {return nBodyWidth
;};
617 virtual void AdaptToX(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
618 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
620 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
624 /** Dynamic Integral symbol node
626 * Node for drawing dynamically sized integral symbols.
628 * TODO: It might be created a parent class SmDynamicSizedNode
629 (for both dynamic integrals, roots and other dynamic symbols)
632 class SmDynIntegralSymbolNode
: public SmMathSymbolNode
637 SmDynIntegralSymbolNode(const SmToken
&rNodeToken
)
638 : SmMathSymbolNode(NDYNINTSYMBOL
, rNodeToken
)
641 virtual void AdaptToY(const OutputDevice
&rDev
, sal_uLong nHeight
) SAL_OVERRIDE
;
643 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
651 * Used to create the <?> command, that denotes place where something can be
653 * It is drawn as a square with a shadow.
655 class SmPlaceNode
: public SmMathSymbolNode
658 SmPlaceNode(const SmToken
&rNodeToken
)
659 : SmMathSymbolNode(NPLACE
, rNodeToken
)
662 SmPlaceNode() : SmMathSymbolNode(NPLACE
, SmToken(TPLACE
, MS_PLACE
, "<?>")) {};
664 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
665 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
666 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
672 /** Error node, for parsing errors
674 * This node is used for parsing errors and draws an questionmark turned upside
675 * down (inverted question mark).
677 class SmErrorNode
: public SmMathSymbolNode
680 SmErrorNode(SmParseError
/*eError*/, const SmToken
&rNodeToken
)
681 : SmMathSymbolNode(NERROR
, rNodeToken
)
683 SetText(OUString(MS_ERROR
));
686 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
687 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
688 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
696 * This is the root node for the formula tree. This node is also used for the
697 * STACK and BINOM commands. When used for root node, its
698 * children are instances of SmLineNode, and in some obscure cases the a child
699 * can be an instance of SmExpressionNode, mainly when errors occur.
701 class SmTableNode
: public SmStructureNode
703 long nFormulaBaseline
;
705 SmTableNode(const SmToken
&rNodeToken
)
706 : SmStructureNode(NTABLE
, rNodeToken
)
707 , nFormulaBaseline(0)
711 using SmNode::GetLeftMost
;
712 virtual SmNode
* GetLeftMost() SAL_OVERRIDE
;
714 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
715 virtual long GetFormulaBaseline() const SAL_OVERRIDE
;
717 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
725 * Used as child of SmTableNode when the SmTableNode is the root node of the
728 class SmLineNode
: public SmStructureNode
730 bool bUseExtraSpaces
;
733 SmLineNode(SmNodeType eNodeType
, const SmToken
&rNodeToken
)
734 : SmStructureNode(eNodeType
, rNodeToken
)
736 bUseExtraSpaces
= true;
740 SmLineNode(const SmToken
&rNodeToken
)
741 : SmStructureNode(NLINE
, rNodeToken
)
743 bUseExtraSpaces
= true;
746 void SetUseExtraSpaces(bool bVal
) { bUseExtraSpaces
= bVal
; }
747 bool IsUseExtraSpaces() const { return bUseExtraSpaces
; };
749 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
750 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
751 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
759 * Used whenever you have an expression such as "A OVER {B + C}", here there is
760 * an expression node that allows "B + C" to be the denominator of the
761 * SmBinVerNode, that the OVER command creates.
763 class SmExpressionNode
: public SmLineNode
766 SmExpressionNode(const SmToken
&rNodeToken
)
767 : SmLineNode(NEXPRESSION
, rNodeToken
)
770 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
771 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
772 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
778 /** Unary horizontal node
780 * The same as SmBinHorNode except this is for unary operators.
782 class SmUnHorNode
: public SmStructureNode
785 SmUnHorNode(const SmToken
&rNodeToken
)
786 : SmStructureNode(NUNHOR
, rNodeToken
)
791 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
792 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
800 * Used for create square roots and other roots, example:
801 * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
804 * 0: Argument (optional)<BR>
805 * 1: Symbol (instance of SmRootSymbolNode)<BR>
807 * Where argument is optional and may be NULL.
809 class SmRootNode
: public SmStructureNode
812 void GetHeightVerOffset(const SmRect
&rRect
,
813 long &rHeight
, long &rVerOffset
) const;
814 Point
GetExtraPos(const SmRect
&rRootSymbol
, const SmRect
&rExtra
) const;
817 SmRootNode(const SmToken
&rNodeToken
)
818 : SmStructureNode(NROOT
, rNodeToken
)
823 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
824 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
825 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
828 const SmNode
* Argument() const;
829 SmRootSymbolNode
* Symbol();
830 const SmRootSymbolNode
* Symbol() const;
832 const SmNode
* Body() const;
836 /** Dynamic Integral node
838 * Used to create Dynamically sized integrals
841 * 0: Symbol (instance of DynIntegralSymbolNode)<BR>
844 class SmDynIntegralNode
: public SmStructureNode
847 void GetHeightVerOffset(const SmRect
&rRect
,
848 long &rHeight
, long &rVerOffset
) const;
851 SmDynIntegralNode(const SmToken
&rNodeToken
)
852 : SmStructureNode(NDYNINT
, rNodeToken
)
857 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
858 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
859 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
861 SmDynIntegralSymbolNode
* Symbol();
862 const SmDynIntegralSymbolNode
* Symbol() const;
864 const SmNode
* Body() const;
870 /** Binary horizontal node
872 * This node is used for binary operators. In a formula such as "A + B".
875 * 0: Left operand<BR>
876 * 1: Binary operator<BR>
877 * 2: Right operand<BR>
879 * None of the children may be NULL.
881 class SmBinHorNode
: public SmStructureNode
884 SmBinHorNode(const SmToken
&rNodeToken
)
885 : SmStructureNode(NBINHOR
, rNodeToken
)
890 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
891 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
893 SmMathSymbolNode
* Symbol();
894 const SmMathSymbolNode
* Symbol() const;
895 SmNode
* LeftOperand();
896 const SmNode
* LeftOperand() const;
897 SmNode
* RightOperand();
898 const SmNode
* RightOperand() const;
904 /** Binary horizontal node
906 * This node is used for creating the OVER command, consider the formula:
907 * "numerator OVER denominator", which looks like
908 * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
912 * 1: Line (instance of SmRectangleNode)<BR>
914 * None of the children may be NULL.
916 class SmBinVerNode
: public SmStructureNode
919 SmBinVerNode(const SmToken
&rNodeToken
)
920 : SmStructureNode(NBINVER
, rNodeToken
)
925 using SmNode::GetLeftMost
;
926 virtual SmNode
* GetLeftMost() SAL_OVERRIDE
;
928 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
929 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
930 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
936 /** Binary diagonal node
938 * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
941 * 0: Left operand<BR>
942 * 1: right operand<BR>
943 * 2: Line (instance of SmPolyLineNode).<BR>
944 * None of the children may be NULL.
946 class SmBinDiagonalNode
: public SmStructureNode
950 void GetOperPosSize(Point
&rPos
, Size
&rSize
,
951 const Point
&rDiagPoint
, double fAngleDeg
) const;
954 SmBinDiagonalNode(const SmToken
&rNodeToken
);
956 bool IsAscending() const { return bAscending
; }
957 void SetAscending(bool bVal
) { bAscending
= bVal
; }
959 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
960 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
967 /** Enum used to index sub-/supscripts in the 'aSubNodes' array
970 * See graphic for positions at char:
985 { CSUB
, CSUP
, RSUB
, RSUP
, LSUB
, LSUP
988 /** numbers of entries in the above enum (that is: the number of possible
991 #define SUBSUP_NUM_ENTRIES 6
993 /** Super- and subscript node
995 * Used for creating super- and subscripts for commands such as:
996 * "^", "_", "lsup", "lsub", "csup" and "csub".
997 * Example: "A^2" which looks like: \f$ A^2 \f$
999 * This node is also used for creating limits on SmOperNode, when
1000 * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
1002 * Children of this node can be enumerated using the SmSubSup enum.
1003 * Please note that children may be NULL, except for the body.
1004 * It is recommended that you access children using GetBody() and
1007 class SmSubSupNode
: public SmStructureNode
1012 SmSubSupNode(const SmToken
&rNodeToken
)
1013 : SmStructureNode(NSUBSUP
, rNodeToken
)
1015 SetNumSubNodes(1 + SUBSUP_NUM_ENTRIES
);
1019 /** Get body (Not NULL) */
1020 SmNode
* GetBody() { return GetSubNode(0); }
1021 /** Get body (Not NULL) */
1022 const SmNode
* GetBody() const
1024 return ((SmSubSupNode
*) this)->GetBody();
1027 void SetUseLimits(bool bVal
) { bUseLimits
= bVal
; }
1028 bool IsUseLimits() const { return bUseLimits
; };
1030 /** Get super- or subscript
1031 * @remarks this method may return NULL.
1033 SmNode
* GetSubSup(SmSubSup eSubSup
) { return GetSubNode( sal::static_int_cast
< sal_uInt16
>(1 + eSubSup
) ); };
1034 const SmNode
* GetSubSup(SmSubSup eSubSup
) const { return const_cast< SmSubSupNode
* >( this )->GetSubSup( eSubSup
); }
1037 void SetBody(SmNode
* pBody
) { SetSubNode(0, pBody
); }
1038 void SetSubSup(SmSubSup eSubSup
, SmNode
* pScript
) { SetSubNode( 1 + eSubSup
, pScript
); }
1040 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1041 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1042 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1049 /** Node for brace construction
1051 * Used for "lbrace [body] rbrace" and similar constructions.
1052 * Should look like \f$ \{\mbox{[body]}\} \f$
1055 * 0: Opening brace<BR>
1056 * 1: Body (usually SmBracebodyNode)<BR>
1057 * 2: Closing brace<BR>
1058 * None of the children can be NULL.
1060 * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
1062 class SmBraceNode
: public SmStructureNode
1065 SmBraceNode(const SmToken
&rNodeToken
)
1066 : SmStructureNode(NBRACE
, rNodeToken
)
1071 SmMathSymbolNode
* OpeningBrace();
1072 const SmMathSymbolNode
* OpeningBrace() const;
1074 const SmNode
* Body() const;
1075 SmMathSymbolNode
* ClosingBrace();
1076 const SmMathSymbolNode
* ClosingBrace() const;
1078 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1079 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1080 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1086 /** Body of an SmBraceNode
1088 * This usually only has one child an SmExpressionNode, however, it can also
1089 * have other children.
1090 * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
1091 * \f$ \{\mbox{[body1] | [body2]}\} \f$.
1092 * In this case SmBracebodyNode will have three children, "[body1]", "|" and
1095 class SmBracebodyNode
: public SmStructureNode
1100 inline SmBracebodyNode(const SmToken
&rNodeToken
);
1102 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1103 long GetBodyHeight() const { return nBodyHeight
; }
1104 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1108 inline SmBracebodyNode::SmBracebodyNode(const SmToken
&rNodeToken
) :
1109 SmStructureNode(NBRACEBODY
, rNodeToken
)
1117 /** Node for vertical brace construction
1119 * Used to implement commands "[body] underbrace [script]" and
1120 * "[body] overbrace [script]".
1121 * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
1127 * (None of these children are optional, e.g. they must all be not NULL).
1129 class SmVerticalBraceNode
: public SmStructureNode
1132 inline SmVerticalBraceNode(const SmToken
&rNodeToken
);
1135 const SmNode
* Body() const;
1136 SmMathSymbolNode
* Brace();
1137 const SmMathSymbolNode
* Brace() const;
1139 const SmNode
* Script() const;
1141 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1142 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1146 inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken
&rNodeToken
) :
1147 SmStructureNode(NVERTICAL_BRACE
, rNodeToken
)
1158 * Used for commands like SUM, INT and similar.
1161 * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
1163 * None of the children may be NULL.
1166 class SmOperNode
: public SmStructureNode
1169 SmOperNode(const SmToken
&rNodeToken
)
1170 : SmStructureNode(NOPER
, rNodeToken
)
1175 SmNode
* GetSymbol();
1176 const SmNode
* GetSymbol() const
1178 return ((SmOperNode
*) this)->GetSymbol();
1181 long CalcSymbolHeight(const SmNode
&rSymbol
, const SmFormat
&rFormat
) const;
1183 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1184 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1190 /** Node used for alignment
1192 class SmAlignNode
: public SmStructureNode
1195 SmAlignNode(const SmToken
&rNodeToken
)
1196 : SmStructureNode(NALIGN
, rNodeToken
)
1199 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1200 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1208 * Used to give an attribute to another node. Used for commands such as:
1209 * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHAT and WIDETILDE.
1214 * None of these may be NULL.
1216 class SmAttributNode
: public SmStructureNode
1219 SmAttributNode(const SmToken
&rNodeToken
)
1220 : SmStructureNode(NATTRIBUT
, rNodeToken
)
1223 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1224 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1225 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1227 SmNode
* Attribute();
1228 const SmNode
* Attribute() const;
1230 const SmNode
* Body() const;
1238 * Used to change the font of its children.
1240 class SmFontNode
: public SmStructureNode
1242 sal_uInt16 nSizeType
;
1246 SmFontNode(const SmToken
&rNodeToken
)
1247 : SmStructureNode(NFONT
, rNodeToken
)
1249 nSizeType
= FNTSIZ_MULTIPLY
;
1250 aFontSize
= Fraction(1L);
1253 void SetSizeParameter(const Fraction
&rValue
, sal_uInt16 nType
);
1254 const Fraction
& GetSizeParameter() const {return aFontSize
;}
1255 const sal_uInt16
& GetSizeType() const {return nSizeType
;}
1257 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
1258 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1259 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1260 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1268 * Used to implement the MATRIX command, example:
1269 * "matrix{ 1 # 2 ## 3 # 4}".
1271 class SmMatrixNode
: public SmStructureNode
1273 sal_uInt16 nNumRows
,
1277 SmMatrixNode(const SmToken
&rNodeToken
)
1278 : SmStructureNode(NMATRIX
, rNodeToken
)
1280 nNumRows
= nNumCols
= 0;
1283 sal_uInt16
GetNumRows() const {return nNumRows
;}
1284 sal_uInt16
GetNumCols() const {return nNumCols
;}
1285 void SetRowCol(sal_uInt16 nMatrixRows
, sal_uInt16 nMatrixCols
);
1287 using SmNode::GetLeftMost
;
1288 virtual SmNode
* GetLeftMost() SAL_OVERRIDE
;
1290 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1291 void CreateTextFromNode(OUString
&rText
) SAL_OVERRIDE
;
1292 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1298 /** Node for whitespace
1300 * Used to implement the "~" command. This node is just a blank space.
1302 class SmBlankNode
: public SmGraphicNode
1307 SmBlankNode(const SmToken
&rNodeToken
)
1308 : SmGraphicNode(NBLANK
, rNodeToken
)
1313 void IncreaseBy(const SmToken
&rToken
);
1314 void Clear() { nNum
= 0; }
1315 sal_uInt16
GetBlankNum() const { return nNum
; }
1316 void SetBlankNum(sal_uInt16 nNumber
) { nNum
= nNumber
; }
1318 virtual void Prepare(const SmFormat
&rFormat
, const SmDocShell
&rDocShell
) SAL_OVERRIDE
;
1319 virtual void Arrange(const OutputDevice
&rDev
, const SmFormat
&rFormat
) SAL_OVERRIDE
;
1320 void Accept(SmVisitor
* pVisitor
) SAL_OVERRIDE
;
1327 inline SmNode
* SmRootNode::Argument()
1329 OSL_ASSERT( GetNumSubNodes() > 0 );
1330 return GetSubNode( 0 );
1332 inline const SmNode
* SmRootNode::Argument() const
1334 return const_cast< SmRootNode
* >( this )->Argument();
1336 inline SmRootSymbolNode
* SmRootNode::Symbol()
1338 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NROOTSYMBOL
);
1339 return static_cast< SmRootSymbolNode
* >( GetSubNode( 1 ));
1341 inline const SmRootSymbolNode
* SmRootNode::Symbol() const
1343 return const_cast< SmRootNode
* >( this )->Symbol();
1345 inline SmNode
* SmRootNode::Body()
1347 OSL_ASSERT( GetNumSubNodes() > 2 );
1348 return GetSubNode( 2 );
1350 inline const SmNode
* SmRootNode::Body() const
1352 return const_cast< SmRootNode
* >( this )->Body();
1357 inline SmDynIntegralSymbolNode
* SmDynIntegralNode::Symbol()
1359 OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NDYNINTSYMBOL
);
1360 return static_cast< SmDynIntegralSymbolNode
* >( GetSubNode( 0 ));
1362 inline const SmDynIntegralSymbolNode
* SmDynIntegralNode::Symbol() const
1364 return const_cast< SmDynIntegralNode
* >( this )->Symbol();
1366 inline SmNode
* SmDynIntegralNode::Body()
1368 OSL_ASSERT( GetNumSubNodes() > 1 );
1369 return GetSubNode( 1 );
1371 inline const SmNode
* SmDynIntegralNode::Body() const
1373 return const_cast< SmDynIntegralNode
* >( this )->Body();
1377 inline SmMathSymbolNode
* SmBinHorNode::Symbol()
1379 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH
);
1380 return static_cast< SmMathSymbolNode
* >( GetSubNode( 1 ));
1382 inline const SmMathSymbolNode
* SmBinHorNode::Symbol() const
1384 return const_cast< SmBinHorNode
* >( this )->Symbol();
1386 inline SmNode
* SmBinHorNode::LeftOperand()
1388 OSL_ASSERT( GetNumSubNodes() > 0 );
1389 return GetSubNode( 0 );
1391 inline const SmNode
* SmBinHorNode::LeftOperand() const
1393 return const_cast< SmBinHorNode
* >( this )->LeftOperand();
1395 inline SmNode
* SmBinHorNode::RightOperand()
1397 OSL_ASSERT( GetNumSubNodes() > 2 );
1398 return GetSubNode( 2 );
1400 inline const SmNode
* SmBinHorNode::RightOperand() const
1402 return const_cast< SmBinHorNode
* >( this )->RightOperand();
1405 inline SmNode
* SmAttributNode::Attribute()
1407 OSL_ASSERT( GetNumSubNodes() > 0 );
1408 return GetSubNode( 0 );
1410 inline const SmNode
* SmAttributNode::Attribute() const
1412 return const_cast< SmAttributNode
* >( this )->Attribute();
1414 inline SmNode
* SmAttributNode::Body()
1416 OSL_ASSERT( GetNumSubNodes() > 1 );
1417 return GetSubNode( 1 );
1419 inline const SmNode
* SmAttributNode::Body() const
1421 return const_cast< SmAttributNode
* >( this )->Body();
1424 inline SmMathSymbolNode
* SmBraceNode::OpeningBrace()
1426 OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NMATH
);
1427 return static_cast< SmMathSymbolNode
* >( GetSubNode( 0 ));
1429 inline const SmMathSymbolNode
* SmBraceNode::OpeningBrace() const
1431 return const_cast< SmBraceNode
* >( this )->OpeningBrace();
1433 inline SmNode
* SmBraceNode::Body()
1435 OSL_ASSERT( GetNumSubNodes() > 1 );
1436 return GetSubNode( 1 );
1438 inline const SmNode
* SmBraceNode::Body() const
1440 return const_cast< SmBraceNode
* >( this )->Body();
1442 inline SmMathSymbolNode
* SmBraceNode::ClosingBrace()
1444 OSL_ASSERT( GetNumSubNodes() > 2 && GetSubNode( 2 )->GetType() == NMATH
);
1445 return static_cast< SmMathSymbolNode
* >( GetSubNode( 2 ));
1447 inline const SmMathSymbolNode
* SmBraceNode::ClosingBrace() const
1449 return const_cast< SmBraceNode
* >( this )->ClosingBrace();
1452 inline SmNode
* SmVerticalBraceNode::Body()
1454 OSL_ASSERT( GetNumSubNodes() > 0 );
1455 return GetSubNode( 0 );
1457 inline const SmNode
* SmVerticalBraceNode::Body() const
1459 return const_cast< SmVerticalBraceNode
* >( this )->Body();
1461 inline SmMathSymbolNode
* SmVerticalBraceNode::Brace()
1463 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH
);
1464 return static_cast< SmMathSymbolNode
* >( GetSubNode( 1 ));
1466 inline const SmMathSymbolNode
* SmVerticalBraceNode::Brace() const
1468 return const_cast< SmVerticalBraceNode
* >( this )->Brace();
1470 inline SmNode
* SmVerticalBraceNode::Script()
1472 OSL_ASSERT( GetNumSubNodes() > 2 );
1473 return GetSubNode( 2 );
1475 inline const SmNode
* SmVerticalBraceNode::Script() const
1477 return const_cast< SmVerticalBraceNode
* >( this )->Script();
1483 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */