On Thu, Mar 15, 2007 at 11:09:39PM +0100, Andre Poenitz wrote: > On Thu, Mar 15, 2007 at 02:15:43PM -0700, Jan Peters wrote: > > >Note, however, that sticking too closely to the TeX rules gives fairly > > >dense formulas which are more difficult to navigate, > > > > I believe that SWP is very close to TeX here. > > This might be true.
With the attached patch LyX is also closer to TeX, at least for super/subscript placement. I implemented the rules from 18a to 18f in appendix G of the TeXbook. I also attach here two screenshots showing a formula before and after the patch. As you can see, the patch solves the problem of accent placement in math, too. The remaining problems are the too thin delimiters and the fact that the accents are not scaled when changing the zoom factor. However, I will not have enough free time in the near future to also tackle that, though :( Comments are welcome. -- Enrico
Index: src/mathed/InsetMathScript.C =================================================================== --- src/mathed/InsetMathScript.C (revisione 17450) +++ src/mathed/InsetMathScript.C (copia locale) @@ -146,6 +146,43 @@ } +int InsetMathScript::dy01(int asc, int des, int what) const +{ + int dasc = 0; + int sdrop = 0; + if (hasDown()) { + sdrop = down().minasc(); + int mindes = nuc().size() ? nuc().mindes() : 0; + int desdrop = des + sdrop; + dasc = down().ascent(); + int ascdrop = dasc - sdrop; + des = max(desdrop, ascdrop); + des = max(mindes, des); + } + if (hasUp()) { + int minasc = nuc().size() ? nuc().minasc() : 0; + int uminasc = up().minasc(); + int ascdrop = asc - uminasc; + int udes = up().descent(); + asc = udes + uminasc - up().mindes(); + asc = max(ascdrop, asc); + asc = max(minasc, asc); + if (hasDown()) { + int del = asc - udes - dasc; + if (del + des <= 2) { + des = 2 - del; + del = udes - asc + sdrop; + if (del > 0) { + asc += del; + des -= del; + } + } + } + } + return what ? asc : des; +} + + int InsetMathScript::dy0() const { int nd = ndes(); @@ -154,8 +191,10 @@ int des = down().ascent(); if (hasLimits()) des += nd + 2; - else - des = max(des, nd); + else { + int na = nasc(); + des = dy01(na, nd, 0); + } return des; } @@ -168,8 +207,10 @@ int asc = up().descent(); if (hasLimits()) asc += na + 2; - else - asc = max(asc, na); + else { + int nd = ndes(); + asc = dy01(na, nd, 1); + } asc = max(asc, 5); return asc; } @@ -235,8 +276,18 @@ dim.wid = max(dim.wid, down().width()); dim.wid += nwid(); } - dim.asc = dy1() + (hasUp() ? up().ascent() : 0); - dim.des = dy0() + (hasDown() ? down().descent() : 0); + int na = nasc(); + if (hasUp()) { + int asc = dy1() + up().ascent(); + dim.asc = max(na, asc); + } else + dim.asc = na; + int nd = ndes(); + if (hasDown()) { + int des = dy0() + down().descent(); + dim.des = max(nd, des); + } else + dim.des = nd; metricsMarkers(dim); if (dim_ == dim) return false; Index: src/mathed/MathData.C =================================================================== --- src/mathed/MathData.C (revisione 17450) +++ src/mathed/MathData.C (copia locale) @@ -243,10 +243,13 @@ void MathArray::metrics(MetricsInfo & mi) const { dim_ = theFontMetrics(mi.base.font).dimension('I'); + minasc_ = theFontMetrics(mi.base.font).dimension('x').ascent(); + mindes_ = (3 * minasc_) / 4; if (empty()) return; + dim_.asc = 0; dim_.wid = 0; Dimension d; //BufferView & bv = *mi.base.bv; Index: src/mathed/InsetMathScript.h =================================================================== --- src/mathed/InsetMathScript.h (revisione 17450) +++ src/mathed/InsetMathScript.h (copia locale) @@ -110,6 +110,8 @@ int dxx() const; /// returns width of nucleus if any int nwid() const; + /// returns y offset for either superscript or subscript + int dy01(int asc, int des, int what) const; /// returns y offset for superscript int dy0() const; /// returns y offset for subscript Index: src/mathed/MathData.h =================================================================== --- src/mathed/MathData.h (revisione 17450) +++ src/mathed/MathData.h (copia locale) @@ -150,10 +150,17 @@ Dimension const & dim() const { return dim_; } /// dimensions of cell void setDim(Dimension const & d) const { dim_ = d; } + /// minimum ascent offset for superscript + int minasc() const { return minasc_; } + /// minimum descent offset for subscript + int mindes() const { return mindes_; } protected: /// cached dimensions of cell mutable Dimension dim_; + /// cached values for super/subscript placement + mutable int minasc_; + mutable int mindes_; private: /// is this an exact match at this position?
before.png
Description: PNG image
after.png
Description: PNG image