mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-21 23:09:40 +00:00
try to do with super- and subscripts what TeX does
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@2722 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
e670bed4c5
commit
e4c58b72be
@ -1,3 +1,13 @@
|
||||
2001-09-11 André Pönitz <poenitz@gmx.net>
|
||||
|
||||
* math_atom.[Ch]: new basic item in the MathArray
|
||||
|
||||
* array.[Ch]: move code over to math_atom
|
||||
|
||||
* math_scriptinset.[Ch]:
|
||||
math_parser.C:
|
||||
math_cursor.C: try to do with super- and subscripts what TeX does
|
||||
|
||||
2001-09-04 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
|
||||
|
||||
* math_parser.C (tokenize): add a .c_str() (needed with lyxstring)
|
||||
|
@ -20,6 +20,8 @@ libmathed_la_SOURCES = \
|
||||
formulamacro.h \
|
||||
math_arrayinset.C \
|
||||
math_arrayinset.h \
|
||||
math_atom.C \
|
||||
math_atom.h \
|
||||
math_binominset.C \
|
||||
math_binominset.h \
|
||||
math_charinset.C \
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "math_inset.h"
|
||||
#include "math_charinset.h"
|
||||
#include "math_scriptinset.h"
|
||||
#include "debug.h"
|
||||
#include "array.h"
|
||||
#include "mathed/support.h"
|
||||
@ -11,35 +12,14 @@
|
||||
using std::ostream;
|
||||
using std::endl;
|
||||
|
||||
|
||||
MathArray::MathArray()
|
||||
{}
|
||||
|
||||
|
||||
MathArray::~MathArray()
|
||||
{
|
||||
erase();
|
||||
}
|
||||
|
||||
|
||||
MathArray::MathArray(MathArray const & array)
|
||||
: bf_(array.bf_)
|
||||
{
|
||||
deep_copy(begin(), end());
|
||||
}
|
||||
|
||||
|
||||
MathArray::MathArray(MathArray const & array, int from, int to)
|
||||
: bf_(array.begin() + from, array.begin() + to)
|
||||
{
|
||||
deep_copy(begin(), end());
|
||||
}
|
||||
|
||||
|
||||
void MathArray::deep_copy(iterator from, iterator to)
|
||||
{
|
||||
for (iterator it = from; it != to; ++it)
|
||||
*it = (*it)->clone();
|
||||
}
|
||||
{}
|
||||
|
||||
|
||||
int MathArray::last() const
|
||||
@ -52,41 +32,35 @@ void MathArray::substitute(MathMacro const & m)
|
||||
{
|
||||
MathArray tmp;
|
||||
for (iterator it = begin(); it != end(); ++it)
|
||||
(*it)->substitute(tmp, m);
|
||||
it->substitute(tmp, m);
|
||||
swap(tmp);
|
||||
}
|
||||
|
||||
|
||||
MathArray & MathArray::operator=(MathArray const & array)
|
||||
MathAtom * MathArray::at(int pos)
|
||||
{
|
||||
MathArray tmp(array);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
return (0 <= pos && pos < size()) ? &bf_[pos] : 0;
|
||||
}
|
||||
|
||||
|
||||
MathInset * MathArray::nextInset(int pos)
|
||||
MathAtom const * MathArray::at(int pos) const
|
||||
{
|
||||
return (pos == size()) ? 0 : bf_[pos];
|
||||
}
|
||||
|
||||
|
||||
MathInset const * MathArray::nextInset(int pos) const
|
||||
{
|
||||
return (pos == size()) ? 0 : bf_[pos];
|
||||
return (0 <= pos && pos < size()) ? &bf_[pos] : 0;
|
||||
}
|
||||
|
||||
|
||||
void MathArray::insert(int pos, MathInset * p)
|
||||
{
|
||||
bf_.insert(begin() + pos, p);
|
||||
//cerr << "\n 1: "; p->write(cerr, true); cerr << p << "\n";
|
||||
// inserting th
|
||||
bf_.insert(begin() + pos, MathAtom(p));
|
||||
//cerr << "\n 2: "; p->write(cerr, true); cerr << p << "\n";
|
||||
}
|
||||
|
||||
|
||||
void MathArray::insert(int pos, MathArray const & array)
|
||||
{
|
||||
bf_.insert(begin() + pos, array.begin(), array.end());
|
||||
deep_copy(begin() + pos, begin() + pos + array.size());
|
||||
}
|
||||
|
||||
|
||||
@ -142,15 +116,13 @@ void MathArray::erase(int pos)
|
||||
|
||||
void MathArray::erase(int pos1, int pos2)
|
||||
{
|
||||
for (iterator it = begin() + pos1; it != begin() + pos2; ++it)
|
||||
delete *it;
|
||||
bf_.erase(begin() + pos1, begin() + pos2);
|
||||
}
|
||||
|
||||
|
||||
MathInset * MathArray::back() const
|
||||
MathAtom & MathArray::back()
|
||||
{
|
||||
return size() ? bf_.back() : 0;
|
||||
return bf_.back();
|
||||
}
|
||||
|
||||
|
||||
@ -174,19 +146,21 @@ std::ostream & operator<<(std::ostream & os, MathArray const & ar)
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// returns sequence of char with same code starting at it up to end
|
||||
// it might be less, though...
|
||||
string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
|
||||
{
|
||||
string s;
|
||||
MathCharInset const * p = (*it)->asCharInset();
|
||||
MathCharInset const * p = it->nucleus()->asCharInset();
|
||||
if (!p)
|
||||
return s;
|
||||
|
||||
MathTextCodes c = p->code();
|
||||
while (it != end && (p = (*it)->asCharInset()) && p->code() == c) {
|
||||
for (MathTextCodes c = p->code(); it != end; ++it) {
|
||||
p = it->nucleus()->asCharInset();
|
||||
if (!p || it->up() || it->down() || p->code() != c)
|
||||
break;
|
||||
s += p->getChar();
|
||||
++it;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@ -194,18 +168,17 @@ string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
|
||||
|
||||
void MathArray::write(ostream & os, bool fragile) const
|
||||
{
|
||||
for (const_iterator it = begin(); it != end(); ) {
|
||||
MathCharInset const * p = (*it)->asCharInset();
|
||||
if (p) {
|
||||
for (const_iterator it = begin(); it != end(); ++it) {
|
||||
MathCharInset const * p = it->nucleus()->asCharInset();
|
||||
if (p && !it->up() && !it->down()) {
|
||||
// special handling for character sequences with the same code
|
||||
string s = charSequence(it, end());
|
||||
p->writeHeader(os);
|
||||
os << s;
|
||||
p->writeTrailer(os);
|
||||
it += s.size();
|
||||
it += s.size() - 1;
|
||||
} else {
|
||||
(*it)->write(os, fragile);
|
||||
++it;
|
||||
it->write(os, fragile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,7 +198,7 @@ void MathArray::writeNormal(ostream & os) const
|
||||
void MathArray::validate(LaTeXFeatures & features) const
|
||||
{
|
||||
for (const_iterator it = begin(); it != end(); ++it)
|
||||
(*it)->validate(features);
|
||||
it->validate(features);
|
||||
}
|
||||
|
||||
|
||||
@ -235,7 +208,6 @@ void MathArray::pop_back()
|
||||
lyxerr << "pop_back from empty array!\n";
|
||||
return;
|
||||
}
|
||||
delete back();
|
||||
bf_.pop_back();
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <iosfwd>
|
||||
#include "math_atom.h"
|
||||
|
||||
class MathInset;
|
||||
class MathMacro;
|
||||
@ -35,10 +36,11 @@ class LaTeXFeatures;
|
||||
\author Lars Gullik Bjønnes
|
||||
\version February 2001
|
||||
*/
|
||||
|
||||
class MathArray {
|
||||
public:
|
||||
///
|
||||
typedef std::vector<MathInset *> buffer_type;
|
||||
typedef std::vector<MathAtom> buffer_type;
|
||||
///
|
||||
typedef buffer_type::const_iterator const_iterator;
|
||||
///
|
||||
@ -48,13 +50,7 @@ public:
|
||||
///
|
||||
MathArray();
|
||||
///
|
||||
MathArray(MathArray const &);
|
||||
///
|
||||
MathArray(MathArray const &, int from, int to);
|
||||
///
|
||||
MathArray & operator=(MathArray const &);
|
||||
///
|
||||
~MathArray();
|
||||
|
||||
///
|
||||
int size() const;
|
||||
@ -87,7 +83,7 @@ public:
|
||||
///
|
||||
void pop_back();
|
||||
///
|
||||
MathInset * back() const;
|
||||
MathAtom & back();
|
||||
|
||||
///
|
||||
void dump(std::ostream &) const;
|
||||
@ -95,12 +91,11 @@ public:
|
||||
void dump2(std::ostream &) const;
|
||||
///
|
||||
void substitute(MathMacro const &);
|
||||
///
|
||||
|
||||
///
|
||||
MathInset * nextInset(int pos);
|
||||
MathAtom * at(int pos);
|
||||
///
|
||||
MathInset const * nextInset(int pos) const;
|
||||
MathAtom const * at(int pos) const;
|
||||
///
|
||||
void write(std::ostream &, bool) const;
|
||||
///
|
||||
@ -116,8 +111,6 @@ public:
|
||||
///
|
||||
iterator end();
|
||||
private:
|
||||
///
|
||||
void deep_copy(iterator from, iterator to);
|
||||
/// Buffer
|
||||
buffer_type bf_;
|
||||
};
|
||||
|
@ -698,7 +698,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
|
||||
result = FINISHED_RIGHT;
|
||||
}
|
||||
|
||||
mathcursor->normalize();
|
||||
//mathcursor->normalize();
|
||||
|
||||
if (was_macro != mathcursor->inMacroMode()
|
||||
&& action >= 0 && action != LFUN_BACKSPACE)
|
||||
|
376
src/mathed/math_atom.C
Normal file
376
src/mathed/math_atom.C
Normal file
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* File: math_inset.C
|
||||
* Purpose: Implementation of insets for mathed
|
||||
* Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
|
||||
* Created: January 1996
|
||||
* Description:
|
||||
*
|
||||
* Dependencies: Xlib, XForms
|
||||
*
|
||||
* Copyright: 1996, 1997 Alejandro Aguilar Sierra
|
||||
*
|
||||
* Version: 0.8beta.
|
||||
*
|
||||
* You are free to use and modify this code under the terms of
|
||||
* the GNU General Public Licence version 2 or later.
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "math_atom.h"
|
||||
#include "math_scriptinset.h"
|
||||
#include "debug.h"
|
||||
#include "support.h"
|
||||
#include "support/LAssert.h"
|
||||
|
||||
|
||||
MathAtom::MathAtom()
|
||||
: nucleus_(0), limits_(0), xo_(0), yo_(0)
|
||||
{
|
||||
script_[0] = 0;
|
||||
script_[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
MathAtom::MathAtom(MathInset * p)
|
||||
: nucleus_(p), limits_(0), xo_(0), yo_(0)
|
||||
{
|
||||
script_[0] = 0;
|
||||
script_[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MathAtom::MathAtom(MathAtom const & p)
|
||||
{
|
||||
copy(p);
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::operator=(MathAtom const & p)
|
||||
{
|
||||
if (this != &p) {
|
||||
done();
|
||||
copy(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MathAtom::~MathAtom()
|
||||
{
|
||||
done();
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::done()
|
||||
{
|
||||
delete nucleus_;
|
||||
delete script_[0];
|
||||
delete script_[1];
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::copy(MathAtom const & p)
|
||||
{
|
||||
//cerr << "calling MathAtom::copy\n";
|
||||
xo_ = p.xo_;
|
||||
yo_ = p.yo_;
|
||||
limits_ = p.limits_;
|
||||
nucleus_ = p.nucleus_;
|
||||
script_[0] = p.script_[0];
|
||||
script_[1] = p.script_[1];
|
||||
if (nucleus_)
|
||||
nucleus_ = nucleus_->clone();
|
||||
if (script_[0])
|
||||
script_[0] = new MathScriptInset(*script_[0]);
|
||||
if (script_[1])
|
||||
script_[1] = new MathScriptInset(*script_[1]);
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::height() const
|
||||
{
|
||||
return ascent() + descent();
|
||||
}
|
||||
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, MathAtom const & atom)
|
||||
{
|
||||
atom.write(os, false);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::xo() const
|
||||
{
|
||||
return xo_;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::yo() const
|
||||
{
|
||||
return yo_;
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::xo(int x) const
|
||||
{
|
||||
xo_ = x;
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::yo(int y) const
|
||||
{
|
||||
yo_ = y;
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::getXY(int & x, int & y) const
|
||||
{
|
||||
x = xo();
|
||||
y = yo();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void MathAtom::userSetSize(MathStyles sz)
|
||||
{
|
||||
if (sz >= 0) {
|
||||
size_ = sz;
|
||||
flag = flag & ~LMPF_FIXED_SIZE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void MathAtom::writeNormal(std::ostream & os) const
|
||||
{
|
||||
os << "[unknown] ";
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::dump() const
|
||||
{
|
||||
lyxerr << "---------------------------------------------\n";
|
||||
write(lyxerr, false);
|
||||
lyxerr << "\n---------------------------------------------\n";
|
||||
}
|
||||
|
||||
|
||||
bool MathAtom::covers(int x, int y) const
|
||||
{
|
||||
return
|
||||
x >= xo_ &&
|
||||
x <= xo_ + width() &&
|
||||
y >= yo_ - ascent() &&
|
||||
y <= yo_ + descent();
|
||||
}
|
||||
|
||||
|
||||
MathScriptInset * MathAtom::ensure(bool up)
|
||||
{
|
||||
if (!script_[up])
|
||||
script_[up] = new MathScriptInset(up);
|
||||
return script_[up];
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::validate(LaTeXFeatures &) const
|
||||
{}
|
||||
|
||||
|
||||
void MathAtom::metrics(MathStyles st) const
|
||||
{
|
||||
MathStyles tt = smallerStyleScript(st);
|
||||
if (nucleus())
|
||||
nucleus()->metrics(st);
|
||||
if (up())
|
||||
up()->metrics(tt);
|
||||
if (down())
|
||||
down()->metrics(tt);
|
||||
}
|
||||
|
||||
|
||||
MathScriptInset * MathAtom::up() const
|
||||
{
|
||||
return script_[1];
|
||||
}
|
||||
|
||||
|
||||
MathScriptInset * MathAtom::down() const
|
||||
{
|
||||
return script_[0];
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::dy0() const
|
||||
{
|
||||
lyx::Assert(down());
|
||||
int des = down()->ascent();
|
||||
if (hasLimits())
|
||||
des += ndes() + 2;
|
||||
else
|
||||
des = std::max(des, ndes());
|
||||
return des;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::dy1() const
|
||||
{
|
||||
lyx::Assert(up());
|
||||
int asc = up()->descent();
|
||||
if (hasLimits())
|
||||
asc += nasc() + 2;
|
||||
else
|
||||
asc = std::max(asc, nasc());
|
||||
asc = std::max(asc, mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I'));
|
||||
return asc;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::dx0() const
|
||||
{
|
||||
lyx::Assert(down());
|
||||
return hasLimits() ? (width() - down()->width()) / 2 : nwid();
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::dx1() const
|
||||
{
|
||||
lyx::Assert(up());
|
||||
return hasLimits() ? (width() - up()->width()) / 2 : nwid();
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::dxx() const
|
||||
{
|
||||
lyx::Assert(nucleus());
|
||||
return hasLimits() ? (width() - nwid()) / 2 : 0;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::ascent() const
|
||||
{
|
||||
int asc = nasc();
|
||||
if (up())
|
||||
asc += hasLimits() ? up()->height() + 2 : up()->ascent();
|
||||
return asc;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::descent() const
|
||||
{
|
||||
int des = ndes();
|
||||
if (down())
|
||||
des += hasLimits() ? down()->height() + 2 : down()->descent();
|
||||
return des;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::width() const
|
||||
{
|
||||
int wid = 0;
|
||||
if (hasLimits()) {
|
||||
wid = nwid();
|
||||
if (up())
|
||||
wid = std::max(wid, up()->width());
|
||||
if (down())
|
||||
wid = std::max(wid, down()->width());
|
||||
} else {
|
||||
if (up())
|
||||
wid = std::max(wid, up()->width());
|
||||
if (down())
|
||||
wid = std::max(wid, down()->width());
|
||||
wid += nwid();
|
||||
}
|
||||
return wid;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::nwid() const
|
||||
{
|
||||
return nucleus() ? nucleus()->width() : 0;
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::nasc() const
|
||||
{
|
||||
return nucleus() ? nucleus()->ascent()
|
||||
: mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I');
|
||||
}
|
||||
|
||||
|
||||
int MathAtom::ndes() const
|
||||
{
|
||||
return nucleus() ? nucleus()->descent()
|
||||
: mathed_char_descent(LM_TC_VAR, LM_ST_TEXT, 'I');
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::draw(Painter & pain, int x, int y) const
|
||||
{
|
||||
xo(x);
|
||||
yo(y);
|
||||
if (nucleus())
|
||||
nucleus()->draw(pain, x + dxx(), y);
|
||||
if (up())
|
||||
up()->xcell(0).draw(pain, x + dx1(), y - dy1());
|
||||
if (down())
|
||||
down()->xcell(0).draw(pain, x + dx0(), y + dy0());
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::write(std::ostream & os, bool fragile) const
|
||||
{
|
||||
if (nucleus()) {
|
||||
nucleus()->write(os, fragile);
|
||||
if (nucleus()->takesLimits()) {
|
||||
if (limits_ == -1)
|
||||
os << "\\nolimits ";
|
||||
if (limits_ == 1)
|
||||
os << "\\limits ";
|
||||
}
|
||||
} else
|
||||
os << "{}";
|
||||
|
||||
if (up()) {
|
||||
os << "^{";
|
||||
up()->write(os, fragile);
|
||||
os << "}";
|
||||
}
|
||||
|
||||
if (down()) {
|
||||
os << "_{";
|
||||
down()->write(os, fragile);
|
||||
os << "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MathAtom::hasLimits() const
|
||||
{
|
||||
return
|
||||
limits_ == 1 || (limits_ == 0 && nucleus() && nucleus()->isScriptable());
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::substitute(MathArray & array, MathMacro const & m) const
|
||||
{
|
||||
if (nucleus())
|
||||
nucleus()->substitute(array, m);
|
||||
if (up())
|
||||
up()->substitute(array, m);
|
||||
if (down())
|
||||
down()->substitute(array, m);
|
||||
}
|
||||
|
||||
|
||||
void MathAtom::removeEmptyScripts()
|
||||
{
|
||||
for (int i = 0; i <= 1; ++i)
|
||||
if (script_[i] && !script_[i]->cell(0).size()) {
|
||||
delete script_[i];
|
||||
script_[i] = 0;
|
||||
}
|
||||
}
|
150
src/mathed/math_atom.h
Normal file
150
src/mathed/math_atom.h
Normal file
@ -0,0 +1,150 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef MATH_ATOM_H
|
||||
#define MATH_ATOM_H
|
||||
|
||||
#include <config.h>
|
||||
#include <iosfwd>
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "math_defs.h"
|
||||
|
||||
/**
|
||||
The 'atom' is the major blob in math typesetting. And 'atom' consists
|
||||
of a nucleus, an optional superscript, and an optional subscript.
|
||||
|
||||
Exactly where the subscript and superscript are drawn depends on the
|
||||
size, and type, of the nucleus they are attached to.
|
||||
|
||||
Jules
|
||||
*/
|
||||
|
||||
class LaTeXFeatures;
|
||||
class MathCharInset;
|
||||
class MathScriptInset;
|
||||
class MathInset;
|
||||
class MathMacro;
|
||||
class MathArray;
|
||||
class Painter;
|
||||
|
||||
class MathAtom {
|
||||
public:
|
||||
///
|
||||
MathAtom();
|
||||
///
|
||||
MathAtom(MathAtom const &);
|
||||
///
|
||||
explicit MathAtom(MathInset * p);
|
||||
///
|
||||
virtual ~MathAtom();
|
||||
///
|
||||
void operator=(MathAtom const &);
|
||||
///
|
||||
void swap(MathAtom &);
|
||||
|
||||
/// draw the object, sets xo_ and yo_ cached values
|
||||
virtual void draw(Painter &, int x, int y) const;
|
||||
/// reproduce itself
|
||||
void metrics(MathStyles st) const;
|
||||
///
|
||||
int ascent() const;
|
||||
///
|
||||
int descent() const;
|
||||
///
|
||||
int width() const;
|
||||
///
|
||||
int height() const;
|
||||
|
||||
///
|
||||
int xo() const;
|
||||
///
|
||||
int yo() const;
|
||||
///
|
||||
void xo(int tx) const;
|
||||
///
|
||||
void yo(int ty) const;
|
||||
///
|
||||
|
||||
///
|
||||
void getXY(int & x, int & y) const;
|
||||
///
|
||||
bool covers(int x, int y) const;
|
||||
|
||||
///
|
||||
void dump() const;
|
||||
///
|
||||
void validate(LaTeXFeatures & features) const;
|
||||
///
|
||||
void handleFont(MathTextCodes) {}
|
||||
|
||||
/// make sure superscript is available
|
||||
MathScriptInset * ensure(bool up);
|
||||
/// delete subscript array if empty
|
||||
void removeEmptyScripts();
|
||||
/// can we add a super- or subscript?
|
||||
virtual bool allows(bool up) const { return script_[up] == 0; }
|
||||
/// can we add a super- or subscript?
|
||||
virtual bool allowsLimits() const { return true; }
|
||||
/// set limits
|
||||
void limits(int lim) { limits_ = lim; }
|
||||
///
|
||||
int limits() const { return limits_; }
|
||||
///
|
||||
bool hasLimits() const;
|
||||
/// returns superscript
|
||||
MathScriptInset * up() const;
|
||||
/// returns subscript
|
||||
MathScriptInset * down() const;
|
||||
///
|
||||
MathInset * nucleus() const { return nucleus_; }
|
||||
///
|
||||
void substitute(MathArray &, const MathMacro &) const;
|
||||
///
|
||||
void write(std::ostream &, bool) const;
|
||||
///
|
||||
void writeNormal(std::ostream &) const;
|
||||
|
||||
protected:
|
||||
/// possible subscript (index 0) and superscript (index 1)
|
||||
MathScriptInset * script_[2];
|
||||
///
|
||||
MathInset * nucleus_;
|
||||
///
|
||||
int limits_;
|
||||
|
||||
private:
|
||||
/// the following are used for positioning the cursor with the mouse
|
||||
/// cached cursor start position in pixels from the document left
|
||||
mutable int xo_;
|
||||
/// cached cursor start position in pixels from the document top
|
||||
mutable int yo_;
|
||||
|
||||
/// raw copy
|
||||
void copy(MathAtom const & p);
|
||||
/// raw destruction
|
||||
void done();
|
||||
|
||||
/// returns y offset for superscript
|
||||
int dy0() const;
|
||||
/// returns y offset for subscript
|
||||
int dy1() const;
|
||||
/// returns x offset for superscript
|
||||
int dx0() const;
|
||||
/// returns x offset for subscript
|
||||
int dx1() const;
|
||||
/// returns x offset for main part
|
||||
int dxx() const;
|
||||
/// returns width of nucleus if any
|
||||
int nwid() const;
|
||||
/// returns ascent of nucleus if any
|
||||
int nasc() const;
|
||||
/// returns descent of nucleus if any
|
||||
int ndes() const;
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &, MathAtom const &);
|
||||
|
||||
#endif
|
@ -147,14 +147,17 @@ bool MathCursor::popLeft()
|
||||
if (Cursor_.size() <= 1)
|
||||
return false;
|
||||
Cursor_.pop_back();
|
||||
//array().at(pos())->removeEmptyScripts();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MathCursor::popRight()
|
||||
{
|
||||
if (Cursor_.size() <= 1)
|
||||
return false;
|
||||
Cursor_.pop_back();
|
||||
//array().at(pos())->removeEmptyScripts();
|
||||
posRight();
|
||||
return true;
|
||||
}
|
||||
@ -417,7 +420,8 @@ void MathCursor::insert(MathInset * p)
|
||||
selDel();
|
||||
}
|
||||
|
||||
array().insert(pos(), p);
|
||||
array().insert(pos(), p); // this invalidates the pointer!
|
||||
p = array().at(pos())->nucleus();
|
||||
posRight();
|
||||
}
|
||||
|
||||
@ -429,7 +433,10 @@ void MathCursor::niceInsert(MathInset * p)
|
||||
return;
|
||||
}
|
||||
selCut();
|
||||
insert(p);
|
||||
//cerr << "\n2: "; p->write(cerr, true); cerr << "\n";
|
||||
insert(p); // inserting invalidates the pointer!
|
||||
p = prevAtom()->nucleus();
|
||||
//cerr << "\n3: "; p->write(cerr, true); cerr << "\n";
|
||||
if (p->nargs()) {
|
||||
posLeft();
|
||||
right(); // do not push for e.g. MathSymbolInset
|
||||
@ -522,29 +529,15 @@ bool MathCursor::up(bool sel)
|
||||
if (selection_)
|
||||
return goUp();
|
||||
|
||||
// check whether we could move into an inset on the right or on the left
|
||||
MathInset * p = nextInset();
|
||||
if (p) {
|
||||
int idxx, poss;
|
||||
if (p->idxFirstUp(idxx, poss)) {
|
||||
pushLeft(p);
|
||||
idx() = idxx;
|
||||
pos() = poss;
|
||||
dump("up 3");
|
||||
return true;
|
||||
}
|
||||
// check whether we could move into a superscript on the right or on the left
|
||||
if (prevAtom() && prevAtom()->up()) {
|
||||
pushRight(prevAtom()->up());
|
||||
return true;
|
||||
}
|
||||
|
||||
p = prevInset();
|
||||
if (p) {
|
||||
int idxx, poss;
|
||||
if (p->idxLastUp(idxx, poss)) {
|
||||
pushRight(p);
|
||||
idx() = idxx;
|
||||
pos() = poss;
|
||||
dump("up 4");
|
||||
return true;
|
||||
}
|
||||
if (nextAtom() && nextAtom()->up()) {
|
||||
pushLeft(nextAtom()->up());
|
||||
return true;
|
||||
}
|
||||
|
||||
return goUp();
|
||||
@ -560,31 +553,15 @@ bool MathCursor::down(bool sel)
|
||||
if (selection_)
|
||||
return goDown();
|
||||
|
||||
// check whether we could move into an inset on the right or on the left
|
||||
MathInset * p = nextInset();
|
||||
if (p) {
|
||||
int idxx = 0;
|
||||
int poss = 0;
|
||||
if (p->idxFirstDown(idxx, poss)) {
|
||||
pushLeft(p);
|
||||
idx() = idxx;
|
||||
pos() = poss;
|
||||
dump("Down 3");
|
||||
return true;
|
||||
}
|
||||
// check whether we could move into an subscript on the right or on the left
|
||||
if (prevAtom() && prevAtom()->down()) {
|
||||
pushRight(prevAtom()->down());
|
||||
return true;
|
||||
}
|
||||
|
||||
p = prevInset();
|
||||
if (p) {
|
||||
int idxx = 0;
|
||||
int poss = 0;
|
||||
if (p->idxLastDown(idxx, poss)) {
|
||||
pushRight(p);
|
||||
idx() = idxx;
|
||||
pos() = poss;
|
||||
dump("Down 4");
|
||||
return true;
|
||||
}
|
||||
if (nextAtom() && nextAtom()->down()) {
|
||||
pushLeft(nextAtom()->down());
|
||||
return true;
|
||||
}
|
||||
|
||||
return goDown();
|
||||
@ -593,12 +570,12 @@ bool MathCursor::down(bool sel)
|
||||
|
||||
bool MathCursor::toggleLimits()
|
||||
{
|
||||
MathScriptInset * p = prevScriptInset();
|
||||
if (!p)
|
||||
MathAtom * t = prevAtom();
|
||||
if (!t)
|
||||
return false;
|
||||
int old = p->limits();
|
||||
p->limits(old < 0 ? 1 : -1);
|
||||
return old != p->limits();
|
||||
int old = t->limits();
|
||||
t->limits(old < 0 ? 1 : -1);
|
||||
return old != t->limits();
|
||||
}
|
||||
|
||||
|
||||
@ -624,10 +601,12 @@ void MathCursor::macroModeClose()
|
||||
string MathCursor::macroName() const
|
||||
{
|
||||
string s;
|
||||
int p = pos() - 1;
|
||||
while (p >= 0 && array().nextInset(p)->code() == LM_TC_TEX) {
|
||||
s = array().nextInset(p)->getChar() + s;
|
||||
--p;
|
||||
for (int i = pos() - 1; i >= 0; --i) {
|
||||
MathInset * p = array().at(i)->nucleus();
|
||||
if (p && p->code() == LM_TC_TEX)
|
||||
s = p->getChar() + s;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@ -752,8 +731,11 @@ void MathCursor::handleFont(MathTextCodes t)
|
||||
getSelection(i1, i2);
|
||||
if (i1.idx_ == i2.idx_) {
|
||||
MathArray & ar = i1.cell();
|
||||
for (int pos = i1.pos_; pos != i2.pos_; ++pos)
|
||||
ar.nextInset(pos)->handleFont(t);
|
||||
for (int pos = i1.pos_; pos != i2.pos_; ++pos) {
|
||||
MathInset * p = ar.at(pos)->nucleus();
|
||||
if (p)
|
||||
p->handleFont(t);
|
||||
}
|
||||
}
|
||||
} else
|
||||
lastcode_ = (lastcode_ == t) ? LM_TC_VAR : t;
|
||||
@ -772,7 +754,8 @@ void MathCursor::handleNest(MathInset * p)
|
||||
selCut();
|
||||
p->cell(0) = theSelection.glue();
|
||||
}
|
||||
insert(p);
|
||||
insert(p); // this invalidates p!
|
||||
p = prevAtom()->nucleus();
|
||||
pushRight(p);
|
||||
}
|
||||
|
||||
@ -935,36 +918,47 @@ string MathCursorPos::readString()
|
||||
|
||||
MathInset * MathCursor::prevInset() const
|
||||
{
|
||||
normalize();
|
||||
if (!pos())
|
||||
return 0;
|
||||
return array().nextInset(pos() - 1);
|
||||
return prevAtom() ? prevAtom()->nucleus() : 0;
|
||||
}
|
||||
|
||||
|
||||
MathInset * MathCursor::nextInset() const
|
||||
{
|
||||
normalize();
|
||||
return array().nextInset(pos());
|
||||
}
|
||||
|
||||
|
||||
MathScriptInset * MathCursor::prevScriptInset() const
|
||||
{
|
||||
normalize();
|
||||
MathInset * p = prevInset();
|
||||
return (p && p->isScriptInset()) ? static_cast<MathScriptInset *>(p) : 0;
|
||||
return nextAtom() ? nextAtom()->nucleus() : 0;
|
||||
}
|
||||
|
||||
|
||||
MathSpaceInset * MathCursor::prevSpaceInset() const
|
||||
{
|
||||
normalize();
|
||||
MathInset * p = prevInset();
|
||||
return (p && p->isSpaceInset()) ? static_cast<MathSpaceInset *>(p) : 0;
|
||||
}
|
||||
|
||||
|
||||
MathAtom const * MathCursor::prevAtom() const
|
||||
{
|
||||
return array().at(pos() - 1);
|
||||
}
|
||||
|
||||
|
||||
MathAtom * MathCursor::prevAtom()
|
||||
{
|
||||
return array().at(pos() - 1);
|
||||
}
|
||||
|
||||
|
||||
MathAtom const * MathCursor::nextAtom() const
|
||||
{
|
||||
return array().at(pos());
|
||||
}
|
||||
|
||||
|
||||
MathAtom * MathCursor::nextAtom()
|
||||
{
|
||||
return array().at(pos());
|
||||
}
|
||||
|
||||
|
||||
MathArray & MathCursor::array() const
|
||||
{
|
||||
static MathArray dummy;
|
||||
@ -1231,24 +1225,12 @@ void MathCursor::interpret(string const & s)
|
||||
if (c == '^' || c == '_') {
|
||||
bool const up = (s[0] == '^');
|
||||
selCut();
|
||||
MathScriptInset * p = prevScriptInset();
|
||||
if (!p) {
|
||||
MathInset * b = prevInset();
|
||||
if (b && b->isScriptable()) {
|
||||
p = new MathScriptInset(up, !up, b->clone());
|
||||
posLeft();
|
||||
plainErase();
|
||||
} else
|
||||
p = new MathScriptInset(up, !up);
|
||||
insert(p);
|
||||
if (!prevInset()) {
|
||||
insert('{', LM_TC_TEX);
|
||||
insert('}', LM_TC_TEX);
|
||||
}
|
||||
pushRight(p);
|
||||
if (up)
|
||||
p->up(true);
|
||||
else
|
||||
p->down(true);
|
||||
idx() = up ? 0 : 1;
|
||||
pos() = 0;
|
||||
MathInset * par = prevAtom()->ensure(up);
|
||||
pushRight(par);
|
||||
selPaste();
|
||||
return;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "math_defs.h"
|
||||
|
||||
class MathInset;
|
||||
class MathAtom;
|
||||
class MathArrayInset;
|
||||
class MathFuncInset;
|
||||
class MathMatrixInset;
|
||||
@ -204,6 +205,14 @@ public:
|
||||
MathArray & array() const;
|
||||
///
|
||||
MathXArray & xarray() const;
|
||||
///
|
||||
MathAtom const * prevAtom() const;
|
||||
///
|
||||
MathAtom * prevAtom();
|
||||
///
|
||||
MathAtom const * nextAtom() const;
|
||||
///
|
||||
MathAtom * nextAtom();
|
||||
|
||||
/// returns the selection
|
||||
void getSelection(MathCursorPos &, MathCursorPos &) const;
|
||||
|
@ -28,6 +28,12 @@ bool MathDecorationInset::upper() const
|
||||
}
|
||||
|
||||
|
||||
bool MathDecorationInset::isScriptable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MathDecorationInset::protect() const
|
||||
{
|
||||
return
|
||||
|
@ -27,6 +27,8 @@ public:
|
||||
void metrics(MathStyles st) const;
|
||||
///
|
||||
void writeNormal(std::ostream & os) const;
|
||||
///
|
||||
bool isScriptable() const;
|
||||
|
||||
private:
|
||||
///
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
MathDimInset::MathDimInset()
|
||||
: width_(0), ascent_(0), descent_(0)
|
||||
: MathInset(), width_(0), ascent_(0), descent_(0)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -65,8 +65,9 @@ MathInset * createMathInset(latexkeys const * l)
|
||||
|
||||
MathInset * createMathInset(string const & s)
|
||||
{
|
||||
//cerr << "creating inset with name: '" << s << "'\n";
|
||||
latexkeys const * l = in_word_set(s);
|
||||
if (l)
|
||||
if (l)
|
||||
return createMathInset(l);
|
||||
|
||||
if (MathMacroTable::hasTemplate(s))
|
||||
|
@ -17,6 +17,12 @@ MathInset * MathFuncLimInset::clone() const
|
||||
}
|
||||
|
||||
|
||||
bool MathFuncLimInset::isScriptable() const
|
||||
{
|
||||
return size_ == LM_ST_DISPLAY;
|
||||
}
|
||||
|
||||
|
||||
void MathFuncLimInset::write(ostream & os, bool /* fragile */) const
|
||||
{
|
||||
os << '\\' << sym_->name << ' ';
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
///
|
||||
void draw(Painter &, int x, int y) const;
|
||||
///
|
||||
bool isScriptable() const { return true; }
|
||||
bool isScriptable() const;
|
||||
|
||||
private:
|
||||
///
|
||||
|
@ -268,7 +268,7 @@ string MathGridInset::eolString(int row) const
|
||||
|
||||
// make sure an upcoming '[' does not break anything
|
||||
MathArray const & c = cell(index(row + 1, 0));
|
||||
if (c.size() && (*c.begin())->getChar() == '[')
|
||||
if (c.begin() && c.begin()->nucleus()->getChar() == '[')
|
||||
return "\\\\[0pt]\n";
|
||||
|
||||
return "\\\\\n";
|
||||
|
@ -20,6 +20,7 @@
|
||||
#endif
|
||||
|
||||
#include "math_inset.h"
|
||||
#include "math_scriptinset.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
@ -31,6 +32,10 @@ MathInset::MathInset()
|
||||
{}
|
||||
|
||||
|
||||
MathInset::~MathInset()
|
||||
{}
|
||||
|
||||
|
||||
int MathInset::height() const
|
||||
{
|
||||
return ascent() + descent();
|
||||
|
@ -39,14 +39,14 @@
|
||||
|
||||
class LaTeXFeatures;
|
||||
class MathCharInset;
|
||||
class MathScriptInset;
|
||||
|
||||
class MathInset {
|
||||
public:
|
||||
///
|
||||
MathInset();
|
||||
|
||||
/// the virtual base destructor
|
||||
virtual ~MathInset() {}
|
||||
virtual ~MathInset();
|
||||
|
||||
/// draw the object, sets xo_ and yo_ cached values
|
||||
virtual void draw(Painter &, int x, int y) const;
|
||||
@ -186,6 +186,8 @@ public:
|
||||
virtual char getChar() const { return 0; }
|
||||
///
|
||||
virtual MathTextCodes code() const { return LM_TC_MIN; }
|
||||
/// identifies things that can get \limits or \nolimits
|
||||
virtual bool takesLimits() const { return false; }
|
||||
|
||||
///
|
||||
virtual void push_back(MathInset *);
|
||||
|
@ -36,7 +36,7 @@ int getCols(MathInsetTypes type)
|
||||
int firstRelOp(MathArray const & array)
|
||||
{
|
||||
for (MathArray::const_iterator it = array.begin(); it != array.end(); ++it)
|
||||
if ((*it)->isRelOp())
|
||||
if (it->nucleus()->isRelOp())
|
||||
return it - array.begin();
|
||||
return array.size();
|
||||
}
|
||||
@ -92,6 +92,7 @@ char MathMatrixInset::defaultColAlign(int col)
|
||||
return 'c';
|
||||
}
|
||||
|
||||
|
||||
int MathMatrixInset::defaultColSpace(int col)
|
||||
{
|
||||
switch (getType()) {
|
||||
|
@ -43,9 +43,13 @@ MathArray const & MathNestInset::cell(int i) const
|
||||
|
||||
void MathNestInset::substitute(MathArray & array, MathMacro const & m) const
|
||||
{
|
||||
#warning Huch?
|
||||
/*
|
||||
MathNestInset * p = clone();
|
||||
array.push_back(clone());
|
||||
for (int i = 0; i < nargs(); ++i)
|
||||
array.back()->cell(i).substitute(m);
|
||||
array.back().cellsubstitute(m);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,34 +61,6 @@ bool stared(string const & s)
|
||||
return n && s[n - 1] == '*';
|
||||
}
|
||||
|
||||
MathScriptInset * prevScriptInset(MathArray const & array)
|
||||
{
|
||||
MathInset * p = array.back();
|
||||
return (p && p->isScriptInset()) ? static_cast<MathScriptInset *>(p) : 0;
|
||||
}
|
||||
|
||||
|
||||
MathInset * lastScriptInset(MathArray & array, bool up, int limits)
|
||||
{
|
||||
MathScriptInset * p = prevScriptInset(array);
|
||||
if (!p) {
|
||||
MathInset * b = array.back();
|
||||
if (b && b->isScriptable()) {
|
||||
p = new MathScriptInset(up, !up, b->clone());
|
||||
array.pop_back();
|
||||
} else {
|
||||
p = new MathScriptInset(up, !up);
|
||||
}
|
||||
array.push_back(p);
|
||||
}
|
||||
if (up)
|
||||
p->up(true);
|
||||
else
|
||||
p->down(true);
|
||||
if (limits)
|
||||
p->limits(limits);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
// These are TeX's catcodes
|
||||
@ -647,7 +619,6 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
|
||||
MathTextCodes yyvarcode = LM_TC_MIN;
|
||||
|
||||
bool panic = false;
|
||||
int limits = 0;
|
||||
|
||||
while (good()) {
|
||||
Token const & t = getToken();
|
||||
@ -723,12 +694,13 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
|
||||
array.push_back(new MathCharInset('&', LM_TC_TEX));
|
||||
}
|
||||
|
||||
else if (t.cat() == catSuper)
|
||||
parse_into(lastScriptInset(array, true, limits)->cell(0), FLAG_ITEM);
|
||||
|
||||
else if (t.cat() == catSub)
|
||||
parse_into(lastScriptInset(array, false, limits)->cell(1), FLAG_ITEM);
|
||||
|
||||
else if (t.cat() == catSuper || t.cat() == catSub) {
|
||||
bool up = (t.cat() == catSuper);
|
||||
if (array.empty())
|
||||
array.push_back(new MathCharInset(' '));
|
||||
parse_into(array.back().ensure(up)->cell(0), FLAG_ITEM);
|
||||
}
|
||||
|
||||
else if (t.character() == ']' && (flags & FLAG_BRACK_END))
|
||||
return;
|
||||
|
||||
@ -759,11 +731,11 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
|
||||
array.push_back(createMathInset("\\"));
|
||||
}
|
||||
|
||||
else if (t.cs() == "limits")
|
||||
limits = 1;
|
||||
else if (t.cs() == "limits" && array.size())
|
||||
array.back().limits(1);
|
||||
|
||||
else if (t.cs() == "nolimits")
|
||||
limits = -1;
|
||||
else if (t.cs() == "nolimits" && array.size())
|
||||
array.back().limits(-1);
|
||||
|
||||
else if (t.cs() == "nonumber")
|
||||
curr_num_ = false;
|
||||
@ -775,12 +747,12 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
|
||||
char c = getChar();
|
||||
if (c == '[') {
|
||||
array.push_back(new MathRootInset);
|
||||
parse_into(array.back()->cell(0), FLAG_BRACK_END);
|
||||
parse_into(array.back()->cell(1), FLAG_ITEM);
|
||||
parse_into(array.back().nucleus()->cell(0), FLAG_BRACK_END);
|
||||
parse_into(array.back().nucleus()->cell(1), FLAG_ITEM);
|
||||
} else {
|
||||
putback();
|
||||
array.push_back(new MathSqrtInset);
|
||||
parse_into(array.back()->cell(0), FLAG_ITEM);
|
||||
parse_into(array.back().nucleus()->cell(0), FLAG_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
@ -863,15 +835,12 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
|
||||
}
|
||||
|
||||
else if (t.cs() == "choose" || t.cs() == "over" || t.cs() == "atop") {
|
||||
limits = 0;
|
||||
MathInset * p = createMathInset(t.cs());
|
||||
// search backward for position of last '{' if any
|
||||
int pos;
|
||||
for (pos = array.size() - 1; pos >= 0; --pos) {
|
||||
MathInset * q = array.nextInset(pos);
|
||||
if (q->getChar() == '{')
|
||||
for (pos = array.size() - 1; pos >= 0; --pos)
|
||||
if (array.at(pos)->nucleus()->getChar() == '{')
|
||||
break;
|
||||
}
|
||||
if (pos >= 0) {
|
||||
// found it -> use the part after '{' as "numerator", erase the '{'
|
||||
p->cell(0) = MathArray(array, pos + 1, array.size());
|
||||
@ -885,7 +854,6 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
|
||||
}
|
||||
|
||||
else if (t.cs().size()) {
|
||||
limits = 0;
|
||||
latexkeys const * l = in_word_set(t.cs());
|
||||
if (l) {
|
||||
if (l->token == LM_TK_FONT) {
|
||||
@ -900,7 +868,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
|
||||
MathArray ar;
|
||||
parse_into(ar, FLAG_ITEM, t);
|
||||
for (MathArray::iterator it = ar.begin(); it != ar.end(); ++it)
|
||||
(*it)->handleFont(t);
|
||||
it->nucleus()->handleFont(t);
|
||||
array.push_back(ar);
|
||||
|
||||
// undo catcode changes
|
||||
|
@ -1,75 +1,26 @@
|
||||
#include <config.h>
|
||||
#include "debug.h"
|
||||
#include "support.h"
|
||||
#include "support/LOstream.h"
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "math_scriptinset.h"
|
||||
#include "support/LOstream.h"
|
||||
#include "support.h"
|
||||
|
||||
|
||||
MathScriptInset::MathScriptInset()
|
||||
: MathNestInset(2), up_(false), down_(false), limits_(0), symbol_(0)
|
||||
MathScriptInset::MathScriptInset(bool up)
|
||||
: MathNestInset(1), up_(up)
|
||||
{}
|
||||
|
||||
|
||||
MathScriptInset::MathScriptInset(bool up, bool down, MathInset * symbol)
|
||||
: MathNestInset(2), up_(up), down_(down), limits_(0), symbol_(symbol)
|
||||
{}
|
||||
|
||||
|
||||
MathScriptInset::MathScriptInset(MathScriptInset const & p)
|
||||
: MathNestInset(p), up_(p.up_), down_(p.down_),
|
||||
limits_(p.limits_), symbol_(p.symbol_ ? p.symbol_->clone() : 0)
|
||||
{}
|
||||
|
||||
|
||||
MathScriptInset::~MathScriptInset()
|
||||
{
|
||||
delete symbol_;
|
||||
}
|
||||
|
||||
|
||||
MathInset * MathScriptInset::clone() const
|
||||
{
|
||||
{
|
||||
return new MathScriptInset(*this);
|
||||
}
|
||||
|
||||
|
||||
bool MathScriptInset::up() const
|
||||
{
|
||||
return up_;
|
||||
}
|
||||
|
||||
|
||||
bool MathScriptInset::down() const
|
||||
{
|
||||
return down_;
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::up(bool b)
|
||||
{
|
||||
up_ = b;
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::down(bool b)
|
||||
{
|
||||
down_ = b;
|
||||
}
|
||||
|
||||
|
||||
bool MathScriptInset::idxRight(int &, int &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool MathScriptInset::idxLeft(int &, int &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
bool MathScriptInset::idxUp(int & idx, int & pos) const
|
||||
{
|
||||
@ -143,28 +94,6 @@ bool MathScriptInset::idxLastDown(int & idx, int & pos) const
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::write(std::ostream & os, bool fragile) const
|
||||
{
|
||||
if (symbol_) {
|
||||
symbol_->write(os, fragile);
|
||||
if (limits())
|
||||
os << (limits() == 1 ? "\\limits" : "\\nolimits");
|
||||
}
|
||||
if (up()) {
|
||||
os << "^{";
|
||||
cell(0).write(os, fragile);
|
||||
os << "}";
|
||||
}
|
||||
if (down()) {
|
||||
os << "_{";
|
||||
cell(1).write(os, fragile);
|
||||
os << "}";
|
||||
}
|
||||
os << " ";
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::idxDelete(int & idx, bool & popit, bool & deleteit)
|
||||
{
|
||||
if (idx == 0)
|
||||
@ -175,109 +104,28 @@ void MathScriptInset::idxDelete(int & idx, bool & popit, bool & deleteit)
|
||||
deleteit = !(up() || down());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool MathScriptInset::isActive() const
|
||||
|
||||
void MathScriptInset::write(std::ostream & os, bool fragile) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int MathScriptInset::limits() const
|
||||
{
|
||||
return limits_;
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::limits(int limits)
|
||||
{
|
||||
limits_ = limits;
|
||||
}
|
||||
|
||||
|
||||
bool MathScriptInset::hasLimits() const
|
||||
{
|
||||
return
|
||||
symbol_ && (limits_ == 1 || (limits_ == 0 && size() == LM_ST_DISPLAY));
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::writeNormal(std::ostream & os) const
|
||||
{
|
||||
if (limits() && symbol_)
|
||||
os << "[" << (limits() ? "limits" : "nolimits") << "]";
|
||||
if (up()) {
|
||||
os << "[superscript ";
|
||||
cell(0).writeNormal(os);
|
||||
os << "] ";
|
||||
}
|
||||
if (down()) {
|
||||
os << "[subscript ";
|
||||
cell(1).writeNormal(os);
|
||||
os << "] ";
|
||||
}
|
||||
cell(0).write(os, fragile);
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::metrics(MathStyles st) const
|
||||
{
|
||||
size_ = st;
|
||||
MathStyles tt = smallerStyleScript(st);
|
||||
|
||||
xcell(0).metrics(tt);
|
||||
xcell(1).metrics(tt);
|
||||
|
||||
width_ = std::max(xcell(0).width(), xcell(1).width());
|
||||
|
||||
if (hasLimits()) {
|
||||
symbol_->metrics(st);
|
||||
int wid = symbol_->width();
|
||||
ascent_ = symbol_->ascent();
|
||||
descent_ = symbol_->descent();
|
||||
width_ = std::max(width_, wid);
|
||||
if (up()) {
|
||||
ascent_ += xcell(0).height() + 2;
|
||||
dy0_ = - (ascent_ - xcell(0).ascent());
|
||||
}
|
||||
if (down()) {
|
||||
descent_ += xcell(1).height() + 2;
|
||||
dy1_ = descent_ - xcell(1).descent();
|
||||
}
|
||||
dxx_ = (width_ - wid) / 2;
|
||||
dx0_ = (width_ - xcell(0).width()) / 2;
|
||||
dx1_ = (width_ - xcell(1).width()) / 2;
|
||||
} else {
|
||||
int asc = 0;
|
||||
int des = 0;
|
||||
int wid = 0;
|
||||
mathed_char_height(LM_TC_VAR, st, 'I', asc, des);
|
||||
if (symbol_) {
|
||||
symbol_->metrics(st);
|
||||
wid = symbol_->width();
|
||||
asc = symbol_->ascent();
|
||||
des = symbol_->descent();
|
||||
}
|
||||
ascent_ = up() ? xcell(0).height() + asc : 0;
|
||||
descent_ = down() ? xcell(1).height() + des : 0;
|
||||
width_ += wid;
|
||||
dy0_ = - asc - xcell(0).descent();
|
||||
dy1_ = des + xcell(1).ascent();
|
||||
dx0_ = wid;
|
||||
dx1_ = wid;
|
||||
dxx_ = 0;
|
||||
}
|
||||
size_ = st;
|
||||
xcell(0).metrics(st);
|
||||
width_ = xcell(0).width();
|
||||
ascent_ = xcell(0).ascent();
|
||||
descent_ = xcell(0).descent();
|
||||
}
|
||||
|
||||
|
||||
void MathScriptInset::draw(Painter & pain, int x, int y) const
|
||||
{
|
||||
{
|
||||
xo(x);
|
||||
yo(y);
|
||||
|
||||
if (symbol_)
|
||||
symbol_->draw(pain, x + dxx_, y);
|
||||
if (up())
|
||||
xcell(0).draw(pain, x + dx0_, y + dy0_);
|
||||
if (down())
|
||||
xcell(1).draw(pain, x + dx1_, y + dy1_);
|
||||
xcell(0).draw(pain, x, y);
|
||||
}
|
||||
|
||||
|
@ -12,90 +12,22 @@
|
||||
\author André Pönitz
|
||||
*/
|
||||
|
||||
|
||||
class MathScriptInset : public MathNestInset {
|
||||
public:
|
||||
///
|
||||
MathScriptInset();
|
||||
///
|
||||
MathScriptInset(bool up, bool down, MathInset * = 0);
|
||||
///
|
||||
MathScriptInset(MathScriptInset const &);
|
||||
///
|
||||
~MathScriptInset();
|
||||
MathScriptInset(bool up);
|
||||
///
|
||||
MathInset * clone() const;
|
||||
///
|
||||
void write(std::ostream &, bool fragile) const;
|
||||
///
|
||||
void writeNormal(std::ostream &) const;
|
||||
///
|
||||
void metrics(MathStyles st) const;
|
||||
///
|
||||
void draw(Painter &, int x, int y) const;
|
||||
|
||||
///
|
||||
bool idxUp(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxDown(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxLeft(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxRight(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxFirst(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxFirstUp(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxFirstDown(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxLast(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxLastUp(int & idx, int & pos) const;
|
||||
///
|
||||
bool idxLastDown(int & idx, int & pos) const;
|
||||
///
|
||||
void idxDelete(int & idx, bool & popit, bool & deleteit);
|
||||
|
||||
///
|
||||
bool up() const;
|
||||
///
|
||||
bool down() const;
|
||||
///
|
||||
void up(bool);
|
||||
///
|
||||
void down(bool);
|
||||
///
|
||||
void limits(int);
|
||||
///
|
||||
int limits() const;
|
||||
///
|
||||
bool isActive() const;
|
||||
/// Identifies ScriptInsets
|
||||
bool isScriptInset() const { return true; }
|
||||
///
|
||||
int xoffset() const { return dxx_; }
|
||||
private:
|
||||
///
|
||||
bool hasLimits() const;
|
||||
///
|
||||
bool up_;
|
||||
///
|
||||
bool down_;
|
||||
/// 1: \limits, -1: \nolimits, 0: use default
|
||||
int limits_;
|
||||
/// x offset cache for drawing the superscript
|
||||
mutable int dx0_;
|
||||
/// x offset cache for drawing the subscript
|
||||
mutable int dx1_;
|
||||
/// x offset cache for drawing the inner symbol
|
||||
mutable int dxx_;
|
||||
/// y offset cache for drawing the superscript
|
||||
mutable int dy0_;
|
||||
/// y offset cache for drawing the subscript
|
||||
mutable int dy1_;
|
||||
///
|
||||
MathInset * symbol_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -102,6 +102,12 @@ bool MathSymbolInset::isRelOp() const
|
||||
|
||||
|
||||
bool MathSymbolInset::isScriptable() const
|
||||
{
|
||||
return size_ == LM_ST_DISPLAY && sym_->token == LM_TK_CMEX;
|
||||
}
|
||||
|
||||
|
||||
bool MathSymbolInset::takesLimits() const
|
||||
{
|
||||
return sym_->token == LM_TK_CMEX;
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ public:
|
||||
bool isRelOp() const;
|
||||
///
|
||||
bool isScriptable() const;
|
||||
/// identifies things that can get \limits or \nolimits
|
||||
bool takesLimits() const;
|
||||
|
||||
private:
|
||||
///
|
||||
|
@ -11,9 +11,6 @@
|
||||
#include "Painter.h"
|
||||
#include "debug.h"
|
||||
|
||||
using std::max;
|
||||
using std::min;
|
||||
|
||||
|
||||
MathXArray::MathXArray()
|
||||
: width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), style_(LM_ST_TEXT)
|
||||
@ -33,14 +30,11 @@ void MathXArray::metrics(MathStyles st) const
|
||||
|
||||
//lyxerr << "MathXArray::metrics(): '" << data_ << "'\n";
|
||||
for (int pos = 0; pos < data_.size(); ++pos) {
|
||||
MathInset const * p = data_.nextInset(pos);
|
||||
MathAtom const * p = data_.at(pos);
|
||||
p->metrics(st);
|
||||
int asc = p->ascent();
|
||||
int des = p->descent();
|
||||
int wid = p->width();
|
||||
ascent_ = max(ascent_, asc);
|
||||
descent_ = max(descent_, des);
|
||||
width_ += wid;
|
||||
ascent_ = std::max(ascent_, p->ascent());
|
||||
descent_ = std::max(descent_, p->descent());
|
||||
width_ += p->width();
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +50,7 @@ void MathXArray::draw(Painter & pain, int x, int y) const
|
||||
}
|
||||
|
||||
for (int pos = 0; pos < data_.size(); ++pos) {
|
||||
MathInset const * p = data_.nextInset(pos);
|
||||
MathAtom const * p = data_.at(pos);
|
||||
p->draw(pain, x, y);
|
||||
x += p->width();
|
||||
}
|
||||
@ -66,7 +60,7 @@ void MathXArray::draw(Painter & pain, int x, int y) const
|
||||
int MathXArray::pos2x(int targetpos) const
|
||||
{
|
||||
int x = 0;
|
||||
targetpos = min(targetpos, data_.size());
|
||||
targetpos = std::min(targetpos, data_.size());
|
||||
for (int pos = 0; pos < targetpos; ++pos)
|
||||
x += width(pos);
|
||||
return x;
|
||||
@ -90,9 +84,8 @@ int MathXArray::x2pos(int targetx) const
|
||||
|
||||
int MathXArray::width(int pos) const
|
||||
{
|
||||
if (pos >= data_.size())
|
||||
return 0;
|
||||
return data_.nextInset(pos)->width();
|
||||
MathAtom const * t = data_.at(pos);
|
||||
return t ? t->width() : 0;
|
||||
}
|
||||
|
||||
|
||||
@ -101,4 +94,3 @@ std::ostream & operator<<(std::ostream & os, MathXArray const & ar)
|
||||
os << ar.data_;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user