sandflow / imscJS

JavaScript library for rendering IMSC Text and Image Profile documents to HTML5
BSD 2-Clause "Simplified" License
84 stars 31 forks source link

Bugfix - ruby+linepadding #234

Closed btsimonh closed 1 year ago

btsimonh commented 2 years ago

When applying line padding, if the start or end of line element is a span inside an RB element, then instead apply the padding to it's RUBY parent. Not that this is more of a bandaid than a fix, as nested spans will have the same issue - start and end elements are only taken from leaf nodes, so any enclosing nodes may cut off the padding.

Also addresses background colors and ruby

Also avoids splitting rt text into spans (as they are not recombined).

palemieux commented 2 years ago

@btsimonh Can you provide a test?

btsimonh commented 2 years ago

see imsc-tests PRs. Did not cover the color issue....

palemieux commented 2 years ago

@nigelmegitt It looks like getSpanAncestorColor() does not pick up the backgroundColor specified on the rb element, and thus linePadding does not work. Thoughts?

<?xml version="1.0" encoding="UTF-8"?>
<tt xml:lang="en"
    xmlns:tt="http://www.w3.org/ns/ttml"
    xmlns:ttp="http://www.w3.org/ns/ttml#parameter"
    xmlns="http://www.w3.org/ns/ttml"
    xmlns:tts="http://www.w3.org/ns/ttml#styling"
    xmlns:ebutts="urn:ebu:tt:style"
    ttp:contentProfiles="http://www.w3.org/ns/ttml/profile/imsc1.1/text">
  <head>

    <styling>
      <style xml:id="r1"
          tts:color="white"
          tts:lineHeight="125%"
          tts:textAlign="center"
          tts:displayAlign="after"
          ebutts:linePadding="0.25c"/>
      <style xml:id="s1" tts:backgroundColor="#00000080"/>
    </styling>

    <layout>
      <region xml:id="r" style="r1" tts:extent="80% 80%" tts:origin="10% 10%" />
    </layout>
  </head>

  <body region="r">
    <div>
      <p style="r1">
        <span style="s1">ruby container boxed with </span><span tts:ruby="container">
        <span tts:ruby="base" style="s1">padding</span><span tts:ruby="text">0.25em</span></span>
        <br/>
        <span style="s1">a span on a 2nd line</span>
      </p>
    </div>
  </body>
</tt>
nigelmegitt commented 2 years ago

@palemieux The spec (pdf, see Appendix D) for ebutts:linePadding says it applies to line areas. I'm not sure, in a CSS world, how the area in which ruby is painted interacts with what we may consider a line area. Nevertheless, I think it makes sense to apply line padding to ruby areas: it's just unspecified behaviour at the moment.

In particular I'd be concerned that the layout requirements are unclear. Should line padding cause adjacent rubys applied to different ruby base text to be spaced apart further? What if that would cause a line break?

I don't think this is straightforward at all.

btsimonh commented 2 years ago

The below sample file illustrates various boxing with Ruby.

In the test above, @palemieux has boxed the ruby base; in this case even with the patch, the ruby container has been padded, but it's background is transparent, and so the padding not shown. We can't duplicate the color from the ruby text to the ruby container, else we end up with (6) below - undesirable for semi-transparent boxing. We could pad both the ruby container and the ruby base...

The other thing I'm not sure about is if a ruby container's height should be the size of the base and text, or the base only. For background color render in Chrome it's the height of the base span. For other purposes, it's the combined height?

In the below, speaking from a personal 'what would look good' perspective, (3) should get line padding either side of the text '0.25em'. For me, this would satisfy the line padding intent. @nigelmegitt - if line padding from two ruby texts were to conflict, they should not change the position of anything - just like line padding currently is only visual, an has no impact on line length (or does it?)? Edit - I see it DOES impact line length. Would have been nicer if it did not :(.

However, in terms of the constructs, (1) and (4) make most sense to me, the others produce undesirable results in browsers (box overlaps), and are more complex to author. I tried really hard to understand how to control browser ruby text background presentation, and decided it was variable amongst browsers and likely to change, so not worth further effort for the moment.

Another 'boxed' presentation which I do not think can be simply achieved would be a rectangular box which (just) covered both base text and ruby text for the line. I think (5) should probably do this, but does not.

Generates: Original renderer: ![image](https://user-images.githubusercontent.com/3137332/195612818-ae361b90-5769-455b-979a-9f591cf8a7d6.png) With PR: ![image](https://user-images.githubusercontent.com/3137332/195612907-174caf60-7114-4223-9f81-a8fb6522f5ad.png) ```