Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle border and padding CSS in CHTML and SVG output #799

Merged
merged 4 commits into from
May 1, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ts/output/chtml/Wrappers/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ CommonMathMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
if (this.bbox.pwidth === BBox.fullWidth) {
adaptor.setAttribute(parent, 'width', 'full');
if (this.jax.table) {
let {L, w, R} = this.jax.table.getBBox();
let {L, w, R} = this.jax.table.getOuterBBox();
if (align === 'right') {
R = Math.max(R || -shift, -shift);
} else if (align === 'left') {
Expand Down
2 changes: 1 addition & 1 deletion ts/output/chtml/Wrappers/msqrt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class CHTMLmsqrt<N, T, D> extends CommonMsqrtMixin<CHTMLConstructor<any,
// Get the parameters for the spacing of the parts
//
const sbox = surd.getBBox();
const bbox = base.getBBox();
const bbox = base.getOuterBBox();
const [ , q] = this.getPQ(sbox);
const t = this.font.params.rule_thickness;
const H = bbox.h + q + t;
Expand Down
14 changes: 7 additions & 7 deletions ts/output/chtml/Wrappers/munderover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ CommonMunderMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsub<any, any, a
) as N;
this.baseChild.toCHTML(base);
this.scriptChild.toCHTML(under);
const basebox = this.baseChild.getBBox();
const underbox = this.scriptChild.getBBox();
const basebox = this.baseChild.getOuterBBox();
const underbox = this.scriptChild.getOuterBBox();
const k = this.getUnderKV(basebox, underbox)[0];
const delta = (this.isLineBelow ? 0 : this.getDelta(true));
this.adaptor.setStyle(under, 'paddingTop', this.em(k));
Expand Down Expand Up @@ -140,8 +140,8 @@ CommonMoverMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsup<any, any, an
const base = this.adaptor.append(this.chtml, this.html('mjx-base')) as N;
this.scriptChild.toCHTML(over);
this.baseChild.toCHTML(base);
const overbox = this.scriptChild.getBBox();
const basebox = this.baseChild.getBBox();
const overbox = this.scriptChild.getOuterBBox();
const basebox = this.baseChild.getOuterBBox();
this.adjustBaseHeight(base, basebox);
const k = this.getOverKU(basebox, overbox)[0];
const delta = (this.isLineAbove ? 0 : this.getDelta());
Expand Down Expand Up @@ -207,9 +207,9 @@ CommonMunderoverMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsubsup<any,
this.overChild.toCHTML(over);
this.baseChild.toCHTML(base);
this.underChild.toCHTML(under);
const overbox = this.overChild.getBBox();
const basebox = this.baseChild.getBBox();
const underbox = this.underChild.getBBox();
const overbox = this.overChild.getOuterBBox();
const basebox = this.baseChild.getOuterBBox();
const underbox = this.underChild.getOuterBBox();
this.adjustBaseHeight(base, basebox);
const ok = this.getOverKU(basebox, overbox)[0];
const uk = this.getUnderKV(basebox, underbox)[0];
Expand Down
2 changes: 1 addition & 1 deletion ts/output/common/OutputJax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ export abstract class CommonOutputJax<
this.math = math;
math.root.setTeXclass(null);
this.nodeMap = new Map<MmlNode, W>();
let bbox = this.factory.wrap(math.root).getBBox();
let bbox = this.factory.wrap(math.root).getOuterBBox();
this.nodeMap = null;
return bbox;
}
Expand Down
24 changes: 22 additions & 2 deletions ts/output/common/Wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,14 +314,34 @@ export class CommonWrapper<
return bbox;
}

/**
* Return the wrapped node's bounding box that includes borders and padding
*
* @param {boolean} save Whether to cache the bbox or not (used for stretchy elements)
* @return {BBox} The computed bounding box
*/
public getOuterBBox(save: boolean = true): BBox {
const bbox = this.getBBox(save);
if (!this.styles) return bbox;
const obox = new BBox();
Object.assign(obox, bbox);
for (const [name, side] of BBox.StyleAdjust) {
const x = this.styles.get(name);
if (x) {
dpvc marked this conversation as resolved.
Show resolved Hide resolved
(obox as any)[side] += this.length2em(this.styles.get(name), 1, obox.rscale);
}
}
return obox;
}

/**
* @param {BBox} bbox The bounding box to modify (either this.bbox, or an empty one)
* @param {boolean} recompute True if we are recomputing due to changes in children that have percentage widths
*/
protected computeBBox(bbox: BBox, recompute: boolean = false) {
bbox.empty();
for (const child of this.childNodes) {
bbox.append(child.getBBox());
bbox.append(child.getOuterBBox());
}
bbox.clean();
if (this.fixesPWidth && this.setChildPWidths(recompute)) {
Expand All @@ -348,7 +368,7 @@ export class CommonWrapper<
}
let changed = false;
for (const child of this.childNodes) {
const cbox = child.getBBox();
const cbox = child.getOuterBBox();
if (cbox.pwidth && child.setChildPWidths(recompute, w === null ? cbox.w : w, clear)) {
changed = true;
}
Expand Down
2 changes: 1 addition & 1 deletion ts/output/common/Wrappers/maction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export function CommonMactionMixin<
* @override
*/
public computeBBox(bbox: BBox, recompute: boolean = false) {
bbox.updateFrom(this.selected.getBBox());
bbox.updateFrom(this.selected.getOuterBBox());
this.selected.setChildPWidths(recompute);
}

Expand Down
2 changes: 1 addition & 1 deletion ts/output/common/Wrappers/mfenced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export function CommonMfencedMixin<T extends WrapperConstructor>(Base: T): Mfenc
* @override
*/
public computeBBox(bbox: BBox, recompute: boolean = false) {
bbox.updateFrom(this.mrow.getBBox());
bbox.updateFrom(this.mrow.getOuterBBox());
this.setChildPWidths(recompute);
}

Expand Down
16 changes: 8 additions & 8 deletions ts/output/common/Wrappers/mfrac.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ export function CommonMfracMixin<T extends WrapperConstructor>(Base: T): MfracCo
* @param {number} t The thickness of the line
*/
public getFractionBBox(bbox: BBox, display: boolean, t: number) {
const nbox = this.childNodes[0].getBBox();
const dbox = this.childNodes[1].getBBox();
const nbox = this.childNodes[0].getOuterBBox();
const dbox = this.childNodes[1].getOuterBBox();
const tex = this.font.params;
const a = tex.axis_height;
const {T, u, v} = this.getTUV(display, t);
Expand Down Expand Up @@ -204,8 +204,8 @@ export function CommonMfracMixin<T extends WrapperConstructor>(Base: T): MfracCo
* the separation between the two, and the bboxes themselves.
*/
public getUVQ(display: boolean): {u: number, v: number, q: number, nbox: BBox, dbox: BBox} {
const nbox = this.childNodes[0].getBBox() as BBox;
const dbox = this.childNodes[1].getBBox() as BBox;
const nbox = this.childNodes[0].getOuterBBox();
const dbox = this.childNodes[1].getOuterBBox();
const tex = this.font.params;
//
// Initial offsets (u, v)
Expand Down Expand Up @@ -234,7 +234,7 @@ export function CommonMfracMixin<T extends WrapperConstructor>(Base: T): MfracCo
*/
public getBevelledBBox(bbox: BBox, display: boolean) {
const {u, v, delta, nbox, dbox} = this.getBevelData(display);
const lbox = this.bevel.getBBox();
const lbox = this.bevel.getOuterBBox();
bbox.combine(nbox, 0, u);
bbox.combine(lbox, bbox.w - delta / 2, 0);
bbox.combine(dbox, bbox.w - delta / 2, v);
Expand All @@ -249,8 +249,8 @@ export function CommonMfracMixin<T extends WrapperConstructor>(Base: T): MfracCo
public getBevelData(display: boolean): {
H: number, delta: number, u: number, v: number, nbox: BBox, dbox: BBox
} {
const nbox = this.childNodes[0].getBBox() as BBox;
const dbox = this.childNodes[1].getBBox() as BBox;
const nbox = this.childNodes[0].getOuterBBox();
const dbox = this.childNodes[1].getOuterBBox();
const delta = (display ? .4 : .15);
const H = Math.max(nbox.scale * (nbox.h + nbox.d), dbox.scale * (dbox.h + dbox.d)) + 2 * delta;
const a = this.font.params.axis_height;
Expand Down Expand Up @@ -282,7 +282,7 @@ export function CommonMfracMixin<T extends WrapperConstructor>(Base: T): MfracCo
public getWrapWidth(i: number) {
const attributes = this.node.attributes;
if (attributes.get('bevelled')) {
return this.childNodes[i].getBBox().w;
return this.childNodes[i].getOuterBBox().w;
}
const w = this.getBBox().w;
const thickness = this.length2em(attributes.get('linethickness'));
Expand Down
2 changes: 1 addition & 1 deletion ts/output/common/Wrappers/mmultiscripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export function CommonMmultiscriptsMixin<
if (child.node.isKind('mprescripts')) {
script = 'psubList';
} else {
lists[script].push(child.getBBox());
lists[script].push(child.getOuterBBox());
script = NextScript[script];
}
}
Expand Down
4 changes: 2 additions & 2 deletions ts/output/common/Wrappers/mroot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function CommonMrootMixin<T extends MsqrtConstructor>(Base: T): MrootCons
* @override
*/
public combineRootBBox(BBOX: BBox, sbox: BBox, H: number) {
const bbox = this.childNodes[this.root].getBBox();
const bbox = this.childNodes[this.root].getOuterBBox();
const h = this.getRootDimens(sbox, H)[1];
BBOX.combine(bbox, 0, h);
}
Expand All @@ -76,7 +76,7 @@ export function CommonMrootMixin<T extends MsqrtConstructor>(Base: T): MrootCons
*/
public getRootDimens(sbox: BBox, H: number) {
const surd = this.childNodes[this.surd] as CommonMo;
const bbox = this.childNodes[this.root].getBBox();
const bbox = this.childNodes[this.root].getOuterBBox();
const offset = (surd.size < 0 ? .5 : .6) * sbox.w;
const {w, rscale} = bbox;
const W = Math.max(w, offset / rscale);
Expand Down
2 changes: 1 addition & 1 deletion ts/output/common/Wrappers/mrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function CommonMrowMixin<T extends WrapperConstructor>(Base: T): MrowCons
for (const child of this.childNodes) {
const noStretch = (child.stretch.dir === DIRECTION.None);
if (all || noStretch) {
let {h, d, rscale} = child.getBBox(noStretch);
let {h, d, rscale} = child.getOuterBBox(noStretch);
h *= rscale;
d *= rscale;
if (h > H) H = h;
Expand Down
4 changes: 2 additions & 2 deletions ts/output/common/Wrappers/msqrt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export function CommonMsqrtMixin<T extends WrapperConstructor>(Base: T): MsqrtCo
super(...args);
const surd = this.createMo('\u221A');
surd.canStretch(DIRECTION.Vertical);
const {h, d} = this.childNodes[this.base].getBBox();
const {h, d} = this.childNodes[this.base].getOuterBBox();
const t = this.font.params.rule_thickness;
const p = (this.node.attributes.get('displaystyle') ? this.font.params.x_height : t);
this.surdH = h + d + 2 * t + p / 4;
Expand All @@ -146,7 +146,7 @@ export function CommonMsqrtMixin<T extends WrapperConstructor>(Base: T): MsqrtCo
*/
public computeBBox(bbox: BBox, recompute: boolean = false) {
const surdbox = this.childNodes[this.surd].getBBox();
const basebox = new BBox(this.childNodes[this.base].getBBox());
const basebox = new BBox(this.childNodes[this.base].getOuterBBox());
const q = this.getPQ(surdbox)[1];
const t = this.font.params.rule_thickness;
const H = basebox.h + q + t;
Expand Down
10 changes: 5 additions & 5 deletions ts/output/common/Wrappers/msubsup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ export function CommonMsubsupMixin<
* @override
*/
public computeBBox(bbox: BBox, recompute: boolean = false) {
const basebox = this.baseChild.getBBox();
const [subbox, supbox] = [this.subChild.getBBox(), this.supChild.getBBox()];
const basebox = this.baseChild.getOuterBBox();
const [subbox, supbox] = [this.subChild.getOuterBBox(), this.supChild.getOuterBBox()];
bbox.empty();
bbox.append(basebox);
const w = this.getBaseWidth();
Expand All @@ -239,10 +239,10 @@ export function CommonMsubsupMixin<
* @return {number[]} The vertical offsets for super and subscripts, and the space between them
*/
public getUVQ(
subbox: BBox = this.subChild.getBBox(),
supbox: BBox = this.supChild.getBBox()
subbox: BBox = this.subChild.getOuterBBox(),
supbox: BBox = this.supChild.getOuterBBox()
): number[] {
const basebox = this.baseCore.getBBox();
const basebox = this.baseCore.getOuterBBox();
if (this.UVQ) return this.UVQ;
const tex = this.font.params;
const t = 3 * tex.rule_thickness;
Expand Down
14 changes: 7 additions & 7 deletions ts/output/common/Wrappers/munderover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ export function CommonMunderMixin<
return;
}
bbox.empty();
const basebox = this.baseChild.getBBox();
const underbox = this.scriptChild.getBBox();
const basebox = this.baseChild.getOuterBBox();
const underbox = this.scriptChild.getOuterBBox();
const v = this.getUnderKV(basebox, underbox)[1];
const delta = (this.isLineBelow ? 0 : this.getDelta(true));
const [bw, uw] = this.getDeltaW([basebox, underbox], [0, -delta]);
Expand Down Expand Up @@ -153,8 +153,8 @@ export function CommonMoverMixin<
return;
}
bbox.empty();
const basebox = this.baseChild.getBBox();
const overbox = this.scriptChild.getBBox();
const basebox = this.baseChild.getOuterBBox();
const overbox = this.scriptChild.getOuterBBox();
if (this.node.attributes.get('accent')) {
basebox.h = Math.max(basebox.h, this.font.params.x_height * basebox.scale);
}
Expand Down Expand Up @@ -262,9 +262,9 @@ export function CommonMunderoverMixin<
return;
}
bbox.empty();
const overbox = this.overChild.getBBox();
const basebox = this.baseChild.getBBox();
const underbox = this.underChild.getBBox();
const overbox = this.overChild.getOuterBBox();
const basebox = this.baseChild.getOuterBBox();
const underbox = this.underChild.getOuterBBox();
if (this.node.attributes.get('accent')) {
basebox.h = Math.max(basebox.h, this.font.params.x_height * basebox.scale);
}
Expand Down
24 changes: 12 additions & 12 deletions ts/output/common/Wrappers/scriptbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ export function CommonScriptbaseMixin<
let child = this.baseCore as any;
let scale = 1;
while (child && child !== this) {
const bbox = child.getBBox();
const bbox = child.getOuterBBox();
scale *= bbox.rscale;
child = child.parent;
}
Expand All @@ -446,14 +446,14 @@ export function CommonScriptbaseMixin<
* The base's italic correction (properly scaled)
*/
public getBaseIc(): number {
return this.baseCore.getBBox().ic * this.baseScale;
return this.baseCore.getOuterBBox().ic * this.baseScale;
}

/**
* An adjusted italic correction (for slightly better results)
*/
public getAdjustedIc(): number {
const bbox = this.baseCore.getBBox();
const bbox = this.baseCore.getOuterBBox();
return (bbox.ic ? 1.05 * bbox.ic + .05 : 0) * this.baseScale;
}

Expand Down Expand Up @@ -501,7 +501,7 @@ export function CommonScriptbaseMixin<
* @return {number} The base child's width without the base italic correction (if not needed)
*/
public getBaseWidth(): number {
const bbox = this.baseChild.getBBox();
const bbox = this.baseChild.getOuterBBox();
return bbox.w * bbox.rscale - (this.baseRemoveIc ? this.baseIc : 0) + this.font.params.extra_ic;
}

Expand All @@ -514,8 +514,8 @@ export function CommonScriptbaseMixin<
public computeBBox(bbox: BBox, recompute: boolean = false) {
const w = this.getBaseWidth();
const [x, y] = this.getOffset();
bbox.append(this.baseChild.getBBox());
bbox.combine(this.scriptChild.getBBox(), w + x, y);
bbox.append(this.baseChild.getOuterBBox());
bbox.combine(this.scriptChild.getOuterBBox(), w + x, y);
bbox.w += this.font.params.scriptspace;
bbox.clean();
this.setChildPWidths(recompute);
Expand Down Expand Up @@ -546,8 +546,8 @@ export function CommonScriptbaseMixin<
* @return {number} The vertical offset for the script
*/
public getV(): number {
const bbox = this.baseCore.getBBox();
const sbox = this.scriptChild.getBBox();
const bbox = this.baseCore.getOuterBBox();
const sbox = this.scriptChild.getOuterBBox();
const tex = this.font.params;
const subscriptshift = this.length2em(this.node.attributes.get('subscriptshift'), tex.sub1);
return Math.max(
Expand All @@ -563,8 +563,8 @@ export function CommonScriptbaseMixin<
* @return {number} The vertical offset for the script
*/
public getU(): number {
const bbox = this.baseCore.getBBox();
const sbox = this.scriptChild.getBBox();
const bbox = this.baseCore.getOuterBBox();
const sbox = this.scriptChild.getOuterBBox();
const tex = this.font.params;
const attr = this.node.attributes.getList('displaystyle', 'superscriptshift');
const prime = this.node.getProperty('texprimestyle');
Expand Down Expand Up @@ -661,7 +661,7 @@ export function CommonScriptbaseMixin<
*/
public getDelta(noskew: boolean = false): number {
const accent = this.node.attributes.get('accent');
const {sk, ic} = this.baseCore.getBBox();
const {sk, ic} = this.baseCore.getOuterBBox();
return ((accent && !noskew ? sk : 0) + this.font.skewIcFactor * ic) * this.baseScale;
}

Expand Down Expand Up @@ -691,7 +691,7 @@ export function CommonScriptbaseMixin<
for (const child of this.childNodes) {
const noStretch = (child.stretch.dir === DIRECTION.None);
if (all || noStretch) {
const {w, rscale} = child.getBBox(noStretch);
const {w, rscale} = child.getOuterBBox(noStretch);
if (w * rscale > W) W = w * rscale;
}
}
Expand Down
2 changes: 1 addition & 1 deletion ts/output/svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ CommonOutputJax<N, T, D, SVGWrapper<N, T, D>, SVGWrapperFactory<N, T, D>, SVGFon
* @return {[N, N]} The svg and g nodes for the math
*/
protected createRoot(wrapper: SVGWrapper<N, T, D>): [N, N] {
const {w, h, d, pwidth} = wrapper.getBBox();
const {w, h, d, pwidth} = wrapper.getOuterBBox();
const px = wrapper.metrics.em / 1000;
const W = Math.max(w, px); // make sure we are at least one px wide (needed for e.g. \llap)
const H = Math.max(h + d, px); // make sure we are at least one px tall (needed for e.g., \smash)
Expand Down
Loading