X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fformula.C;h=5b10679fb142b219f6d7a2125bc00f4a90453ebd;hb=d597ece5e7efac2a25251034d89fa761759d28f7;hp=8c03d3fd86e363ec47a7bd8764bab8618370a96b;hpb=77e706c44175f3cf71473a42d5db890c77b3b7b3;p=lyx.git diff --git a/src/mathed/formula.C b/src/mathed/formula.C index 8c03d3fd86..5b10679fb1 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -1,5 +1,5 @@ /* - * File: formula.h + * File: formula.C * Purpose: Implementation of formula inset * Author: Alejandro Aguilar Sierra * Created: January 1996 @@ -15,12 +15,7 @@ #include -#ifdef HAVE_SSTREAM -#include -using std::istringstream; -#else -#include -#endif +#include "Lsstream.h" #ifdef __GNUG__ #pragma implementation "formula.h" @@ -42,25 +37,31 @@ using std::istringstream; #include "LyXView.h" #include "Painter.h" #include "font.h" +#include "support/lyxlib.h" using std::ostream; using std::istream; using std::pair; using std::endl; +using std::vector; +using std::max; -extern char * mathed_label; +//extern char * mathed_label; +extern string mathed_label; extern char const * latex_special_chars; -short greek_kb_flag = 0; +int greek_kb_flag = 0; LyXFont * Math_Fonts = 0; // this is only used by Whichfont and mathed_init_fonts (Lgb) static LyXFont::FONT_SIZE lfont_size = LyXFont::SIZE_NORMAL; -// local global -static int sel_x, sel_y; +// local global +static int sel_x; +static int sel_y; static bool sel_flag; + MathedCursor * InsetFormula::mathcursor = 0; @@ -69,14 +70,6 @@ int MathedInset::df_des; int MathedInset::df_width; -inline -bool IsMacro(short token, int id) -{ - return (token != LM_TK_FRAC && token != LM_TK_SQRT && - !((token == LM_TK_SYM || token == LM_TC_BSYM) && id < 255)); -} - - static void mathedValidate(LaTeXFeatures & features, MathParInset * par); @@ -198,21 +191,23 @@ LyXFont mathed_get_font(short type, int size) int mathed_string_width(short type, int size, byte const * s, int ls) { - LyXFont f = WhichFont(type, size); - - byte sx[80]; - if (MathIsBinary(type)) { - byte * ps = &sx[0]; - for (int i = 0; i < ls && i < 75; ++i) { - *(ps++) = ' '; - *(ps++) = s[i]; - *(ps++) = ' '; - } - *(ps++) = '\0'; - ls *= 3; - s = &sx[0]; - } - return lyxfont::width(reinterpret_cast(s), ls, f); + string st; + if (MathIsBinary(type)) + for (int i = 0; i < ls; ++i) { + st += ' '; + st += s[i]; + st += ' '; + } + else + st = string(reinterpret_cast(s), ls); + + LyXFont const f = WhichFont(type, size); + return lyxfont::width(st, f); +} + +int mathed_string_width(short type, int size, string const & str) +{ + return mathed_string_width(type, size, reinterpret_cast(str.c_str()), str.length()); } @@ -230,19 +225,25 @@ int mathed_string_height(short type, int size, byte const * s, LyXFont font = WhichFont(type, size); asc = des = 0; for (int i = 0; i < ls; ++i) { - if (lyxfont::descent(s[i], font) > des) - des = lyxfont::descent(s[i], font); - if (lyxfont::ascent(s[i], font) > asc) - asc = lyxfont::ascent(s[i], font); + des = max(des, lyxfont::descent(s[i], font)); + asc = max(asc, lyxfont::ascent(s[i], font)); } return asc + des; } +int mathed_string_height(short type, int size, string const & str, + int & asc, int & des) +{ + return mathed_string_height(type, size, + reinterpret_cast(str.c_str()), str.length(), + asc, des); +} + + int mathed_char_height(short type, int size, byte c, int & asc, int & des) { LyXFont font = WhichFont(type, size); - asc = des = 0; des = lyxfont::descent(c, font); asc = lyxfont::ascent(c, font); return asc + des; @@ -250,18 +251,20 @@ int mathed_char_height(short type, int size, byte c, int & asc, int & des) // In a near future maybe we use a better fonts renderer -void MathedInset::drawStr(Painter & pain, short type, int size, +void MathedInset::drawStr(Painter & pain, short type, int siz, int x, int y, byte const * s, int ls) { string st; - if (MathIsBinary(type)) { + if (MathIsBinary(type)) for (int i = 0; i < ls; ++i) { - st += string(" ") + char(s[i]) + ' '; + st += ' '; + st += char(s[i]); + st += ' '; } - } else { + else st = string(reinterpret_cast(s), ls); - } - LyXFont mf = mathed_get_font(type, size); + + LyXFont const mf = mathed_get_font(type, siz); pain.text(x, y, st, mf); } @@ -297,7 +300,7 @@ InsetFormula::~InsetFormula() } -Inset * InsetFormula::Clone() const +Inset * InsetFormula::Clone(Buffer const &) const { InsetFormula * f = new InsetFormula(par); f->label = label; @@ -305,35 +308,39 @@ Inset * InsetFormula::Clone() const } -void InsetFormula::Write(ostream & os) const +void InsetFormula::Write(Buffer const * buf, ostream & os) const { os << "Formula "; - Latex(os, 0, 0); + Latex(buf, os, false, false); } -int InsetFormula::Latex(ostream & os, signed char fragile, bool) const +int InsetFormula::Latex(Buffer const *, ostream & os, bool fragile, bool) const { int ret = 0; //#warning Alejandro, the number of lines is not returned in this case // This problem will disapear at 0.13. - if (fragile < 0) - par->Write(os); - else - mathed_write(par, os, &ret, fragile, label.c_str()); + mathed_write(par, os, &ret, fragile, label); return ret; } -int InsetFormula::Linuxdoc(ostream &) const +int InsetFormula::Ascii(Buffer const *, ostream & os, int) const { + par->Write(os, false); return 0; } -int InsetFormula::DocBook(ostream&) const +int InsetFormula::Linuxdoc(Buffer const * buf, ostream & os) const { - return 0; + return Ascii(buf, os, 0); +} + + +int InsetFormula::DocBook(Buffer const * buf, ostream & os) const +{ + return Ascii(buf, os, 0); } @@ -346,14 +353,16 @@ void InsetFormula::Validate(LaTeXFeatures & features) const } -void InsetFormula::Read(LyXLex & lex) +void InsetFormula::Read(Buffer const *, LyXLex & lex) { istream & is = lex.getStream(); mathed_parser_file(is, lex.GetLineNo()); // Silly hack to read labels. - mathed_label = 0; + //mathed_label = 0; + mathed_label.erase(); + mathed_parse(0, 0, &par); par->Metrics(); disp_flag = (par->GetType() > 0); @@ -361,9 +370,20 @@ void InsetFormula::Read(LyXLex & lex) // Update line number lex.setLineNo(mathed_parser_lineno()); - if (mathed_label) { + //if (mathed_label) { + if (!mathed_label.empty()) { label = mathed_label; - mathed_label = 0; + //mathed_label = 0; + mathed_label.erase(); + } + + // reading of end_inset in the inset!!! + while (lex.IsOK()) { + lex.nextToken(); + if (lex.GetString() == "\\end_inset") + break; + lyxerr << "InsetFormula::Read: Garbage before \\end_inset," + " or missing \\end_inset!" << endl; } #ifdef DEBUG @@ -372,19 +392,19 @@ void InsetFormula::Read(LyXLex & lex) } -int InsetFormula::ascent(Painter &, LyXFont const &) const +int InsetFormula::ascent(BufferView *, LyXFont const &) const { return par->Ascent() + ((disp_flag) ? 8 : 1); } -int InsetFormula::descent(Painter &, LyXFont const &) const +int InsetFormula::descent(BufferView *, LyXFont const &) const { return par->Descent() + ((disp_flag) ? 8 : 1); } -int InsetFormula::width(Painter &, LyXFont const & f) const +int InsetFormula::width(BufferView *, LyXFont const & f) const { lfont_size = f.size(); par->Metrics(); @@ -392,9 +412,10 @@ int InsetFormula::width(Painter &, LyXFont const & f) const } -void InsetFormula::draw(Painter & pain, LyXFont const & f, - int baseline, float & x) const +void InsetFormula::draw(BufferView * bv, LyXFont const & f, + int baseline, float & x, bool) const { + Painter & pain = bv->painter(); // Seems commenting out solves a problem. LyXFont font = mathed_get_font(LM_TC_TEXTRM, LM_ST_TEXT); font.setSize(f.size()); @@ -416,11 +437,11 @@ void InsetFormula::draw(Painter & pain, LyXFont const & f, } else { par->draw(pain, int(x), baseline); } - x += float(width(pain, font)); + x += float(width(bv, font)); if (par->GetType() == LM_OT_PARN || par->GetType() == LM_OT_MPARN) { - LyXFont font = WhichFont(LM_TC_BF, par->size); - font.setLatex(LyXFont::OFF); + LyXFont wfont = WhichFont(LM_TC_BF, par->size); + wfont.setLatex(LyXFont::OFF); if (par->GetType() == LM_OT_PARN) { string str; @@ -428,7 +449,7 @@ void InsetFormula::draw(Painter & pain, LyXFont const & f, str = string("(") + label + ")"; else str = string("(#)"); - pain.text(int(x + 20), baseline, str, font); + pain.text(int(x + 20), baseline, str, wfont); } else if (par->GetType() == LM_OT_MPARN) { MathMatrixInset * mt = static_cast(par); @@ -438,11 +459,11 @@ void InsetFormula::draw(Painter & pain, LyXFont const & f, y = baseline + crow->getBaseline(); if (crow->isNumbered()) { string str; - if (crow->getLabel()) + if (!crow->getLabel().empty()) str = string("(") + crow->getLabel() + ")"; else str = "(#)"; - pain.text(int(x + 20), y, str, font); + pain.text(int(x + 20), y, str, wfont); } crow = crow->getNext(); } @@ -452,7 +473,7 @@ void InsetFormula::draw(Painter & pain, LyXFont const & f, } -char const * InsetFormula::EditMessage() const +string const InsetFormula::EditMessage() const { return _("Math editor mode"); } @@ -461,7 +482,8 @@ char const * InsetFormula::EditMessage() const void InsetFormula::Edit(BufferView * bv, int x, int y, unsigned int) { mathcursor = new MathedCursor(par); - bv->lockInset(this); + if (!bv->lockInset(this)) + lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl; par->Metrics(); bv->updateInset(this, false); x += par->xo; @@ -487,27 +509,29 @@ void InsetFormula::InsetUnlock(BufferView * bv) // Now a symbol can be inserted only if the inset is locked -void InsetFormula::InsertSymbol(BufferView * bv, char const * s) +void InsetFormula::InsertSymbol(BufferView * bv, string const & s) { - if (!s || !mathcursor) return; + if (s.empty() || !mathcursor) return; mathcursor->Interpret(s); UpdateLocal(bv); } -void InsetFormula::GetCursorPos(int& x, int& y) const +void InsetFormula::GetCursorPos(BufferView *, int & x, int & y) const { mathcursor->GetPos(x, y); x -= par->xo; y -= par->yo; } + void InsetFormula::ToggleInsetCursor(BufferView * bv) { if (!mathcursor) return; - int x, y; + int x; + int y; mathcursor->GetPos(x, y); // x -= par->xo; y -= par->yo; @@ -523,11 +547,12 @@ void InsetFormula::ToggleInsetCursor(BufferView * bv) } -void InsetFormula::ShowInsetCursor(BufferView * bv) +void InsetFormula::ShowInsetCursor(BufferView * bv, bool) { if (!cursor_visible) { if (mathcursor) { - int x, y; + int x; + int y; mathcursor->GetPos(x, y); // x -= par->xo; y -= par->yo; @@ -557,7 +582,7 @@ void InsetFormula::ToggleInsetSelection(BufferView * bv) //int n; //XPoint * p = //mathcursor->SelGetArea(n); -// XFillPolygon(fl_display, pm, LyXGetSelectionGC(), p, n, Nonconvex, CoordModeOrigin); +// XFillPolygon(fl_get_display(), pm, LyXGetSelectionGC(), p, n, Nonconvex, CoordModeOrigin); // x -= par->xo; // y -= par->yo; @@ -583,7 +608,7 @@ void InsetFormula::display(bool dspf) par->SetType(LM_OT_MIN); par->SetStyle(LM_ST_TEXT); if (!label.empty() && par->GetType() != LM_OT_MPARN) { - label.clear(); + label.erase(); } } disp_flag = dspf; @@ -591,48 +616,25 @@ void InsetFormula::display(bool dspf) } -int InsetFormula::GetNumberOfLabels() const +vector const InsetFormula::getLabelList() const { - // This is dirty, I know. I'll clean it at 0.13 - if (par->GetType() == LM_OT_MPARN) { - MathMatrixInset * mt = static_cast(par); - int nl = 0; - MathedRowSt const * crow = mt->getRowSt(); - while (crow) { - if (crow->getLabel()) ++nl; - crow = crow->getNext(); - } - return nl; - } else - if (!label.empty()) - return 1; - else - return 0; -} +//#warning This is dirty, I know. Ill clean it at 0.11 +// Correction, the only way to clean this is with a new kernel: 0.13. + vector label_list; -string InsetFormula::getLabel(int il) const -{ -//#warning This is dirty, I know. Ill clean it at 0.11 - // Correction, the only way to clean this is with a new kernel: 0.13. if (par->GetType() == LM_OT_MPARN) { - string lab; MathMatrixInset * mt = static_cast(par); - int nl = 0; MathedRowSt const * crow = mt->getRowSt(); while (crow) { - if (crow->getLabel()) { - if (nl == il) { - lab = crow->getLabel(); - break; - } - ++nl; - } + if (!crow->getLabel().empty()) + label_list.push_back(crow->getLabel()); crow = crow->getNext(); } - return lab; - } - return label; + } else if (!label.empty()) + label_list.push_back(label); + + return label_list; } @@ -684,8 +686,7 @@ void InsetFormula::InsetMotionNotify(BufferView * bv, mathcursor->SelStart(); ShowInsetCursor(bv); mathcursor->GetPos(sel_x, sel_y); - } else - if (sel_flag) { + } else if (sel_flag) { HideInsetCursor(bv); x += par->xo; y += par->yo; @@ -745,32 +746,41 @@ InsetFormula::LocalDispatch(BufferView * bv, case LFUN_RIGHT: { result = DISPATCH_RESULT(mathcursor->Right(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; } case LFUN_LEFTSEL: sel = true; case LFUN_LEFT: { result = DISPATCH_RESULT(mathcursor->Left(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; } case LFUN_UPSEL: sel = true; case LFUN_UP: result = DISPATCH_RESULT(mathcursor->Up(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; case LFUN_DOWNSEL: sel = true; case LFUN_DOWN: result = DISPATCH_RESULT(mathcursor->Down(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; case LFUN_HOME: mathcursor->Home(); + result = DISPATCHED_NOUPDATE; break; case LFUN_END: mathcursor->End(); + result = DISPATCHED_NOUPDATE; break; case LFUN_DELETE_LINE_FORWARD: - //current_view->lockedInsetStoreUndo(Undo::INSERT); - bv->lockedInsetStoreUndo(Undo::DELETE); + bv->lockedInsetStoreUndo(Undo::DELETE); mathcursor->DelLine(); UpdateLocal(bv); break; @@ -800,8 +810,7 @@ InsetFormula::LocalDispatch(BufferView * bv, } case LFUN_DELETE: - //current_view->lockedInsetStoreUndo(Undo::INSERT); - bv->lockedInsetStoreUndo(Undo::DELETE); + bv->lockedInsetStoreUndo(Undo::DELETE); mathcursor->Delete(); bv->updateInset(this, true); break; @@ -811,12 +820,11 @@ InsetFormula::LocalDispatch(BufferView * bv, // break; case LFUN_SETXY: { - int x, y, x1, y1; -#ifdef HAVE_SSTREAM + int x; + int y; + int x1; + int y1; istringstream ist(arg.c_str()); -#else - istrstream ist(arg.c_str()); -#endif ist >> x >> y; par->GetXY(x1, y1); mathcursor->SetPos(x1 + x, y1 + y); @@ -899,7 +907,7 @@ InsetFormula::LocalDispatch(BufferView * bv, if (oldf) { --type; if (!label.empty()) { - label.clear(); + label.erase(); } bv->owner()->getMiniBuffer()->Set(_("No number")); } else { @@ -934,7 +942,7 @@ InsetFormula::LocalDispatch(BufferView * bv, case LFUN_MATH_SIZE: if (!arg.empty()) { - latexkeys * l = in_word_set (arg.c_str(), strlen(arg.c_str())); + latexkeys * l = in_word_set (arg); int sz = (l) ? l->id: -1; mathcursor->SetSize(sz); UpdateLocal(bv); @@ -944,7 +952,7 @@ InsetFormula::LocalDispatch(BufferView * bv, case LFUN_INSERT_MATH: { bv->lockedInsetStoreUndo(Undo::INSERT); - InsertSymbol(bv, arg.c_str()); + InsertSymbol(bv, arg); break; } @@ -984,13 +992,13 @@ InsetFormula::LocalDispatch(BufferView * bv, if (arg.empty()) break; - strncpy(arg2, arg.c_str(), 40); arg2[39]= '\0'; + ::strncpy(arg2, arg.c_str(), 40); arg2[39]= '\0'; int n = sscanf(arg2, "%s %s", lf, rg); lf[39] = '\0'; rg[39] = '\0'; if (n > 0) { if (isdigit(lf[0])) - ilf = atoi(lf); + ilf = lyx::atoi(lf); else if (lf[1]) { l = in_word_set(lf, strlen(lf)); @@ -1002,7 +1010,7 @@ InsetFormula::LocalDispatch(BufferView * bv, if (n > 1) { if (isdigit(rg[0])) - irg = atoi(rg); + irg = lyx::atoi(rg); else if (rg[1]) { l = in_word_set(rg, strlen(rg)); @@ -1036,15 +1044,15 @@ InsetFormula::LocalDispatch(BufferView * bv, string lb = arg; if (lb.empty()) { pair - result = askForText(_("Enter new label to insert:")); - if (result.first) { - lb = result.second; + res = askForText(_("Enter new label to insert:")); + if (res.first) { + lb = res.second; } } if (!lb.empty() && lb[0] > ' ') { SetNumber(true); if (par->GetType() == LM_OT_MPARN) { - mathcursor->setLabel(lb.c_str()); + mathcursor->setLabel(lb); // MathMatrixInset *mt = (MathMatrixInset*)par; // mt->SetLabel(lb); } else { @@ -1053,13 +1061,12 @@ InsetFormula::LocalDispatch(BufferView * bv, } UpdateLocal(bv); } else - label.clear(); + label.erase(); break; } case LFUN_MATH_DISPLAY: - //current_view->lockedInsetStoreUndo(Undo::INSERT); - bv->lockedInsetStoreUndo(Undo::EDIT); + bv->lockedInsetStoreUndo(Undo::EDIT); display(!disp_flag); UpdateLocal(bv); break; @@ -1082,7 +1089,7 @@ InsetFormula::LocalDispatch(BufferView * bv, //------- dummy actions case LFUN_EXEC_COMMAND: - bv->owner()->getMiniBuffer()->ExecCommand(); + bv->owner()->getMiniBuffer()->PrepareForCommand(); break; default: @@ -1114,7 +1121,21 @@ InsetFormula::LocalDispatch(BufferView * bv, } // lyxerr << "Varcode << vardoce; - mathcursor->Insert(c, (greek_kb_flag) ? LM_TC_SYMB: varcode); + MathedTextCodes char_code = varcode; + if (greek_kb_flag) { + char greek[26] = + {'A', 'B', 'X', 0 , 'E', 0 , 0 , 'H', 'I', 0 , + 'K', 0 , 'M', 'N', 'O', 0 , 0 , 'P', 0 , 'T', + 'Y', 0, 0, 0, 0 , 'Z' }; + if ('A' <= c && c <= 'Z' && greek[c - 'A']) { + char_code = LM_TC_RM; + c = greek[c - 'A']; + } else + char_code = LM_TC_SYMB; + } + mathcursor->Insert(c, char_code); + if (greek_kb_flag && char_code == LM_TC_RM ) + mathcursor->setLastCode(LM_TC_VAR); varcode = LM_TC_MIN; if (greek_kb_flag<2) greek_kb_flag = 0; } else @@ -1177,7 +1198,7 @@ InsetFormula::LocalDispatch(BufferView * bv, result = FINISHED; } } else - if (c == '\'') { + if (c == '\'' || c == '@') { mathcursor->Insert (c, LM_TC_VAR); } else if (c == '\\') { @@ -1200,7 +1221,7 @@ InsetFormula::LocalDispatch(BufferView * bv, if (mathcursor->Selection() || was_selection) ToggleInsetSelection(bv); - if (result == DISPATCHED) + if ((result == DISPATCHED) || (result == DISPATCHED_NOUPDATE)) ShowInsetCursor(bv); else bv->unlockInset(this); @@ -1212,7 +1233,7 @@ InsetFormula::LocalDispatch(BufferView * bv, void MathFuncInset::draw(Painter & pain, int x, int y) { - if (name && name[0] > ' ') { + if (!name.empty() && name[0] > ' ') { LyXFont font = WhichFont(LM_TC_TEXTRM, size); font.setLatex(LyXFont::ON); x += (lyxfont::width('I', font) + 3) / 4; @@ -1223,14 +1244,18 @@ MathFuncInset::draw(Painter & pain, int x, int y) void MathFuncInset::Metrics() { - ln = (name) ? strlen(name): 0; + //ln = (name) ? strlen(name): 0; LyXFont font = WhichFont(LM_TC_TEXTRM, size); font.setLatex(LyXFont::ON); - width = lyxfont::width(name, ln, font) - + lyxfont::width('I', font) / 2; - mathed_string_height(LM_TC_TEXTRM, size, - reinterpret_cast(name), - strlen(name), ascent, descent); + if (name.empty()) { + width = df_width; + descent = df_des; + ascent = df_asc; + } else { + width = lyxfont::width(name, font) + + lyxfont::width('I', font) / 2; + mathed_string_height(LM_TC_TEXTRM, size, name, ascent, descent); + } } @@ -1244,7 +1269,7 @@ void mathedValidate(LaTeXFeatures & features, MathParInset * par) if(it.IsActive()) { MathParInset * p = it.GetActiveInset(); if (!features.binom && p->GetType() == LM_OT_MACRO && - strcmp(p->GetName(), "binom") == 0) { + p->GetName() == "binom") { features.binom = true; } else { for (int i = 0; i <= p->getMaxArgumentIdx(); ++i) { @@ -1254,8 +1279,8 @@ void mathedValidate(LaTeXFeatures & features, MathParInset * par) } } else { MathedInset* p = it.GetInset(); - if (!features.boldsymbol && p->GetName() && - strcmp(p->GetName(), "boldsymbol") == 0) { + if (!features.boldsymbol && + p->GetName() == "boldsymbol") { features.boldsymbol = true; } }