Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef INCLUDED_STARMATH_INC_NODE_HXX
21 : #define INCLUDED_STARMATH_INC_NODE_HXX
22 :
23 : #include <vector>
24 : #include <ostream>
25 :
26 : #include "types.hxx"
27 : #include "token.hxx"
28 : #include "error.hxx"
29 : #include "rect.hxx"
30 : #include "format.hxx"
31 : #include <boost/ptr_container/ptr_deque.hpp>
32 : #include <memory>
33 :
34 : #define ATTR_BOLD 0x0001
35 : #define ATTR_ITALIC 0x0002
36 :
37 :
38 : enum class FontSizeType {
39 : ABSOLUT = 1,
40 : PLUS = 2,
41 : MINUS = 3,
42 : MULTIPLY = 4,
43 : DIVIDE = 5
44 : };
45 :
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
54 :
55 :
56 : extern SmFormat *pActiveFormat;
57 :
58 : class SmVisitor;
59 : class SmDocShell;
60 : class SmNode;
61 : class SmStructureNode;
62 :
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;
67 :
68 : template < typename T >
69 18052 : T* popOrZero( boost::ptr_deque<T> & rStack )
70 : {
71 18052 : if (rStack.empty())
72 2 : return 0;
73 18050 : auto pTmp = rStack.pop_front();
74 18050 : return pTmp.release();
75 : }
76 :
77 : enum SmScaleMode { SCALE_NONE, SCALE_WIDTH, SCALE_HEIGHT };
78 :
79 : enum SmNodeType
80 : {
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
87 : };
88 :
89 :
90 :
91 :
92 :
93 0 : class SmNode : public SmRect
94 : {
95 : SmFace aFace;
96 :
97 : SmToken aNodeToken;
98 : SmNodeType eType;
99 : SmScaleMode eScaleMode;
100 : RectHorAlign eRectHorAlign;
101 : sal_uInt16 nFlags,
102 : nAttributes;
103 : bool bIsPhantom;
104 : bool bIsSelected;
105 :
106 : protected:
107 : SmNode(SmNodeType eNodeType, const SmToken &rNodeToken);
108 :
109 : // index in accessible text -1 if not (yet) applicable
110 : sal_Int32 nAccIndex;
111 :
112 : public:
113 : virtual ~SmNode();
114 :
115 : virtual bool IsVisible() const;
116 :
117 : virtual sal_uInt16 GetNumSubNodes() const;
118 : virtual SmNode * GetSubNode(sal_uInt16 nIndex);
119 12923 : const SmNode * GetSubNode(sal_uInt16 nIndex) const
120 : {
121 12923 : return const_cast<SmNode *>(this)->GetSubNode(nIndex);
122 : }
123 :
124 : virtual SmNode * GetLeftMost();
125 : const SmNode * GetLeftMost() const
126 : {
127 : return const_cast<SmNode *>(this)->GetLeftMost();
128 : }
129 :
130 7154 : sal_uInt16 & Flags() { return nFlags; }
131 18295 : sal_uInt16 & Attributes() { return nAttributes; }
132 :
133 70264 : bool IsPhantom() const { return bIsPhantom; }
134 : void SetPhantom(bool bIsPhantom);
135 : void SetColor(const Color &rColor);
136 :
137 : void SetAttribut(sal_uInt16 nAttrib);
138 : void ClearAttribut(sal_uInt16 nAttrib);
139 :
140 2151 : const SmFace & GetFont() const { return aFace; };
141 187622 : SmFace & GetFont() { return aFace; };
142 :
143 : void SetFont(const SmFace &rFace);
144 : void SetFontSize(const Fraction &rRelSize, FontSizeType nType);
145 : void SetSize(const Fraction &rScale);
146 :
147 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
148 : void PrepareAttributes();
149 :
150 : sal_uInt16 FindIndex() const;
151 :
152 : void SetRectHorAlign(RectHorAlign eHorAlign, bool bApplyToSubTree = true );
153 2721 : RectHorAlign GetRectHorAlign() const { return eRectHorAlign; }
154 :
155 : const SmRect & GetRect() const { return *this; }
156 5756 : SmRect & GetRect() { return *this; }
157 :
158 : void Move(const Point &rPosition);
159 7730 : void MoveTo(const Point &rPosition) { Move(rPosition - GetTopLeft()); }
160 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
161 : virtual void CreateTextFromNode(OUString &rText);
162 :
163 : virtual void GetAccessibleText( OUStringBuffer &rText ) const;
164 0 : sal_Int32 GetAccessibleIndex() const { return nAccIndex; }
165 : const SmNode * FindNodeWithAccessibleIndex(sal_Int32 nAccIndex) const;
166 :
167 0 : sal_uInt16 GetRow() const { return (sal_uInt16)aNodeToken.nRow; }
168 0 : sal_uInt16 GetColumn() const { return (sal_uInt16)aNodeToken.nCol; }
169 :
170 2638 : SmScaleMode GetScaleMode() const { return eScaleMode; }
171 1340 : void SetScaleMode(SmScaleMode eMode) { eScaleMode = eMode; }
172 :
173 : virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
174 : virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
175 :
176 17542 : SmNodeType GetType() const { return eType; }
177 34313 : const SmToken & GetToken() const { return aNodeToken; }
178 :
179 : const SmNode * FindTokenAt(sal_uInt16 nRow, sal_uInt16 nCol) const;
180 : const SmNode * FindRectClosestTo(const Point &rPoint) const;
181 :
182 : virtual long GetFormulaBaseline() const;
183 :
184 : /** Accept a visitor
185 : * Calls the method for this class on the visitor
186 : */
187 : virtual void Accept(SmVisitor* pVisitor);
188 :
189 : /** True if this node is selected */
190 36 : bool IsSelected() const {return bIsSelected;}
191 230 : void SetSelected(bool Selected = true) {bIsSelected = Selected;}
192 :
193 : #ifdef DEBUG_ENABLE_DUMPASDOT
194 : /** The tree as dot graph for graphviz, usable for debugging
195 : * Convert the output to a image using $ dot graph.gv -Tpng > graph.png
196 : */
197 : inline void DumpAsDot(std::ostream &out, OUString* label = NULL) const{
198 : int id = 0;
199 : DumpAsDot(out, label, -1, id, -1);
200 : }
201 : #endif /* DEBUG_ENABLE_DUMPASDOT */
202 :
203 : /** Get the parent node of this node */
204 175 : SmStructureNode* GetParent(){ return aParentNode; }
205 0 : const SmStructureNode* GetParent() const { return aParentNode; }
206 : /** Set the parent node */
207 14292 : void SetParent(SmStructureNode* parent){
208 14292 : aParentNode = parent;
209 14292 : }
210 :
211 : /** Get the index of a child node
212 : *
213 : * Returns -1, if pSubNode isn't a subnode of this.
214 : */
215 32 : int IndexOfSubNode(SmNode* pSubNode){
216 32 : sal_uInt16 nSize = GetNumSubNodes();
217 64 : for(sal_uInt16 i = 0; i < nSize; i++)
218 64 : if(pSubNode == GetSubNode(i))
219 32 : return i;
220 0 : return -1;
221 : }
222 : /** Set the token for this node */
223 17 : void SetToken(SmToken& token){
224 17 : aNodeToken = token;
225 17 : }
226 : protected:
227 : /** Sets parent on children of this node */
228 : inline void ClaimPaternity();
229 : private:
230 : SmStructureNode* aParentNode;
231 : void DumpAsDot(std::ostream &out, OUString* label, int number, int& id, int parent) const;
232 : };
233 :
234 :
235 :
236 : /** A simple auxiliary iterator class for SmNode
237 : *
238 : * Example of iteration over children of pMyNode:
239 : * \code
240 : * //Node to iterate over:
241 : * SmNode* pMyNode = 0;// A pointer from somewhere
242 : * //The iterator:
243 : * SmNodeIterator it(pMyNode);
244 : * //The iteration:
245 : * while(it.Next()) {
246 : * it->SetSelected(true);
247 : * }
248 : * \endcode
249 : */
250 : class SmNodeIterator{
251 : public:
252 33253 : SmNodeIterator(SmNode* node, bool bReverse = false){
253 33253 : pNode = node;
254 33253 : nSize = pNode->GetNumSubNodes();
255 33253 : nIndex = 0;
256 33253 : pChildNode = NULL;
257 33253 : bIsReverse = bReverse;
258 33253 : }
259 : /** Get the subnode or NULL if none */
260 99862 : SmNode* Next(){
261 218799 : while(!bIsReverse && nIndex < nSize){
262 85686 : if(NULL != (pChildNode = pNode->GetSubNode(nIndex++)))
263 66611 : return pChildNode;
264 : }
265 66502 : while(bIsReverse && nSize > 0){
266 4 : if(NULL != (pChildNode = pNode->GetSubNode((nSize--)-1)))
267 4 : return pChildNode;
268 : }
269 33247 : pChildNode = NULL;
270 33247 : return NULL;
271 : }
272 : /** Get the current child node, NULL if none */
273 100 : SmNode* Current(){
274 100 : return pChildNode;
275 : }
276 : /** Get the current child node, NULL if none */
277 131206 : SmNode* operator->(){
278 131206 : return pChildNode;
279 : }
280 : private:
281 : /** Current child */
282 : SmNode* pChildNode;
283 : /** Node whos children we're iterating over */
284 : SmNode* pNode;
285 : /** Size of the node */
286 : sal_uInt16 nSize;
287 : /** Current index in the node */
288 : sal_uInt16 nIndex;
289 : /** Move reverse */
290 : bool bIsReverse;
291 : };
292 :
293 :
294 :
295 : /** Abstract baseclass for all composite node
296 : *
297 : * Subclasses of this class can have subnodes. Nodes that doesn't derivate from
298 : * this class does not have subnodes.
299 : */
300 : class SmStructureNode : public SmNode
301 : {
302 : SmNodeArray aSubNodes;
303 :
304 : protected:
305 6787 : SmStructureNode(SmNodeType eNodeType, const SmToken &rNodeToken)
306 6787 : : SmNode(eNodeType, rNodeToken)
307 6787 : {}
308 :
309 : public:
310 : SmStructureNode( const SmStructureNode &rNode );
311 : virtual ~SmStructureNode();
312 :
313 : virtual bool IsVisible() const SAL_OVERRIDE;
314 :
315 : virtual sal_uInt16 GetNumSubNodes() const SAL_OVERRIDE;
316 3037 : void SetNumSubNodes(sal_uInt16 nSize) { aSubNodes.resize(nSize); }
317 :
318 : using SmNode::GetSubNode;
319 : virtual SmNode * GetSubNode(sal_uInt16 nIndex) SAL_OVERRIDE;
320 : void SetSubNodes(SmNode *pFirst, SmNode *pSecond, SmNode *pThird = NULL);
321 : void SetSubNodes(const SmNodeArray &rNodeArray);
322 :
323 : SmStructureNode & operator = ( const SmStructureNode &rNode );
324 :
325 : virtual void GetAccessibleText( OUStringBuffer &rText ) const SAL_OVERRIDE;
326 :
327 34 : void SetSubNode(size_t nIndex, SmNode* pNode)
328 : {
329 34 : size_t size = aSubNodes.size();
330 34 : if (size <= nIndex)
331 : {
332 : //Resize subnodes array
333 0 : aSubNodes.resize(nIndex + 1);
334 : //Set new slots to NULL
335 0 : for (size_t i = size; i < nIndex+1; i++)
336 0 : aSubNodes[i] = NULL;
337 : }
338 34 : aSubNodes[nIndex] = pNode;
339 34 : ClaimPaternity();
340 34 : }
341 : };
342 :
343 7099 : inline void SmNode::ClaimPaternity() {
344 : SmNode* pNode;
345 7099 : sal_uInt16 nSize = GetNumSubNodes();
346 25334 : for (sal_uInt16 i = 0; i < nSize; i++)
347 18235 : if (NULL != (pNode = GetSubNode(i)))
348 14292 : pNode->SetParent(static_cast<SmStructureNode*>(this)); //Cast is valid if we have children
349 7099 : }
350 :
351 : /** Abstract base class for all visible node
352 : *
353 : * Nodes that doesn't derivate from this class doesn't draw anything, but their
354 : * children.
355 : */
356 8969 : class SmVisibleNode : public SmNode
357 : {
358 : protected:
359 8969 : SmVisibleNode(SmNodeType eNodeType, const SmToken &rNodeToken)
360 8969 : : SmNode(eNodeType, rNodeToken)
361 8969 : {}
362 :
363 : public:
364 :
365 : virtual bool IsVisible() const SAL_OVERRIDE;
366 : virtual sal_uInt16 GetNumSubNodes() const SAL_OVERRIDE;
367 : using SmNode::GetSubNode;
368 : virtual SmNode * GetSubNode(sal_uInt16 nIndex) SAL_OVERRIDE;
369 : };
370 :
371 :
372 :
373 :
374 :
375 337 : class SmGraphicNode : public SmVisibleNode
376 : {
377 : protected:
378 337 : SmGraphicNode(SmNodeType eNodeType, const SmToken &rNodeToken)
379 337 : : SmVisibleNode(eNodeType, rNodeToken)
380 337 : {}
381 :
382 : public:
383 :
384 : virtual void GetAccessibleText( OUStringBuffer &rText ) const SAL_OVERRIDE;
385 : };
386 :
387 :
388 :
389 :
390 : /** Draws a rectangle
391 : *
392 : * Used for drawing the line in the OVER and OVERSTRIKE commands.
393 : */
394 598 : class SmRectangleNode : public SmGraphicNode
395 : {
396 : Size aToSize;
397 :
398 : public:
399 299 : SmRectangleNode(const SmToken &rNodeToken)
400 299 : : SmGraphicNode(NRECTANGLE, rNodeToken)
401 299 : {}
402 :
403 : virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth) SAL_OVERRIDE;
404 : virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
405 :
406 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
407 :
408 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
409 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
410 : };
411 :
412 :
413 :
414 :
415 : /** Polygon line node
416 : *
417 : * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
418 : */
419 68 : class SmPolyLineNode : public SmGraphicNode
420 : {
421 : Polygon aPoly;
422 : Size aToSize;
423 : long nWidth;
424 :
425 : public:
426 : SmPolyLineNode(const SmToken &rNodeToken);
427 :
428 98 : long GetWidth() const { return nWidth; }
429 : Size GetToSize() const { return aToSize; }
430 192 : Polygon &GetPolygon() { return aPoly; }
431 :
432 : virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth) SAL_OVERRIDE;
433 : virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
434 :
435 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
436 :
437 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
438 : };
439 :
440 :
441 :
442 :
443 : /** Text node
444 : *
445 : * @remarks This class also serves as baseclass for all nodes that contains text.
446 : */
447 13572 : class SmTextNode : public SmVisibleNode
448 : {
449 : OUString aText;
450 : sal_uInt16 nFontDesc;
451 : /** Index within text where the selection starts
452 : * @remarks Only valid if SmNode::IsSelected() is true
453 : */
454 : sal_Int32 nSelectionStart;
455 : /** Index within text where the selection ends
456 : * @remarks Only valid if SmNode::IsSelected() is true
457 : */
458 : sal_Int32 nSelectionEnd;
459 :
460 : protected:
461 : SmTextNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 nFontDescP );
462 :
463 : public:
464 : SmTextNode(const SmToken &rNodeToken, sal_uInt16 nFontDescP );
465 :
466 12067 : sal_uInt16 GetFontDesc() const { return nFontDesc; }
467 3667 : void SetText(const OUString &rText) { aText = rText; }
468 129762 : const OUString & GetText() const { return aText; }
469 : /** Change the text of this node, including the underlying token */
470 4 : void ChangeText(const OUString &rText) {
471 4 : aText = rText;
472 4 : SmToken token = GetToken();
473 4 : token.aText = rText;
474 4 : SetToken(token); //TODO: Merge this with AdjustFontDesc for better performance
475 4 : AdjustFontDesc();
476 4 : }
477 : /** Try to guess the correct FontDesc, used during visual editing */
478 : void AdjustFontDesc();
479 : /** Index within GetText() where the selection starts
480 : * @remarks Only valid of SmNode::IsSelected() is true
481 : */
482 2 : sal_Int32 GetSelectionStart() const {return nSelectionStart;}
483 : /** Index within GetText() where the selection end
484 : * @remarks Only valid of SmNode::IsSelected() is true
485 : */
486 2 : sal_Int32 GetSelectionEnd() const {return nSelectionEnd;}
487 : /** Set the index within GetText() where the selection starts */
488 42 : void SetSelectionStart(sal_Int32 index) {nSelectionStart = index;}
489 : /** Set the index within GetText() where the selection end */
490 42 : void SetSelectionEnd(sal_Int32 index) {nSelectionEnd = index;}
491 :
492 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
493 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
494 : virtual void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
495 :
496 : virtual void GetAccessibleText( OUStringBuffer &rText ) const SAL_OVERRIDE;
497 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
498 : /**
499 : Converts the character from StarMath's private area symbols to a matching Unicode
500 : character, if necessary. To be used when converting GetText() to a normal text.
501 : */
502 : static sal_Unicode ConvertSymbolToUnicode(sal_Unicode nIn);
503 : };
504 :
505 :
506 :
507 :
508 : /** Special node for user defined characters
509 : *
510 : * Node used for pre- and user-defined characters from:
511 : * officecfg/registry/data/org/openoffice/Office/Math.xcu
512 : *
513 : * This is just single characters, I think.
514 : */
515 3823 : class SmSpecialNode : public SmTextNode
516 : {
517 : bool bIsFromGreekSymbolSet;
518 :
519 : protected:
520 : SmSpecialNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 _nFontDesc);
521 :
522 : public:
523 : SmSpecialNode(const SmToken &rNodeToken);
524 :
525 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
526 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
527 :
528 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
529 : };
530 :
531 :
532 :
533 :
534 : /** Glyph node for custom operators
535 : *
536 : * This node is used with commands: oper, uoper and boper.
537 : * E.g. in "A boper op B", "op" will be an instance of SmGlyphSpecialNode.
538 : * "boper" simply inteprets "op", the following token, as an binary operator.
539 : * The command "uoper" interprets the following token as unary operator.
540 : * For these commands an instance of SmGlyphSpecialNode is used for the
541 : * operator token, following the command.
542 : */
543 0 : class SmGlyphSpecialNode : public SmSpecialNode
544 : {
545 : public:
546 0 : SmGlyphSpecialNode(const SmToken &rNodeToken)
547 0 : : SmSpecialNode(NGLYPH_SPECIAL, rNodeToken, FNT_MATH)
548 0 : {}
549 :
550 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
551 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
552 : };
553 :
554 :
555 :
556 :
557 : /** Math symbol node
558 : *
559 : * Use for math symbols such as plus, minus and integrale in the INT command.
560 : */
561 6327 : class SmMathSymbolNode : public SmSpecialNode
562 : {
563 : protected:
564 795 : SmMathSymbolNode(SmNodeType eNodeType, const SmToken &rNodeToken)
565 795 : : SmSpecialNode(eNodeType, rNodeToken, FNT_MATH)
566 : {
567 795 : sal_Unicode cChar = GetToken().cMathChar;
568 795 : if ((sal_Unicode) '\0' != cChar)
569 765 : SetText(OUString(cChar));
570 795 : }
571 :
572 : public:
573 : SmMathSymbolNode(const SmToken &rNodeToken);
574 :
575 : virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth) SAL_OVERRIDE;
576 : virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
577 :
578 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
579 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
580 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
581 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
582 : };
583 :
584 :
585 :
586 : /** Math Identifier
587 : *
588 : * This behaves essentially the same as SmMathSymbolNode and is only used to
589 : * represent math symbols that should be exported as <mi> elements rather than
590 : * <mo> elements.
591 : */
592 52 : class SmMathIdentifierNode : public SmMathSymbolNode
593 : {
594 : public:
595 26 : SmMathIdentifierNode(const SmToken &rNodeToken)
596 26 : : SmMathSymbolNode(NMATHIDENT, rNodeToken) {}
597 : };
598 :
599 :
600 :
601 : /** Root symbol node
602 : *
603 : * Root symbol node used by SmRootNode to create the root symbol, in front of
604 : * the line with the line above. I don't think this node should be used for
605 : * anything else.
606 : */
607 164 : class SmRootSymbolNode : public SmMathSymbolNode
608 : {
609 : sal_uLong nBodyWidth; // width of body (argument) of root sign
610 :
611 : public:
612 82 : SmRootSymbolNode(const SmToken &rNodeToken)
613 : : SmMathSymbolNode(NROOTSYMBOL, rNodeToken)
614 82 : , nBodyWidth(0)
615 : {
616 82 : }
617 :
618 442 : sal_uLong GetBodyWidth() const {return nBodyWidth;};
619 : virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
620 : virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
621 :
622 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
623 : };
624 :
625 :
626 : /** Dynamic Integral symbol node
627 : *
628 : * Node for drawing dynamically sized integral symbols.
629 : *
630 : * TODO: It might be created a parent class SmDynamicSizedNode
631 : (for both dynamic integrals, roots and other dynamic symbols)
632 :
633 : */
634 0 : class SmDynIntegralSymbolNode : public SmMathSymbolNode
635 : {
636 :
637 :
638 : public:
639 0 : SmDynIntegralSymbolNode(const SmToken &rNodeToken)
640 0 : : SmMathSymbolNode(NDYNINTSYMBOL, rNodeToken)
641 0 : {}
642 :
643 : virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
644 :
645 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
646 : };
647 :
648 :
649 :
650 :
651 : /** Place node
652 : *
653 : * Used to create the <?> command, that denotes place where something can be
654 : * written.
655 : * It is drawn as a square with a shadow.
656 : */
657 1312 : class SmPlaceNode : public SmMathSymbolNode
658 : {
659 : public:
660 654 : SmPlaceNode(const SmToken &rNodeToken)
661 654 : : SmMathSymbolNode(NPLACE, rNodeToken)
662 : {
663 654 : }
664 2 : SmPlaceNode() : SmMathSymbolNode(NPLACE, SmToken(TPLACE, MS_PLACE, "<?>")) {};
665 :
666 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
667 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
668 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
669 : };
670 :
671 :
672 :
673 :
674 : /** Error node, for parsing errors
675 : *
676 : * This node is used for parsing errors and draws an questionmark turned upside
677 : * down (inverted question mark).
678 : */
679 62 : class SmErrorNode : public SmMathSymbolNode
680 : {
681 : public:
682 31 : SmErrorNode(SmParseError /*eError*/, const SmToken &rNodeToken)
683 31 : : SmMathSymbolNode(NERROR, rNodeToken)
684 : {
685 31 : SetText(OUString(MS_ERROR));
686 31 : }
687 :
688 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
689 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
690 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
691 : };
692 :
693 :
694 :
695 :
696 : /** Table node
697 : *
698 : * This is the root node for the formula tree. This node is also used for the
699 : * STACK and BINOM commands. When used for root node, its
700 : * children are instances of SmLineNode, and in some obscure cases the a child
701 : * can be an instance of SmExpressionNode, mainly when errors occur.
702 : */
703 2036 : class SmTableNode : public SmStructureNode
704 : {
705 : long nFormulaBaseline;
706 : public:
707 1024 : SmTableNode(const SmToken &rNodeToken)
708 : : SmStructureNode(NTABLE, rNodeToken)
709 1024 : , nFormulaBaseline(0)
710 : {
711 1024 : }
712 :
713 : using SmNode::GetLeftMost;
714 : virtual SmNode * GetLeftMost() SAL_OVERRIDE;
715 :
716 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
717 : virtual long GetFormulaBaseline() const SAL_OVERRIDE;
718 :
719 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
720 : };
721 :
722 :
723 :
724 :
725 : /** A line
726 : *
727 : * Used as child of SmTableNode when the SmTableNode is the root node of the
728 : * formula tree.
729 : */
730 2648 : class SmLineNode : public SmStructureNode
731 : {
732 : bool bUseExtraSpaces;
733 :
734 : protected:
735 839 : SmLineNode(SmNodeType eNodeType, const SmToken &rNodeToken)
736 839 : : SmStructureNode(eNodeType, rNodeToken)
737 : {
738 839 : bUseExtraSpaces = true;
739 839 : }
740 :
741 : public:
742 915 : SmLineNode(const SmToken &rNodeToken)
743 915 : : SmStructureNode(NLINE, rNodeToken)
744 : {
745 915 : bUseExtraSpaces = true;
746 915 : }
747 :
748 713 : void SetUseExtraSpaces(bool bVal) { bUseExtraSpaces = bVal; }
749 1754 : bool IsUseExtraSpaces() const { return bUseExtraSpaces; };
750 :
751 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
752 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
753 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
754 : };
755 :
756 :
757 :
758 :
759 : /** Expression node
760 : *
761 : * Used whenever you have an expression such as "A OVER {B + C}", here there is
762 : * an expression node that allows "B + C" to be the denominator of the
763 : * SmBinVerNode, that the OVER command creates.
764 : */
765 1660 : class SmExpressionNode : public SmLineNode
766 : {
767 : public:
768 839 : SmExpressionNode(const SmToken &rNodeToken)
769 839 : : SmLineNode(NEXPRESSION, rNodeToken)
770 839 : {}
771 :
772 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
773 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
774 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
775 : };
776 :
777 :
778 :
779 :
780 : /** Unary horizontal node
781 : *
782 : * The same as SmBinHorNode except this is for unary operators.
783 : */
784 348 : class SmUnHorNode : public SmStructureNode
785 : {
786 : public:
787 174 : SmUnHorNode(const SmToken &rNodeToken)
788 174 : : SmStructureNode(NUNHOR, rNodeToken)
789 : {
790 174 : SetNumSubNodes(2);
791 174 : }
792 :
793 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
794 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
795 : };
796 :
797 :
798 :
799 :
800 : /** Root node
801 : *
802 : * Used for create square roots and other roots, example:
803 : * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
804 : *
805 : * Children:<BR>
806 : * 0: Argument (optional)<BR>
807 : * 1: Symbol (instance of SmRootSymbolNode)<BR>
808 : * 2: Body<BR>
809 : * Where argument is optional and may be NULL.
810 : */
811 164 : class SmRootNode : public SmStructureNode
812 : {
813 : protected:
814 : static void GetHeightVerOffset(const SmRect &rRect,
815 : long &rHeight, long &rVerOffset);
816 : static Point GetExtraPos(const SmRect &rRootSymbol, const SmRect &rExtra);
817 :
818 : public:
819 82 : SmRootNode(const SmToken &rNodeToken)
820 82 : : SmStructureNode(NROOT, rNodeToken)
821 : {
822 82 : SetNumSubNodes(3);
823 82 : }
824 :
825 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
826 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
827 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
828 :
829 : SmNode* Argument();
830 : const SmNode* Argument() const;
831 : SmRootSymbolNode* Symbol();
832 : const SmRootSymbolNode* Symbol() const;
833 : SmNode* Body();
834 : const SmNode* Body() const;
835 : };
836 :
837 :
838 : /** Dynamic Integral node
839 : *
840 : * Used to create Dynamically sized integrals
841 : *
842 : * Children:<BR>
843 : * 0: Symbol (instance of DynIntegralSymbolNode)<BR>
844 : * 1: Body<BR>
845 : */
846 0 : class SmDynIntegralNode : public SmStructureNode
847 : {
848 : protected:
849 : void GetHeightVerOffset(const SmRect &rRect,
850 : long &rHeight, long &rVerOffset) const;
851 :
852 : public:
853 0 : SmDynIntegralNode(const SmToken &rNodeToken)
854 0 : : SmStructureNode(NDYNINT, rNodeToken)
855 : {
856 0 : SetNumSubNodes(2);
857 0 : }
858 :
859 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
860 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
861 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
862 :
863 : SmDynIntegralSymbolNode* Symbol();
864 : const SmDynIntegralSymbolNode* Symbol() const;
865 : SmNode* Body();
866 : const SmNode* Body() const;
867 : };
868 :
869 :
870 :
871 :
872 : /** Binary horizontal node
873 : *
874 : * This node is used for binary operators. In a formula such as "A + B".
875 : *
876 : * Children:<BR>
877 : * 0: Left operand<BR>
878 : * 1: Binary operator<BR>
879 : * 2: Right operand<BR>
880 : *
881 : * None of the children may be NULL.
882 : */
883 1878 : class SmBinHorNode : public SmStructureNode
884 : {
885 : public:
886 939 : SmBinHorNode(const SmToken &rNodeToken)
887 939 : : SmStructureNode(NBINHOR, rNodeToken)
888 : {
889 939 : SetNumSubNodes(3);
890 939 : }
891 :
892 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
893 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
894 :
895 : SmMathSymbolNode* Symbol();
896 : const SmMathSymbolNode* Symbol() const;
897 : SmNode* LeftOperand();
898 : const SmNode* LeftOperand() const;
899 : SmNode* RightOperand();
900 : const SmNode* RightOperand() const;
901 : };
902 :
903 :
904 :
905 :
906 : /** Binary horizontal node
907 : *
908 : * This node is used for creating the OVER command, consider the formula:
909 : * "numerator OVER denominator", which looks like
910 : * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
911 : *
912 : * Children:<BR>
913 : * 0: Numerator<BR>
914 : * 1: Line (instance of SmRectangleNode)<BR>
915 : * 2: Denominator<BR>
916 : * None of the children may be NULL.
917 : */
918 514 : class SmBinVerNode : public SmStructureNode
919 : {
920 : public:
921 257 : SmBinVerNode(const SmToken &rNodeToken)
922 257 : : SmStructureNode(NBINVER, rNodeToken)
923 : {
924 257 : SetNumSubNodes(3);
925 257 : }
926 :
927 : using SmNode::GetLeftMost;
928 : virtual SmNode * GetLeftMost() SAL_OVERRIDE;
929 :
930 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
931 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
932 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
933 : };
934 :
935 :
936 :
937 :
938 : /** Binary diagonal node
939 : *
940 : * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
941 : *
942 : * Children:<BR>
943 : * 0: Left operand<BR>
944 : * 1: right operand<BR>
945 : * 2: Line (instance of SmPolyLineNode).<BR>
946 : * None of the children may be NULL.
947 : */
948 68 : class SmBinDiagonalNode : public SmStructureNode
949 : {
950 : bool bAscending;
951 :
952 : void GetOperPosSize(Point &rPos, Size &rSize,
953 : const Point &rDiagPoint, double fAngleDeg) const;
954 :
955 : public:
956 : SmBinDiagonalNode(const SmToken &rNodeToken);
957 :
958 136 : bool IsAscending() const { return bAscending; }
959 34 : void SetAscending(bool bVal) { bAscending = bVal; }
960 :
961 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
962 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
963 : };
964 :
965 :
966 :
967 :
968 :
969 : /** Enum used to index sub-/supscripts in the 'aSubNodes' array
970 : * in 'SmSubSupNode'
971 : *
972 : * See graphic for positions at char:
973 : *
974 : * \code
975 : * CSUP
976 : *
977 : * LSUP H H RSUP
978 : * H H
979 : * HHHH
980 : * H H
981 : * LSUB H H RSUB
982 : *
983 : * CSUB
984 : * \endcode
985 : */
986 : enum SmSubSup
987 : { CSUB, CSUP, RSUB, RSUP, LSUB, LSUP
988 : };
989 :
990 : /** numbers of entries in the above enum (that is: the number of possible
991 : * sub-/supscripts)
992 : */
993 : #define SUBSUP_NUM_ENTRIES 6
994 :
995 : /** Super- and subscript node
996 : *
997 : * Used for creating super- and subscripts for commands such as:
998 : * "^", "_", "lsup", "lsub", "csup" and "csub".
999 : * Example: "A^2" which looks like: \f$ A^2 \f$
1000 : *
1001 : * This node is also used for creating limits on SmOperNode, when
1002 : * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
1003 : *
1004 : * Children of this node can be enumerated using the SmSubSup enum.
1005 : * Please note that children may be NULL, except for the body.
1006 : * It is recommended that you access children using GetBody() and
1007 : * GetSubSup().
1008 : */
1009 1588 : class SmSubSupNode : public SmStructureNode
1010 : {
1011 : bool bUseLimits;
1012 :
1013 : public:
1014 794 : SmSubSupNode(const SmToken &rNodeToken)
1015 794 : : SmStructureNode(NSUBSUP, rNodeToken)
1016 : {
1017 794 : SetNumSubNodes(1 + SUBSUP_NUM_ENTRIES);
1018 794 : bUseLimits = false;
1019 794 : }
1020 :
1021 : /** Get body (Not NULL) */
1022 1044 : SmNode * GetBody() { return GetSubNode(0); }
1023 : /** Get body (Not NULL) */
1024 93 : const SmNode * GetBody() const
1025 : {
1026 93 : return const_cast<SmSubSupNode *>(this)->GetBody();
1027 : }
1028 :
1029 787 : void SetUseLimits(bool bVal) { bUseLimits = bVal; }
1030 16 : bool IsUseLimits() const { return bUseLimits; };
1031 :
1032 : /** Get super- or subscript
1033 : * @remarks this method may return NULL.
1034 : */
1035 5398 : SmNode * GetSubSup(SmSubSup eSubSup) { return GetSubNode( sal::static_int_cast< sal_uInt16 >(1 + eSubSup) ); };
1036 651 : const SmNode * GetSubSup(SmSubSup eSubSup) const { return const_cast< SmSubSupNode* >( this )->GetSubSup( eSubSup ); }
1037 :
1038 : /** Set the body */
1039 1 : void SetBody(SmNode* pBody) { SetSubNode(0, pBody); }
1040 1 : void SetSubSup(SmSubSup eSubSup, SmNode* pScript) { SetSubNode( 1 + eSubSup, pScript); }
1041 :
1042 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1043 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
1044 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1045 :
1046 : };
1047 :
1048 :
1049 :
1050 :
1051 : /** Node for brace construction
1052 : *
1053 : * Used for "lbrace [body] rbrace" and similar constructions.
1054 : * Should look like \f$ \{\mbox{[body]}\} \f$
1055 : *
1056 : * Children:<BR>
1057 : * 0: Opening brace<BR>
1058 : * 1: Body (usually SmBracebodyNode)<BR>
1059 : * 2: Closing brace<BR>
1060 : * None of the children can be NULL.
1061 : *
1062 : * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
1063 : */
1064 1056 : class SmBraceNode : public SmStructureNode
1065 : {
1066 : public:
1067 528 : SmBraceNode(const SmToken &rNodeToken)
1068 528 : : SmStructureNode(NBRACE, rNodeToken)
1069 : {
1070 528 : SetNumSubNodes(3);
1071 528 : }
1072 :
1073 : SmMathSymbolNode* OpeningBrace();
1074 : const SmMathSymbolNode* OpeningBrace() const;
1075 : SmNode* Body();
1076 : const SmNode* Body() const;
1077 : SmMathSymbolNode* ClosingBrace();
1078 : const SmMathSymbolNode* ClosingBrace() const;
1079 :
1080 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1081 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
1082 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1083 : };
1084 :
1085 :
1086 :
1087 :
1088 : /** Body of an SmBraceNode
1089 : *
1090 : * This usually only has one child an SmExpressionNode, however, it can also
1091 : * have other children.
1092 : * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
1093 : * \f$ \{\mbox{[body1] | [body2]}\} \f$.
1094 : * In this case SmBracebodyNode will have three children, "[body1]", "|" and
1095 : * [body2].
1096 : */
1097 1044 : class SmBracebodyNode : public SmStructureNode
1098 : {
1099 : long nBodyHeight;
1100 :
1101 : public:
1102 : inline SmBracebodyNode(const SmToken &rNodeToken);
1103 :
1104 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1105 409 : long GetBodyHeight() const { return nBodyHeight; }
1106 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1107 : };
1108 :
1109 :
1110 522 : inline SmBracebodyNode::SmBracebodyNode(const SmToken &rNodeToken) :
1111 522 : SmStructureNode(NBRACEBODY, rNodeToken)
1112 : {
1113 522 : nBodyHeight = 0;
1114 522 : }
1115 :
1116 :
1117 :
1118 :
1119 : /** Node for vertical brace construction
1120 : *
1121 : * Used to implement commands "[body] underbrace [script]" and
1122 : * "[body] overbrace [script]".
1123 : * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
1124 : *
1125 : * Children:<BR>
1126 : * 0: body<BR>
1127 : * 1: brace<BR>
1128 : * 2: script<BR>
1129 : * (None of these children are optional, e.g. they must all be not NULL).
1130 : */
1131 80 : class SmVerticalBraceNode : public SmStructureNode
1132 : {
1133 : public:
1134 : inline SmVerticalBraceNode(const SmToken &rNodeToken);
1135 :
1136 : SmNode* Body();
1137 : const SmNode* Body() const;
1138 : SmMathSymbolNode* Brace();
1139 : const SmMathSymbolNode* Brace() const;
1140 : SmNode* Script();
1141 : const SmNode* Script() const;
1142 :
1143 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1144 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1145 : };
1146 :
1147 :
1148 40 : inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken &rNodeToken) :
1149 40 : SmStructureNode(NVERTICAL_BRACE, rNodeToken)
1150 : {
1151 40 : SetNumSubNodes(3);
1152 40 : }
1153 :
1154 :
1155 :
1156 :
1157 :
1158 : /** Operation Node
1159 : *
1160 : * Used for commands like SUM, INT and similar.
1161 : *
1162 : * Children:<BR>
1163 : * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
1164 : * 1: Body<BR>
1165 : * None of the children may be NULL.
1166 : *
1167 : */
1168 378 : class SmOperNode : public SmStructureNode
1169 : {
1170 : public:
1171 189 : SmOperNode(const SmToken &rNodeToken)
1172 189 : : SmStructureNode(NOPER, rNodeToken)
1173 : {
1174 189 : SetNumSubNodes(2);
1175 189 : }
1176 :
1177 : SmNode * GetSymbol();
1178 2 : const SmNode * GetSymbol() const
1179 : {
1180 2 : return const_cast<SmOperNode *>(this)->GetSymbol();
1181 : }
1182 :
1183 : long CalcSymbolHeight(const SmNode &rSymbol, const SmFormat &rFormat) const;
1184 :
1185 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1186 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1187 : };
1188 :
1189 :
1190 :
1191 :
1192 : /** Node used for alignment
1193 : */
1194 28 : class SmAlignNode : public SmStructureNode
1195 : {
1196 : public:
1197 14 : SmAlignNode(const SmToken &rNodeToken)
1198 14 : : SmStructureNode(NALIGN, rNodeToken)
1199 14 : {}
1200 :
1201 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1202 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1203 : };
1204 :
1205 :
1206 :
1207 :
1208 : /** Attribute node
1209 : *
1210 : * Used to give an attribute to another node. Used for commands such as:
1211 : * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHAT and WIDETILDE.
1212 : *
1213 : * Children:<BR>
1214 : * 0: Attribute<BR>
1215 : * 1: Body<BR>
1216 : * None of these may be NULL.
1217 : */
1218 580 : class SmAttributNode : public SmStructureNode
1219 : {
1220 : public:
1221 290 : SmAttributNode(const SmToken &rNodeToken)
1222 290 : : SmStructureNode(NATTRIBUT, rNodeToken)
1223 290 : {}
1224 :
1225 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1226 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
1227 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1228 :
1229 : SmNode* Attribute();
1230 : const SmNode* Attribute() const;
1231 : SmNode* Body();
1232 : const SmNode* Body() const;
1233 : };
1234 :
1235 :
1236 :
1237 :
1238 : /** Font node
1239 : *
1240 : * Used to change the font of its children.
1241 : */
1242 242 : class SmFontNode : public SmStructureNode
1243 : {
1244 : FontSizeType nSizeType;
1245 : Fraction aFontSize;
1246 :
1247 : public:
1248 121 : SmFontNode(const SmToken &rNodeToken)
1249 121 : : SmStructureNode(NFONT, rNodeToken)
1250 : {
1251 121 : nSizeType = FontSizeType::MULTIPLY;
1252 121 : aFontSize = Fraction(1L);
1253 121 : }
1254 :
1255 : void SetSizeParameter(const Fraction &rValue, FontSizeType nType);
1256 42 : const Fraction & GetSizeParameter() const {return aFontSize;}
1257 42 : const FontSizeType& GetSizeType() const {return nSizeType;}
1258 :
1259 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
1260 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1261 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
1262 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1263 : };
1264 :
1265 :
1266 :
1267 :
1268 : /** Matrix node
1269 : *
1270 : * Used to implement the MATRIX command, example:
1271 : * "matrix{ 1 # 2 ## 3 # 4}".
1272 : */
1273 50 : class SmMatrixNode : public SmStructureNode
1274 : {
1275 : sal_uInt16 nNumRows,
1276 : nNumCols;
1277 :
1278 : public:
1279 25 : SmMatrixNode(const SmToken &rNodeToken)
1280 25 : : SmStructureNode(NMATRIX, rNodeToken)
1281 : {
1282 25 : nNumRows = nNumCols = 0;
1283 25 : }
1284 :
1285 62 : sal_uInt16 GetNumRows() const {return nNumRows;}
1286 160 : sal_uInt16 GetNumCols() const {return nNumCols;}
1287 : void SetRowCol(sal_uInt16 nMatrixRows, sal_uInt16 nMatrixCols);
1288 :
1289 : using SmNode::GetLeftMost;
1290 : virtual SmNode * GetLeftMost() SAL_OVERRIDE;
1291 :
1292 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1293 : void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
1294 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1295 : };
1296 :
1297 :
1298 :
1299 :
1300 : /** Node for whitespace
1301 : *
1302 : * Used to implement the "~" command. This node is just a blank space.
1303 : */
1304 8 : class SmBlankNode : public SmGraphicNode
1305 : {
1306 : sal_uInt16 nNum;
1307 :
1308 : public:
1309 4 : SmBlankNode(const SmToken &rNodeToken)
1310 4 : : SmGraphicNode(NBLANK, rNodeToken)
1311 : {
1312 4 : nNum = 0;
1313 4 : }
1314 :
1315 : void IncreaseBy(const SmToken &rToken);
1316 0 : void Clear() { nNum = 0; }
1317 0 : sal_uInt16 GetBlankNum() const { return nNum; }
1318 0 : void SetBlankNum(sal_uInt16 nNumber) { nNum = nNumber; }
1319 :
1320 : virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
1321 : virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
1322 : void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
1323 : };
1324 :
1325 :
1326 :
1327 :
1328 :
1329 10 : inline SmNode* SmRootNode::Argument()
1330 : {
1331 : OSL_ASSERT( GetNumSubNodes() > 0 );
1332 10 : return GetSubNode( 0 );
1333 : }
1334 10 : inline const SmNode* SmRootNode::Argument() const
1335 : {
1336 10 : return const_cast< SmRootNode* >( this )->Argument();
1337 : }
1338 : inline SmRootSymbolNode* SmRootNode::Symbol()
1339 : {
1340 : OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NROOTSYMBOL );
1341 : return static_cast< SmRootSymbolNode* >( GetSubNode( 1 ));
1342 : }
1343 : inline const SmRootSymbolNode* SmRootNode::Symbol() const
1344 : {
1345 : return const_cast< SmRootNode* >( this )->Symbol();
1346 : }
1347 10 : inline SmNode* SmRootNode::Body()
1348 : {
1349 : OSL_ASSERT( GetNumSubNodes() > 2 );
1350 10 : return GetSubNode( 2 );
1351 : }
1352 10 : inline const SmNode* SmRootNode::Body() const
1353 : {
1354 10 : return const_cast< SmRootNode* >( this )->Body();
1355 : }
1356 :
1357 :
1358 :
1359 0 : inline SmDynIntegralSymbolNode* SmDynIntegralNode::Symbol()
1360 : {
1361 : OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NDYNINTSYMBOL );
1362 0 : return static_cast< SmDynIntegralSymbolNode* >( GetSubNode( 0 ));
1363 : }
1364 : inline const SmDynIntegralSymbolNode* SmDynIntegralNode::Symbol() const
1365 : {
1366 : return const_cast< SmDynIntegralNode* >( this )->Symbol();
1367 : }
1368 0 : inline SmNode* SmDynIntegralNode::Body()
1369 : {
1370 : OSL_ASSERT( GetNumSubNodes() > 1 );
1371 0 : return GetSubNode( 1 );
1372 : }
1373 : inline const SmNode* SmDynIntegralNode::Body() const
1374 : {
1375 : return const_cast< SmDynIntegralNode* >( this )->Body();
1376 : }
1377 :
1378 :
1379 530 : inline SmMathSymbolNode* SmBinHorNode::Symbol()
1380 : {
1381 : OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH );
1382 530 : return static_cast< SmMathSymbolNode* >( GetSubNode( 1 ));
1383 : }
1384 530 : inline const SmMathSymbolNode* SmBinHorNode::Symbol() const
1385 : {
1386 530 : return const_cast< SmBinHorNode* >( this )->Symbol();
1387 : }
1388 432 : inline SmNode* SmBinHorNode::LeftOperand()
1389 : {
1390 : OSL_ASSERT( GetNumSubNodes() > 0 );
1391 432 : return GetSubNode( 0 );
1392 : }
1393 432 : inline const SmNode* SmBinHorNode::LeftOperand() const
1394 : {
1395 432 : return const_cast< SmBinHorNode* >( this )->LeftOperand();
1396 : }
1397 432 : inline SmNode* SmBinHorNode::RightOperand()
1398 : {
1399 : OSL_ASSERT( GetNumSubNodes() > 2 );
1400 432 : return GetSubNode( 2 );
1401 : }
1402 432 : inline const SmNode* SmBinHorNode::RightOperand() const
1403 : {
1404 432 : return const_cast< SmBinHorNode* >( this )->RightOperand();
1405 : }
1406 :
1407 54 : inline SmNode* SmAttributNode::Attribute()
1408 : {
1409 : OSL_ASSERT( GetNumSubNodes() > 0 );
1410 54 : return GetSubNode( 0 );
1411 : }
1412 54 : inline const SmNode* SmAttributNode::Attribute() const
1413 : {
1414 54 : return const_cast< SmAttributNode* >( this )->Attribute();
1415 : }
1416 28 : inline SmNode* SmAttributNode::Body()
1417 : {
1418 : OSL_ASSERT( GetNumSubNodes() > 1 );
1419 28 : return GetSubNode( 1 );
1420 : }
1421 28 : inline const SmNode* SmAttributNode::Body() const
1422 : {
1423 28 : return const_cast< SmAttributNode* >( this )->Body();
1424 : }
1425 :
1426 56 : inline SmMathSymbolNode* SmBraceNode::OpeningBrace()
1427 : {
1428 : OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NMATH );
1429 56 : return static_cast< SmMathSymbolNode* >( GetSubNode( 0 ));
1430 : }
1431 56 : inline const SmMathSymbolNode* SmBraceNode::OpeningBrace() const
1432 : {
1433 56 : return const_cast< SmBraceNode* >( this )->OpeningBrace();
1434 : }
1435 114 : inline SmNode* SmBraceNode::Body()
1436 : {
1437 : OSL_ASSERT( GetNumSubNodes() > 1 );
1438 114 : return GetSubNode( 1 );
1439 : }
1440 114 : inline const SmNode* SmBraceNode::Body() const
1441 : {
1442 114 : return const_cast< SmBraceNode* >( this )->Body();
1443 : }
1444 56 : inline SmMathSymbolNode* SmBraceNode::ClosingBrace()
1445 : {
1446 : OSL_ASSERT( GetNumSubNodes() > 2 && GetSubNode( 2 )->GetType() == NMATH );
1447 56 : return static_cast< SmMathSymbolNode* >( GetSubNode( 2 ));
1448 : }
1449 56 : inline const SmMathSymbolNode* SmBraceNode::ClosingBrace() const
1450 : {
1451 56 : return const_cast< SmBraceNode* >( this )->ClosingBrace();
1452 : }
1453 :
1454 4 : inline SmNode* SmVerticalBraceNode::Body()
1455 : {
1456 : OSL_ASSERT( GetNumSubNodes() > 0 );
1457 4 : return GetSubNode( 0 );
1458 : }
1459 4 : inline const SmNode* SmVerticalBraceNode::Body() const
1460 : {
1461 4 : return const_cast< SmVerticalBraceNode* >( this )->Body();
1462 : }
1463 4 : inline SmMathSymbolNode* SmVerticalBraceNode::Brace()
1464 : {
1465 : OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH );
1466 4 : return static_cast< SmMathSymbolNode* >( GetSubNode( 1 ));
1467 : }
1468 4 : inline const SmMathSymbolNode* SmVerticalBraceNode::Brace() const
1469 : {
1470 4 : return const_cast< SmVerticalBraceNode* >( this )->Brace();
1471 : }
1472 4 : inline SmNode* SmVerticalBraceNode::Script()
1473 : {
1474 : OSL_ASSERT( GetNumSubNodes() > 2 );
1475 4 : return GetSubNode( 2 );
1476 : }
1477 4 : inline const SmNode* SmVerticalBraceNode::Script() const
1478 : {
1479 4 : return const_cast< SmVerticalBraceNode* >( this )->Script();
1480 : }
1481 :
1482 : #endif
1483 :
1484 :
1485 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|