From 54cd34f60bbf2a1100302b48b34ae94b96b4b71d Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Sun, 18 Mar 2007 15:00:57 +0000 Subject: [PATCH] Fig bug 3335 (http://bugzilla.lyx.org/show_bug.cgi?id=3335) * 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 | 62 ++++++++++++++++++++++++++++++++---- src/mathed/InsetMathScript.h | 2 ++ src/mathed/MathData.C | 6 ++++ src/mathed/MathData.h | 13 ++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/mathed/InsetMathScript.C b/src/mathed/InsetMathScript.C index b6b3d87e4a..d7e1d879bc 100644 --- a/src/mathed/InsetMathScript.C +++ b/src/mathed/InsetMathScript.C @@ -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; diff --git a/src/mathed/InsetMathScript.h b/src/mathed/InsetMathScript.h index 2c00668384..1a631b3ba8 100644 --- a/src/mathed/InsetMathScript.h +++ b/src/mathed/InsetMathScript.h @@ -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 diff --git a/src/mathed/MathData.C b/src/mathed/MathData.C index afc5457bbe..2509dae423 100644 --- a/src/mathed/MathData.C +++ b/src/mathed/MathData.C @@ -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; diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h index bf4d5909c0..db7b28024e 100644 --- a/src/mathed/MathData.h +++ b/src/mathed/MathData.h @@ -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? -- 2.39.2