X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathHull.cpp;h=0f7e9a85df7fbd1b39362121b8f326772999a8f9;hb=ebe6612e2661f49dcfae6103f056c27afd47751f;hp=2916bb2ea0fc1a1ddd97c5991792350bf4f8f282;hpb=de786bfcdf739822fe4c21847735c54140cf84f4;p=lyx.git diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 2916bb2ea0..0f7e9a85df 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -15,7 +15,6 @@ #include "InsetMathChar.h" #include "InsetMathColor.h" #include "InsetMathFrac.h" -#include "InsetMathGrid.h" #include "InsetMathNest.h" #include "InsetMathScript.h" #include "MathExtern.h" @@ -36,13 +35,14 @@ #include "LaTeXFeatures.h" #include "LyXRC.h" #include "MacroTable.h" -#include "MathMacro.h" -#include "MathMacroTemplate.h" +#include "InsetMathMacro.h" +#include "InsetMathMacroTemplate.h" #include "MetricsInfo.h" #include "output_xhtml.h" #include "Paragraph.h" #include "ParIterator.h" #include "sgml.h" +#include "TexRow.h" #include "TextClass.h" #include "TextPainter.h" #include "TocBackend.h" @@ -59,11 +59,12 @@ #include "frontends/Painter.h" #include "support/convert.h" -#include "support/lassert.h" #include "support/debug.h" -#include "support/filetools.h" #include "support/gettext.h" +#include "support/filetools.h" +#include "support/lassert.h" #include "support/lstrings.h" +#include "support/RefChanger.h" #include @@ -107,7 +108,7 @@ namespace { size_t firstRelOp(MathData const & ar) { for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it) - if ((*it)->isMathRel()) + if ((*it)->mathClass() == MC_REL) return it - ar.begin(); return ar.size(); } @@ -119,7 +120,38 @@ namespace { } -} // end anon namespace + // writes a preamble for underlined or struck out math display + void writeMathdisplayPreamble(WriteStream & os) + { + if (os.strikeoutMath()) { + if (os.ulemCmd() == WriteStream::UNDERLINE) + os << "\\raisebox{-\\belowdisplayshortskip}{" + "\\lyxmathsout{\\parbox[b]{\\linewidth}{"; + else + os << "\\lyxmathsout{\\parbox{\\linewidth}{"; + } else if (os.ulemCmd() == WriteStream::UNDERLINE) + os << "\\raisebox{-\\belowdisplayshortskip}{" + "\\parbox[b]{\\linewidth}{"; + else if (os.ulemCmd() == WriteStream::STRIKEOUT) + os << "\\parbox{\\linewidth}{"; + } + + + // writes a postamble for underlined or struck out math display + void writeMathdisplayPostamble(WriteStream & os) + { + if (os.strikeoutMath()) { + if (os.ulemCmd() == WriteStream::UNDERLINE) + os << "}"; + os << "}}\\\\\n"; + } else if (os.ulemCmd() == WriteStream::UNDERLINE) + os << "}}\\\\\n"; + else if (os.ulemCmd() == WriteStream::STRIKEOUT) + os << "}\\\\\n"; + } + + +} // namespace HullType hullType(docstring const & s) @@ -248,7 +280,7 @@ void InsetMathHull::setBuffer(Buffer & buffer) namespace { const char * counters_to_save[] = {"section", "chapter"}; unsigned int const numcnts = sizeof(counters_to_save)/sizeof(char *); -} +} // namespace void InsetMathHull::updateBuffer(ParIterator const & it, UpdateType utype) @@ -284,8 +316,12 @@ void InsetMathHull::updateBuffer(ParIterator const & it, UpdateType utype) counter_map[eqstr] = cnts.value(eqstr); for (size_t i = 0; i != label_.size(); ++i) { if (numbered(i)) { - cnts.step(eqstr, utype); - numbers_[i] = cnts.theCounter(eqstr, lang); + Paragraph const & par = it.paragraph(); + if (!par.isDeleted(it.pos())) { + cnts.step(eqstr, utype); + numbers_[i] = cnts.theCounter(eqstr, lang); + } else + numbers_[i] = from_ascii("#"); } else numbers_[i] = empty_docstring(); } @@ -303,7 +339,7 @@ void InsetMathHull::updateBuffer(ParIterator const & it, UpdateType utype) void InsetMathHull::addToToc(DocIterator const & pit, bool output_active, - UpdateType utype) const + UpdateType utype, TocBackend & backend) const { if (!buffer_) { //FIXME: buffer_ should be set at creation for this inset! Problem is @@ -312,15 +348,42 @@ void InsetMathHull::addToToc(DocIterator const & pit, bool output_active, return; } - shared_ptr toc = buffer().tocBackend().toc("equation"); - + TocBuilder & b = backend.builder("equation"); + // compute first and last item + row_type first = nrows(); + for (row_type row = 0; row != nrows(); ++row) + if (numbered(row)) { + first = row; + break; + } + if (first == nrows()) + // no equation + return; + row_type last = nrows() - 1; + for (; last != 0; --last) + if (numbered(last)) + break; + // add equation numbers + b.pushItem(pit, docstring(), output_active); + if (first != last) + b.argumentItem(bformat(from_ascii("(%1$s-%2$s)"), + numbers_[first], numbers_[last])); for (row_type row = 0; row != nrows(); ++row) { if (!numbered(row)) continue; if (label_[row]) - label_[row]->addToToc(pit, output_active, utype); - toc->push_back(TocItem(pit, 0, nicelabel(row), output_active)); + label_[row]->addToToc(pit, output_active, utype, backend); + docstring label = nicelabel(row); + if (first == last) + // this is the only equation + b.argumentItem(label); + else { + // insert as sub-items + b.pushItem(pit, label, output_active); + b.pop(); + } } + b.pop(); } @@ -483,14 +546,12 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const if (display()) dim.des += displayMargin(); } - // Cache the inset dimension. - setDimCache(mi, dim); return; } - // FIXME: Changing the same object repeatedly is inefficient. Changer dummy1 = mi.base.changeFontSet(standardFont()); - Changer dummy2 = mi.base.changeStyle(display() ? LM_ST_DISPLAY : LM_ST_TEXT); + Changer dummy2 = mi.base.font.changeStyle(display() ? LM_ST_DISPLAY + : LM_ST_TEXT); // let the cells adjust themselves InsetMathGrid::metrics(mi, dim); @@ -501,26 +562,18 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const } if (numberedType()) { - Changer dummy = mi.base.changeFontSet("mathbf"); + Changer dummy = mi.base.changeFontSet("mathrm"); int l = 0; for (row_type row = 0; row < nrows(); ++row) l = max(l, mathed_string_width(mi.base.font, nicelabel(row))); if (l) - dim.wid += 30 + l; + // Value was hardcoded to 30 pixels + dim.wid += Length(0.3, Length::IN).inPixels(mi.base) + l; } - if (type_ == hullRegexp) - dim.wid += 2; - // make it at least as high as the current font - int asc = 0; - int des = 0; - math_font_max_dim(mi.base.font, asc, des); - dim.asc = max(dim.asc, asc); - dim.des = max(dim.des, des); - // Cache the inset dimension. - // FIXME: This will overwrite InsetMathGrid dimension, is that OK? - setDimCache(mi, dim); + // reserve some space for marker. + dim.wid += 2; } @@ -543,6 +596,25 @@ ColorCode InsetMathHull::backgroundColor(PainterInfo const & pi) const } +void InsetMathHull::drawMarkers(PainterInfo & pi, int x, int y) const +{ + ColorCode pen_color = mouseHovered(pi.base.bv) || editing(pi.base.bv)? + Color_mathframe : Color_mathcorners; + // If the corners have the same color as the background, do not paint them. + if (lcolor.getX11Name(Color_mathbg) == lcolor.getX11Name(pen_color)) + return; + + Inset::drawMarkers(pi, x, y); + Dimension const dim = dimension(*pi.base.bv); + int const t = x + dim.width() - 1; + int const a = y - dim.ascent(); + pi.pain.line(x, a + 3, x, a, pen_color); + pi.pain.line(t, a + 3, t, a, pen_color); + pi.pain.line(x, a, x + 3, a, pen_color); + pi.pain.line(t - 3, a, t, a, pen_color); +} + + void InsetMathHull::drawBackground(PainterInfo & pi, int x, int y) const { Dimension const dim = dimension(*pi.base.bv); @@ -561,13 +633,15 @@ void InsetMathHull::draw(PainterInfo & pi, int x, int y) const BufferView const * const bv = pi.base.bv; Dimension const dim = dimension(*bv); - if (type_ == hullRegexp) { - pi.pain.rectangle(x + 1, y - dim.ascent() + 1, - dim.width() - 2, dim.height() - 2, Color_regexpframe); - } + if (type_ == hullRegexp) + pi.pain.rectangle(x + 2, y - dim.ascent() + 1, + dim.width() - 3, dim.height() - 2, Color_regexpframe); if (previewState(bv)) { - // FIXME CT this + // Do not draw change tracking cue if taken care of by RowPainter + // already. + Changer dummy = !canPaintChange(*bv) ? make_change(pi.change_, Change()) + : Changer(); if (previewTooSmall(dim)) { // we have an extra frame preview_->draw(pi, x + ERROR_FRAME_WIDTH, y); @@ -575,33 +649,52 @@ void InsetMathHull::draw(PainterInfo & pi, int x, int y) const // one pixel gap in front preview_->draw(pi, x + 1, y); } - setPosCache(pi, x, y); return; } ColorCode color = pi.selected && lyxrc.use_system_colors ? Color_selectiontext : standardColor(); bool const really_change_color = pi.base.font.color() == Color_none; - Changer dummy0 = pi.base.font.changeColor(color, really_change_color); + Changer dummy0 = really_change_color ? pi.base.font.changeColor(color) + : Changer(); Changer dummy1 = pi.base.changeFontSet(standardFont()); - Changer dummy2 = pi.base.changeStyle(display() ? LM_ST_DISPLAY : LM_ST_TEXT); + Changer dummy2 = pi.base.font.changeStyle(display() ? LM_ST_DISPLAY + : LM_ST_TEXT); + + int xmath = x; + BufferParams::MathNumber const math_number = buffer().params().getMathNumber(); + if (numberedType() && math_number == BufferParams::LEFT) { + Changer dummy = pi.base.changeFontSet("mathrm"); + int l = 0; + for (row_type row = 0; row < nrows(); ++row) + l = max(l, mathed_string_width(pi.base.font, nicelabel(row))); - InsetMathGrid::draw(pi, x + 1, y); + if (l) + // Value was hardcoded to 30 pixels + xmath += Length(0.3, Length::IN).inPixels(pi.base) + l; + } + + InsetMathGrid::draw(pi, xmath + 1, y); + drawMarkers(pi, x, y); if (numberedType()) { - int const xx = x + colinfo_.back().offset_ + colinfo_.back().width_ + 20; + Changer dummy = pi.base.changeFontSet("mathrm"); for (row_type row = 0; row < nrows(); ++row) { int const yy = y + rowinfo_[row].offset_; - Changer dummy = pi.base.changeFontSet("mathrm"); docstring const nl = nicelabel(row); - pi.draw(xx, yy, nl); + if (math_number == BufferParams::LEFT) + pi.draw(x, yy, nl); + else { + int l = mathed_string_width(pi.base.font, nl); + pi.draw(x + dim.wid - l, yy, nl); + } } } + // drawing change line if (canPaintChange(*bv)) pi.change_.paintCue(pi, x + 1, y + 1 - dim.asc, x + dim.wid, y + dim.des); - setPosCache(pi, x, y); } @@ -611,8 +704,7 @@ void InsetMathHull::metricsT(TextMetricsInfo const & mi, Dimension & dim) const InsetMathGrid::metricsT(mi, dim); } else { odocstringstream os; - TexRow texrow(false); - otexrowstream ots(os,texrow); + otexrowstream ots(os); WriteStream wi(ots, false, true, WriteStream::wsDefault); write(wi); dim.wid = os.str().size(); @@ -628,8 +720,7 @@ void InsetMathHull::drawT(TextPainter & pain, int x, int y) const InsetMathGrid::drawT(pain, x, y); } else { odocstringstream os; - TexRow texrow(false); - otexrowstream ots(os,texrow); + otexrowstream ots(os); WriteStream wi(ots, false, true, WriteStream::wsDefault); write(wi); pain.draw(x, y, os.str().c_str()); @@ -648,8 +739,7 @@ static docstring latexString(InsetMathHull const & inset) static Encoding const * encoding = 0; if (inset.isBufferValid()) encoding = &(inset.buffer().params().encoding()); - TexRow texrow(false); - otexrowstream ots(ls,texrow); + otexrowstream ots(ls); WriteStream wi(ots, false, true, WriteStream::wsPreview, encoding); inset.write(wi); return ls.str(); @@ -678,8 +768,8 @@ void InsetMathHull::usedMacros(MathData const & md, DocIterator const & pos, MacroNameSet::iterator const end = macros.end(); for (size_t i = 0; i < md.size(); ++i) { - MathMacro const * mi = md[i].nucleus()->asMacro(); - MathMacroTemplate const * mt = md[i].nucleus()->asMacroTemplate(); + InsetMathMacro const * mi = md[i].nucleus()->asMacro(); + InsetMathMacroTemplate const * mt = md[i].nucleus()->asMacroTemplate(); InsetMathScript const * si = md[i].nucleus()->asScriptInset(); InsetMathFracBase const * fi = md[i].nucleus()->asFracBaseInset(); InsetMathGrid const * gi = md[i].nucleus()->asGridInset(); @@ -768,7 +858,7 @@ void InsetMathHull::preparePreview(DocIterator const & pos, endfont += '}'; } if (lsize != "normalsize" && !prefixIs(lsize, "error")) - setfont += from_ascii("\\" + lsize + '\n'); + setfont += from_ascii("\\" + lsize + '\n'); docstring setcnt; if (forexport && haveNumbers()) { @@ -898,6 +988,29 @@ bool InsetMathHull::ams() const } +bool InsetMathHull::outerDisplay() const +{ + switch (type_) { + case hullEquation: + case hullEqnArray: + case hullAlign: + case hullFlAlign: + case hullGather: + case hullMultline: + return true; + case hullNone: + case hullSimple: + case hullAlignAt: + case hullXAlignAt: + case hullXXAlignAt: + case hullUnknown: + case hullRegexp: + break; + } + return false; +} + + Inset::DisplayType InsetMathHull::display() const { switch (type_) { @@ -915,12 +1028,31 @@ Inset::DisplayType InsetMathHull::display() const case hullEquation: case hullMultline: case hullGather: - return AlignCenter; + if (buffer().params().is_math_indent) + return AlignLeft; + else + return AlignCenter; } // avoid warning return AlignCenter; } + +int InsetMathHull::indent(BufferView const & bv) const +{ + // FIXME: set this in the textclass. This value is what the article class uses. + static Length default_indent(2.5, Length::EM); + if (display() != Inline && buffer().params().is_math_indent) { + Length const & len = buffer().params().getMathIndent(); + if (len.empty()) + return bv.inPixels(default_indent); + else + return bv.inPixels(len); + } else + return Inset::indent(bv); +} + + bool InsetMathHull::numberedType() const { switch (type_) { @@ -955,14 +1087,17 @@ void InsetMathHull::validate(LaTeXFeatures & features) const if (type_ == hullRegexp) { features.require("color"); - string frcol = lcolor.getLaTeXName(Color_regexpframe); - string bgcol = "white"; + docstring frcol = from_utf8(lcolor.getLaTeXName(Color_regexpframe)); + docstring bgcol = from_ascii("white"); features.addPreambleSnippet( - string("\\newcommand{\\regexp}[1]{\\fcolorbox{") - + frcol + string("}{") - + bgcol + string("}{\\ensuremath{\\mathtt{#1}}}}")); + "\\newcommand{\\regexp}[1]{\\fcolorbox{" + + frcol + "}{" + + bgcol + "}{\\ensuremath{\\mathtt{#1}}}}"); features.addPreambleSnippet( - string("\\newcommand{\\endregexp}{}")); + from_ascii("\\newcommand{\\endregexp}{}")); + } else if (outerDisplay() && features.inDeletedInset() + && !features.mustProvide("ct-dvipost")) { + features.require("ct-tikz-math-sout"); } // Validation is necessary only if not using AMS math. @@ -994,6 +1129,8 @@ void InsetMathHull::header_write(WriteStream & os) const break; case hullSimple: + if (os.ulemCmd()) + os << "\\mbox{"; os << '$'; os.startOuterRow(); if (cell(0).empty()) @@ -1001,6 +1138,7 @@ void InsetMathHull::header_write(WriteStream & os) const break; case hullEquation: + writeMathdisplayPreamble(os); os << "\n"; os.startOuterRow(); if (n) @@ -1014,6 +1152,7 @@ void InsetMathHull::header_write(WriteStream & os) const case hullFlAlign: case hullGather: case hullMultline: + writeMathdisplayPreamble(os); os << "\n"; os.startOuterRow(); os << "\\begin{" << hullName(type_) << star(n) << "}\n"; @@ -1058,6 +1197,8 @@ void InsetMathHull::footer_write(WriteStream & os) const case hullSimple: os << '$'; + if (os.ulemCmd()) + os << "}"; break; case hullEquation: @@ -1067,15 +1208,22 @@ void InsetMathHull::footer_write(WriteStream & os) const os << "\\end{equation" << star(n) << "}\n"; else os << "\\]\n"; + writeMathdisplayPostamble(os); break; case hullEqnArray: case hullAlign: case hullFlAlign: - case hullAlignAt: - case hullXAlignAt: case hullGather: case hullMultline: + os << "\n"; + os.startOuterRow(); + os << "\\end{" << hullName(type_) << star(n) << "}\n"; + writeMathdisplayPostamble(os); + break; + + case hullAlignAt: + case hullXAlignAt: os << "\n"; os.startOuterRow(); os << "\\end{" << hullName(type_) << star(n) << "}\n"; @@ -1888,7 +2036,7 @@ bool allowDisplayMath(Cursor const & cur) return tmpcur.getStatus(cmd, status) && status.enabled(); } -} +} // namespace bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd, @@ -2023,9 +2171,24 @@ bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd, default: return InsetMathGrid::getStatus(cur, cmd, status); } +} + + +int InsetMathHull::leftMargin() const +{ + return (getType() == hullSimple) ? 0 : InsetMathGrid::leftMargin(); +} + - // This cannot really happen, but inserted to shut-up gcc - return InsetMathGrid::getStatus(cur, cmd, status); +int InsetMathHull::rightMargin() const +{ + return (getType() == hullSimple) ? 0 : InsetMathGrid::rightMargin(); +} + + +int InsetMathHull::border() const +{ + return (getType() == hullSimple) ? 0 : InsetMathGrid::border(); } @@ -2101,7 +2264,7 @@ void InsetMathHull::revealCodes(Cursor & cur) const if (!cur.inMathed()) return; odocstringstream os; - cur.info(os); + cur.info(os, false); cur.message(os.str()); /* // write something to the minibuffer @@ -2179,8 +2342,7 @@ bool InsetMathHull::searchForward(BufferView * bv, string const & str, void InsetMathHull::write(ostream & os) const { odocstringstream oss; - TexRow texrow(false); - otexrowstream ots(oss,texrow); + otexrowstream ots(oss); WriteStream wi(ots, false, false, WriteStream::wsDefault); oss << "Formula "; write(wi); @@ -2223,8 +2385,7 @@ int InsetMathHull::plaintext(odocstringstream & os, } odocstringstream oss; - TexRow texrow(false); - otexrowstream ots(oss,texrow); + otexrowstream ots(oss); Encoding const * const enc = encodings.fromLyXName("utf8"); WriteStream wi(ots, false, true, WriteStream::wsDefault, enc); @@ -2266,8 +2427,7 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons ++ms.tab(); ms.cr(); ms.os() << '<' << bname << '>'; odocstringstream ls; - TexRow texrow; - otexstream ols(ls, texrow); + otexstream ols(ls); if (runparams.flavor == OutputParams::XML) { ms << MTag("alt role='tex' "); // Workaround for db2latex: db2latex always includes equations with @@ -2285,7 +2445,7 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons } else { ms << MTag("alt role='tex'"); latex(ols, runparams); - res = texrow.rows(); + res = ols.texrow().rows(); ms << from_utf8(subst(subst(to_utf8(ls.str()), "&", "&"), "<", "<")); ms << ETag("alt"); } @@ -2534,8 +2694,7 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const // Unfortunately, we cannot use latexString() because we do not want // $...$ or whatever. odocstringstream ls; - TexRow texrow(false); - otexrowstream ots(ls,texrow); + otexrowstream ots(ls); WriteStream wi(ots, false, true, WriteStream::wsPreview); ModeSpecifier specifier(wi, MATH_MODE); mathAsLatex(wi);