Support "mu" units for sizes.

18mu is 1em.

And use emPerEx when converting ex to em, rather than xHeight.
(Previously some places used emPerEx and others used xHeight.)
This commit is contained in:
Eddie Kohler 2016-12-08 15:00:57 -05:00
parent 3900936f63
commit d5cedc55c9
3 changed files with 22 additions and 30 deletions

View File

@ -733,7 +733,7 @@ Parser.prototype.parseSizeGroup = function(optional) {
number: +(match[1] + match[2]), // sign + magnitude, cast to number number: +(match[1] + match[2]), // sign + magnitude, cast to number
unit: match[3], unit: match[3],
}; };
if (data.unit !== "em" && data.unit !== "ex") { if (data.unit !== "em" && data.unit !== "ex" && data.unit !== "mu") {
throw new ParseError("Invalid unit: '" + data.unit + "'", res); throw new ParseError("Invalid unit: '" + data.unit + "'", res);
} }
return new ParseFuncOrArgument( return new ParseFuncOrArgument(

View File

@ -543,6 +543,16 @@ groupTypes.genfrac = function(group, options) {
options); options);
}; };
var calculateSize = function(sizeValue, style) {
var x = sizeValue.number;
if (sizeValue.unit === "ex") {
x *= style.metrics.emPerEx;
} else if (sizeValue.unit === "mu") {
x /= 18;
}
return x;
};
groupTypes.array = function(group, options) { groupTypes.array = function(group, options) {
var r; var r;
var c; var c;
@ -589,18 +599,7 @@ groupTypes.array = function(group, options) {
var gap = 0; var gap = 0;
if (group.value.rowGaps[r]) { if (group.value.rowGaps[r]) {
gap = group.value.rowGaps[r].value; gap = calculateSize(group.value.rowGaps[r].value, style);
switch (gap.unit) {
case "em":
gap = gap.number;
break;
case "ex":
gap = gap.number * style.metrics.emPerEx;
break;
default:
console.error("Can't handle unit " + gap.unit);
gap = 0;
}
if (gap > 0) { // \@argarraycr if (gap > 0) { // \@argarraycr
gap += arstrutDepth; gap += arstrutDepth;
if (depth < gap) { if (depth < gap) {
@ -1269,21 +1268,11 @@ groupTypes.rule = function(group, options) {
// Calculate the shift, width, and height of the rule, and account for units // Calculate the shift, width, and height of the rule, and account for units
var shift = 0; var shift = 0;
if (group.value.shift) { if (group.value.shift) {
shift = group.value.shift.number; shift = calculateSize(group.value.shift, style);
if (group.value.shift.unit === "ex") {
shift *= style.metrics.xHeight;
}
} }
var width = group.value.width.number; var width = calculateSize(group.value.width, style);
if (group.value.width.unit === "ex") { var height = calculateSize(group.value.height, style);
width *= style.metrics.xHeight;
}
var height = group.value.height.number;
if (group.value.height.unit === "ex") {
height *= style.metrics.xHeight;
}
// The sizes of rules are absolute, so make it larger if we are in a // The sizes of rules are absolute, so make it larger if we are in a
// smaller style. // smaller style.
@ -1311,10 +1300,7 @@ groupTypes.kern = function(group, options) {
var dimension = 0; var dimension = 0;
if (group.value.dimension) { if (group.value.dimension) {
dimension = group.value.dimension.number; dimension = calculateSize(group.value.dimension, style);
if (group.value.dimension.unit === "ex") {
dimension *= style.metrics.xHeight;
}
} }
dimension /= style.sizeMultiplier; dimension /= style.sizeMultiplier;

View File

@ -977,15 +977,18 @@ describe("A rule parser", function() {
describe("A kern parser", function() { describe("A kern parser", function() {
var emKern = "\\kern{1em}"; var emKern = "\\kern{1em}";
var exKern = "\\kern{1ex}"; var exKern = "\\kern{1ex}";
var muKern = "\\kern{1mu}";
var badUnitRule = "\\kern{1px}"; var badUnitRule = "\\kern{1px}";
var noNumberRule = "\\kern{em}"; var noNumberRule = "\\kern{em}";
it("should list the correct units", function() { it("should list the correct units", function() {
var emParse = getParsed(emKern)[0]; var emParse = getParsed(emKern)[0];
var exParse = getParsed(exKern)[0]; var exParse = getParsed(exKern)[0];
var muParse = getParsed(muKern)[0];
expect(emParse.value.dimension.unit).toEqual("em"); expect(emParse.value.dimension.unit).toEqual("em");
expect(exParse.value.dimension.unit).toEqual("ex"); expect(exParse.value.dimension.unit).toEqual("ex");
expect(muParse.value.dimension.unit).toEqual("mu");
}); });
it("should not parse invalid units", function() { it("should not parse invalid units", function() {
@ -1007,15 +1010,18 @@ describe("A kern parser", function() {
describe("A non-braced kern parser", function() { describe("A non-braced kern parser", function() {
var emKern = "\\kern1em"; var emKern = "\\kern1em";
var exKern = "\\kern 1 ex"; var exKern = "\\kern 1 ex";
var muKern = "\\kern 1mu";
var badUnitRule = "\\kern1px"; var badUnitRule = "\\kern1px";
var noNumberRule = "\\kern em"; var noNumberRule = "\\kern em";
it("should list the correct units", function() { it("should list the correct units", function() {
var emParse = getParsed(emKern)[0]; var emParse = getParsed(emKern)[0];
var exParse = getParsed(exKern)[0]; var exParse = getParsed(exKern)[0];
var muParse = getParsed(muKern)[0];
expect(emParse.value.dimension.unit).toEqual("em"); expect(emParse.value.dimension.unit).toEqual("em");
expect(exParse.value.dimension.unit).toEqual("ex"); expect(exParse.value.dimension.unit).toEqual("ex");
expect(muParse.value.dimension.unit).toEqual("mu");
}); });
it("should not parse invalid units", function() { it("should not parse invalid units", function() {