// Copyright (C) 2000-2007, Luca Padovani . // // This file is part of GtkMathView, a flexible, high-quality rendering // engine for MathML documents. // // GtkMathView is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // GtkMathView 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 for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . #include #include #include #include "traverseAux.hh" #include "MathMLElement.hh" #include "MathMLRowElement.hh" #include "MathMLActionElement.hh" #include "MathMLOperatorElement.hh" // the following are needed for the dynamic casts #include "MathMLScriptElement.hh" #include "MathMLUnderOverElement.hh" #include "MathMLFractionElement.hh" #include "MathMLMultiScriptsElement.hh" #include "MathMLStyleElement.hh" #include "MathMLPhantomElement.hh" #include "MathMLPaddedElement.hh" SmartPtr findEmbellishedOperatorRoot(const SmartPtr& op) { SmartPtr root = op; while (root && root->getParent()) { SmartPtr newRoot = root->getParent(); if (newRoot->getCoreOperator() != op) return root; root = newRoot; } return root; } #if 0 SmartPtr findEmbellishedOperatorRoot(const SmartPtr& root) { assert(root); if (!root->getParent()) return root; SmartPtr rootParent = root->getParent(); assert(rootParent); if (is_a(rootParent)) { SmartPtr row = smart_cast(rootParent); assert(row); for (std::vector< SmartPtr >::const_iterator i = row->GetContent().begin(); i != row->GetContent().end(); i++) { SmartPtr elem = *i; assert(elem); if (!elem->IsSpaceLike() && root != elem) return root; } return findEmbellishedOperatorRoot(rootParent); } else if (is_a(rootParent) || is_a(rootParent) || is_a(rootParent) || is_a(rootParent) || is_a(rootParent)) { SmartPtr cont = smart_cast(rootParent); assert(cont); if (cont->GetSize() > 0 && cont->GetChild(0) != root) return root; else return findEmbellishedOperatorRoot(rootParent); } else if (is_a(rootParent) || is_a(rootParent) || is_a(rootParent)) return findEmbellishedOperatorRoot(rootParent); else return root; } #endif SmartPtr findStretchyOperator(const SmartPtr& elem) { if (elem) if (SmartPtr coreOp = elem->getCoreOperator()) if (coreOp->IsStretchy()) return coreOp; return 0; } #if 0 SmartPtr findCommonAncestor(const SmartPtr& first, const SmartPtr& last) { assert(first); assert(last); SmartPtr firstP(first); SmartPtr lastP(last); if (firstP != lastP) { unsigned firstDepth = first->getDepth(); unsigned lastDepth = last->getDepth(); while (firstP && firstDepth > lastDepth) { firstP = firstP->getParent(); firstDepth--; } while (lastP && lastDepth > firstDepth) { lastP = lastP->getParent(); lastDepth--; } assert(firstDepth == lastDepth); while (firstP && lastP && firstP != lastP) { firstP = firstP->getParent(); lastP = lastP->getParent(); } } return firstP; } SmartPtr findActionElement(const SmartPtr& elem) { SmartPtr elemP(elem); while (elemP && !is_a(elemP)) elemP = elemP->getParent(); return (elemP) ? smart_cast(elemP) : SmartPtr(0); } #endif #if defined(HAVE_GMETADOM) #if 0 DOM::Element findDOMNode(const SmartPtr& elem) { SmartPtr elemP(elem); while (elemP && !elemP->getDOMElement()) elemP = smart_cast(elemP->getParent()); if (elemP) return elemP->getDOMElement(); else return DOM::Element(0); } SmartPtr findMathMLElement(const SmartPtr& view, const DOM::Element& node) { if (SmartPtr elem = smart_cast(view->getLinker()->get(node))) { while (SmartPtr row = smart_cast(elem)) { if (row->getSize() != 1) break; elem = row->getChild(0); } return elem; } else return 0; } #endif #endif // HAVE_GMETADOM SmartPtr findRightmostChild(const SmartPtr& elem) { if (SmartPtr row = smart_cast(elem)) { if (row->getSize() == 0) return elem; else return findRightmostChild(row->getChild(row->getSize() - 1)); } else return elem; } SmartPtr findLeftmostChild(const SmartPtr& elem) { if (SmartPtr row = smart_cast(elem)) { if (row->getSize() == 0) return elem; else return findLeftmostChild(row->getChild(0)); } else return elem; } SmartPtr findRightSibling(const SmartPtr& elem) { if (!elem) return 0; else if (SmartPtr row = elem->getParent()) { std::vector< SmartPtr >::const_iterator p = std::find(row->getContent().begin(), row->getContent().end(), elem); assert(p != row->getContent().end()); if (p + 1 != row->getContent().end()) return findLeftmostChild(*(p + 1)); else return findRightSibling(row); } else return findRightSibling(elem->getParent()); } SmartPtr findLeftSibling(const SmartPtr& elem) { if (!elem) return 0; else if (SmartPtr row = elem->getParent()) { std::vector< SmartPtr >::const_iterator p = std::find(row->getContent().begin(), row->getContent().end(), elem); assert(p != row->getContent().end()); if (p != row->getContent().begin()) return findRightmostChild(*(p - 1)); else return findLeftSibling(row); } else return findLeftSibling(elem->getParent()); }