]> git.lyx.org Git - features.git/commitdiff
Fig bug 3335 (http://bugzilla.lyx.org/show_bug.cgi?id=3335)
authorEnrico Forestieri <forenr@lyx.org>
Sun, 18 Mar 2007 15:00:57 +0000 (15:00 +0000)
committerEnrico Forestieri <forenr@lyx.org>
Sun, 18 Mar 2007 15:00:57 +0000 (15:00 +0000)
* src/mathed/InsetMathScript.[Ch]
(InsetMathScript::dy01): new, jointly account for both superscript
and subscript according to the rules in Appendix G of the TeXbook.
(InsetMathScript::dy0, InsetMathScript::dy1): set ascent and descent
values using dy01 for non-limits super/subscripts.
(InsetMathScript::metrics): account for the new super/subscript
placement rules when setting ascent and descent values.

* src/mathed/MathData.[Ch]
(MathArray::metrics): cache parameters needed for super/subscript
placement. When nucleus is not empty, set its ascent value to zero
such that it is correctly computed later, otherwise ascent values
less than that of an 'I' are not reported.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17471 a592a061-630c-0410-9148-cb99ea01b6c8

src/mathed/InsetMathScript.C
src/mathed/InsetMathScript.h
src/mathed/MathData.C
src/mathed/MathData.h

index b6b3d87e4a71b417ed008a97c6b26b906384946f..d7e1d879bc0d1ea040ac96b5ea2f514eb4cf9e85 100644 (file)
@@ -146,6 +146,42 @@ MathArray & InsetMathScript::nuc()
 }
 
 
+int InsetMathScript::dy01(int asc, int des, int what) const
+{
+       int dasc = 0;
+       int slevel = 0;
+       if (hasDown()) {
+               dasc = down().ascent();
+               slevel = nuc().slevel();
+               int ascdrop = dasc - slevel;
+               int desdrop = des + nuc().sshift();
+               int mindes = nuc().mindes();
+               des = max(desdrop, ascdrop);
+               des = max(mindes, des);
+       }
+       if (hasUp()) {
+               int minasc = nuc().minasc();
+               int ascdrop = asc - up().mindes();
+               int udes = up().descent();
+               asc = udes + nuc().sshift();
+               asc = max(ascdrop, asc);
+               asc = max(minasc, asc);
+               if (hasDown()) {
+                       int del = asc - udes - dasc;
+                       if (del + des <= 2) {
+                               des = 2 - del;
+                               del = slevel - asc + udes;
+                               if (del > 0) {
+                                       asc += del;
+                                       des -= del;
+                               }
+                       }
+               }
+       }
+       return what ? asc : des;
+}
+
+
 int InsetMathScript::dy0() const
 {
        int nd = ndes();
@@ -154,8 +190,10 @@ int InsetMathScript::dy0() const
        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 +206,10 @@ int InsetMathScript::dy1() const
        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 +275,18 @@ bool InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const
                        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 2c00668384b306afa17282a237013a37f3bf624a..1a631b3ba8f1ede3b702f8f7969365ee5e29a42b 100644 (file)
@@ -110,6 +110,8 @@ private:
        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 afc5457bbe71fc425f80d87bfb5e45e8bf8dd4b2..2509dae423def97ed325ae696b937c3b8f8a1d61 100644 (file)
@@ -243,10 +243,16 @@ bool isInside(DocIterator const & it, MathArray const & ar,
 void MathArray::metrics(MetricsInfo & mi) const
 {
        dim_ = theFontMetrics(mi.base.font).dimension('I');
+       int xascent = theFontMetrics(mi.base.font).dimension('x').ascent();
+       minasc_ = xascent;
+       mindes_ = (3 * xascent) / 4;
+       slevel_ = (4 * xascent) / 5;
+       sshift_ = xascent / 4;
 
        if (empty())
                return;
 
+       dim_.asc = 0;
        dim_.wid = 0;
        Dimension d;
        //BufferView & bv  = *mi.base.bv;
index bf4d5909c015f7fc6492ae9259f3f33cdca4cf18..db7b28024e644896495a00a69691363d104c2043 100644 (file)
@@ -150,10 +150,23 @@ public:
        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_; }
+       /// level above/below which super/subscript should extend
+       int slevel() const { return slevel_; }
+       /// additional super/subscript shift
+       int sshift() const { return sshift_; }
 
 protected:
        /// cached dimensions of cell
        mutable Dimension dim_;
+       /// cached values for super/subscript placement
+       mutable int minasc_;
+       mutable int mindes_;
+       mutable int slevel_;
+       mutable int sshift_;
 
 private:
        /// is this an exact match at this position?