Hi everybody!
Attached there is a patch for bug 53472.
It allows to use adaptively-sized integral symbols in Starmath by means of
a new command "intd".

Cheers,
Matteo
From 8960e64124a29fe77e75cd04c3609ba55ea2eefd Mon Sep 17 00:00:00 2001
From: matteocam <matteo.campane...@gmail.com>
Date: Tue, 25 Feb 2014 14:37:55 -0500
Subject: [PATCH 1/5] Created Dynamic Integral Symbols class

Change-Id: Id86ea4292126b36c37d973ac4acbcc1e5cb7ed97
---
 starmath/inc/node.hxx    | 28 +++++++++++++++++++++++++++-
 starmath/source/node.cxx | 23 +++++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index bce53f2..5335e6a 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
 };
 
 
@@ -618,6 +618,32 @@ public:
     void Accept(SmVisitor* pVisitor);
 };
 
+////////////////////////////////////////////////////////////////////////////////
+
+/** Dynamic Integral symbol node
+ *
+ * Node for drawing dynamicall sized integral symbols.
+ *
+ * XXX: It might be created a parent class SmDynamicSizedNode
+        (for both dynamic integrals, roots and other dynamic symbols)
+
+ */
+class SmDynIntegralNode : public SmMathSymbolNode
+{
+    sal_uLong  nBodyWidth;  // width of body (argument) of integral sign
+
+public:
+    SmDynIntegralNode(const SmToken &rNodeToken)
+    :   SmMathSymbolNode(NDYNINT, rNodeToken)
+    {}
+
+    sal_uLong GetBodyWidth() const {return nBodyWidth;};
+    virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nHeight);
+    virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
+
+    void Accept(SmVisitor* pVisitor);
+};
+
 
 ////////////////////////////////////////////////////////////////////////////////
 
diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx
index 6ffd0fb..9268e55 100644
--- a/starmath/source/node.cxx
+++ b/starmath/source/node.cxx
@@ -622,6 +622,7 @@ 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 NINTDYN:            out<<"SmDynIntegralNode"; break;
         default:
             out<<"Unknown Node";
     }
@@ -2296,6 +2297,24 @@ void SmRootSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
 
 /**************************************************************************/
 
+void SmDynIntegralNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth)
+{
+    // XXX: copied from SmRootSymbol for now
+    //nBodyWidth = nWidth;
+}
+
+
+void SmDynIntegralNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
+{
+    // XXX: copied from SmRootSymbol for now
+    // some additional length so that the horizontal
+    // bar will be positioned above the argument
+    //SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / 10L);
+}
+
+
+/**************************************************************************/
+
 
 void SmRectangleNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth)
 {
@@ -3194,6 +3213,10 @@ void SmRootSymbolNode::Accept(SmVisitor* pVisitor) {
     pVisitor->Visit(this);
 }
 
+void SmDynIntegralNode::Accept(SmVisitor* pVisitor) {
+    pVisitor->Visit(this);
+}
+
 void SmRectangleNode::Accept(SmVisitor* pVisitor) {
     pVisitor->Visit(this);
 }
-- 
1.8.3.2

From a9019baf943d56c225e02d7c4f87119c2ba79d12 Mon Sep 17 00:00:00 2001
From: matteocam <matteo.campane...@gmail.com>
Date: Tue, 25 Feb 2014 21:47:22 -0500
Subject: [PATCH 2/5] Added files

Change-Id: I71862f579784890d3075ff9f5a63bd756a55b93d
---
 starmath/source/mathtype.cxx    | 2 ++
 starmath/source/mathtype.hxx    | 2 +-
 starmath/source/ooxmlexport.cxx | 1 +
 starmath/source/rtfexport.cxx   | 1 +
 4 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/starmath/source/mathtype.cxx b/starmath/source/mathtype.cxx
index b90b79d..8212421 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 332cd27..8246769 100644
--- a/starmath/source/mathtype.hxx
+++ b/starmath/source/mathtype.hxx
@@ -157,7 +157,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/ooxmlexport.cxx b/starmath/source/ooxmlexport.cxx
index 8d1c808..c0c3be5 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/rtfexport.cxx b/starmath/source/rtfexport.cxx
index 45354fc..aa2dbe3 100644
--- a/starmath/source/rtfexport.cxx
+++ b/starmath/source/rtfexport.cxx
@@ -197,6 +197,7 @@ void SmRtfExport::HandleOperator(const SmOperNode* pNode, int nLevel)
     switch (pNode->GetToken().eType)
     {
     case TINT:
+    case TINTD:
     case TIINT:
     case TIIINT:
     case TLINT:
-- 
1.8.3.2

From aece34164a4c5235c38492800daa15b8952812a1 Mon Sep 17 00:00:00 2001
From: matteocam <matteo.campane...@gmail.com>
Date: Sat, 1 Mar 2014 05:00:44 -0500
Subject: [PATCH 3/5] Created behavior for SmDynIntegralNode

Change-Id: I53182a5735c814a5c0f80c0521bf0bc2ccf63d2e
---
 starmath/inc/node.hxx        |  70 ++++++++++++++++++++++++---
 starmath/inc/parse.hxx       |   3 +-
 starmath/inc/visitors.hxx    |  14 ++++++
 starmath/source/node.cxx     |  88 +++++++++++++++++++++++++++++-----
 starmath/source/parse.cxx    |  10 +++-
 starmath/source/visitors.cxx | 109 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 274 insertions(+), 20 deletions(-)

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index 5335e6a..b2c4df9 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,    NDYNINT
+/*25*/ NRECTANGLE,  NVERTICAL_BRACE, NMATHIDENT,  NDYNINT, NDYNINTSYMBOL
 };
 
 
@@ -628,17 +628,15 @@ public:
         (for both dynamic integrals, roots and other dynamic symbols)
 
  */
-class SmDynIntegralNode : public SmMathSymbolNode
+class SmDynIntegralSymbolNode : public SmMathSymbolNode
 {
-    sal_uLong  nBodyWidth;  // width of body (argument) of integral sign
+
 
 public:
-    SmDynIntegralNode(const SmToken &rNodeToken)
-    :   SmMathSymbolNode(NDYNINT, rNodeToken)
+    SmDynIntegralSymbolNode(const SmToken &rNodeToken)
+    :   SmMathSymbolNode(NDYNINTSYMBOL, rNodeToken)
     {}
 
-    sal_uLong GetBodyWidth() const {return nBodyWidth;};
-    virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nHeight);
     virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
 
     void Accept(SmVisitor* pVisitor);
@@ -834,6 +832,42 @@ public:
 
 ////////////////////////////////////////////////////////////////////////////////
 
+/** Dynamic Integral node
+ *
+ * Used for create Dynamically sized integrals
+ *
+ * Children:<BR>
+ * 0: Argument (optional)<BR>
+ * 1: Symbol (instance of DynIntegralSymbolNode)<BR>
+ * 2: Body<BR>
+ * Where argument is optional and may be NULL.
+ */
+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
  *
  * This node is used for binary operators. In a formula such as "A + B".
@@ -1319,6 +1353,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 996d914..104a2d3 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 5c872cf..ad9f72b 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/node.cxx b/starmath/source/node.cxx
index 9268e55..9cceb57 100644
--- a/starmath/source/node.cxx
+++ b/starmath/source/node.cxx
@@ -622,6 +622,7 @@ 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";
@@ -1116,6 +1117,74 @@ void SmRootNode::CreateTextFromNode(OUString &rText)
         rText += "} ";
 }
 
+/**************************************************************************/
+
+
+void SmDynIntegralNode::GetHeightVerOffset(const SmRect &rRect,
+                                    long &rHeight, long &rVerOffset) const
+    // calculate height and vertical offset of root sign suitable for 'rRect'
+    //! Code copied from SmRootNode
+{
+    rVerOffset = (rRect.GetBottom() - rRect.GetAlignB()) / 2;
+    rHeight    = rRect.GetHeight() - rVerOffset;
+
+    OSL_ENSURE(rHeight    >= 0, "Sm : Ooops...");
+    OSL_ENSURE(rVerOffset >= 0, "Sm : Ooops...");
+}
+
+
+void SmDynIntegralNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+
+    SmNode  *pDynIntegralSym = GetSubNode(0),
+           *pBody    = GetSubNode(1);
+    OSL_ENSURE(pDynIntegralSym, "Sm: NULL pointer");
+    OSL_ENSURE(pBody,    "Sm: NULL pointer");
+
+    pBody->Arrange(rDev, rFormat);
+
+    long  nHeight,
+          nVerOffset;
+    // XXX This is root-specific too
+    GetHeightVerOffset(*pBody, nHeight, nVerOffset);
+    //XXX I suppose I don't need the lines below which seem root-specific
+    //nHeight += rFormat.GetDistance(DIS_ROOT) // XXX
+               //* GetFont().GetSize().Height() / 100L;
+
+    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();
+    aPos.Y() -= nVerOffset;
+    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,19 +2366,11 @@ void SmRootSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
 
 /**************************************************************************/
 
-void SmDynIntegralNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth)
-{
-    // XXX: copied from SmRootSymbol for now
-    //nBodyWidth = nWidth;
-}
-
 
-void SmDynIntegralNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
+void SmDynIntegralSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
 {
-    // XXX: copied from SmRootSymbol for now
-    // some additional length so that the horizontal
-    // bar will be positioned above the argument
-    //SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / 10L);
+    // XXX: testing with a slightly higher height
+    SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / 2L);
 }
 
 
@@ -3217,6 +3278,11 @@ 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/parse.cxx b/starmath/source/parse.cxx
index 1ab966b0..6c42db6 100644
--- a/starmath/source/parse.cxx
+++ b/starmath/source/parse.cxx
@@ -160,6 +160,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, TGOPER, 5},
     { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0},
     { "ital", TITALIC, '\0', TGFONTATTR, 5},
     { "italic", TITALIC, '\0', TGFONTATTR, 5},
@@ -1633,6 +1634,7 @@ void SmParser::Oper()
         case TPROD :
         case TCOPROD :
         case TINT :
+        case TINTD:
         case TIINT :
         case TIIINT :
         case TLINT :
@@ -1698,6 +1700,7 @@ void SmParser::UnOper()
     {
         case TABS :
         case TSQRT :
+        case TINTD:
             NextToken();
             break;
 
@@ -1752,10 +1755,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/visitors.cxx b/starmath/source/visitors.cxx
index 922d6c3..935c5bc 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* )
 {
 }
-- 
1.8.3.2

From 8bfd4be3b12aae73f8d4ed9fc12475f06a196fe7 Mon Sep 17 00:00:00 2001
From: matteocam <matteo.campane...@gmail.com>
Date: Sat, 1 Mar 2014 06:27:47 -0500
Subject: [PATCH 4/5] Added code for keeping ratio and having right positioning

Change-Id: I1a35c90fd21b0786c7a98e8be3d26240e52fe527
---
 starmath/source/node.cxx  | 17 ++++++++++++-----
 starmath/source/parse.cxx |  4 ++--
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx
index 9cceb57..e30ea17 100644
--- a/starmath/source/node.cxx
+++ b/starmath/source/node.cxx
@@ -1135,9 +1135,8 @@ void SmDynIntegralNode::GetHeightVerOffset(const SmRect &rRect,
 
 void SmDynIntegralNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
 {
-
-    SmNode  *pDynIntegralSym = GetSubNode(0),
-           *pBody    = GetSubNode(1);
+    SmNode  *pDynIntegralSym = Symbol(),
+           *pBody    = Body();
     OSL_ENSURE(pDynIntegralSym, "Sm: NULL pointer");
     OSL_ENSURE(pBody,    "Sm: NULL pointer");
 
@@ -1158,9 +1157,10 @@ void SmDynIntegralNode::Arrange(const OutputDevice &rDev, const SmFormat &rForma
     Point  aPos = pDynIntegralSym->AlignTo(*pBody, RP_LEFT, RHA_CENTER, RVA_BASELINE);
     //! override calculated vertical position
     aPos.Y()  = pDynIntegralSym->GetTop() + pBody->GetBottom() - pDynIntegralSym->GetBottom();
-    aPos.Y() -= nVerOffset;
+    //aPos.Y() -= nVerOffset;
     pDynIntegralSym->MoveTo(aPos);
 
+
     // override its own rectangle with pBody's
     SmRect::operator = (*pBody);
     // extends this rectangle with the symbol's one
@@ -2369,8 +2369,15 @@ void SmRootSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
 
 void SmDynIntegralSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
 {
+    long nFactor = 12L;
+
     // XXX: testing with a slightly higher height
-    SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / 2L);
+    SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / nFactor);
+
+    //XXX Assuming we can only increase the size?
+    // keep the ratio
+    long nCurWidth = GetSize().Width();
+    SmMathSymbolNode::AdaptToX(rDev, nCurWidth + nCurWidth / nFactor);
 }
 
 
diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx
index 6c42db6..d46ff63 100644
--- a/starmath/source/parse.cxx
+++ b/starmath/source/parse.cxx
@@ -160,7 +160,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, TGOPER, 5},
+    { "intd", TINTD, MS_INT, TGUNOPER, 5},
     { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0},
     { "ital", TITALIC, '\0', TGFONTATTR, 5},
     { "italic", TITALIC, '\0', TGFONTATTR, 5},
@@ -1634,7 +1634,7 @@ void SmParser::Oper()
         case TPROD :
         case TCOPROD :
         case TINT :
-        case TINTD:
+        //case TINTD:
         case TIINT :
         case TIIINT :
         case TLINT :
-- 
1.8.3.2

From 614380cad5d0958a71e3c2ce369957a9a0fe3120 Mon Sep 17 00:00:00 2001
From: matteocam <matteo.campane...@gmail.com>
Date: Thu, 13 Mar 2014 03:34:06 -0400
Subject: [PATCH 5/5] Cleaned code and comments

Change-Id: I0348155f2429cf7dd3cbe7d71f333879ec6de980
---
 starmath/inc/node.hxx     | 10 ++++------
 starmath/source/node.cxx  | 27 +++------------------------
 starmath/source/parse.cxx |  4 +++-
 3 files changed, 10 insertions(+), 31 deletions(-)

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index b2c4df9..bfb6ae9 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -624,7 +624,7 @@ public:
  *
  * Node for drawing dynamicall sized integral symbols.
  *
- * XXX: It might be created a parent class SmDynamicSizedNode
+ * TODO: It might be created a parent class SmDynamicSizedNode
         (for both dynamic integrals, roots and other dynamic symbols)
 
  */
@@ -834,13 +834,11 @@ public:
 
 /** Dynamic Integral node
  *
- * Used for create Dynamically sized integrals
+ * Used to create Dynamically sized integrals
  *
  * Children:<BR>
- * 0: Argument (optional)<BR>
- * 1: Symbol (instance of DynIntegralSymbolNode)<BR>
- * 2: Body<BR>
- * Where argument is optional and may be NULL.
+ * 0: Symbol (instance of DynIntegralSymbolNode)<BR>
+ * 1: Body<BR>
  */
 class SmDynIntegralNode : public SmStructureNode
 {
diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx
index e30ea17..a85e14c 100644
--- a/starmath/source/node.cxx
+++ b/starmath/source/node.cxx
@@ -1120,19 +1120,6 @@ void SmRootNode::CreateTextFromNode(OUString &rText)
 /**************************************************************************/
 
 
-void SmDynIntegralNode::GetHeightVerOffset(const SmRect &rRect,
-                                    long &rHeight, long &rVerOffset) const
-    // calculate height and vertical offset of root sign suitable for 'rRect'
-    //! Code copied from SmRootNode
-{
-    rVerOffset = (rRect.GetBottom() - rRect.GetAlignB()) / 2;
-    rHeight    = rRect.GetHeight() - rVerOffset;
-
-    OSL_ENSURE(rHeight    >= 0, "Sm : Ooops...");
-    OSL_ENSURE(rVerOffset >= 0, "Sm : Ooops...");
-}
-
-
 void SmDynIntegralNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
 {
     SmNode  *pDynIntegralSym = Symbol(),
@@ -1142,14 +1129,7 @@ void SmDynIntegralNode::Arrange(const OutputDevice &rDev, const SmFormat &rForma
 
     pBody->Arrange(rDev, rFormat);
 
-    long  nHeight,
-          nVerOffset;
-    // XXX This is root-specific too
-    GetHeightVerOffset(*pBody, nHeight, nVerOffset);
-    //XXX I suppose I don't need the lines below which seem root-specific
-    //nHeight += rFormat.GetDistance(DIS_ROOT) // XXX
-               //* GetFont().GetSize().Height() / 100L;
-
+    long  nHeight = pBody->GetHeight();
     pDynIntegralSym->AdaptToY(rDev, nHeight);
 
     pDynIntegralSym->Arrange(rDev, rFormat);
@@ -1157,7 +1137,6 @@ void SmDynIntegralNode::Arrange(const OutputDevice &rDev, const SmFormat &rForma
     Point  aPos = pDynIntegralSym->AlignTo(*pBody, RP_LEFT, RHA_CENTER, RVA_BASELINE);
     //! override calculated vertical position
     aPos.Y()  = pDynIntegralSym->GetTop() + pBody->GetBottom() - pDynIntegralSym->GetBottom();
-    //aPos.Y() -= nVerOffset;
     pDynIntegralSym->MoveTo(aPos);
 
 
@@ -2371,10 +2350,10 @@ void SmDynIntegralSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeig
 {
     long nFactor = 12L;
 
-    // XXX: testing with a slightly higher height
+    // 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);
 
-    //XXX Assuming we can only increase the size?
     // keep the ratio
     long nCurWidth = GetSize().Width();
     SmMathSymbolNode::AdaptToX(rDev, nCurWidth + nCurWidth / nFactor);
diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx
index d46ff63..db1359a 100644
--- a/starmath/source/parse.cxx
+++ b/starmath/source/parse.cxx
@@ -1634,7 +1634,6 @@ void SmParser::Oper()
         case TPROD :
         case TCOPROD :
         case TINT :
-        //case TINTD:
         case TIINT :
         case TIIINT :
         case TLINT :
@@ -1700,6 +1699,9 @@ 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;
-- 
1.8.3.2

_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to