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

Define how children of various mathml elements paint. #130

Closed
bfgeek opened this issue Feb 25, 2019 · 19 comments
Closed

Define how children of various mathml elements paint. #130

bfgeek opened this issue Feb 25, 2019 · 19 comments

Comments

@bfgeek
Copy link

bfgeek commented Feb 25, 2019

Does things paint like a block formatting context, or a flex formatting context?

This needs tests.

@fred-wang
Copy link
Contributor

cc @mrego @javifernandez

Ian clarified this:

Basically different layout modes paint differently, e.g. flex/grid paint all their children atomically, whereas flow layout paints per-phase.

@fred-wang
Copy link
Contributor

After talking to @mrego my first feeling would be that MathML is treated as flow layout since

(1) that's what all the MathML layout classes are in WebKit/Chromium
(2) It seems natural for me to have overlapping text when we have "negative math spacing", even when the items have background colors.

However, the latter is really subjective and I'm not sure there is an obvious answer.

Anyway, I wrote a test case here:

https://people.igalia.com/fwang/mathml-layout-ng/mathml-painting-order.html

It's a bit tricky to cause an overlap because currently all browser do not implement the "negative math spacing" consistently/completely.

Here is the screenshot in different engines (from left to right: gecko/webkit/blink):
mathml-painting-order

So WebKit/Blink paint children per-phase while Gecko paint them like inline-block. I think @rwlbuis mentioned to me that most MathML elements have display: inline in Gecko so that might just be a side effect of this rather than an intended choice.

Adding this to the mathml core's agenda.

@rwlbuis
Copy link
Contributor

rwlbuis commented Jul 15, 2019

To be clear, Firefox is on the left and paints atomically.
Webkit is in the middle, chromium to the right and they paint per phase.

@NSoiffer
Copy link
Contributor

I've modified the example above to use MathML (MathJax version) only for the painting (no CSS except last case). Here are some test results:

FireFox

image

MathPlayer

image

MathJax 2.7

image

Comparison

Looking at the four cases:

  1. Firefox draws the second mtext on top of the first. Although a little harder to tell, the trailing '1' is not visible in the MathJax rendering, so it does the same as MathJax. In the MathPlayer rendering, the blue trialing '1' is visible, so it draws the background, then the foreground, in the order of the boxes.
  2. Same as '1'
  3. Firefox and MathJax both ignore (or set to zero) the negative lspace/rspace around the +. MathPlayer handles it and draws background, then foreground.
  4. Firefox seems to set the margin to zero; MathPlayer ignores it; MathJax uses it and produces the same result as it does in '1' and '2'.

Heights: curiously, Firefox's rendering is taller than the other two renderes for all cases.

Note: I also tried MathJax V3 beta 4 and it renders the same as V2.7.5, even for the CSS example.

Conclusions

All the renders act differently in some respects. For drawing order, both Firefox and MathJax fully draw a child whereas MathPlayer draws all the backgrounds, then the foregrounds.

The generic drawing code in MathPlayer predates my time at Design Science, so I don't know if drawing order was intentionally done as drawing all the background followed by drawing all the foreground, or if that was just convenient. I like that order. However, I'm fine with defining the order as drawing the parent's background, then foreground, followed by drawing the children's background then foreground in the order of the children elements. MathML doesn't define a z-order, so that's not relevant. The differences only show up where someone is doing something that is probably not good MathML, so I think whatever is easiest to implement is what should go in the spec... but I don't knw what to say if whatever is easiest differs by browser implementation.

Note: the example doesn't cover the drawing order of parent vs child. The spec says that, at least for mathbackground, that is required. It doesn't make sense for a parent's background to obliterate a child's background. There aren't many cases where the foreground is an issue, but laying out a fraction or menclose where someone uses mpadded to shift the contents around outside of it's bounding box is when it matters.

@NSoiffer
Copy link
Contributor

What the spec says about rendering order

The current full spec leaves it up to the renderer as to what to do. From the section that talks about about mathcolor and mathbackground:

Note that the suggested MathML visual rendering rules do not define the precise extent of the region whose background is affected by the mathbackground attribute, except that, when the content does not have negative dimensions and its drawing region is not overlapped by other drawing due to surrounding negative spacing, this region should lie behind all the drawing done to render the content, but should not lie behind any of the drawing done to render surrounding expressions. The effect of overlap of drawing regions caused by negative spacing on the extent of the region affected by the mathbackground attribute is not defined by these rules.

Related to that statement is this one at the end of the mstyle section:

As a presentation element, mstyle directly accepts the mathcolor and mathbackground attributes. Thus, the mathbackground specifies the color to fill the bounding box of the mstyle element itself; it does not specify the default background color. This is an incompatible change from MathML 2, but we feel it is more useful and intuitive. Since the default for mathcolor is inherited, this is no change in its behaviour.

@fred-wang
Copy link
Contributor

Thanks. A few remarks:

(0) So the summary is that MathPlayer behaves like WebKit and Blink while MathJax (HTML+CSS) behaves like Gecko.

(1) I'm not sure everything is intentional in MathJax either. I suspect the drawing order and support for negative CSS margin is just a consequence of using the HTML+CSS output which I believe is built with inline-block boxes. If they were built with block boxes then probably it would render like MathPlayer/WebKit/Blink. I also wonder how the SVG output renders, but probably negative margin are ignored?

(2) The paint ordering for child/parent, z-order ordering as well as the background size are defined by CSS so browsers will just use that. I don't think we need to specify that in Core, unless we introduce new properties like "order" (grid and flexbox) that change the CSS behavior.

(3) Gecko distinguishes the block size (which is used for the background) and the ink block size (exact size of the text) and the MathML Core spec currently follows this. Note that WebKit sets the block size to the ink block size (so the background has the same size of the text) while Blink (currently) sets the ink block size to the block size (so the background is larger than the text). Blink's behavior is causing other spacing issues so we plan to change that anyway. Anyway, that's a separate issue... #139 is a special case.

(4) Regarding the mstyle one, I think Karl Tomlinson requested it. In MathML2

<mstyle mathbackground="red">
    <mspace width="20px"/>
    <mn>1</mn>
</mstyle>

was equivalent to

<mstyle>
   <mspace mathbackground="red" width="20px"/>
   <mn mathbackground="red">1</mn>
</mstyle>

which is not compatible with CSS's background behavior. So this was a good
move.

@NSoiffer
Copy link
Contributor

I changed the codepen example to use SVG. There are a few differences in the rendering, but the overall conclusion that the elements are painted in order (same as Gecko) remains the same:
image

@fred-wang is correct that the negative margins for the last case go away.

I'll inquire as to whether the painting order in MathJax was intentional. I doubt it, but I'll get confirmation.

@NSoiffer
Copy link
Contributor

I heard back from Davide Cervone, the lead MathJax implementer. He said it was mostly because that is how HTML works. It makes things easier to implement. He said it is also the way he would have expected it to be done. "...it wasn't really a decision, per se, but if I had thought about having to make one, it is the decision I would have made."

@fred-wang
Copy link
Contributor

that is how HTML works.

By default, that is not how div work but how span do.

@fred-wang
Copy link
Contributor

As discussed during today's meeting, the negative mo@mspace/mo@rspace had an issue because the mo is embellished. in my test page, I replaced mtext elements with mn elements to avoid that issue. In any case, negative lspace/rspace is currently not implemented in any browser and prohibited by the core spec.

@NSoiffer
Copy link
Contributor

NSoiffer commented Aug 5, 2019

Here's the corresponding updated results (codepen MathJax version):

MathPlayer:

image

Firefox:

image

MathJax:

image

@fred-wang
Copy link
Contributor

We (@rwlbuis and I) haven't made any progress on experimenting this thing. Since we have 2/3 native implementations using per phase and since it has a reasonable argument (text is important and should not be hidden by background) and since anyway overlapping+background is an edge case, I would lean towards choosing painting "per-phase". This could be reconsidered later if someone has a strong justification for painting "atomically" but I can't see one for now.

@NSoiffer
Copy link
Contributor

I agree with the argument that text is important and shouldn't be hidden by background (in general). I also agree this is an edge case and likely not important.

I'm not sure I agree with the native implementation argument though. MathJax accounts for the vast majority of MathML that is rendered, and it uses element order. As I noted in an earlier comment, this rendering was arbitrary but also would have been the way the implementer would have done it if he had thought about it.

Bottom line for me: I remain on the fence which is the "right" thing to do. I also feel this is a pretty minor issue and not worth a lot of time.

@fred-wang
Copy link
Contributor

I'm not sure I agree with the native implementation argument though. MathJax accounts for the vast majority of MathML that is rendered, and it uses element order. As I noted in an earlier comment, this rendering was arbitrary but also would have been the way the implementer would have done it if he had thought about it.

There are a lot of features that non-native implementations do differently but as always my proposal is for MathML Core. I thought we agreed from the beginning that the spec targets native browser implementations, are you now disagreeing with that? I also think the consensus is that MathML4 can continue to be ambiguous for this and other issues, though.

Regarding the reply from MathJax's implementers it also sounds a very weak argument to me: IIUC they said that they haven't thought about it but now the issue was raised they also replied something inaccurate (as I mentioned in https://github.com/mathml-refresh/mathml/issues/52#issuecomment-516073886 not all HTML elements behave the same way, this is what we are deciding here!)

@fred-wang
Copy link
Contributor

We discussed this during the hackfest, the consensus is that we should paint "per-phase" because overlapping of text can actually happen in a lot of important situation e.g. integral with an italic correction, fraction numerator/denom with a bar etc and we don't want text or bars to be hidden by possible background colors. Any opinion?

@chrishtr
Copy link

paint "per-phase"

This only makes sense if you have a notion of stacking context. Which MathML elements would have a stacking context?

Also, the discussion in this issue indicates you intend to allow z-index. I think it would be better not to since it introduces more complexity. And SVG doesn't have z-index either.

@bfgeek
Copy link
Author

bfgeek commented Dec 19, 2019

Also, the discussion in this issue indicates you intend to allow z-index. I think it would be better not to since it introduces more complexity. And SVG doesn't have z-index either.

SVG isn't a good analogy here - MathML is more integrated with the standard HTML, CSS, (e.g. you can set the 'display' on an arbitrary element) than SVG. (Put another way MathML is built with a lot more extensibility in mind). Disallowing z-index would actually be a lot more work, and add complexity that what its probably worth.

This only makes sense if you have a notion of stacking context. Which MathML elements would have a stacking context?

Following logic above - the default things should create a stacking context. This issue is only about how a child paints, e.g. see for flex "atomic" children behaviour. https://drafts.csswg.org/css-flexbox-1/#painting

@fred-wang
Copy link
Contributor

We discussed this during the hackfest, the consensus is that we should paint "per-phase" because overlapping of text can actually happen in a lot of important situation e.g. integral with an italic correction, fraction numerator/denom with a bar etc and we don't want text or bars to be hidden by possible background colors.

Removing "need resolution" label since the consensus was to paint per-phase. We still need to update the spec and write tests.

moz-v2v-gh referenced this issue in mozilla/gecko-dev Jun 23, 2020
…-like elements., a=testonly

Automatic update from web-platform-tests
Add test to check painting order of mrow-like elements. (#24162)

https://github.com/mathml-refresh/mathml/issues/52
--

wpt-commits: 307056c29ae77cbd65e4b994fc0383d8cd9b9ed3
wpt-pr: 24162
xeonchen referenced this issue in xeonchen/gecko Jun 26, 2020
…-like elements., a=testonly

Automatic update from web-platform-tests
Add test to check painting order of mrow-like elements. (#24162)

https://github.com/mathml-refresh/mathml/issues/52
--

wpt-commits: 307056c29ae77cbd65e4b994fc0383d8cd9b9ed3
wpt-pr: 24162
@fred-wang
Copy link
Contributor

This is defined in the spec at https://w3c.github.io/mathml-core/#stacking-contexts
And there is one test: mathml/presentation-markup/mrow/mrow-painting-order.html

So closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants