diff options
author | matteocam <matteo.campanelli@gmail.com> | 2014-02-25 14:37:55 -0500 |
---|---|---|
committer | Norbert Thiebaud <nthiebaud@gmail.com> | 2014-03-15 22:45:51 +0000 |
commit | 93e6291c29d547c0c29c6e43b2ca4b36a3e8506f (patch) | |
tree | 50d3560576046dd111e5a9aad5d37afa1add69a9 | |
parent | edc8ee009943e7fc9a68730b0efb303b019a62d4 (diff) |
fdo#53472 Created Dynamic Integral Node classes. Integrals size made dependent on body.
Change-Id: I0348155f2429cf7dd3cbe7d71f333879ec6de980
Reviewed-on: https://gerrit.libreoffice.org/8569
Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com>
Tested-by: Norbert Thiebaud <nthiebaud@gmail.com>
-rw-r--r-- | starmath/inc/node.hxx | 82 | ||||
-rw-r--r-- | starmath/inc/parse.hxx | 3 | ||||
-rw-r--r-- | starmath/inc/visitors.hxx | 14 | ||||
-rw-r--r-- | starmath/source/mathtype.cxx | 2 | ||||
-rw-r--r-- | starmath/source/mathtype.hxx | 2 | ||||
-rw-r--r-- | starmath/source/node.cxx | 75 | ||||
-rw-r--r-- | starmath/source/ooxmlexport.cxx | 1 | ||||
-rw-r--r-- | starmath/source/parse.cxx | 12 | ||||
-rw-r--r-- | starmath/source/rtfexport.cxx | 1 | ||||
-rw-r--r-- | starmath/source/visitors.cxx | 109 |
10 files changed, 297 insertions, 4 deletions
diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx index c15ab259afbe..ab27af014df9 100644 --- a/starmath/inc/node.hxx +++ b/starmath/inc/node.hxx @@ -73,7 +73,7 @@ enum SmNodeType /*10*/ NBINDIAGONAL, NSUBSUP, NMATRIX, NPLACE, NTEXT, /*15*/ NSPECIAL, NGLYPH_SPECIAL, NMATH, NBLANK, NERROR, /*20*/ NLINE, NEXPRESSION, NPOLYLINE, NROOT, NROOTSYMBOL, -/*25*/ NRECTANGLE, NVERTICAL_BRACE, NMATHIDENT +/*25*/ NRECTANGLE, NVERTICAL_BRACE, NMATHIDENT, NDYNINT, NDYNINTSYMBOL }; @@ -618,6 +618,30 @@ public: void Accept(SmVisitor* pVisitor); }; +//////////////////////////////////////////////////////////////////////////////// + +/** Dynamic Integral symbol node + * + * Node for drawing dynamicall sized integral symbols. + * + * TODO: It might be created a parent class SmDynamicSizedNode + (for both dynamic integrals, roots and other dynamic symbols) + + */ +class SmDynIntegralSymbolNode : public SmMathSymbolNode +{ + + +public: + SmDynIntegralSymbolNode(const SmToken &rNodeToken) + : SmMathSymbolNode(NDYNINTSYMBOL, rNodeToken) + {} + + virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight); + + void Accept(SmVisitor* pVisitor); +}; + @@ -806,6 +830,40 @@ public: }; +//////////////////////////////////////////////////////////////////////////////// + +/** Dynamic Integral node + * + * Used to create Dynamically sized integrals + * + * Children:<BR> + * 0: Symbol (instance of DynIntegralSymbolNode)<BR> + * 1: Body<BR> + */ +class SmDynIntegralNode : public SmStructureNode +{ +protected: + void GetHeightVerOffset(const SmRect &rRect, + long &rHeight, long &rVerOffset) const; + +public: + SmDynIntegralNode(const SmToken &rNodeToken) + : SmStructureNode(NDYNINT, rNodeToken) + { + SetNumSubNodes(2); + } + + virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat); + void CreateTextFromNode(OUString &rText); + void Accept(SmVisitor* pVisitor); + + SmDynIntegralSymbolNode* Symbol(); + const SmDynIntegralSymbolNode* Symbol() const; + SmNode* Body(); + const SmNode* Body() const; +}; + + /** Binary horizontial node @@ -1293,6 +1351,28 @@ inline const SmNode* SmRootNode::Body() const return const_cast< SmRootNode* >( this )->Body(); } + + +inline SmDynIntegralSymbolNode* SmDynIntegralNode::Symbol() +{ + OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NDYNINTSYMBOL ); + return static_cast< SmDynIntegralSymbolNode* >( GetSubNode( 0 )); +} +inline const SmDynIntegralSymbolNode* SmDynIntegralNode::Symbol() const +{ + return const_cast< SmDynIntegralNode* >( this )->Symbol(); +} +inline SmNode* SmDynIntegralNode::Body() +{ + OSL_ASSERT( GetNumSubNodes() > 1 ); + return GetSubNode( 1 ); +} +inline const SmNode* SmDynIntegralNode::Body() const +{ + return const_cast< SmDynIntegralNode* >( this )->Body(); +} + + inline SmMathSymbolNode* SmBinHorNode::Symbol() { OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH ); diff --git a/starmath/inc/parse.hxx b/starmath/inc/parse.hxx index 41071f26759c..d967be7a69c3 100644 --- a/starmath/inc/parse.hxx +++ b/starmath/inc/parse.hxx @@ -102,7 +102,8 @@ enum SmTokenType /*215*/ TSETR, TSETC, TWIDEVEC, TWIDETILDE, TWIDEHAT, /*220*/ TWIDESLASH, TWIDEBACKSLASH, TLDBRACKET, TRDBRACKET, TNOSPACE, /*225*/ TUNKNOWN, TDEBUG, TPRECEDES, TSUCCEEDS, TPRECEDESEQUAL, -/*230*/ TSUCCEEDSEQUAL, TPRECEDESEQUIV, TSUCCEEDSEQUIV, TNOTPRECEDES, TNOTSUCCEEDS +/*230*/ TSUCCEEDSEQUAL, TPRECEDESEQUIV, TSUCCEEDSEQUIV, TNOTPRECEDES, TNOTSUCCEEDS, +/*235*/ TINTD }; diff --git a/starmath/inc/visitors.hxx b/starmath/inc/visitors.hxx index 630b311411b7..7c4dcf7b6d50 100644 --- a/starmath/inc/visitors.hxx +++ b/starmath/inc/visitors.hxx @@ -42,6 +42,8 @@ public: virtual void Visit( SmLineNode* pNode ) = 0; virtual void Visit( SmExpressionNode* pNode ) = 0; virtual void Visit( SmPolyLineNode* pNode ) = 0; + virtual void Visit( SmDynIntegralNode* pNode ) = 0; + virtual void Visit( SmDynIntegralSymbolNode* pNode ) = 0; virtual void Visit( SmRootNode* pNode ) = 0; virtual void Visit( SmRootSymbolNode* pNode ) = 0; virtual void Visit( SmRectangleNode* pNode ) = 0; @@ -81,6 +83,8 @@ public: void Visit( SmPolyLineNode* pNode ); void Visit( SmRootNode* pNode ); void Visit( SmRootSymbolNode* pNode ); + void Visit( SmDynIntegralNode* pNode ); + void Visit( SmDynIntegralSymbolNode* pNode ); void Visit( SmRectangleNode* pNode ); void Visit( SmVerticalBraceNode* pNode ); private: @@ -124,6 +128,8 @@ public: void Visit( SmPolyLineNode* pNode ); void Visit( SmRootNode* pNode ); void Visit( SmRootSymbolNode* pNode ); + void Visit( SmDynIntegralNode* pNode ); + void Visit( SmDynIntegralSymbolNode* pNode ); void Visit( SmRectangleNode* pNode ); void Visit( SmVerticalBraceNode* pNode ); protected: @@ -227,6 +233,8 @@ public: void Visit( SmPolyLineNode* pNode ); void Visit( SmRootNode* pNode ); void Visit( SmRootSymbolNode* pNode ); + void Visit( SmDynIntegralNode* pNode ); + void Visit( SmDynIntegralSymbolNode* pNode ); void Visit( SmRectangleNode* pNode ); void Visit( SmVerticalBraceNode* pNode ); private: @@ -344,6 +352,8 @@ public: void Visit( SmPolyLineNode* pNode ); void Visit( SmRootNode* pNode ); void Visit( SmRootSymbolNode* pNode ); + void Visit( SmDynIntegralNode* pNode ); + void Visit( SmDynIntegralSymbolNode* pNode ); void Visit( SmRectangleNode* pNode ); void Visit( SmVerticalBraceNode* pNode ); SmCaretPosGraph* takeGraph() @@ -393,6 +403,8 @@ public: void Visit( SmPolyLineNode* pNode ); void Visit( SmRootNode* pNode ); void Visit( SmRootSymbolNode* pNode ); + void Visit( SmDynIntegralNode* pNode ); + void Visit( SmDynIntegralSymbolNode* pNode ); void Visit( SmRectangleNode* pNode ); void Visit( SmVerticalBraceNode* pNode ); /** Clone a pNode */ @@ -465,6 +477,8 @@ public: void Visit( SmPolyLineNode* pNode ); void Visit( SmRootNode* pNode ); void Visit( SmRootSymbolNode* pNode ); + void Visit( SmDynIntegralNode* pNode ); + void Visit( SmDynIntegralSymbolNode* pNode ); void Visit( SmRectangleNode* pNode ); void Visit( SmVerticalBraceNode* pNode ); private: diff --git a/starmath/source/mathtype.cxx b/starmath/source/mathtype.cxx index b90b79d3303a..82124212ccea 100644 --- a/starmath/source/mathtype.cxx +++ b/starmath/source/mathtype.cxx @@ -2516,6 +2516,7 @@ void MathType::HandleOperator(SmNode *pNode,int nLevel) switch(pNode->GetToken().eType) { case TINT: + case TINTD: if (nOldVariation != 0xff) pS->WriteUChar( sal_uInt8(0x18) ); //selector else @@ -2640,6 +2641,7 @@ void MathType::HandleOperator(SmNode *pNode,int nLevel) pS->WriteUChar( sal_uInt8(0x86) ); pS->WriteUInt16( sal_uInt16(0x222B) ); case TINT: + case TINTD: case TLINT: pS->WriteUChar( sal_uInt8(CHAR) ); pS->WriteUChar( sal_uInt8(0x86) ); diff --git a/starmath/source/mathtype.hxx b/starmath/source/mathtype.hxx index 20bed43d54f5..402e017b0301 100644 --- a/starmath/source/mathtype.hxx +++ b/starmath/source/mathtype.hxx @@ -197,7 +197,7 @@ private: tmANGLE,tmPAREN,tmBRACE,tmBRACK,tmBAR,tmDBAR,tmFLOOR,tmCEILING, tmLBLB,tmRBRB,tmRBLB,tmLBRP,tmLPRB,tmROOT,tmFRACT,tmSCRIPT,tmUBAR, tmOBAR,tmLARROW,tmRARROW,tmBARROW,tmSINT,tmDINT,tmTINT,tmSSINT, - tmDSINT,tmTSINT,tmUHBRACE,tmLHBRACE,tmSUM + tmDSINT,tmTSINT,tmUHBRACE,tmLHBRACE,tmSUM,tmTINTD }; public: static sal_Bool LookupChar(sal_Unicode nChar,OUString &rRet, diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx index bbac173f9b69..75d752901d4c 100644 --- a/starmath/source/node.cxx +++ b/starmath/source/node.cxx @@ -622,6 +622,8 @@ void SmNode::DumpAsDot(std::ostream &out, OUString* label, int number, int& id, case NRECTANGLE: out<<"SmRectangleNode"; break; case NVERTICAL_BRACE: out<<"SmVerticalBraceNode"; break; case NMATHIDENT: out<<"SmMathIdentifierNode"; break; + case NINTDYNSYMBOL: out<<"SmDynIntegralSymbolNode"; break; + case NINTDYN: out<<"SmDynIntegralNode"; break; default: out<<"Unknown Node"; } @@ -1115,6 +1117,53 @@ void SmRootNode::CreateTextFromNode(OUString &rText) rText += "} "; } +/**************************************************************************/ + + +void SmDynIntegralNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat) +{ + SmNode *pDynIntegralSym = Symbol(), + *pBody = Body(); + OSL_ENSURE(pDynIntegralSym, "Sm: NULL pointer"); + OSL_ENSURE(pBody, "Sm: NULL pointer"); + + pBody->Arrange(rDev, rFormat); + + long nHeight = pBody->GetHeight(); + pDynIntegralSym->AdaptToY(rDev, nHeight); + + pDynIntegralSym->Arrange(rDev, rFormat); + + Point aPos = pDynIntegralSym->AlignTo(*pBody, RP_LEFT, RHA_CENTER, RVA_BASELINE); + //! override calculated vertical position + aPos.Y() = pDynIntegralSym->GetTop() + pBody->GetBottom() - pDynIntegralSym->GetBottom(); + pDynIntegralSym->MoveTo(aPos); + + + // override its own rectangle with pBody's + SmRect::operator = (*pBody); + // extends this rectangle with the symbol's one + ExtendBy(*pDynIntegralSym, RCP_THIS); + +} + + +void SmDynIntegralNode::CreateTextFromNode(OUString &rText) +{ + + rText += "intd "; + SmNode *pBody = GetSubNode(1); + + if (pBody->GetNumSubNodes() > 1) + rText += "{ "; + + pBody->CreateTextFromNode(rText); + + if (pBody->GetNumSubNodes() > 1) + rText += "} "; +} + + /**************************************************************************/ @@ -2297,6 +2346,23 @@ void SmRootSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) /**************************************************************************/ +void SmDynIntegralSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) +{ + long nFactor = 12L; + + // The new height equals (1 + nFactor) * oldHeight + // nFactor was chosen for keeping the integral sign from becoming too "fat". + SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / nFactor); + + // keep the ratio + long nCurWidth = GetSize().Width(); + SmMathSymbolNode::AdaptToX(rDev, nCurWidth + nCurWidth / nFactor); +} + + +/**************************************************************************/ + + void SmRectangleNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth) { aToSize.Width() = nWidth; @@ -3196,6 +3262,15 @@ void SmRootSymbolNode::Accept(SmVisitor* pVisitor) { pVisitor->Visit(this); } +void SmDynIntegralNode::Accept(SmVisitor* pVisitor) { + pVisitor->Visit(this); +} + + +void SmDynIntegralSymbolNode::Accept(SmVisitor* pVisitor) { + pVisitor->Visit(this); +} + void SmRectangleNode::Accept(SmVisitor* pVisitor) { pVisitor->Visit(this); } diff --git a/starmath/source/ooxmlexport.cxx b/starmath/source/ooxmlexport.cxx index 0a98d985dc1d..7110c81a492c 100644 --- a/starmath/source/ooxmlexport.cxx +++ b/starmath/source/ooxmlexport.cxx @@ -249,6 +249,7 @@ void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel ) switch( pNode->GetToken().eType ) { case TINT: + case TINTD: case TIINT: case TIIINT: case TLINT: diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx index d4c94f48db8f..bb4598d4c377 100644 --- a/starmath/source/parse.cxx +++ b/starmath/source/parse.cxx @@ -161,6 +161,7 @@ static const SmTokenTableEntry aTokenTable[] = { "infinity" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5}, { "infty" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5}, { "int", TINT, MS_INT, TGOPER, 5}, + { "intd", TINTD, MS_INT, TGUNOPER, 5}, { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0}, { "ital", TITALIC, '\0', TGFONTATTR, 5}, { "italic", TITALIC, '\0', TGFONTATTR, 5}, @@ -1689,6 +1690,10 @@ void SmParser::UnOper() { case TABS : case TSQRT : + /* Dynamic integrals are handled as unary operators so we can wrap + the symbol together with the body in a upper level node and make + proper graphic arrangements */ + case TINTD: NextToken(); break; @@ -1743,10 +1748,15 @@ void SmParser::UnOper() pSNode->SetSubNodes(pLeft, pArg, pRight); } else if (eType == TSQRT || eType == TNROOT) - { pSNode = new SmRootNode(aNodeToken); + { pSNode = new SmRootNode(aNodeToken); pOper = new SmRootSymbolNode(aNodeToken); pSNode->SetSubNodes(pExtra, pOper, pArg); } + else if(eType == TINTD) + { pSNode = new SmDynIntegralNode(aNodeToken); + pOper = new SmDynIntegralSymbolNode(aNodeToken); + pSNode->SetSubNodes(pOper, pArg); + } else { pSNode = new SmUnHorNode(aNodeToken); diff --git a/starmath/source/rtfexport.cxx b/starmath/source/rtfexport.cxx index bc121f54ec25..d700732ab38e 100644 --- a/starmath/source/rtfexport.cxx +++ b/starmath/source/rtfexport.cxx @@ -198,6 +198,7 @@ void SmRtfExport::HandleOperator(const SmOperNode* pNode, int nLevel) switch (pNode->GetToken().eType) { case TINT: + case TINTD: case TIINT: case TIIINT: case TLINT: diff --git a/starmath/source/visitors.cxx b/starmath/source/visitors.cxx index 33624b0d5ae6..4c515df44af0 100644 --- a/starmath/source/visitors.cxx +++ b/starmath/source/visitors.cxx @@ -161,6 +161,18 @@ void SmVisitorTest::Visit( SmRootSymbolNode* pNode ) VisitChildren( pNode ); } +void SmVisitorTest::Visit( SmDynIntegralNode* pNode ) +{ + assert( pNode->GetType( ) == NDYNINT ); + VisitChildren( pNode ); +} + +void SmVisitorTest::Visit( SmDynIntegralSymbolNode* pNode ) +{ + assert( pNode->GetType( ) == NDYNINTSYMBOL ); + VisitChildren( pNode ); +} + void SmVisitorTest::Visit( SmRectangleNode* pNode ) { assert( pNode->GetType( ) == NRECTANGLE ); @@ -307,6 +319,16 @@ void SmDefaultingVisitor::Visit( SmRootSymbolNode* pNode ) DefaultVisit( pNode ); } +void SmDefaultingVisitor::Visit( SmDynIntegralNode* pNode ) +{ + DefaultVisit( pNode ); +} + +void SmDefaultingVisitor::Visit( SmDynIntegralSymbolNode* pNode ) +{ + DefaultVisit( pNode ); +} + void SmDefaultingVisitor::Visit( SmRectangleNode* pNode ) { DefaultVisit( pNode ); @@ -630,6 +652,11 @@ void SmDrawingVisitor::Visit( SmRootNode* pNode ) DrawChildren( pNode ); } +void SmDrawingVisitor::Visit(SmDynIntegralNode* pNode) +{ + DrawChildren( pNode ); +} + void SmDrawingVisitor::Visit( SmVerticalBraceNode* pNode ) { DrawChildren( pNode ); @@ -668,6 +695,22 @@ void SmDrawingVisitor::Visit( SmRootSymbolNode* pNode ) rDev.DrawRect( aBar ); } +void SmDrawingVisitor::Visit( SmDynIntegralSymbolNode* pNode ) +{ + if ( pNode->IsPhantom( ) ) + return; + + // draw integral-sign itself + DrawSpecialNode( pNode ); + + //! the rest of this may not be needed at all + + // this should be something like: + // instead of just drawing the node, take some information about the body. + // This is also how SmRootSymbol does it (probably by means of SmRootNode) + // NEXT: Check out SmRootNode +} + void SmDrawingVisitor::Visit( SmPolyLineNode* pNode ) { if ( pNode->IsPhantom( ) ) @@ -1630,6 +1673,40 @@ void SmCaretPosGraphBuildingVisitor::Visit( SmRootNode* pNode ) pRightMost = right; } + +void SmCaretPosGraphBuildingVisitor::Visit( SmDynIntegralNode* pNode ) +{ + //! To be changed: Integrals don't have args. + SmNode *pBody = pNode->Body(); //Body of the root + SAL_WARN_IF( !pBody, "starmath", "pBody cannot be NULL" ); + + SmCaretPosGraphEntry *left, + *right, + *bodyLeft, + *bodyRight; + + //Get left and save it + SAL_WARN_IF( !pRightMost, "starmath", "There must be a position in front of this" ); + left = pRightMost; + + //Create body left + bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left ); + left->SetRight( bodyLeft ); + + //Create right + right = pGraph->Add( SmCaretPos( pNode, 1 ) ); + + //Visit body + pRightMost = bodyLeft; + pBody->Accept( this ); + bodyRight = pRightMost; + bodyRight->SetRight( right ); + right->SetLeft( bodyRight ); + + pRightMost = right; +} + + /** Build SmCaretPosGraph for SmPlaceNode * Consider this a single character. */ @@ -1772,6 +1849,13 @@ void SmCaretPosGraphBuildingVisitor::Visit( SmRootSymbolNode* ) { //Do nothing } + +void SmCaretPosGraphBuildingVisitor::Visit( SmDynIntegralSymbolNode* ) +{ + //Do nothing +} + + void SmCaretPosGraphBuildingVisitor::Visit( SmRectangleNode* ) { //Do nothing @@ -2016,6 +2100,20 @@ void SmCloningVisitor::Visit( SmRootSymbolNode* pNode ) CloneNodeAttr( pNode, pResult ); } +void SmCloningVisitor::Visit( SmDynIntegralNode* pNode ) +{ + SmDynIntegralNode* pClone = new SmDynIntegralNode( pNode->GetToken( ) ); + CloneNodeAttr( pNode, pClone ); + CloneKids( pNode, pClone ); + pResult = pClone; +} + +void SmCloningVisitor::Visit( SmDynIntegralSymbolNode* pNode ) +{ + pResult = new SmDynIntegralSymbolNode( pNode->GetToken( ) ); + CloneNodeAttr( pNode, pResult ); +} + void SmCloningVisitor::Visit( SmRectangleNode* pNode ) { pResult = new SmRectangleNode( pNode->GetToken( ) ); @@ -2539,6 +2637,17 @@ void SmNodeToTextVisitor::Visit( SmRootSymbolNode* ) { } +void SmNodeToTextVisitor::Visit( SmDynIntegralNode* pNode ) +{ + SmNode *pBody = pNode->Body(); + Append( "intd" ); + LineToText( pBody ); +} + +void SmNodeToTextVisitor::Visit( SmDynIntegralSymbolNode* ) +{ +} + void SmNodeToTextVisitor::Visit( SmRectangleNode* ) { } |