-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Upgrade \sqrt zoom and width #890
Conversation
This PR evades a Safari bug which causes nested SVGs to zoom improperly. `\sqrt` and single-ended arrow SVGs have been modified. These have been converted from nested SVGs to single level. Their long tails are now sliced off using CSS `overflow: hidden`. Safari will still improperly zoom any double-ended stretchy arrows and horizontal braces.
Even if the function argument is empty, still render an SVG whose width equals the surd glyph.
I've updated the test page. |
I've added a commit which fixes #889. |
update screenshots affected by sqrt fixes
I assumed that |
more screenshots after changes to fix sqrt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice solution using overflow: hidden
to avoid nested SVGs.
// still get a line. So, we use a simple heuristic to decide if we | ||
// should omit the body entirely. (note this doesn't work for something | ||
// like `\sqrt{\rlap{x}}`, but if someone is doing that they deserve for | ||
// it not to work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol. I missed this comment in the previous review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take no credit for that comment. It was there before I got here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's explains why I missed in previous reviews. 😅
src/delimiter.js
Outdated
@@ -329,14 +329,12 @@ const sqrtSvg = function(sqrtName, height, viewBoxHeight, options) { | |||
} | |||
const pathNode = new domTree.pathNode(sqrtName, alternate); | |||
|
|||
let attributes = [["width", "100%"], ["height", height + "em"]]; | |||
const attributes = [["width", "400em"], ["height", height + "em"]]; | |||
attributes.push(["viewBox", "0 0 400000 " + viewBoxHeight]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be good to compute the width
attribute in terms of the viewBox
's width (or vice versa) so that they stay in sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've consistently used 400 ems for all the wide paths. I suppose that might not be obvious to someone looking at this cold. I'll look at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is good enough for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is good enough for now.
Let's suppose that someone other than me comes along and writes a PR with an SVG in it. They will need to coordinate viewBox
geometry and document geometry. They will need to realize this early, when they are arranging the <path>
geometry. So I am trying to leave multiple comments regarding the 1000:1 ratio.
Such is my reasoning for writing 400em
. Reasoning with which you may disagree, but there it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to define a const hugeWidth = '400em'
somewhere and use that variable repeatedly, instead of repeating a constant like this? (And one comment could explain why this choice is sensible.) Sorry if this suggestion doesn't make sense, coming from out of context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A constant for 400em would do no harm. But the more critical concept is the 1000:1 ratio between ems and viewBox
geometry. Some future contributor could waste a lot of time if they don't realize that early in their work. So any constant, defined in one place, would be improved by adding multiple comments, scattered widely.
src/delimiter.js
Outdated
@@ -353,21 +351,24 @@ const sqrtSpan = function(height, delim, options) { | |||
sizeMultiplier = newOptions.sizeMultiplier / options.sizeMultiplier; | |||
spanHeight = 1 * sizeMultiplier; | |||
span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, options); | |||
span.style.minWidth = "0.781em"; | |||
span.surdWidth = 0.833 * sizeMultiplier; // from the font. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is minWidth
different from surdWidth
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not the best choice of variable names. For the CSS minWidth
, I used the actual width of the ink in the glyph. What I have called surdwidth
is actually the horizontal advance value from the font. Horizontal advance value is of course, a little wider than the ink.
I might adjust the surdwidth
name and re-commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will also adjust the values of min-width
. The paths in these surds have the xMin
value baked into the SVG paths. So I'll increase each min-width
by that amount.
span.surdWidth = 1.0 / sizeMultiplier; // from the font | ||
|
||
} else { | ||
// Tall sqrt. In TeX, this would be stacked using multiple glyphs. | ||
// We'll use a single SVG to accomplish the same thing. | ||
spanHeight = height / sizeMultiplier; | ||
viewBoxHeight = Math.floor(1000 * spanHeight); | ||
viewBoxHeight = Math.floor(1000 * height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes the issue with the tall \sqrt
being the wrong size when sizing functions are involved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct.
src/delimiter.js
Outdated
@@ -329,14 +329,12 @@ const sqrtSvg = function(sqrtName, height, viewBoxHeight, options) { | |||
} | |||
const pathNode = new domTree.pathNode(sqrtName, alternate); | |||
|
|||
let attributes = [["width", "100%"], ["height", height + "em"]]; | |||
const attributes = [["width", "400em"], ["height", height + "em"]]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this have to be 400em
as opposed to 100%
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll give 100%
a try, but I don't think it will work. I'm now defining the viewBox
dimensions in the same SVG as the width attribute. The height has a factor of 1000, so I think the width needs consistent treatment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wrong. It does work to use width='100%'
. Not only that but when width='100%'
, I can remove the CSS oveflow:hidden
and it still works. So consider that done.
I wonder if that will cause sub-pixel changes in all the screenshots.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I retract my last statement. When I use width='100%
, IE does not slice off the long tail. I going back to width='400em'
and CSS overflow:hidden
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final word. It turns out that it doesn't matter if I write width='400em'
or width='100%'
. It would matter, except that IE will not work unless I include CSS overflow:hidden
. Once I include the CSS condition, both widths work. I'm going with 400em.
src/delimiter.js
Outdated
span.style.minWidth = "0.781em"; | ||
span.surdWidth = 0.833 * sizeMultiplier; // from the font. | ||
span.style.minWidth = "0.853em"; | ||
span.advanceWidth = 0.833 * sizeMultiplier; // from the font. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is clearer. Thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@ronkok thanks for the PR. |
This PR does two things:
It evades a Safari bug which improperly zooms nested SVGs. The fix applies to
\sqrt
and to single-ended stretchy arrows. These SVGs are now single level. Their tails are sliced off using CSSoverflow: hidden
. Double-ended stretchy arrows and horizontal braces are not fixed. Fixes part of \sqrt doesn't scale properly when browser is zoomed in or out on Safari #883.It adds a
min-width
to\sqrt
so that a\sqrt{}
with an empty argument will still render an SVG whose width matches the font glyph width. Fixes \sqrt{} doesn't render anything #888.