Improve rule coding, including for \sqrt. (#776)

* Improve rule coding.

* Rule widths (overline, underline, fraction, sqrt) actually scale
  with the current font size in AMS-TeX. Implement that. (Sqrt is
  a special case: the rule width depends on the font size *of the
  surd*.)
* Change the CSS coding for rules. The old, complex coding prevented
  variable-width lines and may have contributed to issues like #696.
  Its purpose, according to 0a3a2271f4,
  was IE8 support; but KaTeX no longer supports IE8.

* The 0.5px offset makes larger sizes better, smaller sizes worse.

Smaller sizes seem more important.

* Cleanup (intended to be squashed).
This commit is contained in:
Eddie Kohler
2017-08-06 15:11:23 -04:00
committed by Kevin Barabash
parent 766487bfe3
commit dcdca732a3
14 changed files with 49 additions and 72 deletions

View File

@@ -432,12 +432,17 @@ groupTypes.genfrac = function(group, options) {
const denomm = buildGroup(group.value.denom, newOptions, options);
let rule;
let ruleWidth;
let ruleSpacing;
if (group.value.hasBarLine) {
rule = makeLineSpan("frac-line", options);
ruleWidth = rule.height;
ruleSpacing = rule.height;
} else {
rule = null;
ruleWidth = 0;
ruleSpacing = options.fontMetrics().defaultRuleThickness;
}
const ruleWidth = rule ? rule.height : 0;
// Rule 15b
let numShift;
@@ -446,18 +451,18 @@ groupTypes.genfrac = function(group, options) {
if (style.size === Style.DISPLAY.size) {
numShift = options.fontMetrics().num1;
if (ruleWidth > 0) {
clearance = 3 * ruleWidth;
clearance = 3 * ruleSpacing;
} else {
clearance = 7 * options.fontMetrics().defaultRuleThickness;
clearance = 7 * ruleSpacing;
}
denomShift = options.fontMetrics().denom1;
} else {
if (ruleWidth > 0) {
numShift = options.fontMetrics().num2;
clearance = ruleWidth;
clearance = ruleSpacing;
} else {
numShift = options.fontMetrics().num3;
clearance = 3 * options.fontMetrics().defaultRuleThickness;
clearance = 3 * ruleSpacing;
}
denomShift = options.fontMetrics().denom2;
}
@@ -1020,13 +1025,10 @@ groupTypes.katex = function(group, options) {
["mord", "katex-logo"], [k, a, t, e, x], options);
};
const makeLineSpan = function(className, options) {
const baseOptions = options.havingBaseStyle();
const line = makeSpan(
[className].concat(baseOptions.sizingClasses(options)),
[], options);
line.height = options.fontMetrics().defaultRuleThickness /
options.sizeMultiplier;
const makeLineSpan = function(className, options, thickness) {
const line = makeSpan([className], [], options);
line.height = thickness || options.fontMetrics().defaultRuleThickness;
line.style.borderBottomWidth = line.height + "em";
line.maxFontSize = 1.0;
return line;
};
@@ -1078,25 +1080,33 @@ groupTypes.sqrt = function(group, options) {
// and line
const inner = buildGroup(group.value.body, options.havingCrampedStyle());
const line = makeLineSpan("sqrt-line", options);
const ruleWidth = line.height;
// Calculate the minimum size for the \surd delimiter
const metrics = options.fontMetrics();
const theta = metrics.defaultRuleThickness;
let phi = ruleWidth;
let phi = theta;
if (options.style.id < Style.TEXT.id) {
phi = options.fontMetrics().xHeight * options.sizeMultiplier;
phi = options.fontMetrics().xHeight;
}
// Calculate the clearance between the body and line
let lineClearance = ruleWidth + phi / 4;
let lineClearance = theta + phi / 4;
const minDelimiterHeight = (inner.height + inner.depth +
lineClearance + ruleWidth) * options.sizeMultiplier;
lineClearance + theta) * options.sizeMultiplier;
// Create a \surd delimiter of the required minimum size
const delim = makeSpan(["sqrt-sign"], [
delimiter.customSizedDelim("\\surd", minDelimiterHeight,
false, options, group.mode)],
options);
const delimChar = delimiter.customSizedDelim("\\surd", minDelimiterHeight,
false, options, group.mode);
const delim = makeSpan(["sqrt-sign"], [delimChar], options);
// Calculate the actual line width.
// This actually should depend on the chosen font -- e.g. \boldmath
// should use the thicker surd symbols from e.g. KaTeX_Main-Bold, and
// have thicker rules.
const ruleWidth = options.fontMetrics().sqrtRuleThickness *
delimChar.delimSizeMultiplier;
const line = makeLineSpan("sqrt-line", options, ruleWidth);
const delimDepth = (delim.height + delim.depth) - ruleWidth;

View File

@@ -53,8 +53,9 @@ const styleWrap = function(delim, toStyle, options, classes) {
(classes || []).concat(newOptions.sizingClasses(options)),
[delim], options);
span.height *= newOptions.sizeMultiplier / options.sizeMultiplier;
span.depth *= newOptions.sizeMultiplier / options.sizeMultiplier;
span.delimSizeMultiplier = newOptions.sizeMultiplier / options.sizeMultiplier;
span.height *= span.delimSizeMultiplier;
span.depth *= span.delimSizeMultiplier;
span.maxFontSize = newOptions.sizeMultiplier;
return span;

View File

@@ -59,12 +59,16 @@ const sigmasAndXis = {
// See the TeXbook, page 441. In AMSTeX, the extension fonts scale; to
// match cmex7, we'd use cmex7.tfm values for script and scriptscript
// values.
defaultRuleThickness: [0.04, 0.04, 0.04], // xi8; cmex7: 0.049
defaultRuleThickness: [0.04, 0.049, 0.049], // xi8; cmex7: 0.049
bigOpSpacing1: [0.111, 0.111, 0.111], // xi9
bigOpSpacing2: [0.166, 0.166, 0.166], // xi10
bigOpSpacing3: [0.2, 0.2, 0.2], // xi11
bigOpSpacing4: [0.6, 0.6, 0.6], // xi12; cmex7: 0.611
bigOpSpacing5: [0.1, 0.1, 0.1], // xi13; cmex7: 0.143
bigOpSpacing4: [0.6, 0.611, 0.611], // xi12; cmex7: 0.611
bigOpSpacing5: [0.1, 0.143, 0.143], // xi13; cmex7: 0.143
// The \sqrt rule width is taken from the height of the surd character.
// Since we use the same font at all sizes, this thickness doesn't scale.
sqrtRuleThickness: [0.04, 0.04, 0.04],
// This value determines how large a pt is, for metrics which are defined
// in terms of pts.

View File

@@ -289,22 +289,9 @@
}
.frac-line {
display: inline-block;
width: 100%;
&:before {
border-bottom-style: solid;
border-bottom-width: 1px;
content: "";
display: block;
}
&:after {
border-bottom-style: solid;
border-bottom-width: 0.04em;
content: "";
display: block;
margin-top: -1px;
}
border-bottom-style: solid;
}
}
@@ -406,22 +393,9 @@
.overline .overline-line,
.underline .underline-line {
display: inline-block;
width: 100%;
&:before {
border-bottom-style: solid;
border-bottom-width: 1px;
content: "";
display: block;
}
&:after {
border-bottom-style: solid;
border-bottom-width: 0.04em;
content: "";
display: block;
margin-top: -1px;
}
border-bottom-style: solid;
}
.sqrt {
@@ -430,22 +404,10 @@
}
.sqrt-line {
display: inline-block;
position: relative;
width: 100%;
&:before {
border-bottom-style: solid;
border-bottom-width: 1px;
content: "";
display: block;
}
&:after {
border-bottom-style: solid;
border-bottom-width: 0.04em;
content: "";
display: block;
margin-top: -1px;
}
border-bottom-style: solid;
}
> .root {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB