X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathHull.cpp;h=807475e63aa771ed8381db02f0bc10d6424ed2f0;hb=2de30c62f8d671a8c8d4d52a6a7310e2c5ca84de;hp=e684d237f5547fe487ec66d743c9a4be10669ab4;hpb=935588f2de4703471c1dc9bac6ec0707bf3d4d8f;p=lyx.git diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index e684d237f5..807475e63a 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" @@ -38,10 +37,12 @@ #include "MacroTable.h" #include "MathMacro.h" #include "MathMacroTemplate.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" @@ -58,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 @@ -106,7 +108,7 @@ namespace { size_t firstRelOp(MathData const & ar) { for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it) - if ((*it)->isRelOp()) + if ((*it)->mathClass() == MC_REL) return it - ar.begin(); return ar.size(); } @@ -118,6 +120,37 @@ 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]{\\columnwidth}{"; + else + os << "\\lyxmathsout{\\parbox{\\columnwidth}{"; + } else if (os.ulemCmd() == WriteStream::UNDERLINE) + os << "\\raisebox{-\\belowdisplayshortskip}{" + "\\parbox[b]{\\columnwidth}{"; + else if (os.ulemCmd() == WriteStream::STRIKEOUT) + os << "\\parbox{\\columnwidth}{"; + } + + + // 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"; + } + + } // end anon namespace @@ -425,15 +458,15 @@ int InsetMathHull::defaultColSpace(col_type col) } -docstring InsetMathHull::standardFont() const +string InsetMathHull::standardFont() const { switch (type_) { case hullRegexp: - return from_ascii("texttt"); + return "texttt"; case hullNone: - return from_ascii("lyxnochange"); + return "lyxnochange"; default: - return from_ascii("mathnormal"); + return "mathnormal"; } } @@ -482,13 +515,12 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const if (display()) dim.des += displayMargin(); } - // Cache the inset dimension. - setDimCache(mi, dim); return; } - FontSetChanger dummy1(mi.base, standardFont()); - StyleChanger dummy2(mi.base, display() ? LM_ST_DISPLAY : LM_ST_TEXT); + Changer dummy1 = mi.base.changeFontSet(standardFont()); + Changer dummy2 = mi.base.font.changeStyle(display() ? LM_ST_DISPLAY + : LM_ST_TEXT); // let the cells adjust themselves InsetMathGrid::metrics(mi, dim); @@ -499,7 +531,7 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const } if (numberedType()) { - FontSetChanger dummy(mi.base, from_ascii("mathbf")); + Changer dummy = mi.base.changeFontSet("mathbf"); int l = 0; for (row_type row = 0; row < nrows(); ++row) l = max(l, mathed_string_width(mi.base.font, nicelabel(row))); @@ -516,9 +548,6 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const 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); } @@ -557,15 +586,17 @@ void InsetMathHull::drawBackground(PainterInfo & pi, int x, int y) const 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) { - Dimension const dim = dimension(*bv); - 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)) { - Dimension const dim = dimension(*bv); + // 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); @@ -573,16 +604,17 @@ 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; - ColorChanger dummy0(pi.base.font, color, really_change_color); - FontSetChanger dummy1(pi.base, standardFont()); - StyleChanger dummy2(pi.base, display() ? LM_ST_DISPLAY : LM_ST_TEXT); + Changer dummy0 = really_change_color ? pi.base.font.changeColor(color) + : Changer(); + Changer dummy1 = pi.base.changeFontSet(standardFont()); + Changer dummy2 = pi.base.font.changeStyle(display() ? LM_ST_DISPLAY + : LM_ST_TEXT); InsetMathGrid::draw(pi, x + 1, y); @@ -590,12 +622,15 @@ void InsetMathHull::draw(PainterInfo & pi, int x, int y) const int const xx = x + colinfo_.back().offset_ + colinfo_.back().width_ + 20; for (row_type row = 0; row < nrows(); ++row) { int const yy = y + rowinfo_[row].offset_; - FontSetChanger dummy(pi.base, from_ascii("mathrm")); + Changer dummy = pi.base.changeFontSet("mathrm"); docstring const nl = nicelabel(row); pi.draw(xx, yy, nl); } } - setPosCache(pi, x, y); + // drawing change line + if (canPaintChange(*bv)) + pi.change_.paintCue(pi, x + 1, y + 1 - dim.asc, + x + dim.wid, y + dim.des); } @@ -605,8 +640,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(); @@ -622,8 +656,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()); @@ -642,8 +675,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(); @@ -750,9 +782,7 @@ void InsetMathHull::preparePreview(DocIterator const & pos, macro_preamble.append(*it); // set the font series and size for this snippet - DocIterator dit = pos; - while (dit.inMathed()) - dit.pop_back(); + DocIterator dit = pos.getInnerText(); Paragraph const & par = dit.paragraph(); Font font = par.getFontSettings(buffer->params(), dit.pos()); font.fontInfo().realize(par.layout().font); @@ -894,6 +924,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_) { @@ -951,14 +1004,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. @@ -990,6 +1046,8 @@ void InsetMathHull::header_write(WriteStream & os) const break; case hullSimple: + if (os.ulemCmd()) + os << "\\mbox{"; os << '$'; os.startOuterRow(); if (cell(0).empty()) @@ -997,6 +1055,7 @@ void InsetMathHull::header_write(WriteStream & os) const break; case hullEquation: + writeMathdisplayPreamble(os); os << "\n"; os.startOuterRow(); if (n) @@ -1010,6 +1069,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"; @@ -1054,6 +1114,8 @@ void InsetMathHull::footer_write(WriteStream & os) const case hullSimple: os << '$'; + if (os.ulemCmd()) + os << "}"; break; case hullEquation: @@ -1063,15 +1125,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"; @@ -1097,7 +1166,7 @@ void InsetMathHull::footer_write(WriteStream & os) const } -bool InsetMathHull::isTable() const +bool InsetMathHull::allowsTabularFeatures() const { switch (type_) { case hullEqnArray: @@ -1859,7 +1928,7 @@ void InsetMathHull::doDispatch(Cursor & cur, FuncRequest & cmd) } case LFUN_TABULAR_FEATURE: - if (!isTable()) + if (!allowsTabularFeatures()) cur.undispatched(); else InsetMathGrid::doDispatch(cur, cmd); @@ -1872,6 +1941,21 @@ void InsetMathHull::doDispatch(Cursor & cur, FuncRequest & cmd) } +namespace { + +bool allowDisplayMath(Cursor const & cur) +{ + LATTEST(cur.depth() > 1); + Cursor tmpcur = cur; + tmpcur.pop(); + FuncStatus status; + FuncRequest cmd(LFUN_MATH_DISPLAY); + return tmpcur.getStatus(cmd, status) && status.enabled(); +} + +} + + bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & status) const { @@ -1898,30 +1982,12 @@ bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd, status.setOnOff(type_ == ht); status.setEnabled(isMutable(ht) && isMutable(type_)); - if (ht != hullSimple && status.enabled()) { - Cursor tmpcur = cur; - while (!tmpcur.empty()) { - InsetCode code = tmpcur.inset().lyxCode(); - if (code == BOX_CODE) { - return true; - } else if (code == TABULAR_CODE) { - FuncRequest tmpcmd(LFUN_MATH_DISPLAY); - if (tmpcur.getStatus(tmpcmd, status) && !status.enabled()) - return true; - } - tmpcur.pop_back(); - } - } + if (ht != hullSimple && status.enabled()) + status.setEnabled(allowDisplayMath(cur)); return true; } case LFUN_MATH_DISPLAY: { - bool enable = true; - if (cur.depth() > 1) { - Inset const & in = cur[cur.depth()-2].inset(); - if (in.lyxCode() == SCRIPT_CODE) - enable = display() != Inline; - } - status.setEnabled(enable); + status.setEnabled(display() != Inline || allowDisplayMath(cur)); status.setOnOff(display() != Inline); return true; } @@ -1980,7 +2046,7 @@ bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd, return InsetMathGrid::getStatus(cur, cmd, status); case LFUN_TABULAR_FEATURE: { - if (!isTable()) + if (!allowsTabularFeatures()) return false; string s = cmd.getArg(0); if (!rowChangeOK() @@ -2178,8 +2244,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); @@ -2222,8 +2287,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); @@ -2265,8 +2329,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 @@ -2284,7 +2347,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"); } @@ -2489,7 +2552,9 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const // ) // but what follows is equivalent, since we'll enter only if either (a) we // tried and failed with MathML or HTML or (b) didn't try yet at all but - // aren't doing LaTeX, in which case we are doing Images. + // aren't doing LaTeX. + // + // so this is for Images. if (!success && mathtype != BufferParams::LaTeX) { graphics::PreviewImage const * pimage = 0; if (!op.dryrun) { @@ -2516,7 +2581,7 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const string const tag = (getType() == hullSimple) ? "span" : "div"; xs << html::CR() - << html::StartTag(tag) + << html::StartTag(tag, "style = \"text-align: center;\"") << html::CompTag("img", "src=\"" + filename + "\" alt=\"Mathematical Equation\"") << html::EndTag(tag) << html::CR(); @@ -2531,8 +2596,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); @@ -2583,4 +2647,12 @@ void InsetMathHull::recordLocation(DocIterator const & di) docit_ = di; } + +bool InsetMathHull::canPaintChange(BufferView const &) const +{ + // We let RowPainter do it seamlessly for inline insets + return display() != Inline; +} + + } // namespace lyx