1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 #include "visitors.hxx"
12 ///////////////////////////////////// SmVisitorTest /////////////////////////////////////
14 void SmVisitorTest::Visit( SmTableNode
* pNode
)
16 OSL_ENSURE( pNode
->GetType( ) == NTABLE
, "the visitor-patterns isn't implemented correctly" );
17 VisitChildren( pNode
);
20 void SmVisitorTest::Visit( SmBraceNode
* pNode
)
22 OSL_ENSURE( pNode
->GetType( ) == NBRACE
, "the visitor-patterns isn't implemented correctly" );
23 VisitChildren( pNode
);
26 void SmVisitorTest::Visit( SmBracebodyNode
* pNode
)
28 OSL_ENSURE( pNode
->GetType( ) == NBRACEBODY
, "the visitor-patterns isn't implemented correctly" );
29 VisitChildren( pNode
);
32 void SmVisitorTest::Visit( SmOperNode
* pNode
)
34 OSL_ENSURE( pNode
->GetType( ) == NOPER
, "the visitor-patterns isn't implemented correctly" );
35 VisitChildren( pNode
);
38 void SmVisitorTest::Visit( SmAlignNode
* pNode
)
40 OSL_ENSURE( pNode
->GetType( ) == NALIGN
, "the visitor-patterns isn't implemented correctly" );
41 VisitChildren( pNode
);
44 void SmVisitorTest::Visit( SmAttributNode
* pNode
)
46 OSL_ENSURE( pNode
->GetType( ) == NATTRIBUT
, "the visitor-patterns isn't implemented correctly" );
47 VisitChildren( pNode
);
50 void SmVisitorTest::Visit( SmFontNode
* pNode
)
52 OSL_ENSURE( pNode
->GetType( ) == NFONT
, "the visitor-patterns isn't implemented correctly" );
53 VisitChildren( pNode
);
56 void SmVisitorTest::Visit( SmUnHorNode
* pNode
)
58 OSL_ENSURE( pNode
->GetType( ) == NUNHOR
, "the visitor-patterns isn't implemented correctly" );
59 VisitChildren( pNode
);
62 void SmVisitorTest::Visit( SmBinHorNode
* pNode
)
64 OSL_ENSURE( pNode
->GetType( ) == NBINHOR
, "the visitor-patterns isn't implemented correctly" );
65 VisitChildren( pNode
);
68 void SmVisitorTest::Visit( SmBinVerNode
* pNode
)
70 OSL_ENSURE( pNode
->GetType( ) == NBINVER
, "the visitor-patterns isn't implemented correctly" );
71 VisitChildren( pNode
);
74 void SmVisitorTest::Visit( SmBinDiagonalNode
* pNode
)
76 OSL_ENSURE( pNode
->GetType( ) == NBINDIAGONAL
, "the visitor-patterns isn't implemented correctly" );
77 VisitChildren( pNode
);
80 void SmVisitorTest::Visit( SmSubSupNode
* pNode
)
82 OSL_ENSURE( pNode
->GetType( ) == NSUBSUP
, "the visitor-patterns isn't implemented correctly" );
83 VisitChildren( pNode
);
86 void SmVisitorTest::Visit( SmMatrixNode
* pNode
)
88 OSL_ENSURE( pNode
->GetType( ) == NMATRIX
, "the visitor-patterns isn't implemented correctly" );
89 VisitChildren( pNode
);
92 void SmVisitorTest::Visit( SmPlaceNode
* pNode
)
94 OSL_ENSURE( pNode
->GetType( ) == NPLACE
, "the visitor-patterns isn't implemented correctly" );
95 VisitChildren( pNode
);
98 void SmVisitorTest::Visit( SmTextNode
* pNode
)
100 OSL_ENSURE( pNode
->GetType( ) == NTEXT
, "the visitor-patterns isn't implemented correctly" );
101 VisitChildren( pNode
);
104 void SmVisitorTest::Visit( SmSpecialNode
* pNode
)
106 OSL_ENSURE( pNode
->GetType( ) == NSPECIAL
, "the visitor-patterns isn't implemented correctly" );
107 VisitChildren( pNode
);
110 void SmVisitorTest::Visit( SmGlyphSpecialNode
* pNode
)
112 OSL_ENSURE( pNode
->GetType( ) == NGLYPH_SPECIAL
, "the visitor-patterns isn't implemented correctly" );
113 VisitChildren( pNode
);
116 void SmVisitorTest::Visit( SmMathSymbolNode
* pNode
)
118 OSL_ENSURE( pNode
->GetType( ) == NMATH
, "the visitor-patterns isn't implemented correctly" );
119 VisitChildren( pNode
);
122 void SmVisitorTest::Visit( SmBlankNode
* pNode
)
124 OSL_ENSURE( pNode
->GetType( ) == NBLANK
, "the visitor-patterns isn't implemented correctly" );
125 VisitChildren( pNode
);
128 void SmVisitorTest::Visit( SmErrorNode
* pNode
)
130 OSL_ENSURE( pNode
->GetType( ) == NERROR
, "the visitor-patterns isn't implemented correctly" );
131 VisitChildren( pNode
);
134 void SmVisitorTest::Visit( SmLineNode
* pNode
)
136 OSL_ENSURE( pNode
->GetType( ) == NLINE
, "the visitor-patterns isn't implemented correctly" );
137 VisitChildren( pNode
);
140 void SmVisitorTest::Visit( SmExpressionNode
* pNode
)
142 OSL_ENSURE( pNode
->GetType( ) == NEXPRESSION
, "the visitor-patterns isn't implemented correctly" );
143 VisitChildren( pNode
);
146 void SmVisitorTest::Visit( SmPolyLineNode
* pNode
)
148 OSL_ENSURE( pNode
->GetType( ) == NPOLYLINE
, "the visitor-patterns isn't implemented correctly" );
149 VisitChildren( pNode
);
152 void SmVisitorTest::Visit( SmRootNode
* pNode
)
154 OSL_ENSURE( pNode
->GetType( ) == NROOT
, "the visitor-patterns isn't implemented correctly" );
155 VisitChildren( pNode
);
158 void SmVisitorTest::Visit( SmRootSymbolNode
* pNode
)
160 OSL_ENSURE( pNode
->GetType( ) == NROOTSYMBOL
, "the visitor-patterns isn't implemented correctly" );
161 VisitChildren( pNode
);
164 void SmVisitorTest::Visit( SmRectangleNode
* pNode
)
166 OSL_ENSURE( pNode
->GetType( ) == NRECTANGLE
, "the visitor-patterns isn't implemented correctly" );
167 VisitChildren( pNode
);
170 void SmVisitorTest::Visit( SmVerticalBraceNode
* pNode
)
172 OSL_ENSURE( pNode
->GetType( ) == NVERTICAL_BRACE
, "the visitor-patterns isn't implemented correctly" );
173 VisitChildren( pNode
);
176 void SmVisitorTest::VisitChildren( SmNode
* pNode
)
178 SmNodeIterator
it( pNode
);
183 /////////////////////////////// SmDefaultingVisitor ////////////////////////////////
185 void SmDefaultingVisitor::Visit( SmTableNode
* pNode
)
187 DefaultVisit( pNode
);
190 void SmDefaultingVisitor::Visit( SmBraceNode
* pNode
)
192 DefaultVisit( pNode
);
195 void SmDefaultingVisitor::Visit( SmBracebodyNode
* pNode
)
197 DefaultVisit( pNode
);
200 void SmDefaultingVisitor::Visit( SmOperNode
* pNode
)
202 DefaultVisit( pNode
);
205 void SmDefaultingVisitor::Visit( SmAlignNode
* pNode
)
207 DefaultVisit( pNode
);
210 void SmDefaultingVisitor::Visit( SmAttributNode
* pNode
)
212 DefaultVisit( pNode
);
215 void SmDefaultingVisitor::Visit( SmFontNode
* pNode
)
217 DefaultVisit( pNode
);
220 void SmDefaultingVisitor::Visit( SmUnHorNode
* pNode
)
222 DefaultVisit( pNode
);
225 void SmDefaultingVisitor::Visit( SmBinHorNode
* pNode
)
227 DefaultVisit( pNode
);
230 void SmDefaultingVisitor::Visit( SmBinVerNode
* pNode
)
232 DefaultVisit( pNode
);
235 void SmDefaultingVisitor::Visit( SmBinDiagonalNode
* pNode
)
237 DefaultVisit( pNode
);
240 void SmDefaultingVisitor::Visit( SmSubSupNode
* pNode
)
242 DefaultVisit( pNode
);
245 void SmDefaultingVisitor::Visit( SmMatrixNode
* pNode
)
247 DefaultVisit( pNode
);
250 void SmDefaultingVisitor::Visit( SmPlaceNode
* pNode
)
252 DefaultVisit( pNode
);
255 void SmDefaultingVisitor::Visit( SmTextNode
* pNode
)
257 DefaultVisit( pNode
);
260 void SmDefaultingVisitor::Visit( SmSpecialNode
* pNode
)
262 DefaultVisit( pNode
);
265 void SmDefaultingVisitor::Visit( SmGlyphSpecialNode
* pNode
)
267 DefaultVisit( pNode
);
270 void SmDefaultingVisitor::Visit( SmMathSymbolNode
* pNode
)
272 DefaultVisit( pNode
);
275 void SmDefaultingVisitor::Visit( SmBlankNode
* pNode
)
277 DefaultVisit( pNode
);
280 void SmDefaultingVisitor::Visit( SmErrorNode
* pNode
)
282 DefaultVisit( pNode
);
285 void SmDefaultingVisitor::Visit( SmLineNode
* pNode
)
287 DefaultVisit( pNode
);
290 void SmDefaultingVisitor::Visit( SmExpressionNode
* pNode
)
292 DefaultVisit( pNode
);
295 void SmDefaultingVisitor::Visit( SmPolyLineNode
* pNode
)
297 DefaultVisit( pNode
);
300 void SmDefaultingVisitor::Visit( SmRootNode
* pNode
)
302 DefaultVisit( pNode
);
305 void SmDefaultingVisitor::Visit( SmRootSymbolNode
* pNode
)
307 DefaultVisit( pNode
);
310 void SmDefaultingVisitor::Visit( SmRectangleNode
* pNode
)
312 DefaultVisit( pNode
);
315 void SmDefaultingVisitor::Visit( SmVerticalBraceNode
* pNode
)
317 DefaultVisit( pNode
);
320 /////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
322 SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice
& rDevice
,
330 isCaretVisible
= caretVisible
;
331 OSL_ENSURE( position
.IsValid( ), "Cannot draw invalid position!" );
332 if( !position
.IsValid( ) )
336 rDev
.Push( PUSH_FONT
| PUSH_MAPMODE
| PUSH_LINECOLOR
| PUSH_FILLCOLOR
| PUSH_TEXTCOLOR
);
338 pos
.pSelectedNode
->Accept( this );
339 //Restore device state
343 void SmCaretDrawingVisitor::Visit( SmTextNode
* pNode
)
347 rDev
.SetFont( pNode
->GetFont( ) );
350 SmNode
* pLine
= SmCursor::FindTopMostNodeInLine( pNode
);
353 long left
= pNode
->GetLeft( ) + rDev
.GetTextWidth( pNode
->GetText( ), 0, i
) + Offset
.X( );
354 long top
= pLine
->GetTop( ) + Offset
.Y( );
355 long height
= pLine
->GetHeight( );
356 long left_line
= pLine
->GetLeft( ) + Offset
.X( );
357 long right_line
= pLine
->GetRight( ) + Offset
.X( );
360 rDev
.SetLineColor( Color( COL_BLACK
) );
362 if ( isCaretVisible
) {
364 Point
p1( left
, top
);
365 Point
p2( left
, top
+ height
);
366 rDev
.DrawLine( p1
, p2
);
370 Point
pLeft( left_line
, top
+ height
);
371 Point
pRight( right_line
, top
+ height
);
372 rDev
.DrawLine( pLeft
, pRight
);
375 void SmCaretDrawingVisitor::DefaultVisit( SmNode
* pNode
)
377 rDev
.SetLineColor( Color( COL_BLACK
) );
380 SmNode
* pLine
= SmCursor::FindTopMostNodeInLine( pNode
);
383 long left
= pNode
->GetLeft( ) + Offset
.X( ) + ( pos
.Index
== 1 ? pNode
->GetWidth( ) : 0 );
384 long top
= pLine
->GetTop( ) + Offset
.Y( );
385 long height
= pLine
->GetHeight( );
386 long left_line
= pLine
->GetLeft( ) + Offset
.X( );
387 long right_line
= pLine
->GetRight( ) + Offset
.X( );
390 rDev
.SetLineColor( Color( COL_BLACK
) );
392 if ( isCaretVisible
) {
394 Point
p1( left
, top
);
395 Point
p2( left
, top
+ height
);
396 rDev
.DrawLine( p1
, p2
);
400 Point
pLeft( left_line
, top
+ height
);
401 Point
pRight( right_line
, top
+ height
);
402 rDev
.DrawLine( pLeft
, pRight
);
405 /////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
407 void SmCaretPos2LineVisitor::Visit( SmTextNode
* pNode
)
410 pDev
->Push( PUSH_FONT
| PUSH_TEXTCOLOR
);
414 pDev
->SetFont( pNode
->GetFont( ) );
417 long left
= pNode
->GetLeft( ) + pDev
->GetTextWidth( pNode
->GetText( ), 0, i
);
418 long top
= pNode
->GetTop( );
419 long height
= pNode
->GetHeight( );
421 line
= SmCaretLine( left
, top
, height
);
423 //Restore device state
427 void SmCaretPos2LineVisitor::DefaultVisit( SmNode
* pNode
)
429 //Vertical line ( code from SmCaretDrawingVisitor )
430 Point p1
= pNode
->GetTopLeft( );
432 p1
.Move( pNode
->GetWidth( ), 0 );
434 line
= SmCaretLine( p1
.X( ), p1
.Y( ), pNode
->GetHeight( ) );
437 /////////////////////////////// Nasty temporary device!!! ////////////////////////////////
439 #include <tools/gen.hxx>
440 #include <tools/fract.hxx>
441 #include <rtl/math.hxx>
442 #include <tools/color.hxx>
443 #include <vcl/metric.hxx>
444 #include <vcl/lineinfo.hxx>
445 #include <vcl/outdev.hxx>
446 #include <sfx2/module.hxx>
447 #include "symbol.hxx"
452 OutputDevice
&rOutDev
;
454 // disallow use of copy-constructor and assignment-operator
455 SmTmpDevice2( const SmTmpDevice2
&rTmpDev
);
456 SmTmpDevice2
& operator = ( const SmTmpDevice2
&rTmpDev
);
458 Color
Impl_GetColor( const Color
& rColor
);
461 SmTmpDevice2( OutputDevice
&rTheDev
, bool bUseMap100th_mm
);
462 ~SmTmpDevice2( ) { rOutDev
.Pop( ); }
464 void SetFont( const Font
&rNewFont
);
466 void SetLineColor( const Color
& rColor
) { rOutDev
.SetLineColor( Impl_GetColor( rColor
) ); }
467 void SetFillColor( const Color
& rColor
) { rOutDev
.SetFillColor( Impl_GetColor( rColor
) ); }
468 void SetTextColor( const Color
& rColor
) { rOutDev
.SetTextColor( Impl_GetColor( rColor
) ); }
470 operator OutputDevice
& ( ) const { return rOutDev
; }
473 SmTmpDevice2::SmTmpDevice2( OutputDevice
&rTheDev
, bool bUseMap100th_mm
) :
476 rOutDev
.Push( PUSH_FONT
| PUSH_MAPMODE
|
477 PUSH_LINECOLOR
| PUSH_FILLCOLOR
| PUSH_TEXTCOLOR
);
478 if ( bUseMap100th_mm
&& MAP_100TH_MM
!= rOutDev
.GetMapMode( ).GetMapUnit( ) )
480 OSL_FAIL( "incorrect MapMode?" );
481 rOutDev
.SetMapMode( MAP_100TH_MM
); //format for 100% always
485 Color
SmTmpDevice2::Impl_GetColor( const Color
& rColor
)
487 ColorData nNewCol
= rColor
.GetColor( );
488 if ( COL_AUTO
== nNewCol
)
490 if ( OUTDEV_PRINTER
== rOutDev
.GetOutDevType( ) )
494 Color
aBgCol( rOutDev
.GetBackground( ).GetColor( ) );
495 if ( OUTDEV_WINDOW
== rOutDev
.GetOutDevType( ) )
496 aBgCol
= ( ( Window
& ) rOutDev
).GetDisplayBackground( ).GetColor( );
498 nNewCol
= SM_MOD( )->GetColorConfig( ).GetColorValue( svtools::FONTCOLOR
).nColor
;
500 Color
aTmpColor( nNewCol
);
501 if ( aBgCol
.IsDark( ) && aTmpColor
.IsDark( ) )
503 else if ( aBgCol
.IsBright( ) && aTmpColor
.IsBright( ) )
507 return Color( nNewCol
);
510 void SmTmpDevice2::SetFont( const Font
&rNewFont
)
512 rOutDev
.SetFont( rNewFont
);
513 rOutDev
.SetTextColor( Impl_GetColor( rNewFont
.GetColor( ) ) );
516 /////////////////////////////// SmDrawingVisitor ////////////////////////////////
518 void SmDrawingVisitor::Visit( SmTableNode
* pNode
)
520 DrawChildren( pNode
);
523 void SmDrawingVisitor::Visit( SmBraceNode
* pNode
)
525 DrawChildren( pNode
);
528 void SmDrawingVisitor::Visit( SmBracebodyNode
* pNode
)
530 DrawChildren( pNode
);
533 void SmDrawingVisitor::Visit( SmOperNode
* pNode
)
535 DrawChildren( pNode
);
538 void SmDrawingVisitor::Visit( SmAlignNode
* pNode
)
540 DrawChildren( pNode
);
543 void SmDrawingVisitor::Visit( SmAttributNode
* pNode
)
545 DrawChildren( pNode
);
548 void SmDrawingVisitor::Visit( SmFontNode
* pNode
)
550 DrawChildren( pNode
);
553 void SmDrawingVisitor::Visit( SmUnHorNode
* pNode
)
555 DrawChildren( pNode
);
558 void SmDrawingVisitor::Visit( SmBinHorNode
* pNode
)
560 DrawChildren( pNode
);
563 void SmDrawingVisitor::Visit( SmBinVerNode
* pNode
)
565 DrawChildren( pNode
);
568 void SmDrawingVisitor::Visit( SmBinDiagonalNode
* pNode
)
570 DrawChildren( pNode
);
573 void SmDrawingVisitor::Visit( SmSubSupNode
* pNode
)
575 DrawChildren( pNode
);
578 void SmDrawingVisitor::Visit( SmMatrixNode
* pNode
)
580 DrawChildren( pNode
);
583 void SmDrawingVisitor::Visit( SmPlaceNode
* pNode
)
585 DrawSpecialNode( pNode
);
588 void SmDrawingVisitor::Visit( SmTextNode
* pNode
)
590 DrawTextNode( pNode
);
593 void SmDrawingVisitor::Visit( SmSpecialNode
* pNode
)
595 DrawSpecialNode( pNode
);
598 void SmDrawingVisitor::Visit( SmGlyphSpecialNode
* pNode
)
600 DrawSpecialNode( pNode
);
603 void SmDrawingVisitor::Visit( SmMathSymbolNode
* pNode
)
605 DrawSpecialNode( pNode
);
608 void SmDrawingVisitor::Visit( SmBlankNode
* pNode
)
610 DrawChildren( pNode
);
613 void SmDrawingVisitor::Visit( SmErrorNode
* pNode
)
615 DrawSpecialNode( pNode
);
618 void SmDrawingVisitor::Visit( SmLineNode
* pNode
)
620 DrawChildren( pNode
);
623 void SmDrawingVisitor::Visit( SmExpressionNode
* pNode
)
625 DrawChildren( pNode
);
628 void SmDrawingVisitor::Visit( SmRootNode
* pNode
)
630 DrawChildren( pNode
);
633 void SmDrawingVisitor::Visit( SmVerticalBraceNode
* pNode
)
635 DrawChildren( pNode
);
638 void SmDrawingVisitor::Visit( SmRootSymbolNode
* pNode
)
640 if ( pNode
->IsPhantom( ) )
643 // draw root-sign itself
644 DrawSpecialNode( pNode
);
646 SmTmpDevice2
aTmpDev( ( OutputDevice
& ) rDev
, true );
647 aTmpDev
.SetFillColor( pNode
->GetFont( ).GetColor( ) );
648 rDev
.SetLineColor( );
649 aTmpDev
.SetFont( pNode
->GetFont( ) );
651 // since the width is always unscaled it corresponds ot the _original_
652 // _unscaled_ font height to be used, we use that to calculate the
653 // bar height. Thus it is independent of the arguments height.
654 // ( see display of sqrt QQQ versus sqrt stack{Q#Q#Q#Q} )
655 long nBarHeight
= pNode
->GetWidth( ) * 7L / 100L;
656 long nBarWidth
= pNode
->GetBodyWidth( ) + pNode
->GetBorderWidth( );
657 Point
aBarOffset( pNode
->GetWidth( ), +pNode
->GetBorderWidth( ) );
658 Point
aBarPos( Position
+ aBarOffset
);
660 Rectangle
aBar( aBarPos
, Size( nBarWidth
, nBarHeight
) );
661 //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
662 //! increasing zoomfactor.
663 // This is done by shifting its output-position to a point that
664 // corresponds exactly to a pixel on the output device.
665 Point
aDrawPos( rDev
.PixelToLogic( rDev
.LogicToPixel( aBar
.TopLeft( ) ) ) );
666 aBar
.SetPos( aDrawPos
);
668 rDev
.DrawRect( aBar
);
671 void SmDrawingVisitor::Visit( SmPolyLineNode
* pNode
)
673 if ( pNode
->IsPhantom( ) )
676 long nBorderwidth
= pNode
->GetFont( ).GetBorderWidth( );
679 aInfo
.SetWidth( pNode
->GetWidth( ) - 2 * nBorderwidth
);
681 Point
aOffset ( Point( ) - pNode
->GetPolygon( ).GetBoundRect( ).TopLeft( )
682 + Point( nBorderwidth
, nBorderwidth
) ),
683 aPos ( Position
+ aOffset
);
684 pNode
->GetPolygon( ).Move( aPos
.X( ), aPos
.Y( ) ); //Works because Polygon wraps a pointer
686 SmTmpDevice2
aTmpDev ( ( OutputDevice
& ) rDev
, false );
687 aTmpDev
.SetLineColor( pNode
->GetFont( ).GetColor( ) );
689 rDev
.DrawPolyLine( pNode
->GetPolygon( ), aInfo
);
692 void SmDrawingVisitor::Visit( SmRectangleNode
* pNode
)
694 if ( pNode
->IsPhantom( ) )
697 SmTmpDevice2
aTmpDev ( ( OutputDevice
& ) rDev
, false );
698 aTmpDev
.SetFillColor( pNode
->GetFont( ).GetColor( ) );
699 rDev
.SetLineColor( );
700 aTmpDev
.SetFont( pNode
->GetFont( ) );
702 sal_uLong nTmpBorderWidth
= pNode
->GetFont( ).GetBorderWidth( );
704 // get rectangle and remove borderspace
705 Rectangle
aTmp ( pNode
->AsRectangle( ) + Position
- pNode
->GetTopLeft( ) );
706 aTmp
.Left( ) += nTmpBorderWidth
;
707 aTmp
.Right( ) -= nTmpBorderWidth
;
708 aTmp
.Top( ) += nTmpBorderWidth
;
709 aTmp
.Bottom( ) -= nTmpBorderWidth
;
711 OSL_ENSURE( aTmp
.GetHeight( ) > 0 && aTmp
.GetWidth( ) > 0,
712 "Sm: leeres Rechteck" );
714 //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
715 //! increasing zoomfactor.
716 // This is done by shifting its output-position to a point that
717 // corresponds exactly to a pixel on the output device.
718 Point
aPos ( rDev
.PixelToLogic( rDev
.LogicToPixel( aTmp
.TopLeft( ) ) ) );
721 rDev
.DrawRect( aTmp
);
724 void SmDrawingVisitor::DrawTextNode( SmTextNode
* pNode
)
726 if ( pNode
->IsPhantom() || pNode
->GetText().isEmpty() || pNode
->GetText()[0] == '\0' )
729 SmTmpDevice2
aTmpDev ( ( OutputDevice
& ) rDev
, false );
730 aTmpDev
.SetFont( pNode
->GetFont( ) );
732 Point
aPos ( Position
);
733 aPos
.Y( ) += pNode
->GetBaselineOffset( );
734 // auf Pixelkoordinaten runden
735 aPos
= rDev
.PixelToLogic( rDev
.LogicToPixel( aPos
) );
737 rDev
.DrawStretchText( aPos
, pNode
->GetWidth( ), pNode
->GetText( ) );
740 void SmDrawingVisitor::DrawSpecialNode( SmSpecialNode
* pNode
)
742 //! since this chars might come from any font, that we may not have
743 //! set to ALIGN_BASELINE yet, we do it now.
744 pNode
->GetFont( ).SetAlign( ALIGN_BASELINE
);
746 DrawTextNode( pNode
);
749 void SmDrawingVisitor::DrawChildren( SmNode
* pNode
)
751 if ( pNode
->IsPhantom( ) )
754 Point rPosition
= Position
;
756 SmNodeIterator
it( pNode
);
759 Point
aOffset ( it
->GetTopLeft( ) - pNode
->GetTopLeft( ) );
760 Position
= rPosition
+ aOffset
;
765 /////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
767 SmSetSelectionVisitor::SmSetSelectionVisitor( SmCaretPos startPos
, SmCaretPos endPos
, SmNode
* pTree
) {
772 //Assume that pTree is a SmTableNode
773 OSL_ENSURE(pTree
->GetType() == NTABLE
, "pTree should be a SmTableNode!");
774 //Visit root node, this is special as this node cannot be selected, but its children can!
775 if(pTree
->GetType() == NTABLE
){
776 //Change state if StartPos is in front of this node
777 if( StartPos
.pSelectedNode
== pTree
&& StartPos
.Index
== 0 )
778 IsSelecting
= !IsSelecting
;
779 //Change state if EndPos is in front of this node
780 if( EndPos
.pSelectedNode
== pTree
&& EndPos
.Index
== 0 )
781 IsSelecting
= !IsSelecting
;
782 OSL_ENSURE(!IsSelecting
, "Caret positions needed to set IsSelecting about, shouldn't be possible!");
785 SmNodeIterator
it( pTree
);
786 while( it
.Next( ) ) {
788 //If we started a selection in this line and it haven't ended, we do that now!
791 SetSelectedOnAll(it
.Current(), true);
792 //Set StartPos and EndPos to invalid positions, this ensures that an unused
793 //start or end (because we forced end above), doesn't start a new selection.
794 StartPos
= EndPos
= SmCaretPos();
797 //Check if pTree isn't selected
798 OSL_ENSURE(!pTree
->IsSelected(), "pTree should never be selected!");
799 //Discard the selection if there's a bug (it's better than crashing)
800 if(pTree
->IsSelected())
801 SetSelectedOnAll(pTree
, false);
802 }else //This shouldn't happen, but I don't see any reason to die if it does
806 void SmSetSelectionVisitor::SetSelectedOnAll( SmNode
* pSubTree
, bool IsSelected
) {
807 pSubTree
->SetSelected( IsSelected
);
809 //Quick BFS to set all selections
810 SmNodeIterator
it( pSubTree
);
812 SetSelectedOnAll( it
.Current( ), IsSelected
);
815 void SmSetSelectionVisitor::DefaultVisit( SmNode
* pNode
) {
816 //Change state if StartPos is in front of this node
817 if( StartPos
.pSelectedNode
== pNode
&& StartPos
.Index
== 0 )
818 IsSelecting
= !IsSelecting
;
819 //Change state if EndPos is in front of this node
820 if( EndPos
.pSelectedNode
== pNode
&& EndPos
.Index
== 0 )
821 IsSelecting
= !IsSelecting
;
823 //Cache current state
824 bool WasSelecting
= IsSelecting
;
825 bool ChangedState
= false;
828 pNode
->SetSelected( IsSelecting
);
831 SmNodeIterator
it( pNode
);
835 ChangedState
= ( WasSelecting
!= IsSelecting
) || ChangedState
;
841 //Select this node and all of its children
842 //(Make exception for SmBracebodyNode)
843 if( pNode
->GetType() != NBRACEBODY
||
844 !pNode
->GetParent() ||
845 pNode
->GetParent()->GetType() != NBRACE
)
846 SetSelectedOnAll( pNode
, true );
848 SetSelectedOnAll( pNode
->GetParent(), true );
849 /* If the equation is: sqrt{2 + 4} + 5
850 * And the selection is: sqrt{2 + [4} +] 5
851 * Where [ denotes StartPos and ] denotes EndPos
852 * Then the sqrt node should be selected, so that the
853 * effective selection is: [sqrt{2 + 4} +] 5
854 * The same is the case if we swap StartPos and EndPos.
858 //Change state if StartPos is after this node
859 if( StartPos
.pSelectedNode
== pNode
&& StartPos
.Index
== 1 )
861 IsSelecting
= !IsSelecting
;
863 //Change state if EndPos is after of this node
864 if( EndPos
.pSelectedNode
== pNode
&& EndPos
.Index
== 1 )
866 IsSelecting
= !IsSelecting
;
870 void SmSetSelectionVisitor::VisitCompositionNode( SmNode
* pNode
) {
871 //Change state if StartPos is in front of this node
872 if( StartPos
.pSelectedNode
== pNode
&& StartPos
.Index
== 0 )
873 IsSelecting
= !IsSelecting
;
874 //Change state if EndPos is in front of this node
875 if( EndPos
.pSelectedNode
== pNode
&& EndPos
.Index
== 0 )
876 IsSelecting
= !IsSelecting
;
878 //Cache current state
879 bool WasSelecting
= IsSelecting
;
882 SmNodeIterator
it( pNode
);
886 //Set selected, if everything was selected
887 pNode
->SetSelected( WasSelecting
&& IsSelecting
);
889 //Change state if StartPos is after this node
890 if( StartPos
.pSelectedNode
== pNode
&& StartPos
.Index
== 1 )
891 IsSelecting
= !IsSelecting
;
892 //Change state if EndPos is after of this node
893 if( EndPos
.pSelectedNode
== pNode
&& EndPos
.Index
== 1 )
894 IsSelecting
= !IsSelecting
;
897 void SmSetSelectionVisitor::Visit( SmTextNode
* pNode
) {
900 if( StartPos
.pSelectedNode
== pNode
)
902 if( EndPos
.pSelectedNode
== pNode
)
906 pNode
->SetSelected( true );
907 if( i1
!= -1 && i2
!= -1 ) {
908 start
= i1
< i2
? i1
: i2
; //MIN
909 end
= i1
> i2
? i1
: i2
; //MAX
910 } else if( IsSelecting
&& i1
!= -1 ) {
914 } else if( IsSelecting
&& i2
!= -1 ) {
918 } else if( !IsSelecting
&& i1
!= -1 ) {
920 end
= pNode
->GetText().getLength();
922 } else if( !IsSelecting
&& i2
!= -1 ) {
924 end
= pNode
->GetText().getLength();
926 } else if( IsSelecting
) {
928 end
= pNode
->GetText().getLength();
930 pNode
->SetSelected( false );
934 pNode
->SetSelected( start
!= end
);
935 pNode
->SetSelectionStart( start
);
936 pNode
->SetSelectionEnd( end
);
939 void SmSetSelectionVisitor::Visit( SmExpressionNode
* pNode
) {
940 VisitCompositionNode( pNode
);
943 void SmSetSelectionVisitor::Visit( SmLineNode
* pNode
) {
944 VisitCompositionNode( pNode
);
947 void SmSetSelectionVisitor::Visit( SmAlignNode
* pNode
) {
948 VisitCompositionNode( pNode
);
951 void SmSetSelectionVisitor::Visit( SmBinHorNode
* pNode
) {
952 VisitCompositionNode( pNode
);
955 void SmSetSelectionVisitor::Visit( SmUnHorNode
* pNode
) {
956 VisitCompositionNode( pNode
);
959 void SmSetSelectionVisitor::Visit( SmFontNode
* pNode
) {
960 VisitCompositionNode( pNode
);
963 /////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
965 SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode
* pRootNode
) {
967 pGraph
= new SmCaretPosGraph( );
968 //pRootNode should always be a table
969 OSL_ENSURE( pRootNode
->GetType( ) == NTABLE
, "pRootNode must be a table node");
970 //Handle the special case where NTABLE is used a rootnode
971 if( pRootNode
->GetType( ) == NTABLE
){
972 //Children are SmLineNodes
973 //Or so I thought... Aparently, the children can be instances of SmExpression
974 //especially if there's a error in the formula... So he we go, a simple work around.
975 SmNodeIterator
it( pRootNode
);
977 //There's a special invariant between this method and the Visit( SmLineNode* )
978 //Usually pRightMost may not be NULL, to avoid this pRightMost should here be
979 //set to a new SmCaretPos in front of it.Current( ), however, if it.Current( ) is
980 //an instance of SmLineNode we let SmLineNode create this position in front of
982 //The argument for doing this is that we now don't have to worry about SmLineNode
983 //being a visual line composition node. Thus, no need for yet another special case
984 //in SmCursor::IsLineCompositionNode and everywhere this method is used.
985 //if( it->GetType( ) != NLINE )
986 pRightMost
= pGraph
->Add( SmCaretPos( it
.Current( ), 0 ) );
990 pRootNode
->Accept(this);
993 void SmCaretPosGraphBuildingVisitor::Visit( SmLineNode
* pNode
){
994 SmNodeIterator
it( pNode
);
1000 /** Build SmCaretPosGraph for SmTableNode
1001 * This method covers cases where SmTableNode is used in a binom or stack,
1002 * the special case where it is used as root node for the entire formula is
1003 * handled in the constructor.
1005 void SmCaretPosGraphBuildingVisitor::Visit( SmTableNode
* pNode
){
1006 SmCaretPosGraphEntry
*left
= pRightMost
,
1007 *right
= pGraph
->Add( SmCaretPos( pNode
, 1) );
1008 bool bIsFirst
= true;
1009 SmNodeIterator
it( pNode
);
1011 pRightMost
= pGraph
->Add( SmCaretPos( it
.Current(), 0 ), left
);
1013 left
->SetRight(pRightMost
);
1015 pRightMost
->SetRight(right
);
1017 right
->SetLeft(pRightMost
);
1023 /** Build SmCaretPosGraph for SmSubSupNode
1025 * The child positions in a SubSupNode, where H is the body:
1038 * Graph over these, where "left" is before the SmSubSupNode and "right" is after:
1053 void SmCaretPosGraphBuildingVisitor::Visit( SmSubSupNode
* pNode
)
1055 SmCaretPosGraphEntry
*left
,
1061 OSL_ENSURE( pRightMost
, "pRightMost shouldn't be NULL here!" );
1064 OSL_ENSURE( pNode
->GetBody( ), "SmSubSupNode Doesn't have a body!" );
1065 bodyLeft
= pGraph
->Add( SmCaretPos( pNode
->GetBody( ), 0 ), left
);
1066 left
->SetRight( bodyLeft
); //TODO: Don't make this if LSUP or LSUB are NULL ( not sure??? )
1069 right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1071 //Visit the body, to get bodyRight
1072 pRightMost
= bodyLeft
;
1073 pNode
->GetBody( )->Accept( this );
1074 bodyRight
= pRightMost
;
1075 bodyRight
->SetRight( right
);
1076 right
->SetLeft( bodyRight
);
1079 //If there's an LSUP
1080 if( ( pChild
= pNode
->GetSubSup( LSUP
) ) ){
1081 SmCaretPosGraphEntry
*cLeft
; //Child left
1082 cLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1085 pChild
->Accept( this );
1087 pRightMost
->SetRight( bodyLeft
);
1089 //If there's an LSUB
1090 if( ( pChild
= pNode
->GetSubSup( LSUB
) ) ){
1091 SmCaretPosGraphEntry
*cLeft
; //Child left
1092 cLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1095 pChild
->Accept( this );
1097 pRightMost
->SetRight( bodyLeft
);
1099 //If there's an CSUP
1100 if( ( pChild
= pNode
->GetSubSup( CSUP
) ) ){
1101 SmCaretPosGraphEntry
*cLeft
; //Child left
1102 cLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1105 pChild
->Accept( this );
1107 pRightMost
->SetRight( right
);
1109 //If there's an CSUB
1110 if( ( pChild
= pNode
->GetSubSup( CSUB
) ) ){
1111 SmCaretPosGraphEntry
*cLeft
; //Child left
1112 cLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1115 pChild
->Accept( this );
1117 pRightMost
->SetRight( right
);
1119 //If there's an RSUP
1120 if( ( pChild
= pNode
->GetSubSup( RSUP
) ) ){
1121 SmCaretPosGraphEntry
*cLeft
; //Child left
1122 cLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), bodyRight
);
1125 pChild
->Accept( this );
1127 pRightMost
->SetRight( right
);
1129 //If there's an RSUB
1130 if( ( pChild
= pNode
->GetSubSup( RSUB
) ) ){
1131 SmCaretPosGraphEntry
*cLeft
; //Child left
1132 cLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), bodyRight
);
1135 pChild
->Accept( this );
1137 pRightMost
->SetRight( right
);
1140 //Set return parameters
1144 /** Build caret position for SmOperNode
1146 * If first child is an SmSubSupNode we will ignore its
1147 * body, as this body is a SmMathSymbol, for SUM, INT or similar
1148 * that shouldn't be subject to modification.
1149 * If first child is not a SmSubSupNode, ignore it completely
1150 * as it is a SmMathSymbol.
1152 * The child positions in a SmOperNode, where H is symbol, e.g. int, sum or similar:
1156 * LSUP H H RSUP BBB BB BBB B B
1157 * H H B B B B B B B B
1158 * HHHH BBB B B B B B
1160 * LSUB H H RSUB BBB BB BBB B
1164 * Notice, CSUP, etc. are actually granchildren, but inorder to ignore H, these are visited
1165 * from here. If they are present, that is if pOper is an instance of SmSubSupNode.
1167 * Graph over these, where "left" is before the SmOperNode and "right" is after:
1181 void SmCaretPosGraphBuildingVisitor::Visit( SmOperNode
* pNode
)
1183 SmNode
*pOper
= pNode
->GetSubNode( 0 ),
1184 *pBody
= pNode
->GetSubNode( 1 );
1186 SmCaretPosGraphEntry
*left
= pRightMost
,
1191 bodyLeft
= pGraph
->Add( SmCaretPos( pBody
, 0 ), left
);
1192 left
->SetRight( bodyLeft
);
1194 //Visit body, get bodyRight
1195 pRightMost
= bodyLeft
;
1196 pBody
->Accept( this );
1197 bodyRight
= pRightMost
;
1200 right
= pGraph
->Add( SmCaretPos( pNode
, 1 ), bodyRight
);
1201 bodyRight
->SetRight( right
);
1203 //Get subsup pNode if any
1204 SmSubSupNode
* pSubSup
= pOper
->GetType( ) == NSUBSUP
? ( SmSubSupNode
* )pOper
: NULL
;
1207 SmCaretPosGraphEntry
*childLeft
;
1208 if( pSubSup
&& ( pChild
= pSubSup
->GetSubSup( LSUP
) ) ) {
1209 //Create position in front of pChild
1210 childLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1212 pRightMost
= childLeft
;
1213 pChild
->Accept( this );
1214 //Set right on pRightMost from pChild
1215 pRightMost
->SetRight( bodyLeft
);
1217 if( pSubSup
&& ( pChild
= pSubSup
->GetSubSup( LSUB
) ) ) {
1218 //Create position in front of pChild
1219 childLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1221 pRightMost
= childLeft
;
1222 pChild
->Accept( this );
1223 //Set right on pRightMost from pChild
1224 pRightMost
->SetRight( bodyLeft
);
1226 if( pSubSup
&& ( pChild
= pSubSup
->GetSubSup( CSUP
) ) ) {//TO
1227 //Create position in front of pChild
1228 childLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1230 pRightMost
= childLeft
;
1231 pChild
->Accept( this );
1232 //Set right on pRightMost from pChild
1233 pRightMost
->SetRight( bodyLeft
);
1235 if( pSubSup
&& ( pChild
= pSubSup
->GetSubSup( CSUB
) ) ) { //FROM
1236 //Create position in front of pChild
1237 childLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1239 pRightMost
= childLeft
;
1240 pChild
->Accept( this );
1241 //Set right on pRightMost from pChild
1242 pRightMost
->SetRight( bodyLeft
);
1244 if( pSubSup
&& ( pChild
= pSubSup
->GetSubSup( RSUP
) ) ) {
1245 //Create position in front of pChild
1246 childLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1248 pRightMost
= childLeft
;
1249 pChild
->Accept( this );
1250 //Set right on pRightMost from pChild
1251 pRightMost
->SetRight( bodyLeft
);
1253 if( pSubSup
&& ( pChild
= pSubSup
->GetSubSup( RSUB
) ) ) {
1254 //Create position in front of pChild
1255 childLeft
= pGraph
->Add( SmCaretPos( pChild
, 0 ), left
);
1257 pRightMost
= childLeft
;
1258 pChild
->Accept( this );
1259 //Set right on pRightMost from pChild
1260 pRightMost
->SetRight( bodyLeft
);
1267 void SmCaretPosGraphBuildingVisitor::Visit( SmMatrixNode
* pNode
)
1269 SmCaretPosGraphEntry
*left
= pRightMost
,
1270 *right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1272 for ( sal_uInt16 i
= 0; i
< pNode
->GetNumRows( ); i
++ ) {
1273 SmCaretPosGraphEntry
* r
= left
;
1274 for ( sal_uInt16 j
= 0; j
< pNode
->GetNumCols( ); j
++ ){
1275 SmNode
* pSubNode
= pNode
->GetSubNode( i
* pNode
->GetNumCols( ) + j
);
1277 pRightMost
= pGraph
->Add( SmCaretPos( pSubNode
, 0 ), r
);
1278 if( j
!= 0 || ( pNode
->GetNumRows( ) - 1 ) / 2 == i
)
1279 r
->SetRight( pRightMost
);
1281 pSubNode
->Accept( this );
1285 pRightMost
->SetRight( right
);
1286 if( ( pNode
->GetNumRows( ) - 1 ) / 2 == i
)
1287 right
->SetLeft( pRightMost
);
1293 /** Build SmCaretPosGraph for SmTextNode
1295 * Lines in an SmTextNode:
1299 * Where A B and C are characters in the text.
1301 * Graph over these, where "left" is before the SmTextNode and "right" is after:
1309 * Notice that C and right is the same position here.
1311 void SmCaretPosGraphBuildingVisitor::Visit( SmTextNode
* pNode
)
1313 OSL_ENSURE( !pNode
->GetText().isEmpty(), "Empty SmTextNode is bad" );
1315 int size
= pNode
->GetText().getLength();
1316 for( int i
= 1; i
<= size
; i
++ ){
1317 SmCaretPosGraphEntry
* pRight
= pRightMost
;
1318 pRightMost
= pGraph
->Add( SmCaretPos( pNode
, i
), pRight
);
1319 pRight
->SetRight( pRightMost
);
1323 /** Build SmCaretPosGraph for SmBinVerNode
1325 * Lines in an SmBinVerNode:
1332 * Graph over these, where "left" is before the SmBinVerNode and "right" is after:
1341 void SmCaretPosGraphBuildingVisitor::Visit( SmBinVerNode
* pNode
)
1343 //None if these children can be NULL, see SmBinVerNode::Arrange
1344 SmNode
*pNum
= pNode
->GetSubNode( 0 ),
1345 *pDenom
= pNode
->GetSubNode( 2 );
1347 SmCaretPosGraphEntry
*left
,
1354 OSL_ENSURE( pRightMost
, "There must be a position in front of this" );
1357 right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1360 numLeft
= pGraph
->Add( SmCaretPos( pNum
, 0 ), left
);
1361 left
->SetRight( numLeft
);
1364 pRightMost
= numLeft
;
1365 pNum
->Accept( this );
1366 pRightMost
->SetRight( right
);
1367 right
->SetLeft( pRightMost
);
1370 denomLeft
= pGraph
->Add( SmCaretPos( pDenom
, 0 ), left
);
1373 pRightMost
= denomLeft
;
1374 pDenom
->Accept( this );
1375 pRightMost
->SetRight( right
);
1377 //Set return parameter
1381 /** Build SmCaretPosGraph for SmVerticalBraceNode
1383 * Lines in an SmVerticalBraceNode:
1392 void SmCaretPosGraphBuildingVisitor::Visit( SmVerticalBraceNode
* pNode
)
1394 SmNode
*pBody
= pNode
->GetSubNode( 0 ),
1395 *pScript
= pNode
->GetSubNode( 2 );
1396 //None of these children can be NULL
1398 SmCaretPosGraphEntry
*left
,
1406 right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1409 bodyLeft
= pGraph
->Add( SmCaretPos( pBody
, 0 ), left
);
1410 left
->SetRight( bodyLeft
);
1411 pRightMost
= bodyLeft
;
1412 pBody
->Accept( this );
1413 pRightMost
->SetRight( right
);
1414 right
->SetLeft( pRightMost
);
1417 scriptLeft
= pGraph
->Add( SmCaretPos( pScript
, 0 ), left
);
1418 pRightMost
= scriptLeft
;
1419 pScript
->Accept( this );
1420 pRightMost
->SetRight( right
);
1426 /** Build SmCaretPosGraph for SmBinDiagonalNode
1428 * Lines in an SmBinDiagonalNode:
1434 * Where A and B are lines.
1436 * Used in formulas such as "A wideslash B"
1438 void SmCaretPosGraphBuildingVisitor::Visit( SmBinDiagonalNode
* pNode
)
1440 SmNode
*A
= pNode
->GetSubNode( 0 ),
1441 *B
= pNode
->GetSubNode( 1 );
1443 SmCaretPosGraphEntry
*left
,
1451 right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1454 leftA
= pGraph
->Add( SmCaretPos( A
, 0 ), left
);
1455 left
->SetRight( leftA
);
1460 rightA
= pRightMost
;
1463 leftB
= pGraph
->Add( SmCaretPos( B
, 0 ), rightA
);
1464 rightA
->SetRight( leftB
);
1469 pRightMost
->SetRight( right
);
1470 right
->SetLeft( pRightMost
);
1476 //Straigt forward ( I think )
1477 void SmCaretPosGraphBuildingVisitor::Visit( SmBinHorNode
* pNode
)
1479 SmNodeIterator
it( pNode
);
1483 void SmCaretPosGraphBuildingVisitor::Visit( SmUnHorNode
* pNode
)
1485 // Unary operator node
1486 SmNodeIterator
it( pNode
);
1492 void SmCaretPosGraphBuildingVisitor::Visit( SmExpressionNode
* pNode
)
1494 SmNodeIterator
it( pNode
);
1499 void SmCaretPosGraphBuildingVisitor::Visit( SmFontNode
* pNode
)
1501 //Has only got one child, should act as an expression if possible
1502 SmNodeIterator
it( pNode
);
1507 /** Build SmCaretPosGraph for SmBracebodyNode
1508 * Acts as an SmExpressionNode
1510 * Below is an example of a formula tree that has multiple children for SmBracebodyNode
1514 * label= "Equation: \"lbrace i mline i in setZ rbrace\"";
1515 * n0 [label="SmTableNode"];
1516 * n0 -> n1 [label="0"];
1517 * n1 [label="SmLineNode"];
1518 * n1 -> n2 [label="0"];
1519 * n2 [label="SmExpressionNode"];
1520 * n2 -> n3 [label="0"];
1521 * n3 [label="SmBraceNode"];
1522 * n3 -> n4 [label="0"];
1523 * n4 [label="SmMathSymbolNode: {"];
1524 * n3 -> n5 [label="1"];
1525 * n5 [label="SmBracebodyNode"];
1526 * n5 -> n6 [label="0"];
1527 * n6 [label="SmExpressionNode"];
1528 * n6 -> n7 [label="0"];
1529 * n7 [label="SmTextNode: i"];
1530 * n5 -> n8 [label="1"];
1531 * n8 [label="SmMathSymbolNode: ∣"];
1532 * n5 -> n9 [label="2"];
1533 * n9 [label="SmExpressionNode"];
1534 * n9 -> n10 [label="0"];
1535 * n10 [label="SmBinHorNode"];
1536 * n10 -> n11 [label="0"];
1537 * n11 [label="SmTextNode: i"];
1538 * n10 -> n12 [label="1"];
1539 * n12 [label="SmMathSymbolNode: ∈"];
1540 * n10 -> n13 [label="2"];
1541 * n13 [label="SmMathSymbolNode: ℤ"];
1542 * n3 -> n14 [label="2"];
1543 * n14 [label="SmMathSymbolNode: }"];
1547 void SmCaretPosGraphBuildingVisitor::Visit( SmBracebodyNode
* pNode
)
1549 SmNodeIterator
it( pNode
);
1550 while( it
.Next( ) ) {
1551 SmCaretPosGraphEntry
* pStart
= pGraph
->Add( SmCaretPos( it
.Current(), 0), pRightMost
);
1552 pRightMost
->SetRight( pStart
);
1553 pRightMost
= pStart
;
1558 /** Build SmCaretPosGraph for SmAlignNode
1559 * Acts as an SmExpressionNode, as it only has one child this okay
1561 void SmCaretPosGraphBuildingVisitor::Visit( SmAlignNode
* pNode
)
1563 SmNodeIterator
it( pNode
);
1568 /** Build SmCaretPosGraph for SmRootNode
1570 * Lines in an SmRootNode:
1577 * A: pExtra ( optional, can be NULL ),
1580 * Graph over these, where "left" is before the SmRootNode and "right" is after:
1589 void SmCaretPosGraphBuildingVisitor::Visit( SmRootNode
* pNode
)
1591 SmNode
*pExtra
= pNode
->GetSubNode( 0 ), //Argument, NULL for sqrt, and SmTextNode if cubicroot
1592 *pBody
= pNode
->GetSubNode( 2 ); //Body of the root
1593 OSL_ENSURE( pBody
, "pBody cannot be NULL" );
1595 SmCaretPosGraphEntry
*left
,
1600 //Get left and save it
1601 OSL_ENSURE( pRightMost
, "There must be a position in front of this" );
1605 bodyLeft
= pGraph
->Add( SmCaretPos( pBody
, 0 ), left
);
1606 left
->SetRight( bodyLeft
);
1609 right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1612 pRightMost
= bodyLeft
;
1613 pBody
->Accept( this );
1614 bodyRight
= pRightMost
;
1615 bodyRight
->SetRight( right
);
1616 right
->SetLeft( bodyRight
);
1620 pRightMost
= pGraph
->Add( SmCaretPos( pExtra
, 0 ), left
);
1621 pExtra
->Accept( this );
1622 pRightMost
->SetRight( bodyLeft
);
1628 /** Build SmCaretPosGraph for SmPlaceNode
1629 * Consider this a single character.
1631 void SmCaretPosGraphBuildingVisitor::Visit( SmPlaceNode
* pNode
)
1633 SmCaretPosGraphEntry
* right
= pGraph
->Add( SmCaretPos( pNode
, 1 ), pRightMost
);
1634 pRightMost
->SetRight( right
);
1638 /** SmErrorNode is context dependent metadata, it can't be selected
1640 * @remarks There's no point in deleting, copying and/or moving an instance
1641 * of SmErrorNode as it may not exist in an other context! Thus there are no
1642 * positions to select an SmErrorNode.
1644 void SmCaretPosGraphBuildingVisitor::Visit( SmErrorNode
* )
1648 /** Build SmCaretPosGraph for SmBlankNode
1649 * Consider this a single character, as it is only a blank space
1651 void SmCaretPosGraphBuildingVisitor::Visit( SmBlankNode
* pNode
)
1653 SmCaretPosGraphEntry
* right
= pGraph
->Add( SmCaretPos( pNode
, 1 ), pRightMost
);
1654 pRightMost
->SetRight( right
);
1658 /** Build SmCaretPosGraph for SmBraceNode
1660 * Lines in an SmBraceNode:
1668 * Graph over these, where "left" is before the SmBraceNode and "right" is after:
1676 void SmCaretPosGraphBuildingVisitor::Visit( SmBraceNode
* pNode
)
1678 SmNode
* pBody
= pNode
->GetSubNode( 1 );
1680 SmCaretPosGraphEntry
*left
= pRightMost
,
1681 *right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1683 if( pBody
->GetType() != NBRACEBODY
) {
1684 pRightMost
= pGraph
->Add( SmCaretPos( pBody
, 0 ), left
);
1685 left
->SetRight( pRightMost
);
1689 pBody
->Accept( this );
1690 pRightMost
->SetRight( right
);
1691 right
->SetLeft( pRightMost
);
1696 /** Build SmCaretPosGraph for SmAttributNode
1698 * Lines in an SmAttributNode:
1704 * There's a body and an attribute, the construction is used for "widehat A", where "A" is the body
1705 * and "^" is the attribute ( note GetScaleMode( ) on SmAttributNode tells how the attribute should be
1708 void SmCaretPosGraphBuildingVisitor::Visit( SmAttributNode
* pNode
)
1710 SmNode
*pAttr
= pNode
->GetSubNode( 0 ),
1711 *pBody
= pNode
->GetSubNode( 1 );
1712 //None of the children can be NULL
1714 SmCaretPosGraphEntry
*left
= pRightMost
,
1721 bodyLeft
= pGraph
->Add( SmCaretPos( pBody
, 0 ), left
);
1722 left
->SetRight( bodyLeft
);
1725 right
= pGraph
->Add( SmCaretPos( pNode
, 1 ) );
1728 pRightMost
= bodyLeft
;
1729 pBody
->Accept( this );
1730 bodyRight
= pRightMost
;
1731 bodyRight
->SetRight( right
);
1732 right
->SetLeft( bodyRight
);
1735 attrLeft
= pGraph
->Add( SmCaretPos( pAttr
, 0 ), left
);
1738 pRightMost
= attrLeft
;
1739 pAttr
->Accept( this );
1740 pRightMost
->SetRight( right
);
1746 //Consider these single symboles
1747 void SmCaretPosGraphBuildingVisitor::Visit( SmSpecialNode
* pNode
)
1749 SmCaretPosGraphEntry
* right
= pGraph
->Add( SmCaretPos( pNode
, 1 ), pRightMost
);
1750 pRightMost
->SetRight( right
);
1753 void SmCaretPosGraphBuildingVisitor::Visit( SmGlyphSpecialNode
* pNode
)
1755 SmCaretPosGraphEntry
* right
= pGraph
->Add( SmCaretPos( pNode
, 1 ), pRightMost
);
1756 pRightMost
->SetRight( right
);
1759 void SmCaretPosGraphBuildingVisitor::Visit( SmMathSymbolNode
* pNode
)
1761 SmCaretPosGraphEntry
* right
= pGraph
->Add( SmCaretPos( pNode
, 1 ), pRightMost
);
1762 pRightMost
->SetRight( right
);
1766 void SmCaretPosGraphBuildingVisitor::Visit( SmRootSymbolNode
* )
1770 void SmCaretPosGraphBuildingVisitor::Visit( SmRectangleNode
* )
1774 void SmCaretPosGraphBuildingVisitor::Visit( SmPolyLineNode
* )
1779 /////////////////////////////// SmCloningVisitor ///////////////////////////////
1781 SmNode
* SmCloningVisitor::Clone( SmNode
* pNode
)
1783 SmNode
* pCurrResult
= pResult
;
1784 pNode
->Accept( this );
1785 SmNode
* pClone
= pResult
;
1786 pResult
= pCurrResult
;
1790 void SmCloningVisitor::CloneNodeAttr( SmNode
* pSource
, SmNode
* pTarget
)
1792 pTarget
->SetScaleMode( pSource
->GetScaleMode( ) );
1793 //Other attributes are set when prepare or arrange is executed
1794 //and may depend on stuff not being cloned here.
1797 void SmCloningVisitor::CloneKids( SmStructureNode
* pSource
, SmStructureNode
* pTarget
)
1799 //Cache current result
1800 SmNode
* pCurrResult
= pResult
;
1802 //Create array for holding clones
1803 sal_uInt16 nSize
= pSource
->GetNumSubNodes( );
1804 SmNodeArray
aNodes( nSize
);
1808 for( sal_uInt16 i
= 0; i
< nSize
; i
++ ){
1809 if( NULL
!= ( pKid
= pSource
->GetSubNode( i
) ) )
1810 pKid
->Accept( this );
1813 aNodes
[i
] = pResult
;
1816 //Set subnodes of pTarget
1817 pTarget
->SetSubNodes( aNodes
);
1819 //Restore result as where prior to call
1820 pResult
= pCurrResult
;
1823 void SmCloningVisitor::Visit( SmTableNode
* pNode
)
1825 SmTableNode
* pClone
= new SmTableNode( pNode
->GetToken( ) );
1826 CloneNodeAttr( pNode
, pClone
);
1827 CloneKids( pNode
, pClone
);
1831 void SmCloningVisitor::Visit( SmBraceNode
* pNode
)
1833 SmBraceNode
* pClone
= new SmBraceNode( pNode
->GetToken( ) );
1834 CloneNodeAttr( pNode
, pClone
);
1835 CloneKids( pNode
, pClone
);
1839 void SmCloningVisitor::Visit( SmBracebodyNode
* pNode
)
1841 SmBracebodyNode
* pClone
= new SmBracebodyNode( pNode
->GetToken( ) );
1842 CloneNodeAttr( pNode
, pClone
);
1843 CloneKids( pNode
, pClone
);
1847 void SmCloningVisitor::Visit( SmOperNode
* pNode
)
1849 SmOperNode
* pClone
= new SmOperNode( pNode
->GetToken( ) );
1850 CloneNodeAttr( pNode
, pClone
);
1851 CloneKids( pNode
, pClone
);
1855 void SmCloningVisitor::Visit( SmAlignNode
* pNode
)
1857 SmAlignNode
* pClone
= new SmAlignNode( pNode
->GetToken( ) );
1858 CloneNodeAttr( pNode
, pClone
);
1859 CloneKids( pNode
, pClone
);
1863 void SmCloningVisitor::Visit( SmAttributNode
* pNode
)
1865 SmAttributNode
* pClone
= new SmAttributNode( pNode
->GetToken( ) );
1866 CloneNodeAttr( pNode
, pClone
);
1867 CloneKids( pNode
, pClone
);
1871 void SmCloningVisitor::Visit( SmFontNode
* pNode
)
1873 SmFontNode
* pClone
= new SmFontNode( pNode
->GetToken( ) );
1874 pClone
->SetSizeParameter( pNode
->GetSizeParameter( ), pNode
->GetSizeType( ) );
1875 CloneNodeAttr( pNode
, pClone
);
1876 CloneKids( pNode
, pClone
);
1880 void SmCloningVisitor::Visit( SmUnHorNode
* pNode
)
1882 SmUnHorNode
* pClone
= new SmUnHorNode( pNode
->GetToken( ) );
1883 CloneNodeAttr( pNode
, pClone
);
1884 CloneKids( pNode
, pClone
);
1888 void SmCloningVisitor::Visit( SmBinHorNode
* pNode
)
1890 SmBinHorNode
* pClone
= new SmBinHorNode( pNode
->GetToken( ) );
1891 CloneNodeAttr( pNode
, pClone
);
1892 CloneKids( pNode
, pClone
);
1896 void SmCloningVisitor::Visit( SmBinVerNode
* pNode
)
1898 SmBinVerNode
* pClone
= new SmBinVerNode( pNode
->GetToken( ) );
1899 CloneNodeAttr( pNode
, pClone
);
1900 CloneKids( pNode
, pClone
);
1904 void SmCloningVisitor::Visit( SmBinDiagonalNode
* pNode
)
1906 SmBinDiagonalNode
*pClone
= new SmBinDiagonalNode( pNode
->GetToken( ) );
1907 pClone
->SetAscending( pNode
->IsAscending( ) );
1908 CloneNodeAttr( pNode
, pClone
);
1909 CloneKids( pNode
, pClone
);
1913 void SmCloningVisitor::Visit( SmSubSupNode
* pNode
)
1915 SmSubSupNode
*pClone
= new SmSubSupNode( pNode
->GetToken( ) );
1916 pClone
->SetUseLimits( pNode
->IsUseLimits( ) );
1917 CloneNodeAttr( pNode
, pClone
);
1918 CloneKids( pNode
, pClone
);
1922 void SmCloningVisitor::Visit( SmMatrixNode
* pNode
)
1924 SmMatrixNode
*pClone
= new SmMatrixNode( pNode
->GetToken( ) );
1925 pClone
->SetRowCol( pNode
->GetNumRows( ), pNode
->GetNumCols( ) );
1926 CloneNodeAttr( pNode
, pClone
);
1927 CloneKids( pNode
, pClone
);
1931 void SmCloningVisitor::Visit( SmPlaceNode
* pNode
)
1933 pResult
= new SmPlaceNode( pNode
->GetToken( ) );
1934 CloneNodeAttr( pNode
, pResult
);
1937 void SmCloningVisitor::Visit( SmTextNode
* pNode
)
1939 SmTextNode
* pClone
= new SmTextNode( pNode
->GetToken( ), pNode
->GetFontDesc( ) );
1940 pClone
->ChangeText( pNode
->GetText( ) );
1941 CloneNodeAttr( pNode
, pClone
);
1945 void SmCloningVisitor::Visit( SmSpecialNode
* pNode
)
1947 pResult
= new SmSpecialNode( pNode
->GetToken( ) );
1948 CloneNodeAttr( pNode
, pResult
);
1951 void SmCloningVisitor::Visit( SmGlyphSpecialNode
* pNode
)
1953 pResult
= new SmGlyphSpecialNode( pNode
->GetToken( ) );
1954 CloneNodeAttr( pNode
, pResult
);
1957 void SmCloningVisitor::Visit( SmMathSymbolNode
* pNode
)
1959 pResult
= new SmMathSymbolNode( pNode
->GetToken( ) );
1960 CloneNodeAttr( pNode
, pResult
);
1963 void SmCloningVisitor::Visit( SmBlankNode
* pNode
)
1965 SmBlankNode
* pClone
= new SmBlankNode( pNode
->GetToken( ) );
1966 pClone
->SetBlankNum( pNode
->GetBlankNum( ) );
1968 CloneNodeAttr( pNode
, pResult
);
1971 void SmCloningVisitor::Visit( SmErrorNode
* pNode
)
1973 //PE_NONE is used the information have been discarded and isn't used
1974 pResult
= new SmErrorNode( PE_NONE
, pNode
->GetToken( ) );
1975 CloneNodeAttr( pNode
, pResult
);
1978 void SmCloningVisitor::Visit( SmLineNode
* pNode
)
1980 SmLineNode
* pClone
= new SmLineNode( pNode
->GetToken( ) );
1981 CloneNodeAttr( pNode
, pClone
);
1982 CloneKids( pNode
, pClone
);
1986 void SmCloningVisitor::Visit( SmExpressionNode
* pNode
)
1988 SmExpressionNode
* pClone
= new SmExpressionNode( pNode
->GetToken( ) );
1989 CloneNodeAttr( pNode
, pClone
);
1990 CloneKids( pNode
, pClone
);
1994 void SmCloningVisitor::Visit( SmPolyLineNode
* pNode
)
1996 pResult
= new SmPolyLineNode( pNode
->GetToken( ) );
1997 CloneNodeAttr( pNode
, pResult
);
2000 void SmCloningVisitor::Visit( SmRootNode
* pNode
)
2002 SmRootNode
* pClone
= new SmRootNode( pNode
->GetToken( ) );
2003 CloneNodeAttr( pNode
, pClone
);
2004 CloneKids( pNode
, pClone
);
2008 void SmCloningVisitor::Visit( SmRootSymbolNode
* pNode
)
2010 pResult
= new SmRootSymbolNode( pNode
->GetToken( ) );
2011 CloneNodeAttr( pNode
, pResult
);
2014 void SmCloningVisitor::Visit( SmRectangleNode
* pNode
)
2016 pResult
= new SmRectangleNode( pNode
->GetToken( ) );
2017 CloneNodeAttr( pNode
, pResult
);
2020 void SmCloningVisitor::Visit( SmVerticalBraceNode
* pNode
)
2022 SmVerticalBraceNode
* pClone
= new SmVerticalBraceNode( pNode
->GetToken( ) );
2023 CloneNodeAttr( pNode
, pClone
);
2024 CloneKids( pNode
, pClone
);
2028 /////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
2030 SmSelectionDrawingVisitor::SmSelectionDrawingVisitor( OutputDevice
& rDevice
, SmNode
* pTree
, Point Offset
)
2032 bHasSelectionArea
= false;
2035 OSL_ENSURE( pTree
, "pTree can't be null!" );
2037 pTree
->Accept( this );
2039 //Draw selection if there's any
2040 if( bHasSelectionArea
){
2041 aSelectionArea
.Move( Offset
.X( ), Offset
.Y( ) );
2044 rDev
.Push( PUSH_LINECOLOR
| PUSH_FILLCOLOR
);
2046 rDev
.SetLineColor( );
2047 rDev
.SetFillColor( Color( COL_LIGHTGRAY
) );
2050 rDev
.DrawRect( aSelectionArea
);
2052 //Restore device state
2057 void SmSelectionDrawingVisitor::ExtendSelectionArea( Rectangle aArea
)
2059 if ( ! bHasSelectionArea
) {
2060 aSelectionArea
= aArea
;
2061 bHasSelectionArea
= true;
2063 aSelectionArea
.Union( aArea
);
2066 void SmSelectionDrawingVisitor::DefaultVisit( SmNode
* pNode
)
2068 if( pNode
->IsSelected( ) )
2069 ExtendSelectionArea( pNode
->AsRectangle( ) );
2070 VisitChildren( pNode
);
2073 void SmSelectionDrawingVisitor::VisitChildren( SmNode
* pNode
)
2075 SmNodeIterator
it( pNode
);
2080 void SmSelectionDrawingVisitor::Visit( SmTextNode
* pNode
)
2082 if( pNode
->IsSelected( ) ){
2083 rDev
.Push( PUSH_TEXTCOLOR
| PUSH_FONT
);
2085 rDev
.SetFont( pNode
->GetFont( ) );
2086 Point Position
= pNode
->GetTopLeft( );
2087 long left
= Position
.getX( ) + rDev
.GetTextWidth( pNode
->GetText( ), 0, pNode
->GetSelectionStart( ) );
2088 long right
= Position
.getX( ) + rDev
.GetTextWidth( pNode
->GetText( ), 0, pNode
->GetSelectionEnd( ) );
2089 long top
= Position
.getY( );
2090 long bottom
= top
+ pNode
->GetHeight( );
2091 Rectangle
rect( left
, top
, right
, bottom
);
2093 ExtendSelectionArea( rect
);
2099 /////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
2101 SmNodeToTextVisitor::SmNodeToTextVisitor( SmNode
* pNode
, OUString
&rText
)
2103 pNode
->Accept( this );
2104 rText
= aCmdText
.makeStringAndClear();
2107 void SmNodeToTextVisitor::Visit( SmTableNode
* pNode
)
2109 if( pNode
->GetToken( ).eType
== TBINOM
) {
2110 Append( "{ binom" );
2111 LineToText( pNode
->GetSubNode( 0 ) );
2112 LineToText( pNode
->GetSubNode( 1 ) );
2114 } else if( pNode
->GetToken( ).eType
== TSTACK
) {
2115 Append( "stack{ " );
2116 SmNodeIterator
it( pNode
);
2119 LineToText( it
.Current( ) );
2128 } else { //Assume it's a toplevel table, containing lines
2129 SmNodeIterator
it( pNode
);
2136 Append( "newline" );
2143 void SmNodeToTextVisitor::Visit( SmBraceNode
* pNode
)
2145 SmNode
*pLeftBrace
= pNode
->GetSubNode( 0 ),
2146 *pBody
= pNode
->GetSubNode( 1 ),
2147 *pRightBrace
= pNode
->GetSubNode( 2 );
2148 //Handle special case where it's absolute function
2149 if( pNode
->GetToken( ).eType
== TABS
) {
2151 LineToText( pBody
);
2153 if( pNode
->GetScaleMode( ) == SCALE_HEIGHT
)
2155 pLeftBrace
->Accept( this );
2157 pBody
->Accept( this );
2159 if( pNode
->GetScaleMode( ) == SCALE_HEIGHT
)
2161 pRightBrace
->Accept( this );
2165 void SmNodeToTextVisitor::Visit( SmBracebodyNode
* pNode
)
2167 SmNodeIterator
it( pNode
);
2168 while( it
.Next( ) ){
2174 void SmNodeToTextVisitor::Visit( SmOperNode
* pNode
)
2176 Append( pNode
->GetToken( ).aText
);
2178 if( pNode
->GetToken( ).eType
== TOPER
){
2179 //There's an SmGlyphSpecialNode if eType == TOPER
2180 if( pNode
->GetSubNode( 0 )->GetType( ) == NSUBSUP
)
2181 Append( pNode
->GetSubNode( 0 )->GetSubNode( 0 )->GetToken( ).aText
);
2183 Append( pNode
->GetSubNode( 0 )->GetToken( ).aText
);
2185 if( pNode
->GetSubNode( 0 )->GetType( ) == NSUBSUP
) {
2186 SmSubSupNode
*pSubSup
= ( SmSubSupNode
* )pNode
->GetSubNode( 0 );
2188 if( ( pChild
= pSubSup
->GetSubSup( LSUP
) ) ) {
2190 Append( "lsup { " );
2191 LineToText( pChild
);
2194 if( ( pChild
= pSubSup
->GetSubSup( LSUB
) ) ) {
2196 Append( "lsub { " );
2197 LineToText( pChild
);
2200 if( ( pChild
= pSubSup
->GetSubSup( RSUP
) ) ) {
2203 LineToText( pChild
);
2206 if( ( pChild
= pSubSup
->GetSubSup( RSUB
) ) ) {
2209 LineToText( pChild
);
2212 if( ( pChild
= pSubSup
->GetSubSup( CSUB
) ) ) {
2214 if (pSubSup
->IsUseLimits())
2215 Append( "from { " );
2217 Append( "csub { " );
2218 LineToText( pChild
);
2221 if( ( pChild
= pSubSup
->GetSubSup( CSUP
) ) ) {
2223 if (pSubSup
->IsUseLimits())
2226 Append( "csup { " );
2227 LineToText( pChild
);
2231 LineToText( pNode
->GetSubNode( 1 ) );
2234 void SmNodeToTextVisitor::Visit( SmAlignNode
* pNode
)
2236 Append( pNode
->GetToken( ).aText
);
2237 LineToText( pNode
->GetSubNode( 0 ) );
2240 void SmNodeToTextVisitor::Visit( SmAttributNode
* pNode
)
2242 Append( pNode
->GetToken( ).aText
);
2243 LineToText( pNode
->GetSubNode( 1 ) );
2246 void SmNodeToTextVisitor::Visit( SmFontNode
* pNode
)
2248 switch ( pNode
->GetToken( ).eType
)
2257 Append( "italic " );
2260 Append( "nitalic " );
2263 Append( "phantom " );
2268 switch ( pNode
->GetSizeType( ) )
2276 case FNTSIZ_MULTIPLY
:
2282 case FNTSIZ_ABSOLUT
:
2286 Append( ::rtl::math::doubleToUString(
2287 static_cast<double>( pNode
->GetSizeParameter( ) ),
2288 rtl_math_StringFormat_Automatic
,
2289 rtl_math_DecimalPlaces_Max
, '.', sal_True
) );
2294 Append( "color black " );
2297 Append( "color white " );
2300 Append( "color red " );
2303 Append( "color green " );
2306 Append( "color blue " );
2309 Append( "color cyan " );
2312 Append( "color magenta " );
2315 Append( "color yellow " );
2318 Append( "font sans " );
2321 Append( "font serif " );
2324 Append( "font fixed " );
2329 LineToText( pNode
->GetSubNode( 1 ) );
2332 void SmNodeToTextVisitor::Visit( SmUnHorNode
* pNode
)
2334 SmNodeIterator
it( pNode
, pNode
->GetSubNode( 1 )->GetToken( ).eType
== TFACT
);
2335 while( it
.Next( ) ) {
2341 void SmNodeToTextVisitor::Visit( SmBinHorNode
* pNode
)
2343 SmNode
*pLeft
= pNode
->GetSubNode( 0 ),
2344 *pOper
= pNode
->GetSubNode( 1 ),
2345 *pRight
= pNode
->GetSubNode( 2 );
2347 pLeft
->Accept( this );
2349 pOper
->Accept( this );
2351 pRight
->Accept( this );
2355 void SmNodeToTextVisitor::Visit( SmBinVerNode
* pNode
)
2357 SmNode
*pNum
= pNode
->GetSubNode( 0 ),
2358 *pDenom
= pNode
->GetSubNode( 2 );
2362 LineToText( pDenom
);
2366 void SmNodeToTextVisitor::Visit( SmBinDiagonalNode
* pNode
)
2368 SmNode
*pLeftOperand
= pNode
->GetSubNode( 0 ),
2369 *pRightOperand
= pNode
->GetSubNode( 1 );
2371 LineToText( pLeftOperand
);
2373 Append( "wideslash " );
2374 LineToText( pRightOperand
);
2378 void SmNodeToTextVisitor::Visit( SmSubSupNode
* pNode
)
2380 LineToText( pNode
->GetBody( ) );
2382 if( ( pChild
= pNode
->GetSubSup( LSUP
) ) ) {
2385 LineToText( pChild
);
2387 if( ( pChild
= pNode
->GetSubSup( LSUB
) ) ) {
2390 LineToText( pChild
);
2392 if( ( pChild
= pNode
->GetSubSup( RSUP
) ) ) {
2395 LineToText( pChild
);
2397 if( ( pChild
= pNode
->GetSubSup( RSUB
) ) ) {
2400 LineToText( pChild
);
2402 if( ( pChild
= pNode
->GetSubSup( CSUB
) ) ) {
2404 if (pNode
->IsUseLimits())
2408 LineToText( pChild
);
2410 if( ( pChild
= pNode
->GetSubSup( CSUP
) ) ) {
2412 if (pNode
->IsUseLimits())
2416 LineToText( pChild
);
2420 void SmNodeToTextVisitor::Visit( SmMatrixNode
* pNode
)
2422 Append( "matrix{" );
2423 for ( sal_uInt16 i
= 0; i
< pNode
->GetNumRows( ); i
++ ) {
2424 for ( sal_uInt16 j
= 0; j
< pNode
->GetNumCols( ); j
++ ) {
2425 SmNode
* pSubNode
= pNode
->GetSubNode( i
* pNode
->GetNumCols( ) + j
);
2427 pSubNode
->Accept( this );
2429 if( j
!= pNode
->GetNumCols( ) - 1 )
2433 if( i
!= pNode
->GetNumRows( ) - 1 )
2439 void SmNodeToTextVisitor::Visit( SmPlaceNode
* )
2444 void SmNodeToTextVisitor::Visit( SmTextNode
* pNode
)
2446 //TODO: This method might need improvements, see SmTextNode::CreateTextFromNode
2447 if( pNode
->GetToken( ).eType
== TTEXT
)
2449 Append( pNode
->GetText( ) );
2450 if( pNode
->GetToken( ).eType
== TTEXT
)
2454 void SmNodeToTextVisitor::Visit( SmSpecialNode
* pNode
)
2456 Append( pNode
->GetToken( ).aText
);
2459 void SmNodeToTextVisitor::Visit( SmGlyphSpecialNode
* pNode
)
2461 if( pNode
->GetToken( ).eType
== TBOPER
)
2465 Append( pNode
->GetToken( ).aText
);
2468 void SmNodeToTextVisitor::Visit( SmMathSymbolNode
* pNode
)
2470 Append( pNode
->GetToken( ).aText
);
2473 void SmNodeToTextVisitor::Visit( SmBlankNode
* pNode
)
2475 Append( pNode
->GetToken( ).aText
);
2478 void SmNodeToTextVisitor::Visit( SmErrorNode
* )
2482 void SmNodeToTextVisitor::Visit( SmLineNode
* pNode
)
2484 SmNodeIterator
it( pNode
);
2485 while( it
.Next( ) ){
2491 void SmNodeToTextVisitor::Visit( SmExpressionNode
* pNode
)
2493 bool bracketsNeeded
= pNode
->GetNumSubNodes() != 1 || pNode
->GetSubNode(0)->GetType() == NBINHOR
;
2494 if (!bracketsNeeded
)
2496 const SmNode
*pParent
= pNode
->GetParent();
2499 pParent
&& pParent
->GetType() == NSUBSUP
&&
2500 pNode
->GetNumSubNodes() == 1 &&
2501 pNode
->GetSubNode(0)->GetType() == NSUBSUP
;
2504 if (bracketsNeeded
) {
2507 SmNodeIterator
it( pNode
);
2508 while( it
.Next( ) ) {
2512 if (bracketsNeeded
) {
2517 void SmNodeToTextVisitor::Visit( SmPolyLineNode
* )
2521 void SmNodeToTextVisitor::Visit( SmRootNode
* pNode
)
2523 SmNode
*pExtra
= pNode
->GetSubNode( 0 ),
2524 *pBody
= pNode
->GetSubNode( 2 );
2527 LineToText( pExtra
);
2530 LineToText( pBody
);
2533 void SmNodeToTextVisitor::Visit( SmRootSymbolNode
* )
2537 void SmNodeToTextVisitor::Visit( SmRectangleNode
* )
2541 void SmNodeToTextVisitor::Visit( SmVerticalBraceNode
* pNode
)
2543 SmNode
*pBody
= pNode
->GetSubNode( 0 ),
2544 *pScript
= pNode
->GetSubNode( 2 );
2545 LineToText( pBody
);
2546 Append( pNode
->GetToken( ).aText
);
2547 LineToText( pScript
);
2550 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */