+2001-07-12 André Pönitz <poenitz@htwm.de>
+
+ * math_updowninset.[hC]: new base class for script and bigop insets
+ *.[hC]: subsequnet changes to all Metric() functions
+
+ * math_parser.C: small changes (\sqrt0 is read properly now)
+
2001-07-10 André Pönitz <poenitz@htwm.de>
* math_accentinset.[hC]: rewrite
math_spaceinset.h \
math_sqrtinset.C \
math_sqrtinset.h \
+ math_updowninset.C \
+ math_updowninset.h \
math_utils.C \
math_utils.h \
matriz.C \
{
for (int pos = 0; pos < size(); next(pos))
if (MathIsInset(pos))
- delete GetInset(pos);
+ delete nextInset(pos);
}
{
for (int pos = 0; pos < size(); next(pos))
if (isInset(pos))
- replace(pos, GetInset(pos)->clone());
+ replace(pos, nextInset(pos)->clone());
}
MathArray tmp;
for (int pos = 0; pos < size(); next(pos)) {
if (isInset(pos))
- GetInset(pos)->substitute(tmp, m);
+ nextInset(pos)->substitute(tmp, m);
else
tmp.push_back(GetChar(pos), GetCode(pos));
}
}
-MathInset * MathArray::GetInset(int pos) const
+MathInset * MathArray::nextInset(int pos) const
{
if (!isInset(pos))
return 0;
return p;
}
+MathInset * MathArray::prevInset(int pos) const
+{
+ if (!pos)
+ return 0;
+ prev(pos);
+ return nextInset(pos);
+}
+
byte MathArray::GetChar(int pos) const
{
return pos < size() ? bf_[pos + 1] : '\0';
bf_.insert(bf_.begin() + pos, array.bf_.begin(), array.bf_.end());
for (int p = pos; p < pos + array.size(); next(p))
if (isInset(p))
- replace(p, GetInset(p)->clone());
+ replace(p, nextInset(p)->clone());
}
int pos = size();
prev(pos);
if (isInset(pos))
- return GetInset(pos);
+ return nextInset(pos);
}
return 0;
}
-MathScriptInset * MathArray::prevScriptInset(int pos) const
-{
- if (!pos)
- return 0;
- prev(pos);
-
- MathInset * inset = GetInset(pos);
- if (inset && inset->isScriptInset())
- return static_cast<MathScriptInset *>(inset);
-
- return 0;
-}
-
-MathScriptInset * MathArray::nextScriptInset(int pos) const
-{
- MathInset * inset = GetInset(pos);
- if (inset && inset->isScriptInset())
- return static_cast<MathScriptInset *>(inset);
-
- return 0;
-}
-
-
void MathArray::dump2(ostream & os) const
{
for (buffer_type::const_iterator it = bf_.begin(); it != bf_.end(); ++it)
{
for (int pos = 0; pos < size(); next(pos)) {
if (isInset(pos))
- os << "<inset: " << GetInset(pos) << ">";
+ os << "<inset: " << nextInset(pos) << ">";
else
os << "<" << int(bf_[pos]) << " " << int(bf_[pos+1]) << ">";
}
for (int pos = 0; pos < size(); next(pos)) {
if (isInset(pos)) {
- GetInset(pos)->Write(os, fragile);
+ nextInset(pos)->Write(os, fragile);
} else {
#include "LString.h"
class MathInset;
-class MathScriptInset;
class MathMacro;
class Painter;
#endif
/** \class MathArray
- \brief A resizable array.
-
- A general purpose resizable array.
+ \brief Low level container for math insets
\author Alejandro Aguilar Sierra
\author André Pönitz
///
///
- MathInset * GetInset(int pos) const;
- ///
- MathScriptInset * prevScriptInset(int pos) const;
+ MathInset * nextInset(int pos) const;
///
- MathScriptInset * nextScriptInset(int pos) const;
+ MathInset * prevInset(int pos) const;
///
byte GetChar(int pos) const;
/// read subsequent chars of the same kind.
case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
case LM_TC_TEXTRM:
+ case LM_TC_TEX:
case LM_TC_RM:
f = Math_Fonts[6];
break;
if (type != LM_TC_TEXTRM)
f.setColor(LColor::math);
+ if (type == LM_TC_TEX)
+ f.setColor(LColor::latex);
+
return f;
}
return new MathAccentInset(*this);
}
-void MathAccentInset::Metrics(MathStyles st)
+void MathAccentInset::Metrics(MathStyles st, int, int)
{
xcell(0).Metrics(st);
ascent_ = xcell(0).ascent();
///
void WriteNormal(std::ostream &) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
int getAccentCode() const;
///
#include <config.h>
-#include <functional>
-
#include "math_bigopinset.h"
-#include "LColor.h"
#include "Painter.h"
#include "mathed/support.h"
#include "support/LOstream.h"
+
using std::ostream;
MathBigopInset::MathBigopInset(string const & name, int id)
- : MathScriptInset(false, true), lims_(0), sym_(id)
+ : MathUpDownInset(false, false), sym_(id), limits_(0)
{
SetName(name);
}
}
+int MathBigopInset::limits() const
+{
+ return limits_;
+}
+
+
+void MathBigopInset::limits(int limits)
+{
+ limits_ = limits;
+}
+
+
+bool MathBigopInset::hasLimits() const
+{
+ return limits_ == 1 || (limits_ == 0 && size() == LM_ST_DISPLAY);
+}
+
void MathBigopInset::Write(ostream & os, bool fragile) const
{
//bool f = sym_ != LM_int && sym_ != LM_oint && size() == LM_ST_DISPLAY;
os << '\\' << name();
- if (limits() == 1)
- os << "\\limits ";
- else if (limits() == -1)
- os << "\\nolimits ";
- else
- os << ' ';
- MathScriptInset::Write(os, fragile);
+ MathUpDownInset::Write(os, fragile);
}
void MathBigopInset::WriteNormal(ostream & os) const
{
- os << "[bigop " << name();
- if (limits() == 1)
- os << "\\limits ";
- else if (limits() == -1)
- os << "\\nolimits ";
- else
- os << ' ';
- MathScriptInset::WriteNormal(os);
- os << "] ";
+ os << "[bigop " << name() << "] ";
}
-void MathBigopInset::Metrics(MathStyles st)
+
+void MathBigopInset::Metrics(MathStyles st, int, int)
{
- MathScriptInset::Metrics(st);
+ //cerr << "\nBigopDraw\n";
size(st);
- string s;
- short t;
if (sym_ < 256 || sym_ == LM_oint) {
- char const c = (sym_ == LM_oint) ? LM_int : sym_;
- s += c;
- t = LM_TC_BSYM;
+ ssym_ = string();
+ ssym_ += (sym_ == LM_oint) ? LM_int : sym_;
+ code_ = LM_TC_BSYM;
} else {
- s = name();
- t = LM_TC_TEXTRM;
+ ssym_ = name();
+ code_ = LM_TC_TEXTRM;
}
- int asc, des, wid;
- mathed_string_dim(t, size(), s, asc, des, wid);
+ int wid;
+ mathed_string_dim(code_, size(), ssym_, ascent_, descent_, wid);
if (sym_ == LM_oint)
wid += 2;
+ //cerr << " asc: " << ascent_ << " des: " << descent_
+ // << " wid: " << wid << "\n";
+ //cerr << " hasLimits: " << hasLimits() << " up: "
+ // << up() << " down: " << down() << "\n";
+
+ width_ = wid;
if (hasLimits()) {
- ascent_ = asc + xcell(0).height() + 2;
- descent_ = des + xcell(1).height() + 2;
- width_ = std::max(width_, wid);
+ xcell(0).Metrics(st);
+ xcell(1).Metrics(st);
+ //cerr << " 0: ascent_: " << xcell(0).ascent() << " descent_: " <<
+ // xcell(0).descent() << " width_: " << xcell(0).width() << "\n";
+ //cerr << " 1: ascent_: " << xcell(1).ascent() << " descent_: " <<
+ // xcell(1).descent() << " width_: " << xcell(1).width() << "\n";
+ if (up()) {
+ ascent_ += xcell(0).height() + 1;
+ width_ = std::max(width_, xcell(0).width());
+ dy0_ = - (ascent_ - xcell(0).ascent());
+ }
+ if (down()) {
+ descent_ += xcell(1).height() + 1;
+ width_ = std::max(width_, xcell(1).width());
+ dy1_ = descent_ - xcell(1).descent();
+ }
+ dxx_ = (width_ - wid) / 2;
+ dx0_ = (width_ - xcell(0).width()) / 2;
+ dx1_ = (width_ - xcell(1).width()) / 2;
+ //cerr << " ascent_: " << ascent_ << " descent_: "
+ // << descent_ << " width_: " << width_ << "\n";
+ //cerr << " dx0_: " << dx0_ << " dx1_: " << dx1_
+ // << " dxx_: " << dxx_ << "\n";
+ //cerr << " dy0_: " << dy0_ << " dy1_: " << dy1_
+ // << "\n";
} else {
- ascent_ = std::max(ascent_, asc);
- descent_ = std::max(descent_, des);
- width_ += wid;
+ MathUpDownInset::Metrics(st, ascent_, descent_);
+ width_ += wid;
+ dx0_ = wid;
+ dx1_ = wid;
+ dxx_ = 0;
}
-
}
void MathBigopInset::draw(Painter & pain, int x, int y)
-{
+{
xo(x);
yo(y);
- string s;
- short t;
-
- if (sym_ < 256 || sym_ == LM_oint) {
- s += (sym_ == LM_oint) ? LM_int : sym_;
- t = LM_TC_BSYM;
- } else {
- s = name();
- t = LM_TC_TEXTRM;
- }
- if (sym_ == LM_oint) {
- int wid;
- int asc;
- int des;
- mathed_char_dim(t, size(), LM_int, asc, des, wid);
- wid += 2;
- pain.arc(x - 1, y - (asc - des) / 2, wid, wid, 0, 360 * 64, LColor::mathline);
- }
+ pain.text(x + dxx_, y, ssym_, mathed_get_font(code_, size()));
- int asc, des, wid;
- mathed_string_dim(t, size(), s, asc, des, wid);
+ if (up())
+ xcell(0).draw(pain, x + dx0_, y + dy0_);
+ if (down())
+ xcell(1).draw(pain, x + dx1_, y + dy1_);
- if (hasLimits()) {
- int w = width();
- pain.text(x + (w - wid)/2, y, s, mathed_get_font(t, size()));
- xcell(0).draw
- (pain, x + (w - xcell(0).width())/2, y - asc - xcell(0).descent() - 1);
- xcell(1).draw
- (pain, x + (w - xcell(1).width())/2, y + des + xcell(1).ascent() + 1);
- } else {
- pain.text(x, y, s, mathed_get_font(t, size()));
- MathScriptInset::draw(pain, x + wid, y);
+ if (sym_ == LM_oint) {
+ int xx = x - 1;
+ int yy = y - (ascent_ - descent_) / 2;
+ pain.arc(xx, yy, width_, width_, 0, 360 * 64, LColor::mathline);
}
}
-int MathBigopInset::limits() const
-{
- return lims_;
-}
-
-
-void MathBigopInset::limits(int limit)
-{
- lims_ = limit;
-}
-
-bool MathBigopInset::hasLimits() const
-{
- return limits() == 1 || (limits() == 0 && size() == LM_ST_DISPLAY);
-}
-
-
-void MathBigopInset::idxDelete(int & idx, bool & popit, bool & deleteit)
-{
- if (idx == 0)
- up(false);
- else
- down(false);
- popit = true;
- deleteit = true;
-}
#ifndef MATH_BIGOPINSET_H
#define MATH_BIGOPINSET_H
-#include "math_scriptinset.h"
+#include "math_updowninset.h"
/// big operators
-class MathBigopInset : public MathScriptInset {
+class MathBigopInset : public MathUpDownInset {
public:
///
MathBigopInset(string const &, int);
///
MathInset * clone() const;
///
- void draw(Painter &, int, int);
- ///
void Write(std::ostream &, bool fragile) const;
///
void WriteNormal(std::ostream &) const;
///
- void Metrics(MathStyles st);
- ///
- int limits() const;
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
- bool hasLimits() const;
+ void draw(Painter &, int, int);
///
void limits(int);
///
- void idxDelete(int & idx, bool & popit, bool & deleteit);
+ int limits() const;
+ /// Identifies BigopInsets
+ bool isBigopInset() const { return true; }
private:
- /// 1: \limits, -1: \nolimits, 0: use default
- int lims_;
+ ///
+ bool hasLimits() const;
///
int sym_;
+ ///
+ string ssym_;
+ ///
+ short code_;
+ /// 1: \limits, -1: \nolimits, 0: use default
+ int limits_;
+ /// x offset for drawing the superscript
+ int dx0_;
+ /// x offset for drawing the subscript
+ int dx1_;
+ /// x offset for drawing the inner symbol
+ int dxx_;
};
#endif
lyxerr << "found idx: " << idx_ << " cursor: " << cursor_ << "\n";
MathInset * n = nextInset();
MathInset * p = prevInset();
- if (n && (n->isActive() || n->isScriptInset()) && n->covers(x, y))
+ if (n && (n->isActive() || n->isUpDownInset()) && n->covers(x, y))
push(n, true);
- else if (p && (p->isActive() || p->isScriptInset()) && p->covers(x, y)) {
+ else if (p && (p->isActive() || p->isUpDownInset()) && p->covers(x, y)) {
array().prev(cursor_);
push(p, false);
} else
return false;
MathInset * p = prevInset();
int old = p->limits();
- p->limits(old == -1 ? 1 : -1);
+ p->limits(old < 0 ? 1 : -1);
return old != p->limits();
}
in_word_set(s) << " \n";
if (s[0] == '^') {
- MathScriptInset * p = nearbyScriptInset();
+ MathUpDownInset * p = nearbyUpDownInset();
if (!p) {
- p = new MathScriptInset;
+ p = new MathScriptInset(true, false);
insert(p);
array().prev(cursor_);
}
push(p, true);
- if (!p->up())
- p->up(true);
+ p->up(true);
idx_ = 0;
return;
}
if (s[0] == '_') {
- MathScriptInset * p = nearbyScriptInset();
+ MathUpDownInset * p = nearbyUpDownInset();
if (!p) {
- p = new MathScriptInset;
+ p = new MathScriptInset(false, true);
insert(p);
array().prev(cursor_);
}
push(p, true);
- if (!p->down())
- p->down(true);
+ p->down(true);
idx_ = 1;
return;
}
int c = cursor_;
if (!array().prev(c))
return 0;
- return array().GetInset(c);
+ return array().nextInset(c);
}
MathInset * MathCursor::nextInset() const
{
normalize();
- return array().GetInset(cursor_);
+ return array().nextInset(cursor_);
}
-MathScriptInset * MathCursor::nearbyScriptInset() const
+MathUpDownInset * MathCursor::nearbyUpDownInset() const
{
normalize();
- MathScriptInset * p = array().prevScriptInset(cursor_);
- if (p)
- return p;
- return array().nextScriptInset(cursor_);
+ MathInset * p = array().prevInset(cursor_);
+ if (p && p->isUpDownInset())
+ return static_cast<MathUpDownInset *>(p);
+ p = array().nextInset(cursor_);
+ if (p && p->isUpDownInset())
+ return static_cast<MathUpDownInset *>(p);
+ return 0;
}
-
MathArray & MathCursor::array() const
{
static MathArray dummy;
class MathInset;
class MathFuncInset;
-class MathScriptInset;
+class MathUpDownInset;
class InsetFormulaBase;
class MathArray;
class MathXArray;
///
MathInset * prevInset() const;
///
- MathScriptInset * nearbyScriptInset() const;
+ MathUpDownInset * nearbyUpDownInset() const;
///
MathFuncInset * imacro;
-void MathDecorationInset::Metrics(MathStyles st)
+void MathDecorationInset::Metrics(MathStyles st, int, int)
{
xcell(0).Metrics(st);
size_ = st;
///
void Write(std::ostream &, bool fragile) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
private:
///
int deco_;
}
-void MathDelimInset::Metrics(MathStyles st)
+void MathDelimInset::Metrics(MathStyles st, int, int)
{
xcell(0).Metrics(st);
size_ = st;
///
void Write(std::ostream &, bool fragile) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
private:
int dw() const;
///
}
-void MathDotsInset::Metrics(MathStyles st)
+void MathDotsInset::Metrics(MathStyles st, int, int)
{
size(st);
mathed_char_dim(LM_TC_VAR, size(), 'M', ascent_, descent_, width_);
///
void WriteNormal(std::ostream &) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
protected:
///
int dh_;
}
-void MathFracInset::Metrics(MathStyles st)
+void MathFracInset::Metrics(MathStyles st, int, int)
{
size_ = smallerStyleFrac(st);
xcell(0).Metrics(size_);
///
virtual void WriteNormal(std::ostream &) const;
///
- virtual void Metrics(MathStyles st);
+ virtual void Metrics(MathStyles st, int asc = 0, int des = 0);
///
virtual void draw(Painter &, int x, int baseline);
///
}
-void MathFuncInset::Metrics(MathStyles st)
+void MathFuncInset::Metrics(MathStyles st, int, int)
{
LyXFont font = WhichFont(LM_TC_TEXTRM, size());
#ifndef NO_LATEX
///
void WriteNormal(std::ostream &) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
private:
///
bool lims_;
#include "math_grid.h"
#include "support/LOstream.h"
#include "debug.h"
-#include "Painter.h"
namespace {
return v_align_;
}
-void MathGridInset::Metrics(MathStyles st)
+void MathGridInset::Metrics(MathStyles st, int, int)
{
// let the cells adjust themselves
MathInset::Metrics(st);
///
void Write(std::ostream &, bool fragile) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
void draw(Painter &, int, int);
///
{
}
-bool MathInset::hasLimits() const
-{
- return false;
-}
-
-
string const & MathInset::name() const
{
return name_;
}
-void MathInset::setData(MathArray const & a, int idx)
-{
- cells_[idx].data_ = a;
-}
-
-
void MathInset::substitute(MathArray & array, MathMacro const & m) const
{
MathInset * p = clone();
array.push_back(p);
}
-void MathInset::Metrics(MathStyles st)
+void MathInset::Metrics(MathStyles st, int, int)
{
size_ = st;
for (int i = 0; i < nargs(); ++i)
y >= yo_ - ascent_ &&
y <= yo_ + descent_;
}
-
/// Appends itself with macro arguments substituted
virtual void substitute(MathArray & array, MathMacro const & macro) const;
/// Compute the size of the object
- virtual void Metrics(MathStyles st) = 0;
+ virtual void Metrics(MathStyles st, int = 0, int = 0) = 0;
///
virtual int ascent() const;
///
///
virtual int height() const;
///
- virtual bool hasLimits() const;
- ///
virtual int limits() const;
///
virtual void limits(int);
MathXArray & xcell(int);
///
MathXArray const & xcell(int) const;
- ///
- void setData(MathArray const &, int);
///
int xo() const;
///
bool covers(int x, int y) const;
/// Identifies ScriptInsets
- virtual bool isScriptInset() const { return false; }
+ virtual bool isUpDownInset() const { return false; }
/// Identifies AccentInsets
virtual bool isAccentInset() const { return false; }
+ /// Identifies BigopInsets
+ virtual bool isBigopInset() const { return false; }
///
virtual bool isActive() const { return nargs() > 0; }
}
-void MathMacro::Metrics(MathStyles st)
+void MathMacro::Metrics(MathStyles st, int, int)
{
if (mathcursor && mathcursor->isInside(this)) {
expanded_ = tmplate_->xcell(0);
///
void draw(Painter &, int, int);
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
MathInset * clone() const;
///
}
-void MathMacroArgument::Metrics(MathStyles st)
+void MathMacroArgument::Metrics(MathStyles st, int, int)
{
char str[] = "#0";
str[1] += number_;
///
MathInset * clone() const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
void draw(Painter &, int x, int baseline);
///
{
MathMacroTemplate * t = new MathMacroTemplate("emptyset", 0);
MathAccentInset * p = new MathAccentInset(LM_not);
- p->cell(0).push_back('0', LM_TC_VAR);
+ p->cell(0).push_back('O', LM_TC_VAR);
t->push_back(p);
insertTemplate(t);
}
}
-void MathMacroTemplate::Metrics(MathStyles st)
+void MathMacroTemplate::Metrics(MathStyles st, int, int)
{
xcell(0).Metrics(st);
size_ = st;
///
void draw(Painter &, int, int);
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
private:
///
int numargs_;
}
-void MathMatrixInset::Metrics(MathStyles /* st */)
+void MathMatrixInset::Metrics(MathStyles /* st */, int, int)
{
size_ = (GetType() == LM_OT_SIMPLE) ? LM_ST_TEXT : LM_ST_DISPLAY;
MathIter it(cell());
while (it.OK() && !(features.binom && features.boldsymbol)) {
- MathInset * p = it.GetInset();
+ MathInset * p = it.nextInset();
if (p) {
p = it.GetActiveInset();
if (p) {
///
void Write(std::ostream &, bool fragile) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
void draw(Painter &, int, int);
///
* the GNU General Public Licence version 2 or later.
*/
+// {[(
+
#include <config.h>
#include <cctype>
#include "math_funcinset.h"
#include "math_spaceinset.h"
#include "math_sizeinset.h"
+#include "math_scriptinset.h"
#include "math_dotsinset.h"
#include "math_fracinset.h"
#include "math_deliminset.h"
char const * latex_special_chars = "#$%&_{}";
-/// Read TeX into data, flags give stop conditions
-void mathed_parse(MathArray & data, unsigned flags);
-
-
namespace {
+void mathed_parse(MathArray & array, unsigned flags);
+
unsigned char getuchar(std::istream * is)
{
char c;
enum {
FLAG_BRACE = 1 << 0, // A { needed //}
- FLAG_BRACE_OPT = 1 << 2, // Optional {
- FLAG_BRACE_LAST = 1 << 3, // Last } ends the parsing process
- FLAG_BRACK_ARG = 1 << 4, // Optional [
+ FLAG_BRACE_OPT = 1 << 2, // Optional { //}
+ FLAG_BRACE_LAST = 1 << 3, // // { Last } ends the parsing process
+ FLAG_BRACK_ARG = 1 << 4, // Optional [ //]
FLAG_RIGHT = 1 << 5, // Next right ends the parsing process
FLAG_END = 1 << 6, // Next end ends the parsing process
- FLAG_BRACE_FONT = 1 << 7, // Next } closes a font
- FLAG_BRACK_END = 1 << 9, // Next ] ends the parsing process
+ FLAG_BRACE_FONT = 1 << 7, // // { Next } closes a font
+ FLAG_BRACK_END = 1 << 9, // // [ Next ] ends the parsing process
FLAG_AMPERSAND = 1 << 10, // Next & ends the parsing process
- FLAG_NEWLINE = 1 << 11 // Next \\ ends the parsing process
+ FLAG_NEWLINE = 1 << 11, // Next \\ ends the parsing process
+
+ // Read a (possibly braced token)
+ FLAG_ITEM = FLAG_BRACE_OPT | FLAG_BRACE_LAST
};
+}
+
///
union {
} yylval;
+
string yytext;
int yylineno;
istream * yyis;
yylval.i = (i < 4) ? i : 0;
return LM_TK_SPACE;
}
- if (lexcode[c] == LexAlpha || lexcode[c] == LexDigit) {
+ if (lexcode[c] == LexAlpha) {
yytext.erase();
- while (lexcode[c] == LexAlpha || lexcode[c] == LexDigit) {
+ while (lexcode[c] == LexAlpha) {
yytext += c;
c = getuchar(yyis);
}
}
-void handle_frac(MathArray & dat, string const & name)
-{
- MathFracInset * p = new MathFracInset(name);
- mathed_parse(p->cell(0), FLAG_BRACE | FLAG_BRACE_LAST);
- mathed_parse(p->cell(1), FLAG_BRACE | FLAG_BRACE_LAST);
- dat.push_back(p);
-}
-
-
-MathScriptInset * lastScriptInset(MathArray & array)
+MathInset * lastUpDownInset(MathArray & array, bool up, bool down)
{
MathInset * p = array.back_inset();
- if (!p || !p->isScriptInset()) {
- p = new MathScriptInset;
+ if (!p || !p->isUpDownInset()) {
+ p = new MathScriptInset(up, down);
array.push_back(p);
}
- return static_cast<MathScriptInset *>(p);
+ MathUpDownInset * q = static_cast<MathScriptInset *>(p);
+ if (up)
+ q->up(true);
+ if (down)
+ q->down(down);
+ return p;
}
+
+MathBigopInset * lastBigopInset(MathArray & array)
+{
+ MathInset * p = array.back_inset();
+ return (p && p->isBigopInset()) ? static_cast<MathBigopInset *>(p) : 0;
}
}
+
+namespace {
+
+void handle_frac(MathArray & array, string const & name)
+{
+ MathFracInset * p = new MathFracInset(name);
+ mathed_parse(p->cell(0), FLAG_ITEM);
+ mathed_parse(p->cell(1), FLAG_ITEM);
+ array.push_back(p);
+}
+
+
void mathed_parse(MathArray & array, unsigned flags)
{
int t = yylex();
- int tprev = 0;
bool panic = false;
static int plevel = -1;
yyvarcode = LM_TC_VAR;
break;
case '^':
- {
- MathArray ar;
- mathed_parse(ar, FLAG_BRACE_OPT | FLAG_BRACE_LAST);
- MathScriptInset * p = lastScriptInset(array);
- p->setData(ar, 0);
- p->up(true);
+ mathed_parse(lastUpDownInset(array, true, false)->cell(0), FLAG_ITEM);
break;
- }
case '_':
- {
- MathArray ar;
- mathed_parse(ar, FLAG_BRACE_OPT | FLAG_BRACE_LAST);
- MathScriptInset * p = lastScriptInset(array);
- p->setData(ar, 1);
- p->down(true);
+ mathed_parse(lastUpDownInset(array, false, true)->cell(1), FLAG_ITEM);
break;
- }
case LM_TK_LIMIT:
{
- MathScriptInset * p = lastScriptInset(array);
+ MathBigopInset * p = lastBigopInset(array);
if (p)
p->limits(yylval.l->id ? 1 : -1);
break;
{
unsigned char c = getuchar(yyis);
if (c == '[') {
- MathRootInset * rt = new MathRootInset;
- mathed_parse(rt->cell(0), FLAG_BRACK_END);
- mathed_parse(rt->cell(1), FLAG_BRACE | FLAG_BRACE_LAST);
- array.push_back(rt);
+ array.push_back(new MathRootInset);
+ mathed_parse(array.back_inset()->cell(0), FLAG_BRACK_END);
+ mathed_parse(array.back_inset()->cell(1), FLAG_ITEM);
} else {
yyis->putback(c);
- MathSqrtInset * sq = new MathSqrtInset;
- mathed_parse(sq->cell(0), FLAG_BRACE | FLAG_BRACE_LAST);
- array.push_back(sq);
+ array.push_back(new MathSqrtInset);
+ mathed_parse(array.back_inset()->cell(0), FLAG_ITEM);
}
break;
}
rd = yylval.i;
MathDelimInset * dl = new MathDelimInset(ld, rd);
- dl->setData(ar, 0);
+ dl->cell(0) = ar;
array.push_back(dl);
break;
}
if (MathMacroTable::hasTemplate(yytext)) {
MathMacro * m = MathMacroTable::cloneTemplate(yytext);
for (int i = 0; i < m->nargs(); ++i)
- mathed_parse(m->cell(i), FLAG_BRACE_OPT | FLAG_BRACE_LAST);
+ mathed_parse(m->cell(i), FLAG_ITEM);
array.push_back(m);
m->Metrics(LM_ST_TEXT);
} else
} // end of big switch
- tprev = t;
if (panic) {
lyxerr << " Math Panic, expect problems!" << endl;
// Search for the end command.
--plevel;
}
+}
+
MathInset * mathed_parse(istream & is)
{
return p;
}
+
+//]})
}
-void MathRootInset::Metrics(MathStyles st)
+void MathRootInset::Metrics(MathStyles st, int, int)
{
MathInset::Metrics(st);
size_ = st;
///
void WriteNormal(std::ostream &) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
bool idxUp(int & idx, int & pos) const;
///
#pragma implementation
#endif
-#include <functional>
-
#include "math_scriptinset.h"
-#include "LColor.h"
-#include "Painter.h"
-#include "debug.h"
-#include "mathed/support.h"
#include "support/LOstream.h"
-MathScriptInset::MathScriptInset()
- : MathInset(2), up_(false), down_(false)
-{}
-
MathScriptInset::MathScriptInset(bool up, bool down)
- : MathInset(2), up_(up), down_(down)
+ : MathUpDownInset(up, down)
{}
}
-void MathScriptInset::Metrics(MathStyles st)
-{
- size_ = smallerStyleScript(st);
- xcell(0).Metrics(size_);
- xcell(1).Metrics(size_);
-
- width_ = std::max(xcell(0).width(), xcell(1).width()) + 2;
- if (up())
- ascent_ = std::max(ascent_, xcell(0).height() + 9);
- if (down())
- descent_ = std::max(descent_, xcell(1).height());
-}
-
-
-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;
-}
-
-
-void MathScriptInset::draw(Painter & pain, int x, int y)
-{
- xo(x);
- yo(y);
- if (up())
- xcell(0).draw(pain, x, y - xcell(0).descent() - 9);
- if (down())
- xcell(1).draw(pain, x, y + xcell(1).ascent());
-}
-
-
-void MathScriptInset::Write(std::ostream & os, bool fragile) const
-{
- if (up()) {
- os << "^{";
- cell(0).Write(os, fragile);
- os << "}";
- }
- if (down()) {
- os << "_{";
- cell(1).Write(os, fragile);
- os << "}";
- }
-}
-
-
void MathScriptInset::WriteNormal(std::ostream & os) const
{
if (up()) {
}
}
-bool MathScriptInset::idxRight(int &, int &) const
-{
- return false;
-}
-
-bool MathScriptInset::idxLeft(int &, int &) const
-{
- return false;
-}
-
-
-bool MathScriptInset::idxUp(int & idx, int & pos) const
-{
- if (idx == 0 || !up())
- return false;
- idx = 0;
- pos = 0;
- return true;
-}
-
-bool MathScriptInset::idxDown(int & idx, int & pos) const
-{
- if (idx == 1 || !down())
- return false;
- idx = 1;
- pos = 0;
- return true;
-}
-
-bool MathScriptInset::idxFirst(int & idx, int & pos) const
-{
- idx = up() ? 0 : 1;
- pos = 0;
- return true;
-}
-
-bool MathScriptInset::idxLast(int & idx, int & pos) const
-{
- idx = down() ? 1 : 0;
- pos = cell(idx).size();
- return true;
-}
-
-
-bool MathScriptInset::idxFirstUp(int & idx, int & pos) const
-{
- if (!up())
- return false;
- idx = 0;
- pos = 0;
- return true;
-}
-
-bool MathScriptInset::idxFirstDown(int & idx, int & pos) const
-{
- if (!down())
- return false;
- idx = 1;
- pos = 0;
- return true;
-}
-
-bool MathScriptInset::idxLastUp(int & idx, int & pos) const
-{
- if (!up())
- return false;
- idx = 0;
- pos = cell(idx).size();
- return true;
-}
-
-bool MathScriptInset::idxLastDown(int & idx, int & pos) const
-{
- if (!down())
- return false;
- idx = 1;
- pos = cell(idx).size();
- return true;
-}
-
void MathScriptInset::idxDelete(int & idx, bool & popit, bool & deleteit)
{
#ifndef MATH_SCRIPTINSET_H
#define MATH_SCRIPTINSET_H
-#include "math_inset.h"
+#include "math_updowninset.h"
#ifdef __GNUG__
#pragma interface
\author André Pönitz
*/
-class MathScriptInset : public MathInset {
+class MathScriptInset : public MathUpDownInset {
public:
- ///
- MathScriptInset();
///
MathScriptInset(bool up, bool down);
///
MathInset * clone() const;
///
- void Write(std::ostream &, bool fragile) const;
- ///
void WriteNormal(std::ostream &) const;
- ///
- void Metrics(MathStyles st);
- ///
- void draw(Painter &, int x, int baseline);
- ///
- 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;
- ///
- bool up() const;
- ///
- bool down() const;
- ///
- void up(bool);
- ///
- void down(bool);
- ///
- bool isActive() const { return false; }
/// Identifies ScriptInsets
- bool isScriptInset() const { return true; }
+ bool isUpDownInset() const { return true; }
///
void idxDelete(int & idx, bool & popit, bool & deleteit);
-private:
- ///
- bool up_;
- ///
- bool down_;
};
#endif
}
-void MathSizeInset::Metrics(MathStyles /* st */)
+void MathSizeInset::Metrics(MathStyles /* st */, int, int)
{
xcell(0).Metrics(style_);
ascent_ = xcell(0).ascent_;
///
virtual MathInset * clone() const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
void draw(Painter &, int x, int baseline);
///
}
-void MathSpaceInset::Metrics(MathStyles st)
+void MathSpaceInset::Metrics(MathStyles st, int, int)
{
size_ = st;
width_ = space_ ? space_ * 2 : 2;
///
void WriteNormal(std::ostream &) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
void SetSpace(int sp);
///
}
-void MathSqrtInset::Metrics(MathStyles st)
+void MathSqrtInset::Metrics(MathStyles st, int, int)
{
xcell(0).Metrics(st);
size_ = st;
void MathSqrtInset::Write(std::ostream & os, bool fragile) const
{
- os << '\\' << name_ << '{';
+ os << "\\sqrt{";
cell(0).Write(os, fragile);
os << '}';
}
///
void WriteNormal(std::ostream &) const;
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
};
#endif
--- /dev/null
+#include <config.h>
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "math_updowninset.h"
+#include "support/LOstream.h"
+
+
+MathUpDownInset::MathUpDownInset()
+ : MathInset(2), up_(false), down_(false)
+{}
+
+MathUpDownInset::MathUpDownInset(bool up, bool down)
+ : MathInset(2), up_(up), down_(down)
+{}
+
+
+MathInset * MathUpDownInset::clone() const
+{
+ return new MathUpDownInset(*this);
+}
+
+
+bool MathUpDownInset::up() const
+{
+ return up_;
+}
+
+bool MathUpDownInset::down() const
+{
+ return down_;
+}
+
+void MathUpDownInset::up(bool b)
+{
+ up_ = b;
+}
+
+void MathUpDownInset::down(bool b)
+{
+ down_ = b;
+}
+
+
+bool MathUpDownInset::idxRight(int &, int &) const
+{
+ return false;
+}
+
+bool MathUpDownInset::idxLeft(int &, int &) const
+{
+ return false;
+}
+
+
+bool MathUpDownInset::idxUp(int & idx, int & pos) const
+{
+ if (idx == 0 || !up())
+ return false;
+ idx = 0;
+ pos = 0;
+ return true;
+}
+
+bool MathUpDownInset::idxDown(int & idx, int & pos) const
+{
+ if (idx == 1 || !down())
+ return false;
+ idx = 1;
+ pos = 0;
+ return true;
+}
+
+bool MathUpDownInset::idxFirst(int & idx, int & pos) const
+{
+ idx = up() ? 0 : 1;
+ pos = 0;
+ return true;
+}
+
+bool MathUpDownInset::idxLast(int & idx, int & pos) const
+{
+ idx = down() ? 1 : 0;
+ pos = cell(idx).size();
+ return true;
+}
+
+
+bool MathUpDownInset::idxFirstUp(int & idx, int & pos) const
+{
+ if (!up())
+ return false;
+ idx = 0;
+ pos = 0;
+ return true;
+}
+
+bool MathUpDownInset::idxFirstDown(int & idx, int & pos) const
+{
+ if (!down())
+ return false;
+ idx = 1;
+ pos = 0;
+ return true;
+}
+
+bool MathUpDownInset::idxLastUp(int & idx, int & pos) const
+{
+ if (!up())
+ return false;
+ idx = 0;
+ pos = cell(idx).size();
+ return true;
+}
+
+bool MathUpDownInset::idxLastDown(int & idx, int & pos) const
+{
+ if (!down())
+ return false;
+ idx = 1;
+ pos = cell(idx).size();
+ return true;
+}
+
+
+void MathUpDownInset::idxDelete(int & idx, bool & popit, bool & deleteit)
+{
+ if (idx == 0)
+ up(false);
+ else
+ down(false);
+ popit = true;
+ deleteit = !(up() || down());
+}
+
+void MathUpDownInset::Write(std::ostream & os, bool fragile) const
+{
+ if (up()) {
+ os << "^{";
+ cell(0).Write(os, fragile);
+ os << "}";
+ }
+ if (down()) {
+ os << "_{";
+ cell(1).Write(os, fragile);
+ os << "}";
+ }
+}
+
+void MathUpDownInset::Metrics(MathStyles st, int asc, int des)
+{
+ if (up())
+ xcell(0).Metrics(st);
+ if (down())
+ xcell(1).Metrics(st);
+
+ // we assume that asc, des, wid are the metrics of the item in front
+ // of this MathScriptInset
+ width_ = std::max(xcell(0).width(), xcell(1).width());
+ ascent_ = up() ? xcell(0).height() + 9 : 0;
+ descent_ = down() ? xcell(1).height() : 0;
+ dy0_ = - asc - xcell(0).descent();
+ dy1_ = des + xcell(1).ascent();
+}
+
+
+void MathUpDownInset::draw(Painter & pain, int x, int y)
+{
+ xo(x);
+ yo(y);
+ if (up())
+ xcell(0).draw(pain, x, y + dy0_);
+ if (down())
+ xcell(1).draw(pain, x, y + dy1_);
+}
+
--- /dev/null
+// -*- C++ -*-
+#ifndef MATH_UPDOWNINSET_H
+#define MATH_UPDOWNINSET_H
+
+#include "math_inset.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/** Abstract base class for super- and subscripts and mathop inset
+ \author André Pönitz
+ */
+
+class MathUpDownInset : public MathInset {
+public:
+ ///
+ MathUpDownInset();
+ ///
+ MathUpDownInset(bool up, bool down);
+ ///
+ MathInset * clone() const;
+ ///
+ void Write(std::ostream &, bool fragile) const;
+ ///
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
+ ///
+ void draw(Painter &, int x, int baseline);
+ ///
+ 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;
+ ///
+ bool up() const;
+ ///
+ bool down() const;
+ ///
+ void up(bool);
+ ///
+ void down(bool);
+ ///
+ bool isActive() const { return false; }
+ /// Identifies ScriptInsets
+ bool isUpDownInset() const { return true; }
+ ///
+ void idxDelete(int & idx, bool & popit, bool & deleteit);
+private:
+ ///
+ bool up_;
+ ///
+ bool down_;
+protected:
+ ///
+ int dy0_;
+ ///
+ int dy1_;
+};
+
+#endif
using std::max;
using std::min;
+
MathXArray::MathXArray()
: width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), style_(LM_ST_TEXT)
{}
-void MathXArray::Metrics(MathStyles st)
+void MathXArray::Metrics(MathStyles st, int, int)
{
if (data_.empty()) {
mathed_char_dim(LM_TC_VAR, st, 'I', ascent_, descent_, width_);
width_ = 0;
style_ = st;
+ // keep last values for scriptInset's need to look back
+ int asc = 0;
+ int des = 0;
+ int wid = 0;
+ mathed_char_height(LM_TC_VAR, st, 'I', asc, des);
+
for (int pos = 0; pos < data_.size(); data_.next(pos)) {
- MathInset * p = data_.GetInset(pos);
+ MathInset * p = data_.nextInset(pos);
if (p) {
- p->Metrics(st);
- ascent_ = max(ascent_, p->ascent());
- descent_ = max(descent_, p->descent());
- width_ += p->width();
+ // only MathUpDownInsets will use the asc/des information...
+ p->Metrics(st, asc, des);
+ asc = p->ascent();
+ des = p->descent();
+ wid = p->width();
} else {
char cx = data_.GetChar(pos);
MathTextCodes fc = data_.GetCode(pos);
- int asc;
- int des;
- int wid;
mathed_char_dim(fc, style_, cx, asc, des, wid);
- ascent_ = max(ascent_, asc);
- descent_ = max(descent_, des);
- width_ += wid;
}
+ ascent_ = max(ascent_, asc);
+ descent_ = max(descent_, des);
+ width_ += wid;
}
}
}
for (int pos = 0; pos < data_.size(); data_.next(pos)) {
- MathInset * p = data_.GetInset(pos);
+ MathInset * p = data_.nextInset(pos);
if (p) {
p->draw(pain, x, y);
x += p->width();
return 0;
if (data_.isInset(pos))
- return data_.GetInset(pos)->width();
+ return data_.nextInset(pos)->width();
else
return mathed_char_width(data_.GetCode(pos), style_, data_.GetChar(pos));
}
///
MathXArray();
///
- void Metrics(MathStyles st);
+ void Metrics(MathStyles st, int asc = 0, int des = 0);
///
void draw(Painter & pain, int x, int y);