X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathFrac.cpp;h=90d61913a678236f8582b2b2fb3cb61da1ee1195;hb=014227cc402deb0b8afad0ffd716b8c828373a03;hp=6b768c91c2e159dfc1204730535b2a405102811d;hpb=ad0a0e3b3c2e22804d1db56d80c0be5986511967;p=lyx.git diff --git a/src/mathed/InsetMathFrac.cpp b/src/mathed/InsetMathFrac.cpp index 6b768c91c2..90d61913a6 100644 --- a/src/mathed/InsetMathFrac.cpp +++ b/src/mathed/InsetMathFrac.cpp @@ -14,11 +14,13 @@ #include "InsetMathFrac.h" -#include "Cursor.h" -#include "LaTeXFeatures.h" #include "MathData.h" +#include "MathParser.h" #include "MathStream.h" #include "MathSupport.h" + +#include "Cursor.h" +#include "LaTeXFeatures.h" #include "MetricsInfo.h" #include "TextPainter.h" @@ -152,14 +154,6 @@ MathClass InsetMathFrac::mathClass() const namespace { -// align frac to minus character -int dy_for_frac(MetricsBase & mb) -{ - Changer dummy = mb.changeFontSet("mathnormal"); - return theFontMetrics(mb.font).ascent('-') - 1; -} - - // align the top of M in the cell with the top of M in the surrounding font int dy_for_nicefrac(MetricsBase & mb) { @@ -170,13 +164,20 @@ int dy_for_nicefrac(MetricsBase & mb) return big_m - small_m; } -} // anon namespace +// symbol for nicefrac solidus +latexkeys const * slash_symbol() +{ + return in_word_set(from_ascii("slash")); +} + +} // namespace void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const { Dimension dim0, dim1, dim2; + Changer dummy3 = mi.base.changeEnsureMath(); switch (kind_) { case UNIT: { @@ -202,21 +203,32 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const case NICEFRAC: { // \unitfrac, \unitfracthree, \nicefrac dim.wid = 0; + dim.asc = 0; + dim.des = 0; int const dy = dy_for_nicefrac(mi.base); // is there an extra cell holding the value being given a dimension? // (this is \unitfracthree) if (kind_ == UNITFRAC && nargs() == 3) { cell(2).metrics(mi, dim2); dim.wid += dim2.wid + 4; + dim.asc = dim2.asc; + dim.des = dim2.des; } Changer dummy = (kind_ == UNITFRAC) ? mi.base.font.changeShape(UP_SHAPE) : Changer(); Changer dummy2 = mi.base.changeScript(); + if (latexkeys const * slash = slash_symbol()) { + Dimension dimslash; + mathedSymbolDim(mi.base, dimslash, slash); + dim.wid += dimslash.wid - mathed_mu(mi.base.font, 3.0); + dim.asc = max(dim.asc, dimslash.asc); + dim.des = max(dim.des, dimslash.des); + } cell(0).metrics(mi, dim0); cell(1).metrics(mi, dim1); - dim.wid += dim0.wid + dim1.wid + 5; - dim.asc = max(max(dim2.asc, dim0.asc + dy), dim1.asc); - dim.des = max(max(dim2.des, dim0.des - dy), dim1.des); + dim.wid += dim0.wid + dim1.wid + 2; + dim.asc = max(max(dim.asc, dim0.asc + dy), dim1.asc); + dim.des = max(max(dim.des, dim0.des - dy), dim1.des); } break; @@ -228,7 +240,7 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const case TFRAC: case OVER: case ATOP: { - int const dy = dy_for_frac(mi.base); + int const dy = axis_height(mi.base); Changer dummy = // \tfrac is always in text size (kind_ == TFRAC) ? mi.base.font.changeStyle(LM_ST_SCRIPT) : @@ -239,20 +251,21 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const || kind_ == DFRAC) ? mi.base.font.changeStyle(LM_ST_DISPLAY) : // all others mi.base.changeFrac(); + Changer dummy2 = mi.base.changeEnsureMath(); cell(0).metrics(mi, dim0); cell(1).metrics(mi, dim1); dim.wid = max(dim0.wid, dim1.wid) + 2; - dim.asc = dim0.height() + 2 + dy; - dim.des = max(0, dim1.height() + 2 - dy); + dim.asc = dim0.height() + dy/2 + dy; + int const t = mi.base.solidLineThickness(); + dim.des = max(0, dim1.height() + dy/2 - dy + t); } } //switch (kind_) - metricsMarkers(mi, dim); } void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const { - setPosCache(pi, x, y); + Changer dummy3 = pi.base.changeEnsureMath(); Dimension const dim = dimension(*pi.base.bv); Dimension const dim0 = cell(0).dimension(*pi.base.bv); switch (kind_) { @@ -263,12 +276,12 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const // is there an extra cell holding the value being given a dimension? // (this is \unittwo) if (nargs() == 2) { - cell(0).draw(pi, x + 1, y); + cell(0).draw(pi, x, y); xx += dim0.wid + 4; unit_cell = 1; } Changer dummy = pi.base.font.changeShape(UP_SHAPE); - cell(unit_cell).draw(pi, xx + 1, y); + cell(unit_cell).draw(pi, xx, y); } break; @@ -280,21 +293,24 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const // is there an extra cell holding the value being given a dimension? // (this is \unitfracthree) if (kind_ == UNITFRAC && nargs() == 3) { - cell(2).draw(pi, x + 1, y); + cell(2).draw(pi, x, y); xx += cell(2).dimension(*pi.base.bv).wid + 4; } Changer dummy = (kind_ == UNITFRAC) ? pi.base.font.changeShape(UP_SHAPE) : Changer(); // nice fraction - // FIXME: - // * the solidus should be \kern-2mu/\kern-1mu. Changer dummy2 = pi.base.changeScript(); - cell(0).draw(pi, xx + 2, y - dy); - cell(1).draw(pi, xx + dim0.wid + 5, y); - // Diag line: - pi.pain.line(xx + dim0.wid + 1, y + dim.des - 2, - xx + dim0.wid + 6, y - dim.asc + 2, - pi.base.font.color()); + cell(0).draw(pi, xx + 1, y - dy); + // reference LaTeX code from nicefrac.sty: + // \mkern-2mu/\mkern-1mu + if (latexkeys const * slash = slash_symbol()) { + int mkern = mathed_mu(pi.base.font, 2.0); + mathedSymbolDraw(pi, xx + 1 + dim0.wid - mkern, y, slash); + Dimension dimslash; + mathedSymbolDim(pi.base, dimslash, slash); + xx += dimslash.wid - mathed_mu(pi.base.font, 3.0); + } + cell(1).draw(pi, xx + 1 + dim0.wid, y); } break; @@ -306,7 +322,7 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const case TFRAC: case OVER: case ATOP: { - int const dy = dy_for_frac(pi.base); + int const dy = axis_height(pi.base); Changer dummy = // \tfrac is always in text size (kind_ == TFRAC) ? pi.base.font.changeStyle(LM_ST_SCRIPT) : @@ -318,24 +334,29 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const // all others pi.base.changeFrac(); Dimension const dim1 = cell(1).dimension(*pi.base.bv); - int m = x + dim.wid / 2; - int xx = + int const m = x + dim.wid / 2; + int const xx = // align left - (kind_ == CFRACLEFT) ? x + 2 : + (kind_ == CFRACLEFT) ? x + 1 : // align right (kind_ == CFRACRIGHT) ? x + dim.wid - dim0.wid - 2 : // center m - dim0.wid / 2; - cell(0).draw(pi, xx, y - dim0.des - 2 - dy); + int const t = pi.base.solidLineThickness(); + // take dy/2 for the spacing around the horizontal line. This is + // arbitrary. In LaTeX it is more complicated to ensure that displayed + // fractions line up next to each other. + // For more accurate implementation refer to the TeXbook, Appendix G, + // rules 15a-e. + cell(0).draw(pi, xx, y - dim0.des - dy/2 - dy); // center - cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 2 - dy); + cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + dy/2 - dy + t); // horizontal line if (kind_ != ATOP) - pi.pain.line(x + 1, y - dy, - x + dim.wid - 2, y - dy, pi.base.font.color()); + pi.pain.line(x, y - dy, x + dim.wid, y - dy, + pi.base.font.color(), pi.pain.line_solid, t); } } //switch (kind_) - drawMarkers(pi, x, y); } @@ -514,12 +535,12 @@ void InsetMathFrac::mathmlize(MathStream & os) const // FIXME This is not right, because we still output mi, etc, // when we output the cell. So we need to prevent that somehow. if (nargs() == 2) - os << cell(0) - << MTag("mstyle mathvariant='normal'") - << cell(1) + os << cell(0) + << MTag("mstyle mathvariant='normal'") + << cell(1) << ETag("mstyle"); else - os << MTag("mstyle mathvariant='normal'") + os << MTag("mstyle mathvariant='normal'") << cell(0) << ETag("mstyle"); } @@ -564,12 +585,12 @@ void InsetMathFrac::htmlize(HtmlStream & os) const // FIXME This is not right, because we still output i, etc, // when we output the cell. So we need to prevent that somehow. if (nargs() == 2) - os << cell(0) - << MTag("span") - << cell(1) + os << cell(0) + << MTag("span") + << cell(1) << ETag("span"); else - os << MTag("span") + os << MTag("span") << cell(0) << ETag("span"); } @@ -624,27 +645,28 @@ int InsetMathBinom::dw(int height) const void InsetMathBinom::metrics(MetricsInfo & mi, Dimension & dim) const { + Changer dummy2 = mi.base.changeEnsureMath(); Dimension dim0, dim1; - int const dy = dy_for_frac(mi.base); + int const dy = axis_height(mi.base); Changer dummy = (kind_ == DBINOM) ? mi.base.font.changeStyle(LM_ST_DISPLAY) : (kind_ == TBINOM) ? mi.base.font.changeStyle(LM_ST_SCRIPT) : mi.base.changeFrac(); cell(0).metrics(mi, dim0); cell(1).metrics(mi, dim1); - dim.asc = dim0.height() + 4 + dy; - dim.des = max(0, dim1.height() + 4 - dy); + dim.asc = dim0.height() + 1 + dy/2 + dy; + dim.des = max(0, dim1.height() + 1 + dy/2 - dy); dim.wid = max(dim0.wid, dim1.wid) + 2 * dw(dim.height()) + 4; - metricsMarkers2(mi, dim); } void InsetMathBinom::draw(PainterInfo & pi, int x, int y) const { + Changer dummy2 = pi.base.changeEnsureMath(); Dimension const dim = dimension(*pi.base.bv); Dimension const & dim0 = cell(0).dimension(*pi.base.bv); Dimension const & dim1 = cell(1).dimension(*pi.base.bv); - int const dy = dy_for_frac(pi.base); + int const dy = axis_height(pi.base); // define the binom brackets docstring const bra = kind_ == BRACE ? from_ascii("{") : kind_ == BRACK ? from_ascii("[") : from_ascii("("); @@ -657,15 +679,16 @@ void InsetMathBinom::draw(PainterInfo & pi, int x, int y) const (kind_ == DBINOM) ? pi.base.font.changeStyle(LM_ST_DISPLAY) : (kind_ == TBINOM) ? pi.base.font.changeStyle(LM_ST_SCRIPT) : pi.base.changeFrac(); - cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 3 - dy); - cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 3 - dy); + // take dy both for the vertical alignment and for the spacing between + // cells + cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - dy/2 - dy); + cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + dy/2 - dy); } // draw the brackets and the marker mathed_draw_deco(pi, x, y - dim.ascent(), dw(dim.height()), dim.height(), bra); mathed_draw_deco(pi, x + dim.width() - dw(dim.height()), y - dim.ascent(), dw(dim.height()), dim.height(), ket); - drawMarkers2(pi, x, y); }