mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Clean up and fixes to fractions metrics and drawing
* Factor code for easier maintainance.
* Avoid computing metrics several times. This duplication explained the
exponential blowup during the metrics phase for nested fractions (see
b2b87330
). This happened in particular when using lyxproofs which heavily uses
nested \dfracs for on-screen drawing.
* Call MetricsBase::changeScript instead of MetricsBase::changeFrac for
\nicefrac and \unitfrac.
This commit is contained in:
parent
a9eb87a89d
commit
ffb865d6e8
@ -152,62 +152,71 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dim0, dim1, dim2;
|
||||
|
||||
// This could be simplified, including avoiding useless recalculation of
|
||||
// cell metrics
|
||||
if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
|
||||
if (nargs() == 1) {
|
||||
switch (kind_) {
|
||||
case UNIT: {
|
||||
// \unitone, \unittwo
|
||||
dim.wid = 0;
|
||||
int unit_cell = 0;
|
||||
// is there an extra cell holding the value being given a dimension?
|
||||
// (this is \unittwo)
|
||||
if (nargs() == 2) {
|
||||
cell(0).metrics(mi, dim1);
|
||||
dim.wid += dim1.wid + 4;
|
||||
unit_cell = 1;
|
||||
}
|
||||
Changer dummy = mi.base.font.changeShape(UP_SHAPE);
|
||||
cell(0).metrics(mi, dim0);
|
||||
dim.wid = dim0.width()+ 3;
|
||||
dim.asc = dim0.asc;
|
||||
dim.des = dim0.des;
|
||||
} else if (nargs() == 2) {
|
||||
cell(0).metrics(mi, dim0);
|
||||
Changer dummy = mi.base.font.changeShape(UP_SHAPE);
|
||||
cell(1).metrics(mi, dim1);
|
||||
dim.wid = dim0.width() + dim1.wid + 5;
|
||||
cell(unit_cell).metrics(mi, dim0);
|
||||
dim.wid += dim0.width() + 1;
|
||||
dim.asc = max(dim0.asc, dim1.asc);
|
||||
dim.des = max(dim0.des, dim1.des);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
|
||||
case UNITFRAC:
|
||||
case NICEFRAC: {
|
||||
// \unitfrac, \unitfracthree, \nicefrac
|
||||
dim.wid = 0;
|
||||
// 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);
|
||||
Changer dummy = mi.base.font.changeShape(UP_SHAPE);
|
||||
Changer dummy2 = mi.base.changeFrac();
|
||||
dim.wid += dim2.wid + 4;
|
||||
}
|
||||
Changer dummy = mi.base.font.changeShape(UP_SHAPE, kind_ == UNITFRAC);
|
||||
Changer dummy2 = mi.base.changeScript();
|
||||
cell(0).metrics(mi, dim0);
|
||||
cell(1).metrics(mi, dim1);
|
||||
dim.wid = dim0.width() + dim1.wid + dim2.wid + 10;
|
||||
dim.wid += dim0.wid + dim1.wid + 5;
|
||||
dim.asc = max(dim2.asc, dim0.height() + 5);
|
||||
dim.des = max(dim2.des, dim1.height() - 5);
|
||||
}
|
||||
} else {
|
||||
// general cell metrics used for \frac
|
||||
Changer dummy = mi.base.changeFrac();
|
||||
// FIXME: Exponential blowup
|
||||
cell(0).metrics(mi, dim0);
|
||||
cell(1).metrics(mi, dim1);
|
||||
if (nargs() == 3)
|
||||
cell(2).metrics(mi, dim2);
|
||||
// metrics for special fraction types
|
||||
if (kind_ == NICEFRAC || kind_ == UNITFRAC) {
|
||||
Changer dummy2 = mi.base.font.changeShape(UP_SHAPE, kind_ == UNITFRAC);
|
||||
dim.wid = dim0.width() + dim1.wid + 5;
|
||||
dim.asc = dim0.height() + 5;
|
||||
dim.des = dim1.height() - 5;
|
||||
} else {
|
||||
if (kind_ == CFRAC || kind_ == CFRACLEFT || kind_ == CFRACRIGHT
|
||||
|| kind_ == DFRAC || kind_ == TFRAC) {
|
||||
break;
|
||||
|
||||
case FRAC:
|
||||
case CFRAC:
|
||||
case CFRACLEFT:
|
||||
case CFRACRIGHT:
|
||||
case DFRAC:
|
||||
case TFRAC:
|
||||
case OVER:
|
||||
case ATOP: {
|
||||
Changer dummy =
|
||||
// \tfrac is always in text size
|
||||
(kind_ == TFRAC) ? mi.base.font.changeStyle(LM_ST_SCRIPT) :
|
||||
// \cfrac and \dfrac are always in display size
|
||||
// \tfrac is in always in text size
|
||||
Changer dummy2 = mi.base.font.changeStyle((kind_ == TFRAC)
|
||||
? LM_ST_SCRIPT
|
||||
: LM_ST_DISPLAY);
|
||||
(kind_ == CFRAC
|
||||
|| kind_ == CFRACLEFT
|
||||
|| kind_ == CFRACRIGHT
|
||||
|| kind_ == DFRAC) ? mi.base.font.changeStyle(LM_ST_DISPLAY) :
|
||||
// all others
|
||||
mi.base.changeFrac();
|
||||
cell(0).metrics(mi, dim0);
|
||||
cell(1).metrics(mi, dim1);
|
||||
}
|
||||
dim.wid = max(dim0.wid, dim1.wid) + 2;
|
||||
dim.asc = dim0.height() + 2 + 5;
|
||||
dim.des = dim1.height() + 2 - 5;
|
||||
}
|
||||
}
|
||||
} //switch (kind_)
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
@ -217,74 +226,89 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const
|
||||
setPosCache(pi, x, y);
|
||||
Dimension const dim = dimension(*pi.base.bv);
|
||||
Dimension const dim0 = cell(0).dimension(*pi.base.bv);
|
||||
if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
|
||||
if (nargs() == 1) {
|
||||
Changer dummy = pi.base.font.changeShape(UP_SHAPE);
|
||||
switch (kind_) {
|
||||
case UNIT: {
|
||||
// \unitone, \unittwo
|
||||
int xx = x;
|
||||
int unit_cell = 0;
|
||||
// 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);
|
||||
} else if (nargs() == 2) {
|
||||
cell(0).draw(pi, x + 1, y);
|
||||
Changer dummy = pi.base.font.changeShape(UP_SHAPE);
|
||||
cell(1).draw(pi, x + dim0.width() + 5, y);
|
||||
} else {
|
||||
cell(2).draw(pi, x + 1, y);
|
||||
Changer dummy = pi.base.font.changeShape(UP_SHAPE);
|
||||
Changer dummy2 = pi.base.changeFrac();
|
||||
Dimension const dim1 = cell(1).dimension(*pi.base.bv);
|
||||
Dimension const dim2 = cell(2).dimension(*pi.base.bv);
|
||||
int xx = x + dim2.wid + 5;
|
||||
cell(0).draw(pi, xx + 2,
|
||||
y - dim0.des - 5);
|
||||
cell(1).draw(pi, xx + dim0.width() + 5,
|
||||
y + dim1.asc / 2);
|
||||
xx += dim0.wid + 4;
|
||||
unit_cell = 1;
|
||||
}
|
||||
} else {
|
||||
Changer dummy = pi.base.changeFrac();
|
||||
Changer dummy = pi.base.font.changeShape(UP_SHAPE);
|
||||
cell(unit_cell).draw(pi, xx + 1, y);
|
||||
}
|
||||
break;
|
||||
|
||||
case UNITFRAC:
|
||||
case NICEFRAC: {
|
||||
// \unitfrac, \unitfracthree, \nicefrac
|
||||
int xx = x;
|
||||
// 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);
|
||||
xx += cell(2).dimension(*pi.base.bv).wid + 4;
|
||||
}
|
||||
Changer dummy = pi.base.font.changeShape(UP_SHAPE, kind_ == UNITFRAC);
|
||||
// nice fraction
|
||||
// FIXME:
|
||||
// * the solidus should be \kern-2mu/\kern-1mu.
|
||||
// * the vertical offset of the first cell should be such that the
|
||||
// top of M in the first cell matches the one of the
|
||||
// surrounding text.
|
||||
Changer dummy2 = pi.base.changeScript();
|
||||
cell(0).draw(pi, xx + 2, y - dim0.des - 5);
|
||||
Dimension const dim1 = cell(1).dimension(*pi.base.bv);
|
||||
cell(1).draw(pi, xx + dim0.wid + 5, y + dim1.asc / 2);
|
||||
// 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());
|
||||
}
|
||||
break;
|
||||
|
||||
case FRAC:
|
||||
case CFRAC:
|
||||
case CFRACLEFT:
|
||||
case CFRACRIGHT:
|
||||
case DFRAC:
|
||||
case TFRAC:
|
||||
case OVER:
|
||||
case ATOP: {
|
||||
Changer dummy =
|
||||
// \tfrac is always in text size
|
||||
(kind_ == TFRAC) ? pi.base.font.changeStyle(LM_ST_SCRIPT) :
|
||||
// \cfrac and \dfrac are always in display size
|
||||
(kind_ == CFRAC
|
||||
|| kind_ == CFRACLEFT
|
||||
|| kind_ == CFRACRIGHT
|
||||
|| kind_ == DFRAC) ? pi.base.font.changeStyle(LM_ST_DISPLAY) :
|
||||
// all others
|
||||
pi.base.changeFrac();
|
||||
Dimension const dim1 = cell(1).dimension(*pi.base.bv);
|
||||
int m = x + dim.wid / 2;
|
||||
if (kind_ == NICEFRAC) {
|
||||
cell(0).draw(pi, x + 2,
|
||||
y - dim0.des - 5);
|
||||
cell(1).draw(pi, x + dim0.width() + 5,
|
||||
y + dim1.asc / 2);
|
||||
} else if (kind_ == UNITFRAC) {
|
||||
Changer dummy2 = pi.base.font.changeShape(UP_SHAPE);
|
||||
cell(0).draw(pi, x + 2, y - dim0.des - 5);
|
||||
cell(1).draw(pi, x + dim0.width() + 5, y + dim1.asc / 2);
|
||||
} else if (kind_ == FRAC || kind_ == ATOP || kind_ == OVER
|
||||
|| kind_ == TFRAC) {
|
||||
// tfrac is in always in text size
|
||||
Changer dummy2 = pi.base.font.changeStyle(LM_ST_SCRIPT,
|
||||
kind_ == TFRAC);
|
||||
cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 2 - 5);
|
||||
int xx =
|
||||
// align left
|
||||
(kind_ == CFRACLEFT) ? x + 2 :
|
||||
// align right
|
||||
(kind_ == CFRACRIGHT) ? x + dim.wid - dim0.wid - 2 :
|
||||
// center
|
||||
m - dim0.wid / 2;
|
||||
// FIXME: vertical offset should be based on ex
|
||||
//int dy = theFontMetrics(pi.base.font).ex() / 2;
|
||||
cell(0).draw(pi, xx, y - dim0.des - 2 - 5);
|
||||
// center
|
||||
cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 2 - 5);
|
||||
} else {
|
||||
// \cfrac and \dfrac are always in display size
|
||||
Changer dummy2 = pi.base.font.changeStyle(LM_ST_DISPLAY);
|
||||
if (kind_ == CFRAC || kind_ == DFRAC)
|
||||
cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 2 - 5);
|
||||
else if (kind_ == CFRACLEFT)
|
||||
cell(0).draw(pi, x + 2, y - dim0.des - 2 - 5);
|
||||
else if (kind_ == CFRACRIGHT)
|
||||
cell(0).draw(pi, x + dim.wid - dim0.wid - 2,
|
||||
y - dim0.des - 2 - 5);
|
||||
cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 2 - 5);
|
||||
}
|
||||
}
|
||||
if (kind_ == NICEFRAC || kind_ == UNITFRAC) {
|
||||
// Diag line:
|
||||
int xx = x;
|
||||
if (nargs() == 3)
|
||||
xx += cell(2).dimension(*pi.base.bv).wid + 5;
|
||||
pi.pain.line(xx + dim0.wid,
|
||||
y + dim.des - 2,
|
||||
xx + dim0.wid + 5,
|
||||
y - dim.asc + 2, pi.base.font.color());
|
||||
}
|
||||
if (kind_ == FRAC || kind_ == CFRAC || kind_ == CFRACLEFT
|
||||
|| kind_ == CFRACRIGHT || kind_ == DFRAC
|
||||
|| kind_ == TFRAC || kind_ == OVER)
|
||||
// horizontal line
|
||||
if (kind_ != ATOP)
|
||||
pi.pain.line(x + 1, y - 5,
|
||||
x + dim.wid - 2, y - 5, pi.base.font.color());
|
||||
}
|
||||
} //switch (kind_)
|
||||
drawMarkers(pi, x, y);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user