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