bump product version to 4.1.6.2
[LibreOffice.git] / starmath / inc / node.hxx
blobb1640a338e56f5461657fa77e15acc5291e45460
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 NODE_HXX
21 #define NODE_HXX
23 #include <vector>
24 #include <ostream>
25 #include <stdio.h>
27 #include "parse.hxx"
28 #include "types.hxx"
29 #include "rect.hxx"
30 #include "format.hxx"
33 #define ATTR_BOLD 0x0001
34 #define ATTR_ITALIC 0x0002
37 #define FNTSIZ_ABSOLUT 1
38 #define FNTSIZ_PLUS 2
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;
55 class SmVisitor;
56 class SmDocShell;
57 class SmNode;
58 class SmStructureNode;
60 typedef boost::shared_ptr<SmNode> SmNodePointer;
61 typedef std::vector< SmNode * > SmNodeArray;
62 typedef std::vector< SmStructureNode * > SmStructureNodeArray;
65 ////////////////////////////////////////////////////////////////////////////////
67 enum SmScaleMode { SCALE_NONE, SCALE_WIDTH, SCALE_HEIGHT };
69 enum SmNodeType
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
80 ////////////////////////////////////////////////////////////////////////////////
83 class SmNode : public SmRect
85 SmFace aFace;
87 SmToken aNodeToken;
88 SmNodeType eType;
89 SmScaleMode eScaleMode;
90 RectHorAlign eRectHorAlign;
91 sal_uInt16 nFlags,
92 nAttributes;
93 bool bIsPhantom,
94 bIsDebug;
96 bool bIsSelected;
98 protected:
99 SmNode(SmNodeType eNodeType, const SmToken &rNodeToken);
101 // index in accessible text -1 if not (yet) applicable
102 sal_Int32 nAccIndex;
104 public:
105 virtual ~SmNode();
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;
145 #if OSL_DEBUG_LEVEL
146 void ToggleDebug() const;
147 #endif
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(String &rText);
160 virtual void GetAccessibleText( OUStringBuffer &rText ) const;
161 sal_Int32 GetAccessibleIndex() const { return nAccIndex; }
162 const SmNode * FindNodeWithAccessibleIndex(xub_StrLen 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;
181 /** Accept a visitor
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{
195 int id = 0;
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))
216 return i;
217 return -1;
219 /** Set the token for this node */
220 void SetToken(SmToken& token){
221 aNodeToken = token;
223 protected:
224 /** Sets parent on children of this node */
225 void ClaimPaternity(){
226 SmNode* pNode;
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
232 private:
233 SmStructureNode* aParentNode;
234 void DumpAsDot(std::ostream &out, OUString* label, int number, int& id, int parent) const;
237 ////////////////////////////////////////////////////////////////////////////////
239 /** A simple auxiliary iterator class for SmNode
241 * Example of iteration over children of pMyNode:
242 * \code
243 * //Node to iterate over:
244 * SmNode* pMyNode = 0;// A pointer from somewhere
245 * //The iterator:
246 * SmNodeIterator it(pMyNode);
247 * //The iteration:
248 * while(it.Next()) {
249 * it->SetSelected(true);
251 * \endcode
253 class SmNodeIterator{
254 public:
255 SmNodeIterator(SmNode* node, bool bReverse = false){
256 pNode = node;
257 nSize = pNode->GetNumSubNodes();
258 nIndex = 0;
259 pChildNode = NULL;
260 bIsReverse = bReverse;
262 /** Get the subnode or NULL if none */
263 SmNode* Next(){
264 while(!bIsReverse && nIndex < nSize){
265 if(NULL != (pChildNode = pNode->GetSubNode(nIndex++)))
266 return pChildNode;
268 while(bIsReverse && nSize > 0){
269 if(NULL != (pChildNode = pNode->GetSubNode((nSize--)-1)))
270 return pChildNode;
272 pChildNode = NULL;
273 return NULL;
275 /** Get the current child node, NULL if none */
276 SmNode* Current(){
277 return pChildNode;
279 /** Get the current child node, NULL if none */
280 SmNode* operator->(){
281 return pChildNode;
283 private:
284 /** Current child */
285 SmNode* pChildNode;
286 /** Node whos children we're iterating over */
287 SmNode* pNode;
288 /** Size of the node */
289 sal_uInt16 nSize;
290 /** Current index in the node */
291 sal_uInt16 nIndex;
292 /** Move reverse */
293 bool bIsReverse;
296 ////////////////////////////////////////////////////////////////////////////////
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;
307 protected:
308 SmStructureNode(SmNodeType eNodeType, const SmToken &rNodeToken)
309 : SmNode(eNodeType, rNodeToken)
312 public:
313 SmStructureNode( const SmStructureNode &rNode );
314 virtual ~SmStructureNode();
316 virtual bool IsVisible() const;
318 virtual sal_uInt16 GetNumSubNodes() const;
319 void SetNumSubNodes(sal_uInt16 nSize) { aSubNodes.resize(nSize); }
321 using SmNode::GetSubNode;
322 virtual SmNode * GetSubNode(sal_uInt16 nIndex);
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;
330 void SetSubNode(size_t nIndex, SmNode* pNode)
332 size_t size = aSubNodes.size();
333 if (size <= nIndex)
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++)
339 aSubNodes[i] = NULL;
341 aSubNodes[nIndex] = pNode;
342 ClaimPaternity();
347 ////////////////////////////////////////////////////////////////////////////////
349 /** Abstract base class for all visible node
351 * Nodes that doesn't derivate from this class doesn't draw anything, but their
352 * children.
354 class SmVisibleNode : public SmNode
356 protected:
357 SmVisibleNode(SmNodeType eNodeType, const SmToken &rNodeToken)
358 : SmNode(eNodeType, rNodeToken)
361 public:
363 virtual bool IsVisible() const;
364 virtual sal_uInt16 GetNumSubNodes() const;
365 using SmNode::GetSubNode;
366 virtual SmNode * GetSubNode(sal_uInt16 nIndex);
370 ////////////////////////////////////////////////////////////////////////////////
373 class SmGraphicNode : public SmVisibleNode
375 protected:
376 SmGraphicNode(SmNodeType eNodeType, const SmToken &rNodeToken)
377 : SmVisibleNode(eNodeType, rNodeToken)
380 public:
382 virtual void GetAccessibleText( OUStringBuffer &rText ) const;
386 ////////////////////////////////////////////////////////////////////////////////
388 /** Draws a rectangle
390 * Used for drawing the line in the OVER and OVERSTRIKE commands.
392 class SmRectangleNode : public SmGraphicNode
394 Size aToSize;
396 public:
397 SmRectangleNode(const SmToken &rNodeToken)
398 : SmGraphicNode(NRECTANGLE, rNodeToken)
401 virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
402 virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
404 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
406 void CreateTextFromNode(String &rText);
407 void Accept(SmVisitor* pVisitor);
411 ////////////////////////////////////////////////////////////////////////////////
413 /** Polygon line node
415 * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
417 class SmPolyLineNode : public SmGraphicNode
419 Polygon aPoly;
420 Size aToSize;
421 long nWidth;
423 public:
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);
431 virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
433 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
435 void Accept(SmVisitor* pVisitor);
439 ////////////////////////////////////////////////////////////////////////////////
441 /** Text node
443 * @remarks This class also serves as baseclass for all nodes that contains text.
445 class SmTextNode : public SmVisibleNode
447 OUString aText;
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;
458 protected:
459 SmTextNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 nFontDescP );
461 public:
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) {
469 aText = rText;
470 SmToken token = GetToken();
471 token.aText = rText;
472 SetToken(token); //TODO: Merge this with AdjustFontDesc for better performance
473 AdjustFontDesc();
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);
491 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
492 virtual void CreateTextFromNode(String &rText);
494 virtual void GetAccessibleText( OUStringBuffer &rText ) const;
495 void Accept(SmVisitor* pVisitor);
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);
504 ////////////////////////////////////////////////////////////////////////////////
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;
517 protected:
518 SmSpecialNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 _nFontDesc);
520 public:
521 SmSpecialNode(const SmToken &rNodeToken);
523 virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
524 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
526 void Accept(SmVisitor* pVisitor);
530 ////////////////////////////////////////////////////////////////////////////////
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
543 public:
544 SmGlyphSpecialNode(const SmToken &rNodeToken)
545 : SmSpecialNode(NGLYPH_SPECIAL, rNodeToken, FNT_MATH)
548 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
549 void Accept(SmVisitor* pVisitor);
553 ////////////////////////////////////////////////////////////////////////////////
555 /** Math symbol node
557 * Use for math symbols such as plus, minus and integrale in the INT command.
559 class SmMathSymbolNode : public SmSpecialNode
561 protected:
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));
570 public:
571 SmMathSymbolNode(const SmToken &rNodeToken);
573 virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
574 virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
576 virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
577 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
578 void CreateTextFromNode(String &rText);
579 void Accept(SmVisitor* pVisitor);
583 ////////////////////////////////////////////////////////////////////////////////
585 /** Root symbol node
587 * Root symbol node used by SmRootNode to create the root symbol, in front of
588 * the line with the line above. I don't think this node should be used for
589 * anything else.
591 class SmRootSymbolNode : public SmMathSymbolNode
593 sal_uLong nBodyWidth; // width of body (argument) of root sign
595 public:
596 SmRootSymbolNode(const SmToken &rNodeToken)
597 : SmMathSymbolNode(NROOTSYMBOL, rNodeToken)
600 sal_uLong GetBodyWidth() const {return nBodyWidth;};
601 virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nHeight);
602 virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
604 void Accept(SmVisitor* pVisitor);
608 ////////////////////////////////////////////////////////////////////////////////
610 /** Place node
612 * Used to create the <?> command, that denotes place where something can be
613 * written.
614 * It is drawn as a square with a shadow.
616 class SmPlaceNode : public SmMathSymbolNode
618 public:
619 SmPlaceNode(const SmToken &rNodeToken)
620 : SmMathSymbolNode(NPLACE, rNodeToken)
623 SmPlaceNode() : SmMathSymbolNode(NPLACE, SmToken(TPLACE, MS_PLACE, "<?>")) {};
625 virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
626 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
627 void Accept(SmVisitor* pVisitor);
631 ////////////////////////////////////////////////////////////////////////////////
633 /** Error node, for parsing errors
635 * This node is used for parsing errors and draws an questionmark turned upside
636 * down (inverted question mark).
638 class SmErrorNode : public SmMathSymbolNode
640 public:
641 SmErrorNode(SmParseError /*eError*/, const SmToken &rNodeToken)
642 : SmMathSymbolNode(NERROR, rNodeToken)
644 SetText(OUString(MS_ERROR));
647 virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
648 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
649 void Accept(SmVisitor* pVisitor);
653 ////////////////////////////////////////////////////////////////////////////////
655 /** Table node
657 * This is the root node for the formula tree. This node is also used for the
658 * STACK and BINOM commands. When used for root node, its
659 * children are instances of SmLineNode, and in some obscure cases the a child
660 * can be an instance of SmExpressionNode, mainly when errors occur.
662 class SmTableNode : public SmStructureNode
664 long nFormulaBaseline;
665 public:
666 SmTableNode(const SmToken &rNodeToken)
667 : SmStructureNode(NTABLE, rNodeToken)
670 using SmNode::GetLeftMost;
671 virtual SmNode * GetLeftMost();
673 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
674 virtual long GetFormulaBaseline() const;
676 void Accept(SmVisitor* pVisitor);
680 ////////////////////////////////////////////////////////////////////////////////
682 /** A line
684 * Used as child of SmTableNode when the SmTableNode is the root node of the
685 * formula tree.
687 class SmLineNode : public SmStructureNode
689 bool bUseExtraSpaces;
691 protected:
692 SmLineNode(SmNodeType eNodeType, const SmToken &rNodeToken)
693 : SmStructureNode(eNodeType, rNodeToken)
695 bUseExtraSpaces = true;
698 public:
699 SmLineNode(const SmToken &rNodeToken)
700 : SmStructureNode(NLINE, rNodeToken)
702 bUseExtraSpaces = true;
705 void SetUseExtraSpaces(bool bVal) { bUseExtraSpaces = bVal; }
706 bool IsUseExtraSpaces() const { return bUseExtraSpaces; };
708 virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
709 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
710 void Accept(SmVisitor* pVisitor);
714 ////////////////////////////////////////////////////////////////////////////////
716 /** Expression node
718 * Used whenever you have an expression such as "A OVER {B + C}", here there is
719 * an expression node that allows "B + C" to be the denominator of the
720 * SmBinVerNode, that the OVER command creates.
722 class SmExpressionNode : public SmLineNode
724 public:
725 SmExpressionNode(const SmToken &rNodeToken)
726 : SmLineNode(NEXPRESSION, rNodeToken)
729 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
730 void CreateTextFromNode(String &rText);
731 void Accept(SmVisitor* pVisitor);
735 ////////////////////////////////////////////////////////////////////////////////
737 /** Unary horizontical node
739 * The same as SmBinHorNode except this is for unary operators.
741 class SmUnHorNode : public SmStructureNode
743 public:
744 SmUnHorNode(const SmToken &rNodeToken)
745 : SmStructureNode(NUNHOR, rNodeToken)
747 SetNumSubNodes(2);
750 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
751 void Accept(SmVisitor* pVisitor);
755 ////////////////////////////////////////////////////////////////////////////////
757 /** Root node
759 * Used for create square roots and other roots, example:
760 * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
762 * Children:<BR>
763 * 0: Argument (optional)<BR>
764 * 1: Symbol (instance of SmRootSymbolNode)<BR>
765 * 2: Body<BR>
766 * Where argument is optional and may be NULL.
768 class SmRootNode : public SmStructureNode
770 protected:
771 void GetHeightVerOffset(const SmRect &rRect,
772 long &rHeight, long &rVerOffset) const;
773 Point GetExtraPos(const SmRect &rRootSymbol, const SmRect &rExtra) const;
775 public:
776 SmRootNode(const SmToken &rNodeToken)
777 : SmStructureNode(NROOT, rNodeToken)
779 SetNumSubNodes(3);
782 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
783 void CreateTextFromNode(String &rText);
784 void Accept(SmVisitor* pVisitor);
786 SmNode* Argument();
787 const SmNode* Argument() const;
788 SmRootSymbolNode* Symbol();
789 const SmRootSymbolNode* Symbol() const;
790 SmNode* Body();
791 const SmNode* Body() const;
795 ////////////////////////////////////////////////////////////////////////////////
797 /** Binary horizontial node
799 * This node is used for binary operators. In a formula such as "A + B".
801 * Children:<BR>
802 * 0: Left operand<BR>
803 * 1: Binary operator<BR>
804 * 2: Right operand<BR>
806 * None of the children may be NULL.
808 class SmBinHorNode : public SmStructureNode
810 public:
811 SmBinHorNode(const SmToken &rNodeToken)
812 : SmStructureNode(NBINHOR, rNodeToken)
814 SetNumSubNodes(3);
817 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
818 void Accept(SmVisitor* pVisitor);
820 SmMathSymbolNode* Symbol();
821 const SmMathSymbolNode* Symbol() const;
822 SmNode* LeftOperand();
823 const SmNode* LeftOperand() const;
824 SmNode* RightOperand();
825 const SmNode* RightOperand() const;
829 ////////////////////////////////////////////////////////////////////////////////
831 /** Binary horizontical node
833 * This node is used for creating the OVER command, consider the formula:
834 * "numerator OVER denominator", which looks like
835 * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
837 * Children:<BR>
838 * 0: Numerator<BR>
839 * 1: Line (instance of SmRectangleNode)<BR>
840 * 2: Denominator<BR>
841 * None of the children may be NULL.
843 class SmBinVerNode : public SmStructureNode
845 public:
846 SmBinVerNode(const SmToken &rNodeToken)
847 : SmStructureNode(NBINVER, rNodeToken)
849 SetNumSubNodes(3);
852 using SmNode::GetLeftMost;
853 virtual SmNode * GetLeftMost();
855 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
856 void CreateTextFromNode(String &rText);
857 void Accept(SmVisitor* pVisitor);
861 ////////////////////////////////////////////////////////////////////////////////
863 /** Binary diagonal node
865 * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
867 * Children:<BR>
868 * 0: Left operand<BR>
869 * 1: right operand<BR>
870 * 2: Line (instance of SmPolyLineNode).<BR>
871 * None of the children may be NULL.
873 class SmBinDiagonalNode : public SmStructureNode
875 bool bAscending;
877 void GetOperPosSize(Point &rPos, Size &rSize,
878 const Point &rDiagPoint, double fAngleDeg) const;
880 public:
881 SmBinDiagonalNode(const SmToken &rNodeToken);
883 bool IsAscending() const { return bAscending; }
884 void SetAscending(bool bVal) { bAscending = bVal; }
886 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
887 void Accept(SmVisitor* pVisitor);
891 ////////////////////////////////////////////////////////////////////////////////
894 /** Enum used to index sub-/supscripts in the 'aSubNodes' array
895 * in 'SmSubSupNode'
897 * See graphic for positions at char:
899 * \code
900 * CSUP
902 * LSUP H H RSUP
903 * H H
904 * HHHH
905 * H H
906 * LSUB H H RSUB
908 * CSUB
909 * \endcode
911 enum SmSubSup
912 { CSUB, CSUP, RSUB, RSUP, LSUB, LSUP
915 /** numbers of entries in the above enum (that is: the number of possible
916 * sub-/supscripts)
918 #define SUBSUP_NUM_ENTRIES 6
920 /** Super- and subscript node
922 * Used for creating super- and subscripts for commands such as:
923 * "^", "_", "lsup", "lsub", "csup" and "csub".
924 * Example: "A^2" which looks like: \f$ A^2 \f$
926 * This node is also used for creating limits on SmOperNode, when
927 * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
929 * Children of this node can be enumerated using the SmSubSup enum.
930 * Please note that children may be NULL, except for the body.
931 * It is recommended that you access children using GetBody() and
932 * GetSubSup().
934 class SmSubSupNode : public SmStructureNode
936 bool bUseLimits;
938 public:
939 SmSubSupNode(const SmToken &rNodeToken)
940 : SmStructureNode(NSUBSUP, rNodeToken)
942 SetNumSubNodes(1 + SUBSUP_NUM_ENTRIES);
943 bUseLimits = false;
946 /** Get body (Not NULL) */
947 SmNode * GetBody() { return GetSubNode(0); }
948 /** Get body (Not NULL) */
949 const SmNode * GetBody() const
951 return ((SmSubSupNode *) this)->GetBody();
954 void SetUseLimits(bool bVal) { bUseLimits = bVal; }
955 bool IsUseLimits() const { return bUseLimits; };
957 /** Get super- or subscript
958 * @remarks this method may return NULL.
960 SmNode * GetSubSup(SmSubSup eSubSup) { return GetSubNode( sal::static_int_cast< sal_uInt16 >(1 + eSubSup) ); };
961 const SmNode * GetSubSup(SmSubSup eSubSup) const { return const_cast< SmSubSupNode* >( this )->GetSubSup( eSubSup ); }
963 /** Set the body */
964 void SetBody(SmNode* pBody) { SetSubNode(0, pBody); }
965 void SetSubSup(SmSubSup eSubSup, SmNode* pScript) { SetSubNode( 1 + eSubSup, pScript); }
967 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
968 void CreateTextFromNode(String &rText);
969 void Accept(SmVisitor* pVisitor);
974 ////////////////////////////////////////////////////////////////////////////////
976 /** Node for brace construction
978 * Used for "lbrace [body] rbrace" and similar constructions.
979 * Should look like \f$ \{\mbox{[body]}\} \f$
981 * Children:<BR>
982 * 0: Opening brace<BR>
983 * 1: Body (usually SmBracebodyNode)<BR>
984 * 2: Closing brace<BR>
985 * None of the children can be NULL.
987 * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
989 class SmBraceNode : public SmStructureNode
991 public:
992 SmBraceNode(const SmToken &rNodeToken)
993 : SmStructureNode(NBRACE, rNodeToken)
995 SetNumSubNodes(3);
998 SmMathSymbolNode* OpeningBrace();
999 const SmMathSymbolNode* OpeningBrace() const;
1000 SmNode* Body();
1001 const SmNode* Body() const;
1002 SmMathSymbolNode* ClosingBrace();
1003 const SmMathSymbolNode* ClosingBrace() const;
1005 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1006 void CreateTextFromNode(String &rText);
1007 void Accept(SmVisitor* pVisitor);
1011 ////////////////////////////////////////////////////////////////////////////////
1013 /** Body of an SmBraceNode
1015 * This usually only has one child an SmExpressionNode, however, it can also
1016 * have other children.
1017 * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
1018 * \f$ \{\mbox{[body1] | [body2]}\} \f$.
1019 * In this case SmBracebodyNode will have three children, "[body1]", "|" and
1020 * [body2].
1022 class SmBracebodyNode : public SmStructureNode
1024 long nBodyHeight;
1026 public:
1027 inline SmBracebodyNode(const SmToken &rNodeToken);
1029 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1030 long GetBodyHeight() const { return nBodyHeight; }
1031 void Accept(SmVisitor* pVisitor);
1035 inline SmBracebodyNode::SmBracebodyNode(const SmToken &rNodeToken) :
1036 SmStructureNode(NBRACEBODY, rNodeToken)
1038 nBodyHeight = 0;
1042 ////////////////////////////////////////////////////////////////////////////////
1044 /** Node for vertical brace construction
1046 * Used to implement commands "[body] underbrace [script]" and
1047 * "[body] overbrace [script]".
1048 * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
1050 * Children:<BR>
1051 * 0: body<BR>
1052 * 1: brace<BR>
1053 * 2: script<BR>
1054 * (None of these children are optional, e.g. they must all be not NULL).
1056 class SmVerticalBraceNode : public SmStructureNode
1058 public:
1059 inline SmVerticalBraceNode(const SmToken &rNodeToken);
1061 SmNode* Body();
1062 const SmNode* Body() const;
1063 SmMathSymbolNode* Brace();
1064 const SmMathSymbolNode* Brace() const;
1065 SmNode* Script();
1066 const SmNode* Script() const;
1068 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1069 void Accept(SmVisitor* pVisitor);
1073 inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken &rNodeToken) :
1074 SmStructureNode(NVERTICAL_BRACE, rNodeToken)
1076 SetNumSubNodes(3);
1080 ////////////////////////////////////////////////////////////////////////////////
1083 /** Operation Node
1085 * Used for commands like SUM, INT and similar.
1087 * Children:<BR>
1088 * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
1089 * 1: Body<BR>
1090 * None of the children may be NULL.
1093 class SmOperNode : public SmStructureNode
1095 public:
1096 SmOperNode(const SmToken &rNodeToken)
1097 : SmStructureNode(NOPER, rNodeToken)
1099 SetNumSubNodes(2);
1102 SmNode * GetSymbol();
1103 const SmNode * GetSymbol() const
1105 return ((SmOperNode *) this)->GetSymbol();
1108 long CalcSymbolHeight(const SmNode &rSymbol, const SmFormat &rFormat) const;
1110 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1111 void Accept(SmVisitor* pVisitor);
1115 ////////////////////////////////////////////////////////////////////////////////
1117 /** Node used for alignment
1119 class SmAlignNode : public SmStructureNode
1121 public:
1122 SmAlignNode(const SmToken &rNodeToken)
1123 : SmStructureNode(NALIGN, rNodeToken)
1126 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1127 void Accept(SmVisitor* pVisitor);
1131 ////////////////////////////////////////////////////////////////////////////////
1133 /** Attribute node
1135 * Used to give an attribute to another node. Used for commands such as:
1136 * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHAT and WIDETILDE.
1138 * Children:<BR>
1139 * 0: Attribute<BR>
1140 * 1: Body<BR>
1141 * None of these may be NULL.
1143 class SmAttributNode : public SmStructureNode
1145 public:
1146 SmAttributNode(const SmToken &rNodeToken)
1147 : SmStructureNode(NATTRIBUT, rNodeToken)
1150 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1151 void CreateTextFromNode(String &rText);
1152 void Accept(SmVisitor* pVisitor);
1154 SmNode* Attribute();
1155 const SmNode* Attribute() const;
1156 SmNode* Body();
1157 const SmNode* Body() const;
1161 ////////////////////////////////////////////////////////////////////////////////
1163 /** Font node
1165 * Used to change the font of it's children.
1167 class SmFontNode : public SmStructureNode
1169 sal_uInt16 nSizeType;
1170 Fraction aFontSize;
1172 public:
1173 SmFontNode(const SmToken &rNodeToken)
1174 : SmStructureNode(NFONT, rNodeToken)
1176 nSizeType = FNTSIZ_MULTIPLY;
1177 aFontSize = Fraction(1L);
1180 void SetSizeParameter(const Fraction &rValue, sal_uInt16 nType);
1181 const Fraction & GetSizeParameter() const {return aFontSize;}
1182 const sal_uInt16& GetSizeType() const {return nSizeType;}
1184 virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
1185 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1186 void CreateTextFromNode(String &rText);
1187 void Accept(SmVisitor* pVisitor);
1191 ////////////////////////////////////////////////////////////////////////////////
1193 /** Matrix node
1195 * Used to implement the MATRIX command, example:
1196 * "matrix{ 1 # 2 ## 3 # 4}".
1198 class SmMatrixNode : public SmStructureNode
1200 sal_uInt16 nNumRows,
1201 nNumCols;
1203 public:
1204 SmMatrixNode(const SmToken &rNodeToken)
1205 : SmStructureNode(NMATRIX, rNodeToken)
1207 nNumRows = nNumCols = 0;
1210 sal_uInt16 GetNumRows() const {return nNumRows;}
1211 sal_uInt16 GetNumCols() const {return nNumCols;}
1212 void SetRowCol(sal_uInt16 nMatrixRows, sal_uInt16 nMatrixCols);
1214 using SmNode::GetLeftMost;
1215 virtual SmNode * GetLeftMost();
1217 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1218 void CreateTextFromNode(String &rText);
1219 void Accept(SmVisitor* pVisitor);
1223 ////////////////////////////////////////////////////////////////////////////////
1225 /** Node for whitespace
1227 * Used to implement the "~" command. This node is just a blank space.
1229 class SmBlankNode : public SmGraphicNode
1231 sal_uInt16 nNum;
1233 public:
1234 SmBlankNode(const SmToken &rNodeToken)
1235 : SmGraphicNode(NBLANK, rNodeToken)
1237 nNum = 0;
1240 void IncreaseBy(const SmToken &rToken);
1241 void Clear() { nNum = 0; }
1242 sal_uInt16 GetBlankNum() const { return nNum; }
1243 void SetBlankNum(sal_uInt16 nNumber) { nNum = nNumber; }
1245 virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
1246 virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
1247 void Accept(SmVisitor* pVisitor);
1251 ////////////////////////////////////////////////////////////////////////////////
1254 inline SmNode* SmRootNode::Argument()
1256 OSL_ASSERT( GetNumSubNodes() > 0 );
1257 return GetSubNode( 0 );
1259 inline const SmNode* SmRootNode::Argument() const
1261 return const_cast< SmRootNode* >( this )->Argument();
1263 inline SmRootSymbolNode* SmRootNode::Symbol()
1265 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NROOTSYMBOL );
1266 return static_cast< SmRootSymbolNode* >( GetSubNode( 1 ));
1268 inline const SmRootSymbolNode* SmRootNode::Symbol() const
1270 return const_cast< SmRootNode* >( this )->Symbol();
1272 inline SmNode* SmRootNode::Body()
1274 OSL_ASSERT( GetNumSubNodes() > 2 );
1275 return GetSubNode( 2 );
1277 inline const SmNode* SmRootNode::Body() const
1279 return const_cast< SmRootNode* >( this )->Body();
1282 inline SmMathSymbolNode* SmBinHorNode::Symbol()
1284 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH );
1285 return static_cast< SmMathSymbolNode* >( GetSubNode( 1 ));
1287 inline const SmMathSymbolNode* SmBinHorNode::Symbol() const
1289 return const_cast< SmBinHorNode* >( this )->Symbol();
1291 inline SmNode* SmBinHorNode::LeftOperand()
1293 OSL_ASSERT( GetNumSubNodes() > 0 );
1294 return GetSubNode( 0 );
1296 inline const SmNode* SmBinHorNode::LeftOperand() const
1298 return const_cast< SmBinHorNode* >( this )->LeftOperand();
1300 inline SmNode* SmBinHorNode::RightOperand()
1302 OSL_ASSERT( GetNumSubNodes() > 2 );
1303 return GetSubNode( 2 );
1305 inline const SmNode* SmBinHorNode::RightOperand() const
1307 return const_cast< SmBinHorNode* >( this )->RightOperand();
1310 inline SmNode* SmAttributNode::Attribute()
1312 OSL_ASSERT( GetNumSubNodes() > 0 );
1313 return GetSubNode( 0 );
1315 inline const SmNode* SmAttributNode::Attribute() const
1317 return const_cast< SmAttributNode* >( this )->Attribute();
1319 inline SmNode* SmAttributNode::Body()
1321 OSL_ASSERT( GetNumSubNodes() > 1 );
1322 return GetSubNode( 1 );
1324 inline const SmNode* SmAttributNode::Body() const
1326 return const_cast< SmAttributNode* >( this )->Body();
1329 inline SmMathSymbolNode* SmBraceNode::OpeningBrace()
1331 OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NMATH );
1332 return static_cast< SmMathSymbolNode* >( GetSubNode( 0 ));
1334 inline const SmMathSymbolNode* SmBraceNode::OpeningBrace() const
1336 return const_cast< SmBraceNode* >( this )->OpeningBrace();
1338 inline SmNode* SmBraceNode::Body()
1340 OSL_ASSERT( GetNumSubNodes() > 1 );
1341 return GetSubNode( 1 );
1343 inline const SmNode* SmBraceNode::Body() const
1345 return const_cast< SmBraceNode* >( this )->Body();
1347 inline SmMathSymbolNode* SmBraceNode::ClosingBrace()
1349 OSL_ASSERT( GetNumSubNodes() > 2 && GetSubNode( 2 )->GetType() == NMATH );
1350 return static_cast< SmMathSymbolNode* >( GetSubNode( 2 ));
1352 inline const SmMathSymbolNode* SmBraceNode::ClosingBrace() const
1354 return const_cast< SmBraceNode* >( this )->ClosingBrace();
1357 inline SmNode* SmVerticalBraceNode::Body()
1359 OSL_ASSERT( GetNumSubNodes() > 0 );
1360 return GetSubNode( 0 );
1362 inline const SmNode* SmVerticalBraceNode::Body() const
1364 return const_cast< SmVerticalBraceNode* >( this )->Body();
1366 inline SmMathSymbolNode* SmVerticalBraceNode::Brace()
1368 OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH );
1369 return static_cast< SmMathSymbolNode* >( GetSubNode( 1 ));
1371 inline const SmMathSymbolNode* SmVerticalBraceNode::Brace() const
1373 return const_cast< SmVerticalBraceNode* >( this )->Brace();
1375 inline SmNode* SmVerticalBraceNode::Script()
1377 OSL_ASSERT( GetNumSubNodes() > 2 );
1378 return GetSubNode( 2 );
1380 inline const SmNode* SmVerticalBraceNode::Script() const
1382 return const_cast< SmVerticalBraceNode* >( this )->Script();
1385 #endif
1388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */