summaryrefslogtreecommitdiff
path: root/starmath/source/node.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'starmath/source/node.cxx')
-rw-r--r--starmath/source/node.cxx3151
1 files changed, 0 insertions, 3151 deletions
diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx
deleted file mode 100644
index f4709a26f6..0000000000
--- a/starmath/source/node.cxx
+++ /dev/null
@@ -1,3151 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_starmath.hxx"
-
-#include "node.hxx"
-#include "rect.hxx"
-#include "symbol.hxx"
-#include "smmod.hxx"
-#include "document.hxx"
-#include "view.hxx"
-#include "mathtype.hxx"
-#include "visitors.hxx"
-
-#include <tools/gen.hxx>
-#include <tools/fract.hxx>
-#include <rtl/math.hxx>
-#include <tools/color.hxx>
-#include <vcl/metric.hxx>
-#include <vcl/lineinfo.hxx>
-#include <vcl/outdev.hxx>
-#include <sfx2/module.hxx>
-
-#include <math.h>
-#include <float.h>
-
-
-#define APPEND(str,ascii) str.AppendAscii(RTL_CONSTASCII_STRINGPARAM(ascii))
-
-
-using ::rtl::OUString;
-
-
-////////////////////////////////////////
-// SmTmpDevice
-// Allows for font and color changes. The original settings will be restored
-// in the destructor.
-// It's main purpose is to allow for the "const" in the 'OutputDevice'
-// argument in the 'Arrange' functions and restore changes made in the 'Draw'
-// functions.
-// Usually a MapMode of 1/100th mm will be used.
-//
-
-class SmTmpDevice
-{
- OutputDevice &rOutDev;
-
- // disallow use of copy-constructor and assignment-operator
- SmTmpDevice(const SmTmpDevice &rTmpDev);
- SmTmpDevice & operator = (const SmTmpDevice &rTmpDev);
-
- Color Impl_GetColor( const Color& rColor );
-
-public:
- SmTmpDevice(OutputDevice &rTheDev, bool bUseMap100th_mm);
- ~SmTmpDevice() { rOutDev.Pop(); }
-
- void SetFont(const Font &rNewFont);
-
- void SetLineColor( const Color& rColor ) { rOutDev.SetLineColor( Impl_GetColor(rColor) ); }
- void SetFillColor( const Color& rColor ) { rOutDev.SetFillColor( Impl_GetColor(rColor) ); }
- void SetTextColor( const Color& rColor ) { rOutDev.SetTextColor( Impl_GetColor(rColor) ); }
-
- operator OutputDevice & () { return rOutDev; }
-};
-
-
-SmTmpDevice::SmTmpDevice(OutputDevice &rTheDev, bool bUseMap100th_mm) :
- rOutDev(rTheDev)
-{
- rOutDev.Push( PUSH_FONT | PUSH_MAPMODE |
- PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
- if (bUseMap100th_mm && MAP_100TH_MM != rOutDev.GetMapMode().GetMapUnit())
- {
- OSL_FAIL( "incorrect MapMode?" );
- rOutDev.SetMapMode( MAP_100TH_MM ); //Immer fuer 100% fomatieren
- }
-}
-
-
-Color SmTmpDevice::Impl_GetColor( const Color& rColor )
-{
- ColorData nNewCol = rColor.GetColor();
- if (COL_AUTO == nNewCol)
- {
- if (OUTDEV_PRINTER == rOutDev.GetOutDevType())
- nNewCol = COL_BLACK;
- else
- {
- Color aBgCol( rOutDev.GetBackground().GetColor() );
- if (OUTDEV_WINDOW == rOutDev.GetOutDevType())
- aBgCol = ((Window &) rOutDev).GetDisplayBackground().GetColor();
-
- nNewCol = SM_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
-
- Color aTmpColor( nNewCol );
- if (aBgCol.IsDark() && aTmpColor.IsDark())
- nNewCol = COL_WHITE;
- else if (aBgCol.IsBright() && aTmpColor.IsBright())
- nNewCol = COL_BLACK;
- }
- }
- return Color( nNewCol );
-}
-
-
-void SmTmpDevice::SetFont(const Font &rNewFont)
-{
- rOutDev.SetFont( rNewFont );
- rOutDev.SetTextColor( Impl_GetColor( rNewFont.GetColor() ) );
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-
-
-SmNode::SmNode(SmNodeType eNodeType, const SmToken &rNodeToken)
-{
- eType = eNodeType;
- eScaleMode = SCALE_NONE;
- aNodeToken = rNodeToken;
- nAccIndex = -1;
- SetSelected(false);
- aParentNode = NULL;
-}
-
-
-SmNode::~SmNode()
-{
-}
-
-
-bool SmNode::IsVisible() const
-{
- return false;
-}
-
-
-sal_uInt16 SmNode::GetNumSubNodes() const
-{
- return 0;
-}
-
-
-SmNode * SmNode::GetSubNode(sal_uInt16 /*nIndex*/)
-{
- return NULL;
-}
-
-
-SmNode * SmNode::GetLeftMost()
- // returns leftmost node of current subtree.
- //! (this assumes the one with index 0 is always the leftmost subnode
- //! for the current node).
-{
- SmNode *pNode = GetNumSubNodes() > 0 ?
- GetSubNode(0) : NULL;
-
- return pNode ? pNode->GetLeftMost() : this;
-}
-
-
-void SmNode::SetPhantom(bool bIsPhantomP)
-{
- if (! (Flags() & FLG_VISIBLE))
- bIsPhantom = bIsPhantomP;
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->SetPhantom(bIsPhantom);
-}
-
-
-void SmNode::SetColor(const Color& rColor)
-{
- if (! (Flags() & FLG_COLOR))
- GetFont().SetColor(rColor);
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->SetColor(rColor);
-}
-
-
-void SmNode::SetAttribut(sal_uInt16 nAttrib)
-{
- if (
- (nAttrib == ATTR_BOLD && !(Flags() & FLG_BOLD)) ||
- (nAttrib == ATTR_ITALIC && !(Flags() & FLG_ITALIC))
- )
- {
- nAttributes |= nAttrib;
- }
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->SetAttribut(nAttrib);
-}
-
-
-void SmNode::ClearAttribut(sal_uInt16 nAttrib)
-{
- if (
- (nAttrib == ATTR_BOLD && !(Flags() & FLG_BOLD)) ||
- (nAttrib == ATTR_ITALIC && !(Flags() & FLG_ITALIC))
- )
- {
- nAttributes &= ~nAttrib;
- }
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->ClearAttribut(nAttrib);
-}
-
-
-void SmNode::SetFont(const SmFace &rFace)
-{
- if (!(Flags() & FLG_FONT))
- GetFont() = rFace;
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->SetFont(rFace);
-}
-
-
-void SmNode::SetFontSize(const Fraction &rSize, sal_uInt16 nType)
- //! 'rSize' is in units of pts
-{
- Size aFntSize;
-
- if (!(Flags() & FLG_SIZE))
- {
- Fraction aVal (SmPtsTo100th_mm(rSize.GetNumerator()),
- rSize.GetDenominator());
- long nHeight = (long)aVal;
-
- aFntSize = GetFont().GetSize();
- aFntSize.Width() = 0;
- switch(nType)
- {
- case FNTSIZ_ABSOLUT:
- aFntSize.Height() = nHeight;
- break;
-
- case FNTSIZ_PLUS:
- aFntSize.Height() += nHeight;
- break;
-
- case FNTSIZ_MINUS:
- aFntSize.Height() -= nHeight;
- break;
-
- case FNTSIZ_MULTIPLY:
- aFntSize.Height() = (long) (Fraction(aFntSize.Height()) * rSize);
- break;
-
- case FNTSIZ_DIVIDE:
- if (rSize != Fraction(0L))
- aFntSize.Height() = (long) (Fraction(aFntSize.Height()) / rSize);
- break;
- default:
- break;
- }
-
- // check the requested size against maximum value
- static int const nMaxVal = SmPtsTo100th_mm(128);
- if (aFntSize.Height() > nMaxVal)
- aFntSize.Height() = nMaxVal;
-
- GetFont().SetSize(aFntSize);
- }
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->SetFontSize(rSize, nType);
-}
-
-
-void SmNode::SetSize(const Fraction &rSize)
-{
- GetFont() *= rSize;
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->SetSize(rSize);
-}
-
-
-void SmNode::SetRectHorAlign(RectHorAlign eHorAlign, bool bApplyToSubTree )
-{
- if (!(Flags() & FLG_HORALIGN))
- eRectHorAlign = eHorAlign;
-
- if (bApplyToSubTree)
- {
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->SetRectHorAlign(eHorAlign);
- }
-}
-
-
-void SmNode::PrepareAttributes()
-{
- GetFont().SetWeight((Attributes() & ATTR_BOLD) ? WEIGHT_BOLD : WEIGHT_NORMAL);
- GetFont().SetItalic((Attributes() & ATTR_ITALIC) ? ITALIC_NORMAL : ITALIC_NONE);
-}
-
-
-void SmNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
-#if OSL_DEBUG_LEVEL > 1
- bIsDebug = true;
-#else
- bIsDebug = false;
-#endif
- bIsPhantom = false;
- nFlags = 0;
- nAttributes = 0;
-
- switch (rFormat.GetHorAlign())
- { case AlignLeft: eRectHorAlign = RHA_LEFT; break;
- case AlignCenter: eRectHorAlign = RHA_CENTER; break;
- case AlignRight: eRectHorAlign = RHA_RIGHT; break;
- }
-
- GetFont() = rFormat.GetFont(FNT_MATH);
- OSL_ENSURE( GetFont().GetCharSet() == RTL_TEXTENCODING_UNICODE,
- "unexpected CharSet" );
- GetFont().SetWeight(WEIGHT_NORMAL);
- GetFont().SetItalic(ITALIC_NONE);
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->Prepare(rFormat, rDocShell);
-}
-
-
-#if OSL_DEBUG_LEVEL > 1
-void SmNode::ToggleDebug() const
- // toggle 'bIsDebug' in current subtree
-{
- SmNode *pThis = (SmNode *) this;
-
- pThis->bIsDebug = bIsDebug ? false : true;
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = pThis->GetSubNode(i)))
- pNode->ToggleDebug();
-}
-#endif
-
-
-void SmNode::Move(const Point& rPosition)
-{
- if (rPosition.X() == 0 && rPosition.Y() == 0)
- return;
-
- SmRect::Move(rPosition);
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->Move(rPosition);
-}
-
-
-void SmNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->Arrange(rDev, rFormat);
-}
-
-void SmNode::CreateTextFromNode(String &rText)
-{
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- if (nSize > 1)
- rText.Append('{');
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->CreateTextFromNode(rText);
- if (nSize > 1)
- {
- rText.EraseTrailingChars();
- APPEND(rText,"} ");
- }
-}
-
-
-void SmNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong /*nWidth*/)
-{
-}
-
-
-void SmNode::AdaptToY(const OutputDevice &/*rDev*/, sal_uLong /*nHeight*/)
-{
-}
-
-
-const SmNode * SmNode::FindTokenAt(sal_uInt16 nRow, sal_uInt16 nCol) const
- // returns (first) ** visible ** (sub)node with the tokens text at
- // position 'nRow', 'nCol'.
- //! (there should be exactly one such node if any)
-{
- if ( IsVisible()
- && nRow == GetToken().nRow
- && nCol >= GetToken().nCol && nCol < GetToken().nCol + GetToken().aText.Len())
- return this;
- else
- {
- sal_uInt16 nNumSubNodes = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nNumSubNodes; i++)
- { const SmNode *pNode = GetSubNode(i);
-
- if (!pNode)
- continue;
-
- const SmNode *pResult = pNode->FindTokenAt(nRow, nCol);
- if (pResult)
- return pResult;
- }
- }
-
- return 0;
-}
-
-
-const SmNode * SmNode::FindRectClosestTo(const Point &rPoint) const
-{
- long nDist = LONG_MAX;
- const SmNode *pResult = 0;
-
- if (IsVisible())
- pResult = this;
- else
- {
- sal_uInt16 nNumSubNodes = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nNumSubNodes; i++)
- { const SmNode *pNode = GetSubNode(i);
-
- if (!pNode)
- continue;
-
- long nTmp;
- const SmNode *pFound = pNode->FindRectClosestTo(rPoint);
- if (pFound && (nTmp = pFound->OrientedDist(rPoint)) < nDist)
- { nDist = nTmp;
- pResult = pFound;
-
- // quit immediately if 'rPoint' is inside the *should not
- // overlap with other rectangles* part.
- // This (partly) serves for getting the attributes in eg
- // "bar overstrike a".
- // ('nDist < 0' is used as *quick shot* to avoid evaluation of
- // the following expression, where the result is already determined)
- if (nDist < 0 && pFound->IsInsideRect(rPoint))
- break;
- }
- }
- }
-
- return pResult;
-}
-
-void SmNode::GetAccessibleText( String &/*rText*/ ) const
-{
- OSL_FAIL( "SmNode: GetAccessibleText not overloaded" );
-}
-
-const SmNode * SmNode::FindNodeWithAccessibleIndex(xub_StrLen nAccIdx) const
-{
- const SmNode *pResult = 0;
-
- sal_Int32 nIdx = GetAccessibleIndex();
- String aTxt;
- if (nIdx >= 0)
- GetAccessibleText( aTxt ); // get text if used in following 'if' statement
-
- if (nIdx >= 0
- && nIdx <= nAccIdx && nAccIdx < nIdx + aTxt.Len())
- pResult = this;
- else
- {
- sal_uInt16 nNumSubNodes = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nNumSubNodes; i++)
- {
- const SmNode *pNode = GetSubNode(i);
- if (!pNode)
- continue;
-
- pResult = pNode->FindNodeWithAccessibleIndex(nAccIdx);
- if (pResult)
- return pResult;
- }
- }
-
- return pResult;
-}
-
-#ifdef DEBUG_ENABLE_DUMPASDOT
-void SmNode::DumpAsDot(std::ostream &out, String* label, int number, int& id, int parent) const
-{
- //If this is the root start the file
- if(number == -1){
- out<<"digraph {"<<std::endl;
- if(label){
- out<<"labelloc = \"t\";"<<std::endl;
- String eq(*label);
- //CreateTextFromNode(eq);
- eq.SearchAndReplaceAll(String::CreateFromAscii("\n"), String::CreateFromAscii(" "));
- eq.SearchAndReplaceAll(String::CreateFromAscii("\\"), String::CreateFromAscii("\\\\"));
- eq.SearchAndReplaceAll(String::CreateFromAscii("\""), String::CreateFromAscii("\\\""));
- out<<"label= \"Equation: \\\"";
- out<< rtl::OUStringToOString(eq, RTL_TEXTENCODING_UTF8).getStr();
- out<<"\\\"\";"<<std::endl;
- }
- }
-
- //Some how out<<(int)this; doesn't work... So we do this nasty workaround...
- char strid[100];
- sprintf(strid, "%i", id);
-
- char strnr[100];
- sprintf(strnr, "%i", number);
-
- //Dump connection to this node
- if( parent != -1 ){
- char pid[100];
- sprintf(pid, "%i", parent);
- out<<"n"<<pid<<" -> n"<<strid<<" [label=\""<<strnr<<"\"];"<<std::endl;
- //If doesn't have parent and isn't a rootnode:
- } else if(number != -1) {
- out<<"orphaned -> n"<<strid<<" [label=\""<<strnr<<"\"];"<<std::endl;
- }
-
- //Dump this node
- out<<"n"<< strid<<" [label=\"";
- switch( GetType() ) {
- case NTABLE: out<<"SmTableNode"; break;
- case NBRACE: out<<"SmBraceNode"; break;
- case NBRACEBODY: out<<"SmBracebodyNode"; break;
- case NOPER: out<<"SmOperNode"; break;
- case NALIGN: out<<"SmAlignNode"; break;
- case NATTRIBUT: out<<"SmAttributNode"; break;
- case NFONT: out<<"SmFontNode"; break;
- case NUNHOR: out<<"SmUnHorNode"; break;
- case NBINHOR: out<<"SmBinHorNode"; break;
- case NBINVER: out<<"SmBinVerNode"; break;
- case NBINDIAGONAL: out<<"SmBinDiagonalNode"; break;
- case NSUBSUP: out<<"SmSubSupNode"; break;
- case NMATRIX: out<<"SmMatrixNode"; break;
- case NPLACE: out<<"SmPlaceNode"; break;
- case NTEXT:
- out<<"SmTextNode: ";
- out<< rtl::OUStringToOString(((SmTextNode*)this)->GetText(), RTL_TEXTENCODING_UTF8).getStr();
- break;
- case NSPECIAL: out<<"SmSpecialNode"; break;
- case NGLYPH_SPECIAL: out<<"SmGlyphSpecialNode"; break;
- case NMATH:
- out<<"SmMathSymbolNode: ";
- out<< rtl::OUStringToOString(((SmMathSymbolNode*)this)->GetText(), RTL_TEXTENCODING_UTF8).getStr();
- break;
- case NBLANK: out<<"SmBlankNode"; break;
- case NERROR: out<<"SmErrorNode"; break;
- case NLINE: out<<"SmLineNode"; break;
- case NEXPRESSION: out<<"SmExpressionNode"; break;
- case NPOLYLINE: out<<"SmPolyLineNode"; break;
- case NROOT: out<<"SmRootNode"; break;
- case NROOTSYMBOL: out<<"SmRootSymbolNode"; break;
- case NRECTANGLE: out<<"SmRectangleNode"; break;
- case NVERTICAL_BRACE: out<<"SmVerticalBraceNode"; break;
- default:
- out<<"Unknown Node";
- }
- out<<"\"";
- if(IsSelected())
- out<<", style=dashed";
- out<<"];"<<std::endl;
-
- //Dump subnodes
- int myid = id;
- const SmNode *pNode;
- USHORT nSize = GetNumSubNodes();
- for (USHORT i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->DumpAsDot(out, NULL, i, ++id, myid);
-
- //If this is the root end the file
- if( number == -1 )
- out<<"}"<<std::endl;
-}
-#endif /* DEBUG_ENABLE_DUMPASDOT */
-
-long SmNode::GetFormulaBaseline() const
-{
- OSL_FAIL( "This dummy implementation should not have been called." );
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-SmStructureNode::SmStructureNode( const SmStructureNode &rNode ) :
- SmNode( rNode.GetType(), rNode.GetToken() )
-{
- sal_uLong i;
- for (i = 0; i < aSubNodes.size(); i++)
- delete aSubNodes[i];
- aSubNodes.resize(0);
-
- sal_uLong nSize = rNode.aSubNodes.size();
- aSubNodes.resize( nSize );
- for (i = 0; i < nSize; ++i)
- {
- SmNode *pNode = rNode.aSubNodes[i];
- aSubNodes[i] = pNode ? new SmNode( *pNode ) : 0;
- }
- ClaimPaternity();
-}
-
-
-SmStructureNode::~SmStructureNode()
-{
- SmNode *pNode;
-
- for (sal_uInt16 i = 0; i < GetNumSubNodes(); i++)
- if (NULL != (pNode = GetSubNode(i)))
- delete pNode;
-}
-
-
-SmStructureNode & SmStructureNode::operator = ( const SmStructureNode &rNode )
-{
- SmNode::operator = ( rNode );
-
- sal_uLong i;
- for (i = 0; i < aSubNodes.size(); i++)
- delete aSubNodes[i];
- aSubNodes.resize(0);
-
- sal_uLong nSize = rNode.aSubNodes.size();
- aSubNodes.resize( nSize );
- for (i = 0; i < nSize; ++i)
- {
- SmNode *pNode = rNode.aSubNodes[i];
- aSubNodes[i] = pNode ? new SmNode( *pNode ) : 0;
- }
-
- ClaimPaternity();
-
- return *this;
-}
-
-
-void SmStructureNode::SetSubNodes(SmNode *pFirst, SmNode *pSecond, SmNode *pThird)
-{
- size_t nSize = pThird ? 3 : (pSecond ? 2 : (pFirst ? 1 : 0));
- aSubNodes.resize( nSize );
- if (pFirst)
- aSubNodes[0] = pFirst;
- if (pSecond)
- aSubNodes[1] = pSecond;
- if (pThird)
- aSubNodes[2] = pThird;
-
- ClaimPaternity();
-}
-
-
-void SmStructureNode::SetSubNodes(const SmNodeArray &rNodeArray)
-{
- aSubNodes = rNodeArray;
- ClaimPaternity();
-}
-
-
-bool SmStructureNode::IsVisible() const
-{
- return false;
-}
-
-
-sal_uInt16 SmStructureNode::GetNumSubNodes() const
-{
- return (sal_uInt16) aSubNodes.size();
-}
-
-
-SmNode * SmStructureNode::GetSubNode(sal_uInt16 nIndex)
-{
- return aSubNodes[nIndex];
-}
-
-
-void SmStructureNode::GetAccessibleText( String &rText ) const
-{
- sal_uInt16 nNodes = GetNumSubNodes();
- for (sal_uInt16 i = 0; i < nNodes; ++i)
- {
- const SmNode *pNode = ((SmStructureNode *) this)->GetSubNode(i);
- if (pNode)
- {
- if (pNode->IsVisible())
- ((SmStructureNode *) pNode)->nAccIndex = rText.Len();
- pNode->GetAccessibleText( rText );
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-
-bool SmVisibleNode::IsVisible() const
-{
- return true;
-}
-
-
-sal_uInt16 SmVisibleNode::GetNumSubNodes() const
-{
- return 0;
-}
-
-
-SmNode * SmVisibleNode::GetSubNode(sal_uInt16 /*nIndex*/)
-{
- return NULL;
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-
-void SmGraphicNode::GetAccessibleText( String &rText ) const
-{
- rText += GetToken().aText;
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-
-void SmExpressionNode::CreateTextFromNode(String &rText)
-{
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- if (nSize > 1)
- rText.Append('{');
- for (sal_uInt16 i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- {
- pNode->CreateTextFromNode(rText);
- //Just a bit of foo to make unary +asd -asd +-asd -+asd look nice
- if (pNode->GetType() == NMATH)
- if ((nSize != 2) || ((rText.GetChar(rText.Len()-1) != '+') &&
- (rText.GetChar(rText.Len()-1) != '-')))
- rText.Append(' ');
- }
-
- if (nSize > 1)
- {
- rText.EraseTrailingChars();
- APPEND(rText,"} ");
- }
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-
-void SmTableNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
- // arranges all subnodes in one column
-{
- Point rPosition;
-
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
-
- // make distance depend on font size
- long nDist = +(rFormat.GetDistance(DIS_VERTICAL)
- * GetFont().GetSize().Height()) / 100L;
-
- if (nSize < 1)
- return;
-
- // arrange subnodes and get maximum width of them
- long nMaxWidth = 0,
- nTmp;
- sal_uInt16 i;
- for (i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- { pNode->Arrange(rDev, rFormat);
- if ((nTmp = pNode->GetItalicWidth()) > nMaxWidth)
- nMaxWidth = nTmp;
- }
-
- Point aPos;
- SmRect::operator = (SmRect(nMaxWidth, 1));
- for (i = 0; i < nSize; i++)
- { if (NULL != (pNode = GetSubNode(i)))
- { const SmRect &rNodeRect = pNode->GetRect();
- const SmNode *pCoNode = pNode->GetLeftMost();
- RectHorAlign eHorAlign = pCoNode->GetRectHorAlign();
-
- aPos = rNodeRect.AlignTo(*this, RP_BOTTOM,
- eHorAlign, RVA_BASELINE);
- if (i)
- aPos.Y() += nDist;
- pNode->MoveTo(aPos);
- ExtendBy(rNodeRect, nSize > 1 ? RCP_NONE : RCP_ARG);
- }
- }
- // #i972#
- if (HasBaseline())
- nFormulaBaseline = GetBaseline();
- else
- {
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, sal_True);
- aTmpDev.SetFont(GetFont());
-
- SmRect aRect = (SmRect(aTmpDev, &rFormat, C2S("a"),
- GetFont().GetBorderWidth()));
- nFormulaBaseline = GetAlignM();
- // move from middle position by constant - distance
- // between middle and baseline for single letter
- nFormulaBaseline += aRect.GetBaseline() - aRect.GetAlignM();
- }
-}
-
-
-SmNode * SmTableNode::GetLeftMost()
-{
- return this;
-}
-
-
-long SmTableNode::GetFormulaBaseline() const
-{
- return nFormulaBaseline;
-}
-
-
-/**************************************************************************/
-
-
-void SmLineNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- SmNode::Prepare(rFormat, rDocShell);
-
- //! wir verwenden hier den 'FNT_VARIABLE' Font, da er vom Ascent und Descent
- //! ia besser zum Rest der Formel passt als der 'FNT_MATH' Font.
- GetFont() = rFormat.GetFont(FNT_VARIABLE);
- Flags() |= FLG_FONT;
-}
-
-
-/**************************************************************************/
-
-
-void SmLineNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
- // arranges all subnodes in one row with some extra space between
-{
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- sal_uInt16 i;
- for (i = 0; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- pNode->Arrange(rDev, rFormat);
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- if (nSize < 1)
- {
- // provide an empty rectangle with alignment parameters for the "current"
- // font (in order to make "a^1 {}_2^3 a_4" work correct, that is, have the
- // same sub-/supscript positions.)
- //! be sure to use a character that has explicitly defined HiAttribut
- //! line in rect.cxx such as 'a' in order to make 'vec a' look same to
- //! 'vec {a}'.
- SmRect::operator = (SmRect(aTmpDev, &rFormat, C2S("a"),
- GetFont().GetBorderWidth()));
- // make sure that the rectangle occupies (almost) no space
- SetWidth(1);
- SetItalicSpaces(0, 0);
- return;
- }
-
- // make distance depend on font size
- long nDist = (rFormat.GetDistance(DIS_HORIZONTAL) * GetFont().GetSize().Height()) / 100L;
- if (!IsUseExtraSpaces())
- nDist = 0;
-
- Point aPos;
- // copy the first node into LineNode and extend by the others
- if (NULL != (pNode = GetSubNode(0)))
- SmRect::operator = (pNode->GetRect());
-
- for (i = 1; i < nSize; i++)
- if (NULL != (pNode = GetSubNode(i)))
- {
- aPos = pNode->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
-
- // add horizontal space to the left for each but the first sub node
- aPos.X() += nDist;
-
- pNode->MoveTo(aPos);
- ExtendBy( *pNode, RCP_XOR );
- }
-}
-
-
-/**************************************************************************/
-
-
-void SmExpressionNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
- // as 'SmLineNode::Arrange' but keeps alignment of leftmost subnode
-{
- SmLineNode::Arrange(rDev, rFormat);
-
- // copy alignment of leftmost subnode if any
- SmNode *pNode = GetLeftMost();
- if (pNode)
- SetRectHorAlign(pNode->GetRectHorAlign(), false);
-}
-
-
-/**************************************************************************/
-
-
-void SmUnHorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- bool bIsPostfix = GetToken().eType == TFACT;
-
- SmNode *pOper = GetSubNode(bIsPostfix ? 1 : 0),
- *pBody = GetSubNode(bIsPostfix ? 0 : 1);
- OSL_ENSURE(pOper, "Sm: NULL pointer");
- OSL_ENSURE(pBody, "Sm: NULL pointer");
-
- pOper->SetSize(Fraction (rFormat.GetRelSize(SIZ_OPERATOR), 100));
- pOper->Arrange(rDev, rFormat);
- pBody->Arrange(rDev, rFormat);
-
- Point aPos = pOper->AlignTo(*pBody, bIsPostfix ? RP_RIGHT : RP_LEFT,
- RHA_CENTER, RVA_BASELINE);
- // add a bit space between operator and argument
- // (worst case -{1 over 2} where - and over have almost no space inbetween)
- long nDelta = pOper->GetFont().GetSize().Height() / 20;
- if (bIsPostfix)
- aPos.X() += nDelta;
- else
- aPos.X() -= nDelta;
- pOper->MoveTo(aPos);
-
- SmRect::operator = (*pBody);
- long nOldBot = GetBottom();
-
- ExtendBy(*pOper, RCP_XOR);
-
- // workaround for Bug 50865: "a^2 a^+2" have different baselines
- // for exponents (if size of exponent is large enough)
- SetBottom(nOldBot);
-}
-
-
-/**************************************************************************/
-
-
-void SmRootNode::GetHeightVerOffset(const SmRect &rRect,
- long &rHeight, long &rVerOffset) const
- // calculate height and vertical offset of root sign suitable for 'rRect'
-{
- rVerOffset = (rRect.GetBottom() - rRect.GetAlignB()) / 2;
- rHeight = rRect.GetHeight() - rVerOffset;
-
- OSL_ENSURE(rHeight >= 0, "Sm : Ooops...");
- OSL_ENSURE(rVerOffset >= 0, "Sm : Ooops...");
-}
-
-
-Point SmRootNode::GetExtraPos(const SmRect &rRootSymbol,
- const SmRect &rExtra) const
-{
- const Size &rSymSize = rRootSymbol.GetSize();
-
- Point aPos = rRootSymbol.GetTopLeft()
- + Point((rSymSize.Width() * 70) / 100,
- (rSymSize.Height() * 52) / 100);
-
- // from this calculate topleft edge of 'rExtra'
- aPos.X() -= rExtra.GetWidth() + rExtra.GetItalicRightSpace();
- aPos.Y() -= rExtra.GetHeight();
- // if there's enough space move a bit less to the right
- // examples: "nroot i a", "nroot j a"
- // (it looks better if we don't use italic-spaces here)
- long nX = rRootSymbol.GetLeft() + (rSymSize.Width() * 30) / 100;
- if (aPos.X() > nX)
- aPos.X() = nX;
-
- return aPos;
-}
-
-
-void SmRootNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- //! pExtra needs to have the smaller index than pRootSym in order to
- //! not to get the root symbol but the pExtra when clicking on it in the
- //! GraphicWindow. (That is because of the simplicity of the algorithm
- //! that finds the node corresponding to a mouseclick in the window.)
- SmNode *pExtra = GetSubNode(0),
- *pRootSym = GetSubNode(1),
- *pBody = GetSubNode(2);
- OSL_ENSURE(pRootSym, "Sm: NULL pointer");
- OSL_ENSURE(pBody, "Sm: NULL pointer");
-
- pBody->Arrange(rDev, rFormat);
-
- long nHeight,
- nVerOffset;
- GetHeightVerOffset(*pBody, nHeight, nVerOffset);
- nHeight += rFormat.GetDistance(DIS_ROOT)
- * GetFont().GetSize().Height() / 100L;
-
- // font specialist advised to change the width first
- pRootSym->AdaptToY(rDev, nHeight);
- pRootSym->AdaptToX(rDev, pBody->GetItalicWidth());
-
- pRootSym->Arrange(rDev, rFormat);
-
- Point aPos = pRootSym->AlignTo(*pBody, RP_LEFT, RHA_CENTER, RVA_BASELINE);
- //! overrride calulated vertical position
- aPos.Y() = pRootSym->GetTop() + pBody->GetBottom() - pRootSym->GetBottom();
- aPos.Y() -= nVerOffset;
- pRootSym->MoveTo(aPos);
-
- if (pExtra)
- { pExtra->SetSize(Fraction(rFormat.GetRelSize(SIZ_INDEX), 100));
- pExtra->Arrange(rDev, rFormat);
-
- aPos = GetExtraPos(*pRootSym, *pExtra);
- pExtra->MoveTo(aPos);
- }
-
- SmRect::operator = (*pBody);
- ExtendBy(*pRootSym, RCP_THIS);
- if (pExtra)
- ExtendBy(*pExtra, RCP_THIS, true);
-}
-
-
-void SmRootNode::CreateTextFromNode(String &rText)
-{
- SmNode *pExtra = GetSubNode(0);
- if (pExtra)
- {
- APPEND(rText,"nroot ");
- pExtra->CreateTextFromNode(rText);
- }
- else
- APPEND(rText,"sqrt ");
- GetSubNode(2)->CreateTextFromNode(rText);
-}
-
-
-/**************************************************************************/
-
-
-void SmBinHorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pLeft = GetSubNode(0),
- *pOper = GetSubNode(1),
- *pRight = GetSubNode(2);
- OSL_ENSURE(pLeft != NULL, "Sm: NULL pointer");
- OSL_ENSURE(pOper != NULL, "Sm: NULL pointer");
- OSL_ENSURE(pRight != NULL, "Sm: NULL pointer");
-
- pOper->SetSize(Fraction (rFormat.GetRelSize(SIZ_OPERATOR), 100));
-
- pLeft ->Arrange(rDev, rFormat);
- pOper ->Arrange(rDev, rFormat);
- pRight->Arrange(rDev, rFormat);
-
- const SmRect &rOpRect = pOper->GetRect();
-
- long nDist = (rOpRect.GetWidth() *
- rFormat.GetDistance(DIS_HORIZONTAL)) / 100L;
-
- SmRect::operator = (*pLeft);
-
- Point aPos;
- aPos = pOper->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
- aPos.X() += nDist;
- pOper->MoveTo(aPos);
- ExtendBy(*pOper, RCP_XOR);
-
- aPos = pRight->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
- aPos.X() += nDist;
-
- pRight->MoveTo(aPos);
- ExtendBy(*pRight, RCP_XOR);
-}
-
-
-/**************************************************************************/
-
-
-void SmBinVerNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pNum = GetSubNode(0),
- *pLine = GetSubNode(1),
- *pDenom = GetSubNode(2);
- OSL_ENSURE(pNum, "Sm : NULL pointer");
- OSL_ENSURE(pLine, "Sm : NULL pointer");
- OSL_ENSURE(pDenom, "Sm : NULL pointer");
-
- bool bIsTextmode = rFormat.IsTextmode();
- if (bIsTextmode)
- {
- Fraction aFraction(rFormat.GetRelSize(SIZ_INDEX), 100);
- pNum ->SetSize(aFraction);
- pLine ->SetSize(aFraction);
- pDenom->SetSize(aFraction);
- }
-
- pNum ->Arrange(rDev, rFormat);
- pDenom->Arrange(rDev, rFormat);
-
- long nFontHeight = GetFont().GetSize().Height(),
- nExtLen = nFontHeight * rFormat.GetDistance(DIS_FRACTION) / 100L,
- nThick = nFontHeight * rFormat.GetDistance(DIS_STROKEWIDTH) / 100L,
- nWidth = Max(pNum->GetItalicWidth(), pDenom->GetItalicWidth()),
- nNumDist = bIsTextmode ? 0 :
- nFontHeight * rFormat.GetDistance(DIS_NUMERATOR) / 100L,
- nDenomDist = bIsTextmode ? 0 :
- nFontHeight * rFormat.GetDistance(DIS_DENOMINATOR) / 100L;
-
- // font specialist advised to change the width first
- pLine->AdaptToY(rDev, nThick);
- pLine->AdaptToX(rDev, nWidth + 2 * nExtLen);
- pLine->Arrange(rDev, rFormat);
-
- // get horizontal alignment for numerator
- const SmNode *pLM = pNum->GetLeftMost();
- RectHorAlign eHorAlign = pLM->GetRectHorAlign();
-
- // move numerator to its position
- Point aPos = pNum->AlignTo(*pLine, RP_TOP, eHorAlign, RVA_BASELINE);
- aPos.Y() -= nNumDist;
- pNum->MoveTo(aPos);
-
- // get horizontal alignment for denominator
- pLM = pDenom->GetLeftMost();
- eHorAlign = pLM->GetRectHorAlign();
-
- // move denominator to its position
- aPos = pDenom->AlignTo(*pLine, RP_BOTTOM, eHorAlign, RVA_BASELINE);
- aPos.Y() += nDenomDist;
- pDenom->MoveTo(aPos);
-
- SmRect::operator = (*pNum);
- ExtendBy(*pDenom, RCP_NONE).ExtendBy(*pLine, RCP_NONE, pLine->GetCenterY());
-}
-
-void SmBinVerNode::CreateTextFromNode(String &rText)
-{
- SmNode *pNum = GetSubNode(0),
- *pDenom = GetSubNode(2);
- pNum->CreateTextFromNode(rText);
- APPEND(rText,"over ");
- pDenom->CreateTextFromNode(rText);
-}
-
-
-SmNode * SmBinVerNode::GetLeftMost()
-{
- return this;
-}
-
-
-/**************************************************************************/
-
-
-double Det(const Point &rHeading1, const Point &rHeading2)
- // gibt den Wert der durch die beiden Punkte gebildeten Determinante
- // zurueck
-{
- return rHeading1.X() * rHeading2.Y() - rHeading1.Y() * rHeading2.X();
-}
-
-
-bool IsPointInLine(const Point &rPoint1,
- const Point &rPoint2, const Point &rHeading2)
- // ergibt true genau dann, wenn der Punkt 'rPoint1' zu der Gerade gehoert die
- // durch den Punkt 'rPoint2' geht und den Richtungsvektor 'rHeading2' hat
-{
- OSL_ENSURE(rHeading2 != Point(), "Sm : 0 vector");
-
- bool bRes = false;
- const double eps = 5.0 * DBL_EPSILON;
-
- double fLambda;
- if (labs(rHeading2.X()) > labs(rHeading2.Y()))
- {
- fLambda = (rPoint1.X() - rPoint2.X()) / (double) rHeading2.X();
- bRes = fabs(rPoint1.Y() - (rPoint2.Y() + fLambda * rHeading2.Y())) < eps;
- }
- else
- {
- fLambda = (rPoint1.Y() - rPoint2.Y()) / (double) rHeading2.Y();
- bRes = fabs(rPoint1.X() - (rPoint2.X() + fLambda * rHeading2.X())) < eps;
- }
-
- return bRes;
-}
-
-
-sal_uInt16 GetLineIntersectionPoint(Point &rResult,
- const Point& rPoint1, const Point &rHeading1,
- const Point& rPoint2, const Point &rHeading2)
-{
- OSL_ENSURE(rHeading1 != Point(), "Sm : 0 vector");
- OSL_ENSURE(rHeading2 != Point(), "Sm : 0 vector");
-
- sal_uInt16 nRes = 1;
- const double eps = 5.0 * DBL_EPSILON;
-
- // sind die Richtumgsvektoren linear abhaengig ?
- double fDet = Det(rHeading1, rHeading2);
- if (fabs(fDet) < eps)
- {
- nRes = IsPointInLine(rPoint1, rPoint2, rHeading2) ? USHRT_MAX : 0;
- rResult = nRes ? rPoint1 : Point();
- }
- else
- {
- // hier achten wir nicht auf Rechengenauigkeit
- // (das wuerde aufwendiger und lohnt sich hier kaum)
- double fLambda = ( (rPoint1.Y() - rPoint2.Y()) * rHeading2.X()
- - (rPoint1.X() - rPoint2.X()) * rHeading2.Y())
- / fDet;
- rResult = Point(rPoint1.X() + (long) (fLambda * rHeading1.X()),
- rPoint1.Y() + (long) (fLambda * rHeading1.Y()));
- }
-
- return nRes;
-}
-
-
-
-SmBinDiagonalNode::SmBinDiagonalNode(const SmToken &rNodeToken)
-: SmStructureNode(NBINDIAGONAL, rNodeToken)
-{
- bAscending = false;
- SetNumSubNodes(3);
-}
-
-
-void SmBinDiagonalNode::GetOperPosSize(Point &rPos, Size &rSize,
- const Point &rDiagPoint, double fAngleDeg) const
- // gibt die Position und Groesse fuer den Diagonalstrich zurueck.
- // Vor.: das SmRect des Nodes gibt die Begrenzung vor(!), muss also selbst
- // bereits bekannt sein.
-
-{
- const double fPi = 3.1415926535897932384626433;
- double fAngleRad = fAngleDeg / 180.0 * fPi;
- long nRectLeft = GetItalicLeft(),
- nRectRight = GetItalicRight(),
- nRectTop = GetTop(),
- nRectBottom = GetBottom();
- Point aRightHdg (100, 0),
- aDownHdg (0, 100),
- aDiagHdg ( (long)(100.0 * cos(fAngleRad)),
- (long)(-100.0 * sin(fAngleRad)) );
-
- long nLeft, nRight, nTop, nBottom; // Raender des Rechtecks fuer die
- // Diagonale
- Point aPoint;
- if (IsAscending())
- {
- //
- // obere rechte Ecke bestimmen
- //
- GetLineIntersectionPoint(aPoint,
- Point(nRectLeft, nRectTop), aRightHdg,
- rDiagPoint, aDiagHdg);
- //
- // gibt es einen Schnittpunkt mit dem oberen Rand ?
- if (aPoint.X() <= nRectRight)
- {
- nRight = aPoint.X();
- nTop = nRectTop;
- }
- else
- {
- // es muss einen Schnittpunkt mit dem rechten Rand geben!
- GetLineIntersectionPoint(aPoint,
- Point(nRectRight, nRectTop), aDownHdg,
- rDiagPoint, aDiagHdg);
-
- nRight = nRectRight;
- nTop = aPoint.Y();
- }
-
- //
- // untere linke Ecke bestimmen
- //
- GetLineIntersectionPoint(aPoint,
- Point(nRectLeft, nRectBottom), aRightHdg,
- rDiagPoint, aDiagHdg);
- //
- // gibt es einen Schnittpunkt mit dem unteren Rand ?
- if (aPoint.X() >= nRectLeft)
- {
- nLeft = aPoint.X();
- nBottom = nRectBottom;
- }
- else
- {
- // es muss einen Schnittpunkt mit dem linken Rand geben!
- GetLineIntersectionPoint(aPoint,
- Point(nRectLeft, nRectTop), aDownHdg,
- rDiagPoint, aDiagHdg);
-
- nLeft = nRectLeft;
- nBottom = aPoint.Y();
- }
- }
- else
- {
- //
- // obere linke Ecke bestimmen
- //
- GetLineIntersectionPoint(aPoint,
- Point(nRectLeft, nRectTop), aRightHdg,
- rDiagPoint, aDiagHdg);
- //
- // gibt es einen Schnittpunkt mit dem oberen Rand ?
- if (aPoint.X() >= nRectLeft)
- {
- nLeft = aPoint.X();
- nTop = nRectTop;
- }
- else
- {
- // es muss einen Schnittpunkt mit dem linken Rand geben!
- GetLineIntersectionPoint(aPoint,
- Point(nRectLeft, nRectTop), aDownHdg,
- rDiagPoint, aDiagHdg);
-
- nLeft = nRectLeft;
- nTop = aPoint.Y();
- }
-
- //
- // untere rechte Ecke bestimmen
- //
- GetLineIntersectionPoint(aPoint,
- Point(nRectLeft, nRectBottom), aRightHdg,
- rDiagPoint, aDiagHdg);
- //
- // gibt es einen Schnittpunkt mit dem unteren Rand ?
- if (aPoint.X() <= nRectRight)
- {
- nRight = aPoint.X();
- nBottom = nRectBottom;
- }
- else
- {
- // es muss einen Schnittpunkt mit dem rechten Rand geben!
- GetLineIntersectionPoint(aPoint,
- Point(nRectRight, nRectTop), aDownHdg,
- rDiagPoint, aDiagHdg);
-
- nRight = nRectRight;
- nBottom = aPoint.Y();
- }
- }
-
- rSize = Size(nRight - nLeft + 1, nBottom - nTop + 1);
- rPos.X() = nLeft;
- rPos.Y() = nTop;
-}
-
-
-void SmBinDiagonalNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- //! die beiden Argumente muessen in den Subnodes vor dem Operator kommen,
- //! damit das anklicken im GraphicWindow den FormulaCursor richtig setzt
- //! (vgl SmRootNode)
- SmNode *pLeft = GetSubNode(0),
- *pRight = GetSubNode(1);
- OSL_ENSURE(pLeft, "Sm : NULL pointer");
- OSL_ENSURE(pRight, "Sm : NULL pointer");
-
- OSL_ENSURE(GetSubNode(2)->GetType() == NPOLYLINE, "Sm : wrong node type");
- SmPolyLineNode *pOper = (SmPolyLineNode *) GetSubNode(2);
- OSL_ENSURE(pOper, "Sm : NULL pointer");
-
- //! some routines being called extract some info from the OutputDevice's
- //! font (eg the space to be used for borders OR the font name(!!)).
- //! Thus the font should reflect the needs and has to be set!
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- pLeft->Arrange(aTmpDev, rFormat);
- pRight->Arrange(aTmpDev, rFormat);
-
- // implizit die Weite (incl Rand) des Diagonalstrichs ermitteln
- pOper->Arrange(aTmpDev, rFormat);
-
- long nDelta = pOper->GetWidth() * 8 / 10;
-
- // TopLeft Position vom rechten Argument ermitteln
- Point aPos;
- aPos.X() = pLeft->GetItalicRight() + nDelta + pRight->GetItalicLeftSpace();
- if (IsAscending())
- aPos.Y() = pLeft->GetBottom() + nDelta;
- else
- aPos.Y() = pLeft->GetTop() - nDelta - pRight->GetHeight();
-
- pRight->MoveTo(aPos);
-
- // neue Baseline bestimmen
- long nTmpBaseline = IsAscending() ? (pLeft->GetBottom() + pRight->GetTop()) / 2
- : (pLeft->GetTop() + pRight->GetBottom()) / 2;
- Point aLogCenter ((pLeft->GetItalicRight() + pRight->GetItalicLeft()) / 2,
- nTmpBaseline);
-
- SmRect::operator = (*pLeft);
- ExtendBy(*pRight, RCP_NONE);
-
-
- // Position und Groesse des Diagonalstrich ermitteln
- Size aTmpSize;
- GetOperPosSize(aPos, aTmpSize, aLogCenter, IsAscending() ? 60.0 : -60.0);
-
- // font specialist advised to change the width first
- pOper->AdaptToY(aTmpDev, aTmpSize.Height());
- pOper->AdaptToX(aTmpDev, aTmpSize.Width());
- // und diese wirksam machen
- pOper->Arrange(aTmpDev, rFormat);
-
- pOper->MoveTo(aPos);
-
- ExtendBy(*pOper, RCP_NONE, nTmpBaseline);
-}
-
-
-/**************************************************************************/
-
-
-void SmSubSupNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- OSL_ENSURE(GetNumSubNodes() == 1 + SUBSUP_NUM_ENTRIES,
- "Sm: wrong number of subnodes");
-
- SmNode *pBody = GetBody();
- OSL_ENSURE(pBody, "Sm: NULL pointer");
-
- long nOrigHeight = pBody->GetFont().GetSize().Height();
-
- pBody->Arrange(rDev, rFormat);
-
- const SmRect &rBodyRect = pBody->GetRect();
- SmRect::operator = (rBodyRect);
-
- // line that separates sub- and supscript rectangles
- long nDelimLine = SmFromTo(GetAlignB(), GetAlignT(), 0.4);
-
- Point aPos;
- long nDelta, nDist;
-
- // iterate over all possible sub-/supscripts
- SmRect aTmpRect (rBodyRect);
- for (int i = 0; i < SUBSUP_NUM_ENTRIES; i++)
- { SmSubSup eSubSup = (SmSubSup) i; // cast
- SmNode *pSubSup = GetSubSup(eSubSup);
-
- if (!pSubSup)
- continue;
-
- // switch position of limits if we are in textmode
- if (rFormat.IsTextmode() && (GetToken().nGroup & TGLIMIT))
- switch (eSubSup)
- { case CSUB: eSubSup = RSUB; break;
- case CSUP: eSubSup = RSUP; break;
- default:
- break;
- }
-
- // prevent sub-/supscripts from diminishing in size
- // (as would be in "a_{1_{2_{3_4}}}")
- if (GetFont().GetSize().Height() > rFormat.GetBaseSize().Height() / 3)
- {
- sal_uInt16 nIndex = (eSubSup == CSUB || eSubSup == CSUP) ?
- SIZ_LIMITS : SIZ_INDEX;
- Fraction aFraction ( rFormat.GetRelSize(nIndex), 100 );
- pSubSup->SetSize(aFraction);
- }
-
- pSubSup->Arrange(rDev, rFormat);
-
- bool bIsTextmode = rFormat.IsTextmode();
- nDist = 0;
-
- //! be sure that CSUB, CSUP are handled before the other cases!
- switch (eSubSup)
- { case RSUB :
- case LSUB :
- if (!bIsTextmode)
- nDist = nOrigHeight
- * rFormat.GetDistance(DIS_SUBSCRIPT) / 100L;
- aPos = pSubSup->GetRect().AlignTo(aTmpRect,
- eSubSup == LSUB ? RP_LEFT : RP_RIGHT,
- RHA_CENTER, RVA_BOTTOM);
- aPos.Y() += nDist;
- nDelta = nDelimLine - aPos.Y();
- if (nDelta > 0)
- aPos.Y() += nDelta;
- break;
- case RSUP :
- case LSUP :
- if (!bIsTextmode)
- nDist = nOrigHeight
- * rFormat.GetDistance(DIS_SUPERSCRIPT) / 100L;
- aPos = pSubSup->GetRect().AlignTo(aTmpRect,
- eSubSup == LSUP ? RP_LEFT : RP_RIGHT,
- RHA_CENTER, RVA_TOP);
- aPos.Y() -= nDist;
- nDelta = aPos.Y() + pSubSup->GetHeight() - nDelimLine;
- if (nDelta > 0)
- aPos.Y() -= nDelta;
- break;
- case CSUB :
- if (!bIsTextmode)
- nDist = nOrigHeight
- * rFormat.GetDistance(DIS_LOWERLIMIT) / 100L;
- aPos = pSubSup->GetRect().AlignTo(rBodyRect, RP_BOTTOM,
- RHA_CENTER, RVA_BASELINE);
- aPos.Y() += nDist;
- break;
- case CSUP :
- if (!bIsTextmode)
- nDist = nOrigHeight
- * rFormat.GetDistance(DIS_UPPERLIMIT) / 100L;
- aPos = pSubSup->GetRect().AlignTo(rBodyRect, RP_TOP,
- RHA_CENTER, RVA_BASELINE);
- aPos.Y() -= nDist;
- break;
- default :
- OSL_FAIL("Sm: unknown case");
- break;
- }
-
- pSubSup->MoveTo(aPos);
- ExtendBy(*pSubSup, RCP_THIS, true);
-
- // update rectangle to which RSUB, RSUP, LSUB, LSUP
- // will be aligned to
- if (eSubSup == CSUB || eSubSup == CSUP)
- aTmpRect = *this;
- }
-}
-
-void SmSubSupNode::CreateTextFromNode(String &rText)
-{
- SmNode *pNode;
- GetSubNode(0)->CreateTextFromNode(rText);
-
- if (NULL != (pNode = GetSubNode(LSUB+1)))
- {
- APPEND(rText,"lsub ");
- pNode->CreateTextFromNode(rText);
- }
- if (NULL != (pNode = GetSubNode(LSUP+1)))
- {
- APPEND(rText,"lsup ");
- pNode->CreateTextFromNode(rText);
- }
- if (NULL != (pNode = GetSubNode(CSUB+1)))
- {
- APPEND(rText,"csub ");
- pNode->CreateTextFromNode(rText);
- }
- if (NULL != (pNode = GetSubNode(CSUP+1)))
- {
- APPEND(rText,"csup ");
- pNode->CreateTextFromNode(rText);
- }
- if (NULL != (pNode = GetSubNode(RSUB+1)))
- {
- rText.EraseTrailingChars();
- rText.Append('_');
- pNode->CreateTextFromNode(rText);
- }
- if (NULL != (pNode = GetSubNode(RSUP+1)))
- {
- rText.EraseTrailingChars();
- rText.Append('^');
- pNode->CreateTextFromNode(rText);
- }
-}
-
-
-/**************************************************************************/
-
-void SmBraceNode::CreateTextFromNode(String &rText)
-{
- if (GetScaleMode() == SCALE_HEIGHT)
- APPEND(rText,"left ");
- {
- String aStr;
- GetSubNode(0)->CreateTextFromNode(aStr);
- aStr.EraseLeadingAndTrailingChars();
- aStr.EraseLeadingChars('\\');
- if (aStr.Len())
- {
- if (aStr.EqualsAscii("divides"))
- APPEND(rText,"lline");
- else if (aStr.EqualsAscii("parallel"))
- APPEND(rText,"ldline");
- else if (aStr.EqualsAscii("<"))
- APPEND(rText,"langle");
- else
- rText.Append(aStr);
- rText.Append(' ');
- }
- else
- APPEND(rText,"none ");
- }
- GetSubNode(1)->CreateTextFromNode(rText);
- if (GetScaleMode() == SCALE_HEIGHT)
- APPEND(rText,"right ");
- {
- String aStr;
- GetSubNode(2)->CreateTextFromNode(aStr);
- aStr.EraseLeadingAndTrailingChars();
- aStr.EraseLeadingChars('\\');
- if (aStr.Len())
- {
- if (aStr.EqualsAscii("divides"))
- APPEND(rText,"rline");
- else if (aStr.EqualsAscii("parallel"))
- APPEND(rText,"rdline");
- else if (aStr.EqualsAscii(">"))
- APPEND(rText,"rangle");
- else
- rText.Append(aStr);
- rText.Append(' ');
- }
- else
- APPEND(rText,"none ");
- }
- rText.Append(' ');
-
-}
-
-void SmBraceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pLeft = GetSubNode(0),
- *pBody = GetSubNode(1),
- *pRight = GetSubNode(2);
- OSL_ENSURE(pLeft, "Sm: NULL pointer");
- OSL_ENSURE(pBody, "Sm: NULL pointer");
- OSL_ENSURE(pRight, "Sm: NULL pointer");
-
- pBody->Arrange(rDev, rFormat);
-
- bool bIsScaleNormal = rFormat.IsScaleNormalBrackets(),
- bScale = pBody->GetHeight() > 0 &&
- (GetScaleMode() == SCALE_HEIGHT || bIsScaleNormal),
- bIsABS = GetToken().eType == TABS;
-
- long nFaceHeight = GetFont().GetSize().Height();
-
- // Uebergroesse in % ermitteln
- sal_uInt16 nPerc = 0;
- if (!bIsABS && bScale)
- { // im Fall von Klammern mit Uebergroesse...
- sal_uInt16 nIndex = GetScaleMode() == SCALE_HEIGHT ?
- DIS_BRACKETSIZE : DIS_NORMALBRACKETSIZE;
- nPerc = rFormat.GetDistance(nIndex);
- }
-
- // ermitteln der Hoehe fuer die Klammern
- long nBraceHeight;
- if (bScale)
- {
- nBraceHeight = pBody->GetType() == NBRACEBODY ?
- ((SmBracebodyNode *) pBody)->GetBodyHeight()
- : pBody->GetHeight();
- nBraceHeight += 2 * (nBraceHeight * nPerc / 100L);
- }
- else
- nBraceHeight = nFaceHeight;
-
- // Abstand zum Argument
- nPerc = bIsABS ? 0 : rFormat.GetDistance(DIS_BRACKETSPACE);
- long nDist = nFaceHeight * nPerc / 100L;
-
- // sofern erwuenscht skalieren der Klammern auf die gewuenschte Groesse
- if (bScale)
- {
- Size aTmpSize (pLeft->GetFont().GetSize());
- OSL_ENSURE(pRight->GetFont().GetSize() == aTmpSize,
- "Sm : different font sizes");
- aTmpSize.Width() = Min((long) nBraceHeight * 60L / 100L,
- rFormat.GetBaseSize().Height() * 3L / 2L);
- // correction factor since change from StarMath to OpenSymbol font
- // because of the different font width in the FontMetric
- aTmpSize.Width() *= 182;
- aTmpSize.Width() /= 267;
-
- xub_Unicode cChar = pLeft->GetToken().cMathChar;
- if (cChar != MS_LINE && cChar != MS_DLINE)
- pLeft ->GetFont().SetSize(aTmpSize);
-
- cChar = pRight->GetToken().cMathChar;
- if (cChar != MS_LINE && cChar != MS_DLINE)
- pRight->GetFont().SetSize(aTmpSize);
-
- pLeft ->AdaptToY(rDev, nBraceHeight);
- pRight->AdaptToY(rDev, nBraceHeight);
- }
-
- pLeft ->Arrange(rDev, rFormat);
- pRight->Arrange(rDev, rFormat);
-
- // damit auch "\(a\) - (a) - left ( a right )" vernuenftig aussieht
- RectVerAlign eVerAlign = bScale ? RVA_CENTERY : RVA_BASELINE;
-
- Point aPos;
- aPos = pLeft->AlignTo(*pBody, RP_LEFT, RHA_CENTER, eVerAlign);
- aPos.X() -= nDist;
- pLeft->MoveTo(aPos);
-
- aPos = pRight->AlignTo(*pBody, RP_RIGHT, RHA_CENTER, eVerAlign);
- aPos.X() += nDist;
- pRight->MoveTo(aPos);
-
- SmRect::operator = (*pBody);
- ExtendBy(*pLeft, RCP_THIS).ExtendBy(*pRight, RCP_THIS);
-}
-
-
-/**************************************************************************/
-
-
-void SmBracebodyNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- sal_uInt16 nNumSubNodes = GetNumSubNodes();
- if (nNumSubNodes == 0)
- return;
-
- // arrange arguments
- sal_uInt16 i;
- for (i = 0; i < nNumSubNodes; i += 2)
- GetSubNode(i)->Arrange(rDev, rFormat);
-
- // build reference rectangle with necessary info for vertical alignment
- SmRect aRefRect (*GetSubNode(0));
- for (i = 0; i < nNumSubNodes; i += 2)
- {
- SmRect aTmpRect (*GetSubNode(i));
- Point aPos = aTmpRect.AlignTo(aRefRect, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
- aTmpRect.MoveTo(aPos);
- aRefRect.ExtendBy(aTmpRect, RCP_XOR);
- }
-
- nBodyHeight = aRefRect.GetHeight();
-
- // scale separators to required height and arrange them
- bool bScale = GetScaleMode() == SCALE_HEIGHT || rFormat.IsScaleNormalBrackets();
- long nHeight = bScale ? aRefRect.GetHeight() : GetFont().GetSize().Height();
- sal_uInt16 nIndex = GetScaleMode() == SCALE_HEIGHT ?
- DIS_BRACKETSIZE : DIS_NORMALBRACKETSIZE;
- sal_uInt16 nPerc = rFormat.GetDistance(nIndex);
- if (bScale)
- nHeight += 2 * (nHeight * nPerc / 100L);
- for (i = 1; i < nNumSubNodes; i += 2)
- {
- SmNode *pNode = GetSubNode(i);
- pNode->AdaptToY(rDev, nHeight);
- pNode->Arrange(rDev, rFormat);
- }
-
- // horizontal distance between argument and brackets or separators
- long nDist = GetFont().GetSize().Height()
- * rFormat.GetDistance(DIS_BRACKETSPACE) / 100L;
-
- SmNode *pLeft = GetSubNode(0);
- SmRect::operator = (*pLeft);
- for (i = 1; i < nNumSubNodes; i++)
- {
- bool bIsSeparator = i % 2 != 0;
- RectVerAlign eVerAlign = bIsSeparator ? RVA_CENTERY : RVA_BASELINE;
-
- SmNode *pRight = GetSubNode(i);
- Point aPosX = pRight->AlignTo(*pLeft, RP_RIGHT, RHA_CENTER, eVerAlign),
- aPosY = pRight->AlignTo(aRefRect, RP_RIGHT, RHA_CENTER, eVerAlign);
- aPosX.X() += nDist;
-
- pRight->MoveTo(Point(aPosX.X(), aPosY.Y()));
- ExtendBy(*pRight, bIsSeparator ? RCP_THIS : RCP_XOR);
-
- pLeft = pRight;
- }
-}
-
-
-/**************************************************************************/
-
-
-void SmVerticalBraceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pBody = GetSubNode(0),
- *pBrace = GetSubNode(1),
- *pScript = GetSubNode(2);
- OSL_ENSURE(pBody, "Sm: NULL pointer!");
- OSL_ENSURE(pBrace, "Sm: NULL pointer!");
- OSL_ENSURE(pScript, "Sm: NULL pointer!");
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- pBody->Arrange(aTmpDev, rFormat);
-
- // Groesse wie bei Grenzen fuer diesen Teil
- pScript->SetSize( Fraction( rFormat.GetRelSize(SIZ_LIMITS), 100 ) );
- // etwas hoehere Klammern als normal
- pBrace ->SetSize( Fraction(3, 2) );
-
- long nItalicWidth = pBody->GetItalicWidth();
- if (nItalicWidth > 0)
- pBrace->AdaptToX(aTmpDev, nItalicWidth);
-
- pBrace ->Arrange(aTmpDev, rFormat);
- pScript->Arrange(aTmpDev, rFormat);
-
- // die relativen Position und die Abstaende zueinander bestimmen
- RectPos eRectPos;
- long nFontHeight = pBody->GetFont().GetSize().Height();
- long nDistBody = nFontHeight * rFormat.GetDistance(DIS_ORNAMENTSIZE),
- nDistScript = nFontHeight;
- if (GetToken().eType == TOVERBRACE)
- {
- eRectPos = RP_TOP;
- nDistBody = - nDistBody;
- nDistScript *= - rFormat.GetDistance(DIS_UPPERLIMIT);
- }
- else // TUNDERBRACE
- {
- eRectPos = RP_BOTTOM;
- nDistScript *= + rFormat.GetDistance(DIS_LOWERLIMIT);
- }
- nDistBody /= 100L;
- nDistScript /= 100L;
-
- Point aPos = pBrace->AlignTo(*pBody, eRectPos, RHA_CENTER, RVA_BASELINE);
- aPos.Y() += nDistBody;
- pBrace->MoveTo(aPos);
-
- aPos = pScript->AlignTo(*pBrace, eRectPos, RHA_CENTER, RVA_BASELINE);
- aPos.Y() += nDistScript;
- pScript->MoveTo(aPos);
-
- SmRect::operator = (*pBody);
- ExtendBy(*pBrace, RCP_THIS).ExtendBy(*pScript, RCP_THIS);
-}
-
-
-/**************************************************************************/
-
-
-SmNode * SmOperNode::GetSymbol()
-{
- SmNode *pNode = GetSubNode(0);
- OSL_ENSURE(pNode, "Sm: NULL pointer!");
-
- if (pNode->GetType() == NSUBSUP)
- pNode = ((SmSubSupNode *) pNode)->GetBody();
-
- OSL_ENSURE(pNode, "Sm: NULL pointer!");
- return pNode;
-}
-
-
-long SmOperNode::CalcSymbolHeight(const SmNode &rSymbol,
- const SmFormat &rFormat) const
- // returns the font height to be used for operator-symbol
-{
- long nHeight = GetFont().GetSize().Height();
-
- SmTokenType eTmpType = GetToken().eType;
- if (eTmpType == TLIM || eTmpType == TLIMINF || eTmpType == TLIMSUP)
- return nHeight;
-
- if (!rFormat.IsTextmode())
- {
- // set minimum size ()
- nHeight += (nHeight * 20L) / 100L;
-
- nHeight += nHeight
- * rFormat.GetDistance(DIS_OPERATORSIZE) / 100L;
- nHeight = nHeight * 686L / 845L;
- }
-
- // correct user-defined symbols to match height of sum from used font
- if (rSymbol.GetToken().eType == TSPECIAL)
- nHeight = nHeight * 845L / 686L;
-
- return nHeight;
-}
-
-
-void SmOperNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pOper = GetSubNode(0);
- SmNode *pBody = GetSubNode(1);
-
- OSL_ENSURE(pOper, "Sm: missing subnode");
- OSL_ENSURE(pBody, "Sm: missing subnode");
-
- SmNode *pSymbol = GetSymbol();
- pSymbol->SetSize(Fraction(CalcSymbolHeight(*pSymbol, rFormat),
- pSymbol->GetFont().GetSize().Height()));
-
- pBody->Arrange(rDev, rFormat);
- pOper->Arrange(rDev, rFormat);
-
- long nOrigHeight = GetFont().GetSize().Height(),
- nDist = nOrigHeight
- * rFormat.GetDistance(DIS_OPERATORSPACE) / 100L;
-
- Point aPos = pOper->AlignTo(*pBody, RP_LEFT, RHA_CENTER, /*RVA_CENTERY*/RVA_MID);
- aPos.X() -= nDist;
- pOper->MoveTo(aPos);
-
- SmRect::operator = (*pBody);
- ExtendBy(*pOper, RCP_THIS);
-}
-
-
-/**************************************************************************/
-
-
-void SmAlignNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
- // setzt im ganzen subtree (incl aktuellem node) das alignment
-{
- OSL_ENSURE(GetNumSubNodes() > 0, "Sm: missing subnode");
-
- SmNode *pNode = GetSubNode(0);
-
- RectHorAlign eHorAlign = RHA_CENTER;
- switch (GetToken().eType)
- {
- case TALIGNL: eHorAlign = RHA_LEFT; break;
- case TALIGNC: eHorAlign = RHA_CENTER; break;
- case TALIGNR: eHorAlign = RHA_RIGHT; break;
- default:
- break;
- }
- SetRectHorAlign(eHorAlign);
-
- pNode->Arrange(rDev, rFormat);
-
- SmRect::operator = (pNode->GetRect());
-}
-
-
-/**************************************************************************/
-
-
-void SmAttributNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pAttr = GetSubNode(0),
- *pBody = GetSubNode(1);
- OSL_ENSURE(pBody, "Sm: body missing");
- OSL_ENSURE(pAttr, "Sm: attribute missing");
-
- pBody->Arrange(rDev, rFormat);
-
- if (GetScaleMode() == SCALE_WIDTH)
- pAttr->AdaptToX(rDev, pBody->GetItalicWidth());
- pAttr->Arrange(rDev, rFormat);
-
- // get relative position of attribut
- RectVerAlign eVerAlign;
- long nDist = 0;
- switch (GetToken().eType)
- { case TUNDERLINE :
- eVerAlign = RVA_ATTRIBUT_LO;
- break;
- case TOVERSTRIKE :
- eVerAlign = RVA_ATTRIBUT_MID;
- break;
- default :
- eVerAlign = RVA_ATTRIBUT_HI;
- if (pBody->GetType() == NATTRIBUT)
- nDist = GetFont().GetSize().Height()
- * rFormat.GetDistance(DIS_ORNAMENTSPACE) / 100L;
- }
- Point aPos = pAttr->AlignTo(*pBody, RP_ATTRIBUT, RHA_CENTER, eVerAlign);
- aPos.Y() -= nDist;
- pAttr->MoveTo(aPos);
-
- SmRect::operator = (*pBody);
- ExtendBy(*pAttr, RCP_THIS, true);
-}
-
-
-/**************************************************************************/
-
-
-
-
-void SmFontNode::CreateTextFromNode(String &rText)
-{
- switch (GetToken().eType)
- {
- case TBOLD:
- APPEND(rText,"bold ");
- break;
- case TNBOLD:
- APPEND(rText,"nbold ");
- break;
- case TITALIC:
- APPEND(rText,"italic ");
- break;
- case TNITALIC:
- APPEND(rText,"nitalic ");
- break;
- case TPHANTOM:
- APPEND(rText,"phantom ");
- break;
- case TSIZE:
- {
- APPEND(rText,"size ");
- switch (nSizeType)
- {
- case FNTSIZ_PLUS:
- rText.Append('+');
- break;
- case FNTSIZ_MINUS:
- rText.Append('-');
- break;
- case FNTSIZ_MULTIPLY:
- rText.Append('*');
- break;
- case FNTSIZ_DIVIDE:
- rText.Append('/');
- break;
- case FNTSIZ_ABSOLUT:
- default:
- break;
- }
- rText += String( ::rtl::math::doubleToUString(
- static_cast<double>(aFontSize),
- rtl_math_StringFormat_Automatic,
- rtl_math_DecimalPlaces_Max, '.', sal_True));
- rText.Append(' ');
- }
- break;
- case TBLACK:
- APPEND(rText,"color black ");
- break;
- case TWHITE:
- APPEND(rText,"color white ");
- break;
- case TRED:
- APPEND(rText,"color red ");
- break;
- case TGREEN:
- APPEND(rText,"color green ");
- break;
- case TBLUE:
- APPEND(rText,"color blue ");
- break;
- case TCYAN:
- APPEND(rText,"color cyan ");
- break;
- case TMAGENTA:
- APPEND(rText,"color magenta ");
- break;
- case TYELLOW:
- APPEND(rText,"color yellow ");
- break;
- case TSANS:
- APPEND(rText,"font sans ");
- break;
- case TSERIF:
- APPEND(rText,"font serif ");
- break;
- case TFIXED:
- APPEND(rText,"font fixed ");
- break;
- default:
- break;
- }
- GetSubNode(1)->CreateTextFromNode(rText);
-}
-
-
-void SmFontNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- //! prepare subnodes first
- SmNode::Prepare(rFormat, rDocShell);
-
- int nFnt = -1;
- switch (GetToken().eType)
- {
- case TFIXED: nFnt = FNT_FIXED; break;
- case TSANS: nFnt = FNT_SANS; break;
- case TSERIF: nFnt = FNT_SERIF; break;
- default:
- break;
- }
- if (nFnt != -1)
- { GetFont() = rFormat.GetFont( sal::static_int_cast< sal_uInt16 >(nFnt) );
- SetFont(GetFont());
- }
-
- //! prevent overwrites of this font by 'Arrange' or 'SetFont' calls of
- //! other font nodes (those with lower depth in the tree)
- Flags() |= FLG_FONT;
-}
-
-
-void SmFontNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmNode *pNode = GetSubNode(1);
- OSL_ENSURE(pNode, "Sm: missing subnode");
-
- switch (GetToken().eType)
- { case TSIZE :
- pNode->SetFontSize(aFontSize, nSizeType);
- break;
- case TSANS :
- case TSERIF :
- case TFIXED :
- pNode->SetFont(GetFont());
- break;
- case TUNKNOWN : break; // no assertion on "font <?> <?>"
-
- case TPHANTOM : SetPhantom(true); break;
- case TBOLD : SetAttribut(ATTR_BOLD); break;
- case TITALIC : SetAttribut(ATTR_ITALIC); break;
- case TNBOLD : ClearAttribut(ATTR_BOLD); break;
- case TNITALIC : ClearAttribut(ATTR_ITALIC); break;
-
- case TBLACK : SetColor(Color(COL_BLACK)); break;
- case TWHITE : SetColor(Color(COL_WHITE)); break;
- case TRED : SetColor(Color(COL_RED)); break;
- case TGREEN : SetColor(Color(COL_GREEN)); break;
- case TBLUE : SetColor(Color(COL_BLUE)); break;
- case TCYAN : SetColor(Color(COL_CYAN)); break;
- case TMAGENTA : SetColor(Color(COL_MAGENTA)); break;
- case TYELLOW : SetColor(Color(COL_YELLOW)); break;
-
- default:
- OSL_FAIL("Sm: unknown case");
- }
-
- pNode->Arrange(rDev, rFormat);
-
- SmRect::operator = (pNode->GetRect());
-}
-
-
-void SmFontNode::SetSizeParameter(const Fraction& rValue, sal_uInt16 Type)
-{
- nSizeType = Type;
- aFontSize = rValue;
-}
-
-
-/**************************************************************************/
-
-
-SmPolyLineNode::SmPolyLineNode(const SmToken &rNodeToken)
-: SmGraphicNode(NPOLYLINE, rNodeToken)
-{
- aPoly.SetSize(2);
- nWidth = 0;
-}
-
-
-void SmPolyLineNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nNewWidth)
-{
- aToSize.Width() = nNewWidth;
-}
-
-
-void SmPolyLineNode::AdaptToY(const OutputDevice &/*rDev*/, sal_uLong nNewHeight)
-{
- GetFont().FreezeBorderWidth();
- aToSize.Height() = nNewHeight;
-}
-
-
-void SmPolyLineNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- //! some routines being called extract some info from the OutputDevice's
- //! font (eg the space to be used for borders OR the font name(!!)).
- //! Thus the font should reflect the needs and has to be set!
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- long nBorderwidth = GetFont().GetBorderWidth();
-
- //
- // Das Polygon mit den beiden Endpunkten bilden
- //
- OSL_ENSURE(aPoly.GetSize() == 2, "Sm : wrong number of points");
- Point aPointA, aPointB;
- if (GetToken().eType == TWIDESLASH)
- {
- aPointA.X() = nBorderwidth;
- aPointA.Y() = aToSize.Height() - nBorderwidth;
- aPointB.X() = aToSize.Width() - nBorderwidth;
- aPointB.Y() = nBorderwidth;
- }
- else
- {
- OSL_ENSURE(GetToken().eType == TWIDEBACKSLASH, "Sm : unexpected token");
- aPointA.X() =
- aPointA.Y() = nBorderwidth;
- aPointB.X() = aToSize.Width() - nBorderwidth;
- aPointB.Y() = aToSize.Height() - nBorderwidth;
- }
- aPoly.SetPoint(aPointA, 0);
- aPoly.SetPoint(aPointB, 1);
-
- long nThick = GetFont().GetSize().Height()
- * rFormat.GetDistance(DIS_STROKEWIDTH) / 100L;
- nWidth = nThick + 2 * nBorderwidth;
-
- SmRect::operator = (SmRect(aToSize.Width(), aToSize.Height()));
-}
-
-
-/**************************************************************************/
-
-void SmRootSymbolNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth)
-{
- nBodyWidth = nWidth;
-}
-
-
-void SmRootSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
-{
- // etwas extra Laenge damit der horizontale Balken spaeter ueber dem
- // Argument positioniert ist
- SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / 10L);
-}
-
-
-/**************************************************************************/
-
-
-void SmRectangleNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth)
-{
- aToSize.Width() = nWidth;
-}
-
-
-void SmRectangleNode::AdaptToY(const OutputDevice &/*rDev*/, sal_uLong nHeight)
-{
- GetFont().FreezeBorderWidth();
- aToSize.Height() = nHeight;
-}
-
-
-void SmRectangleNode::Arrange(const OutputDevice &rDev, const SmFormat &/*rFormat*/)
-{
- long nFontHeight = GetFont().GetSize().Height();
- long nWidth = aToSize.Width(),
- nHeight = aToSize.Height();
- if (nHeight == 0)
- nHeight = nFontHeight / 30;
- if (nWidth == 0)
- nWidth = nFontHeight / 3;
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- // add some borderspace
- sal_uLong nTmpBorderWidth = GetFont().GetBorderWidth();
- nHeight += 2 * nTmpBorderWidth;
-
- //! use this method in order to have 'SmRect::HasAlignInfo() == true'
- //! and thus having the attribut-fences updated in 'SmRect::ExtendBy'
- SmRect::operator = (SmRect(nWidth, nHeight));
-}
-
-
-/**************************************************************************/
-
-
-SmTextNode::SmTextNode( SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 nFontDescP ) :
- SmVisibleNode(eNodeType, rNodeToken)
-{
- nFontDesc = nFontDescP;
-}
-
-
-SmTextNode::SmTextNode( const SmToken &rNodeToken, sal_uInt16 nFontDescP ) :
- SmVisibleNode(NTEXT, rNodeToken)
-{
- nFontDesc = nFontDescP;
-}
-
-
-void SmTextNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- SmNode::Prepare(rFormat, rDocShell);
-
- // default setting for horizontal alignment of nodes with TTEXT
- // content is as alignl (cannot be done in Arrange since it would
- // override the settings made by an SmAlignNode before)
- if (TTEXT == GetToken().eType)
- SetRectHorAlign( RHA_LEFT );
-
- aText = GetToken().aText;
- GetFont() = rFormat.GetFont(GetFontDesc());
-
- if (IsItalic( GetFont() ))
- Attributes() |= ATTR_ITALIC;
- if (IsBold( GetFont() ))
- Attributes() |= ATTR_BOLD;
-
- // special handling for ':' where it is a token on it's own and is likely
- // to be used for mathematical notations. (E.g. a:b = 2:3)
- // In that case it should not be displayed in italic.
- if (GetToken().aText.Len() == 1 && GetToken().aText.GetChar(0) == ':')
- Attributes() &= ~ATTR_ITALIC;
-};
-
-
-void SmTextNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- PrepareAttributes();
-
- sal_uInt16 nSizeDesc = GetFontDesc() == FNT_FUNCTION ?
- SIZ_FUNCTION : SIZ_TEXT;
- GetFont() *= Fraction (rFormat.GetRelSize(nSizeDesc), 100);
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- SmRect::operator = (SmRect(aTmpDev, &rFormat, aText, GetFont().GetBorderWidth()));
-}
-
-void SmTextNode::CreateTextFromNode(String &rText)
-{
- bool bQuoted=false;
- if (GetToken().eType == TTEXT)
- {
- rText.Append('\"');
- bQuoted=true;
- }
- else
- {
- SmParser aParseTest;
- SmNode *pTable = aParseTest.Parse(GetToken().aText);
- bQuoted=true;
- if ( (pTable->GetType() == NTABLE) && (pTable->GetNumSubNodes() == 1) )
- {
- SmNode *pResult = pTable->GetSubNode(0);
- if ( (pResult->GetType() == NLINE) &&
- (pResult->GetNumSubNodes() == 1) )
- {
- pResult = pResult->GetSubNode(0);
- if ( (pResult->GetType() == NEXPRESSION) &&
- (pResult->GetNumSubNodes() == 1) )
- {
- pResult = pResult->GetSubNode(0);
- if (pResult->GetType() == NTEXT)
- bQuoted=false;
- }
- }
- }
- delete pTable;
-
- if ((GetToken().eType == TIDENT) && (GetFontDesc() == FNT_FUNCTION))
- {
- //Search for existing functions and remove extraenous keyword
- APPEND(rText,"func ");
- }
- else if (bQuoted)
- APPEND(rText,"italic ");
-
- if (bQuoted)
- rText.Append('\"');
-
- }
-
- rText.Append(GetToken().aText);
-
- if (bQuoted)
- rText.Append('\"');
- rText.Append(' ');
-}
-
-
-void SmTextNode::GetAccessibleText( String &rText ) const
-{
- rText += aText;
-}
-
-void SmTextNode::AdjustFontDesc()
-{
- if (GetToken().eType == TTEXT)
- nFontDesc = FNT_TEXT;
- else if(GetToken().eType == TFUNC)
- nFontDesc = FNT_FUNCTION;
- else {
- SmTokenType nTok;
- const SmTokenTableEntry *pEntry = SmParser::GetTokenTableEntry( aText );
- if (pEntry && pEntry->nGroup == TGFUNCTION) {
- nTok = pEntry->eType;
- nFontDesc = FNT_FUNCTION;
- } else {
- sal_Unicode firstChar = aText.GetChar(0);
- if( ('0' <= firstChar && firstChar <= '9') || firstChar == '.' || firstChar == ',') {
- nFontDesc = FNT_NUMBER;
- nTok = TNUMBER;
- } else if (aText.Len() > 1) {
- nFontDesc = FNT_VARIABLE;
- nTok = TIDENT;
- } else {
- nFontDesc = FNT_VARIABLE;
- nTok = TCHARACTER;
- }
- }
- SmToken tok = GetToken();
- tok.eType = nTok;
- SetToken(tok);
- }
-}
-
-/**************************************************************************/
-
-void SmMatrixNode::CreateTextFromNode(String &rText)
-{
- APPEND(rText,"matrix {");
- for (sal_uInt16 i = 0; i < nNumRows; i++)
- {
- for (sal_uInt16 j = 0; j < nNumCols; j++)
- {
- SmNode *pNode = GetSubNode(i * nNumCols + j);
- pNode->CreateTextFromNode(rText);
- if (j != nNumCols-1)
- APPEND(rText,"# ");
- }
- if (i != nNumRows-1)
- APPEND(rText,"## ");
- }
- rText.EraseTrailingChars();
- APPEND(rText,"} ");
-}
-
-
-void SmMatrixNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- Point aPosition,
- aOffset;
- SmNode *pNode;
- sal_uInt16 i, j;
-
- // initialize array that is to hold the maximum widhts of all
- // elements (subnodes) in that column.
- long *pColWidth = new long[nNumCols];
- for (j = 0; j < nNumCols; j++)
- pColWidth[j] = 0;
-
- // arrange subnodes and calculate the aboves arrays contents
- sal_uInt16 nNodes = GetNumSubNodes();
- for (i = 0; i < nNodes; i++)
- {
- sal_uInt16 nIdx = nNodes - 1 - i;
- if (NULL != (pNode = GetSubNode(nIdx)))
- {
- pNode->Arrange(rDev, rFormat);
- int nCol = nIdx % nNumCols;
- pColWidth[nCol] = Max(pColWidth[nCol], pNode->GetItalicWidth());
- }
- }
-
- // norm distance from which the following two are calcutated
- const int nNormDist = 3 * GetFont().GetSize().Height();
-
- // define horizontal and vertical minimal distances that seperate
- // the elements
- long nHorDist = nNormDist * rFormat.GetDistance(DIS_MATRIXCOL) / 100L,
- nVerDist = nNormDist * rFormat.GetDistance(DIS_MATRIXROW) / 100L;
-
- // build array that holds the leftmost position for each column
- long *pColLeft = new long[nNumCols];
- long nX = 0;
- for (j = 0; j < nNumCols; j++)
- { pColLeft[j] = nX;
- nX += pColWidth[j] + nHorDist;
- }
-
- Point aPos, aDelta;
- SmRect aLineRect;
- SmRect::operator = (SmRect());
- for (i = 0; i < nNumRows; i++)
- { aLineRect = SmRect();
- for (j = 0; j < nNumCols; j++)
- { SmNode *pTmpNode = GetSubNode(i * nNumCols + j);
- OSL_ENSURE(pTmpNode, "Sm: NULL pointer");
-
- const SmRect &rNodeRect = pTmpNode->GetRect();
-
- // align all baselines in that row if possible
- aPos = rNodeRect.AlignTo(aLineRect, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
- aPos.X() += nHorDist;
-
- // get horizontal alignment
- const SmNode *pCoNode = pTmpNode->GetLeftMost();
- RectHorAlign eHorAlign = pCoNode->GetRectHorAlign();
-
- // caculate horizontal position of element depending on column
- // and horizontal alignment
- switch (eHorAlign)
- { case RHA_LEFT:
- aPos.X() = rNodeRect.GetLeft() + pColLeft[j];
- break;
- case RHA_CENTER:
- aPos.X() = rNodeRect.GetLeft() + pColLeft[j]
- + pColWidth[j] / 2
- - rNodeRect.GetItalicCenterX();
- break;
- case RHA_RIGHT:
- aPos.X() = rNodeRect.GetLeft() + pColLeft[j]
- + pColWidth[j] - rNodeRect.GetItalicWidth();
- break;
- }
-
- pTmpNode->MoveTo(aPos);
- aLineRect.ExtendBy(rNodeRect, RCP_XOR);
- }
-
- aPos = aLineRect.AlignTo(*this, RP_BOTTOM, RHA_CENTER, RVA_BASELINE);
- aPos.Y() += nVerDist;
-
- // move 'aLineRect' and rectangles in that line to final position
- aDelta.X() = 0; // since horizontal alignment is already done
- aDelta.Y() = aPos.Y() - aLineRect.GetTop();
- aLineRect.Move(aDelta);
- for (j = 0; j < nNumCols; j++)
- if (NULL != (pNode = GetSubNode(i * nNumCols + j)))
- pNode->Move(aDelta);
-
- ExtendBy(aLineRect, RCP_NONE);
- }
-
- delete [] pColLeft;
- delete [] pColWidth;
-}
-
-
-void SmMatrixNode::SetRowCol(sal_uInt16 nMatrixRows, sal_uInt16 nMatrixCols)
-{
- nNumRows = nMatrixRows;
- nNumCols = nMatrixCols;
-}
-
-
-SmNode * SmMatrixNode::GetLeftMost()
-{
- return this;
-}
-
-
-/**************************************************************************/
-
-
-SmMathSymbolNode::SmMathSymbolNode(const SmToken &rNodeToken)
-: SmSpecialNode(NMATH, rNodeToken, FNT_MATH)
-{
- xub_Unicode cChar = GetToken().cMathChar;
- if ((xub_Unicode) '\0' != cChar)
- SetText( cChar );
-}
-
-void SmMathSymbolNode::AdaptToX(const OutputDevice &rDev, sal_uLong nWidth)
-{
- // Since there is no function to do this, we try to approximate it:
- Size aFntSize (GetFont().GetSize());
-
- //! however the result is a bit better with 'nWidth' as initial font width
- aFntSize.Width() = nWidth;
- GetFont().SetSize(aFntSize);
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- // get denominator of error factor for width
- long nTmpBorderWidth = GetFont().GetBorderWidth();
- long nDenom = SmRect(aTmpDev, NULL, GetText(), nTmpBorderWidth).GetItalicWidth();
-
- // scale fontwidth with this error factor
- aFntSize.Width() *= nWidth;
- aFntSize.Width() /= nDenom ? nDenom : 1;
-
- GetFont().SetSize(aFntSize);
-}
-
-void SmMathSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
-{
- GetFont().FreezeBorderWidth();
- Size aFntSize (GetFont().GetSize());
-
- // da wir nur die Hoehe skalieren wollen muesen wir hier ggf die Fontweite
- // ermitteln um diese beizubehalten.
- if (aFntSize.Width() == 0)
- {
- OutputDevice &rDevNC = (OutputDevice &) rDev;
- rDevNC.Push(PUSH_FONT | PUSH_MAPMODE);
- rDevNC.SetFont(GetFont());
- aFntSize.Width() = rDev.GetFontMetric().GetSize().Width();
- rDevNC.Pop();
- }
- OSL_ENSURE(aFntSize.Width() != 0, "Sm: ");
-
- //! however the result is a bit better with 'nHeight' as initial
- //! font height
- aFntSize.Height() = nHeight;
- GetFont().SetSize(aFntSize);
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- // get denominator of error factor for height
- long nTmpBorderWidth = GetFont().GetBorderWidth();
- long nDenom = SmRect(aTmpDev, NULL, GetText(), nTmpBorderWidth).GetHeight();
-
- // scale fontwidth with this error factor
- aFntSize.Height() *= nHeight;
- aFntSize.Height() /= nDenom ? nDenom : 1;
-
- GetFont().SetSize(aFntSize);
-}
-
-
-void SmMathSymbolNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- SmNode::Prepare(rFormat, rDocShell);
-
- GetFont() = rFormat.GetFont(GetFontDesc());
- // use same font size as is used for variables
- GetFont().SetSize( rFormat.GetFont( FNT_VARIABLE ).GetSize() );
-
- OSL_ENSURE(GetFont().GetCharSet() == RTL_TEXTENCODING_SYMBOL ||
- GetFont().GetCharSet() == RTL_TEXTENCODING_UNICODE,
- "wrong charset for character from StarMath/OpenSymbol font");
-
- Flags() |= FLG_FONT | FLG_ITALIC;
-};
-
-
-void SmMathSymbolNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- const XubString &rText = GetText();
-
- if (rText.Len() == 0 || rText.GetChar(0) == xub_Unicode('\0'))
- { SmRect::operator = (SmRect());
- return;
- }
-
- PrepareAttributes();
-
- GetFont() *= Fraction (rFormat.GetRelSize(SIZ_TEXT), 100);
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- SmRect::operator = (SmRect(aTmpDev, &rFormat, rText, GetFont().GetBorderWidth()));
-}
-
-void SmMathSymbolNode::CreateTextFromNode(String &rText)
-{
- String sStr;
- MathType::LookupChar(GetToken().cMathChar, sStr);
- rText.Append(sStr);
-}
-
-void SmRectangleNode::CreateTextFromNode(String &rText)
-{
- switch (GetToken().eType)
- {
- case TUNDERLINE:
- APPEND(rText,"underline ");
- break;
- case TOVERLINE:
- APPEND(rText,"overline ");
- break;
- case TOVERSTRIKE:
- APPEND(rText,"overstrike ");
- break;
- default:
- break;
- }
-}
-
-void SmAttributNode::CreateTextFromNode(String &rText)
-{
- SmNode *pNode;
- sal_uInt16 nSize = GetNumSubNodes();
- OSL_ENSURE(nSize == 2, "Node missing members");
- rText.Append('{');
- sal_Unicode nLast=0;
- if (NULL != (pNode = GetSubNode(0)))
- {
- String aStr;
- pNode->CreateTextFromNode(aStr);
- if (aStr.Len() > 1)
- rText.Append(aStr);
- else
- {
- nLast = aStr.GetChar(0);
- switch (nLast)
- {
- case 0xAF:
- APPEND(rText,"overline ");
- break;
- case 0x2d9:
- APPEND(rText,"dot ");
- break;
- case 0x2dc:
- APPEND(rText,"widetilde ");
- break;
- case 0xA8:
- APPEND(rText,"ddot ");
- break;
- case 0xE082:
- break;
- case 0xE09B:
- APPEND(rText,"dddot ");
- break;
- default:
- rText.Append(nLast);
- break;
- }
- }
- }
-
- if (nSize == 2)
- if (NULL != (pNode = GetSubNode(1)))
- pNode->CreateTextFromNode(rText);
-
- rText.EraseTrailingChars();
-
- if (nLast == 0xE082)
- APPEND(rText," overbrace {}");
-
- APPEND(rText,"} ");
-}
-
-/**************************************************************************/
-
-bool lcl_IsFromGreekSymbolSet( const String &rTokenText )
-{
- bool bRes = false;
-
- // valid symbol name needs to have a '%' at pos 0 and at least an additonal char
- if (rTokenText.Len() > 2 && rTokenText.GetBuffer()[0] == (sal_Unicode)'%')
- {
- String aName( rTokenText.Copy(1) );
- SmSym *pSymbol = SM_MOD()->GetSymbolManager().GetSymbolByName( aName );
- if (pSymbol && GetExportSymbolSetName( pSymbol->GetSymbolSetName() ).EqualsAscii( "Greek" ) )
- bRes = true;
- }
-
- return bRes;
-}
-
-
-SmSpecialNode::SmSpecialNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 _nFontDesc) :
- SmTextNode(eNodeType, rNodeToken, _nFontDesc)
-{
- bIsFromGreekSymbolSet = lcl_IsFromGreekSymbolSet( rNodeToken.aText );
-}
-
-
-SmSpecialNode::SmSpecialNode(const SmToken &rNodeToken) :
- SmTextNode(NSPECIAL, rNodeToken, FNT_MATH) //! default Font nicht immer richtig
-{
- bIsFromGreekSymbolSet = lcl_IsFromGreekSymbolSet( rNodeToken.aText );
-}
-
-
-void SmSpecialNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- SmNode::Prepare(rFormat, rDocShell);
-
- const SmSym *pSym;
- SmModule *pp = SM_MOD();
-
- String aName( GetToken().aText.Copy(1) );
- if (NULL != (pSym = pp->GetSymbolManager().GetSymbolByName( aName )))
- {
- sal_UCS4 cChar = pSym->GetCharacter();
- String aTmp( OUString( &cChar, 1 ) );
- SetText( aTmp );
- GetFont() = pSym->GetFace();
- }
- else
- {
- SetText( GetToken().aText );
- GetFont() = rFormat.GetFont(FNT_VARIABLE);
- }
- // use same font size as is used for variables
- GetFont().SetSize( rFormat.GetFont( FNT_VARIABLE ).GetSize() );
-
- //! eigentlich sollten nur WEIGHT_NORMAL und WEIGHT_BOLD vorkommen...
- //! In der sms-Datei gibt es jedoch zB auch 'WEIGHT_ULTRALIGHT'
- //! daher vergleichen wir hier mit > statt mit != .
- //! (Langfristig sollte die Notwendigkeit fuer 'PrepareAttribut', und damit
- //! fuer dieses hier, mal entfallen.)
- //
- //! see also SmFontStyles::GetStyleName
- if (IsItalic( GetFont() ))
- SetAttribut(ATTR_ITALIC);
- if (IsBold( GetFont() ))
- SetAttribut(ATTR_BOLD);
-
- Flags() |= FLG_FONT;
-
- if (bIsFromGreekSymbolSet)
- {
- OSL_ENSURE( GetText().Len() == 1, "a symbol should only consist of 1 char!" );
- bool bItalic = false;
- sal_Int16 nStyle = rFormat.GetGreekCharStyle();
- OSL_ENSURE( nStyle >= 0 && nStyle <= 2, "unexpected value for GreekCharStyle" );
- if (nStyle == 1)
- bItalic = true;
- else if (nStyle == 2)
- {
- String aTmp( GetText() );
- if (aTmp.Len() > 0)
- {
- const sal_Unicode cUppercaseAlpha = 0x0391;
- const sal_Unicode cUppercaseOmega = 0x03A9;
- sal_Unicode cChar = aTmp.GetBuffer()[0];
- // uppercase letters should be straight and lowercase letters italic
- bItalic = !(cUppercaseAlpha <= cChar && cChar <= cUppercaseOmega);
- }
- }
-
- if (bItalic)
- Attributes() |= ATTR_ITALIC;
- else
- Attributes() &= ~ATTR_ITALIC;;
- }
-};
-
-
-void SmSpecialNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- PrepareAttributes();
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(), GetFont().GetBorderWidth()));
-}
-
-/**************************************************************************/
-
-
-void SmGlyphSpecialNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- PrepareAttributes();
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(),
- GetFont().GetBorderWidth()).AsGlyphRect());
-}
-
-
-/**************************************************************************/
-
-
-void SmPlaceNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- SmNode::Prepare(rFormat, rDocShell);
-
- GetFont().SetColor(COL_GRAY);
- Flags() |= FLG_COLOR | FLG_FONT | FLG_ITALIC;
-};
-
-
-void SmPlaceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- PrepareAttributes();
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(), GetFont().GetBorderWidth()));
-}
-
-
-/**************************************************************************/
-
-
-void SmErrorNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- SmNode::Prepare(rFormat, rDocShell);
-
- GetFont().SetColor(COL_RED);
- Flags() |= FLG_VISIBLE | FLG_BOLD | FLG_ITALIC
- | FLG_COLOR | FLG_FONT | FLG_SIZE;
-}
-
-
-void SmErrorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- PrepareAttributes();
-
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- const XubString &rText = GetText();
- SmRect::operator = (SmRect(aTmpDev, &rFormat, rText, GetFont().GetBorderWidth()));
-}
-
-
-/**************************************************************************/
-
-
-void SmBlankNode::IncreaseBy(const SmToken &rToken)
-{
- switch(rToken.eType)
- {
- case TBLANK: nNum += 4; break;
- case TSBLANK: nNum += 1; break;
- default:
- break;
- }
-}
-
-
-void SmBlankNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
-{
- SmNode::Prepare(rFormat, rDocShell);
-
- //! hier muss/sollte es lediglich nicht der StarMath Font sein,
- //! damit fuer das in Arrange verwendete Zeichen ein "normales"
- //! (ungecliptes) Rechteck erzeugt wird.
- GetFont() = rFormat.GetFont(FNT_VARIABLE);
-
- Flags() |= FLG_FONT | FLG_BOLD | FLG_ITALIC;
-}
-
-
-void SmBlankNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
-{
- SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
- aTmpDev.SetFont(GetFont());
-
- // Abstand von der Fonthoehe abhaengig machen
- // (damit er beim skalieren (zB size *2 {a ~ b}) mitwaechst)
- long nDist = GetFont().GetSize().Height() / 10L,
- nSpace = nNum * nDist;
-
- // ein SmRect mit Baseline und allem drum und dran besorgen
- SmRect::operator = (SmRect(aTmpDev, &rFormat, XubString(xub_Unicode(' ')),
- GetFont().GetBorderWidth()));
-
- // und dieses auf die gewuenschte Breite bringen
- SetItalicSpaces(0, 0);
- SetWidth(nSpace);
-}
-
-/**************************************************************************/
-//Implementation of all accept methods for SmVisitor
-
-void SmNode::Accept(SmVisitor*){
- //This method is only implemented to avoid making SmNode abstract because an
- //obscure copy constructor is used... I can't find it's implementation, and
- //don't want to figure out how to fix it... If you want to, just delete this
- //method, making SmNode abstract, and see where you can an problem with that.
- OSL_FAIL("SmNode should not be visitable!");
-}
-
-void SmTableNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmBraceNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmBracebodyNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmOperNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmAlignNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmAttributNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmFontNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmUnHorNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmBinHorNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmBinVerNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmBinDiagonalNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmSubSupNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmMatrixNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmPlaceNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmTextNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmSpecialNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmGlyphSpecialNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmMathSymbolNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmBlankNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmErrorNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmLineNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmExpressionNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmPolyLineNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmRootNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmRootSymbolNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmRectangleNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-void SmVerticalBraceNode::Accept(SmVisitor* pVisitor) {
- pVisitor->Visit(this);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */