summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatteocam <matteo.campanelli@gmail.com>2014-02-25 14:37:55 -0500
committerNorbert Thiebaud <nthiebaud@gmail.com>2014-03-15 22:45:51 +0000
commit93e6291c29d547c0c29c6e43b2ca4b36a3e8506f (patch)
tree50d3560576046dd111e5a9aad5d37afa1add69a9
parentedc8ee009943e7fc9a68730b0efb303b019a62d4 (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.hxx82
-rw-r--r--starmath/inc/parse.hxx3
-rw-r--r--starmath/inc/visitors.hxx14
-rw-r--r--starmath/source/mathtype.cxx2
-rw-r--r--starmath/source/mathtype.hxx2
-rw-r--r--starmath/source/node.cxx75
-rw-r--r--starmath/source/ooxmlexport.cxx1
-rw-r--r--starmath/source/parse.cxx12
-rw-r--r--starmath/source/rtfexport.cxx1
-rw-r--r--starmath/source/visitors.cxx109
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* )
{
}