Fop
  1. Fop
  2. FOP-1492

Missing border-after when break-after set on a block

    Details

    • Type: Bug Bug
    • Status: Open
    • Resolution: Unresolved
    • Affects Version/s: trunk
    • Fix Version/s: None
    • Component/s: page-master/layout
    • Labels:
      None
    • Environment:
      Operating System: other
      Platform: Other
    • External issue ID:
      44412

      Description

      On the following:
      <fo:block>Before the block</fo:block>
      <fo:block border="4pt solid black" break-before="page" break-after="page">A
      block with
      borders and break-before and break-after.</fo:block>
      <fo:block>After the block</fo:block>

      The border-after on the second block is missing, although the block is finished.
      It looks like its conditionality is (wrongly) taken into account, as setting
      border-after-width.conditionality="retain" make it re-appear. The problem also
      doesn't show up if break-after is removed from the second block and break-before
      added on the third block instead.

      1. break_border-after_missing.fo
        0.7 kB
        Vincent Hennebert
      2. break_border-before_missing_2.fo
        0.8 kB
        Vincent Hennebert
      3. break_border-before_missing.fo
        0.8 kB
        Vincent Hennebert
      4. break-before.fo
        0.6 kB
        Vincent Hennebert
      5. table-cell-child-break-before.diff
        2 kB
        Jeremias Maerki

        Issue Links

          Activity

          Hide
          Vincent Hennebert added a comment -

          Attachment break_border-after_missing.fo has been added with description: Sample file showing the problem

          Show
          Vincent Hennebert added a comment - Attachment break_border-after_missing.fo has been added with description: Sample file showing the problem
          Hide
          Vincent Hennebert added a comment -

          Another problematic situation: when break-before is set on a block, the before
          border of the enclosing block is not rendered.

          Show
          Vincent Hennebert added a comment - Another problematic situation: when break-before is set on a block, the before border of the enclosing block is not rendered.
          Hide
          Vincent Hennebert added a comment -

          Attachment break_border-before_missing.fo has been added with description: Missing border-before when break-before set

          Show
          Vincent Hennebert added a comment - Attachment break_border-before_missing.fo has been added with description: Missing border-before when break-before set
          Hide
          Jeremias Maerki added a comment -

          (In reply to comment #0)
          > On the following:
          > <fo:block>Before the block</fo:block>
          > <fo:block border="4pt solid black" break-before="page" break-after="page">A
          > block with
          > borders and break-before and break-after.</fo:block>
          > <fo:block>After the block</fo:block>
          >
          > The border-after on the second block is missing, although the block is finished.
          > It looks like its conditionality is (wrongly) taken into account, as setting
          > border-after-width.conditionality="retain" make it re-appear. The problem also
          > doesn't show up if break-after is removed from the second block and break-before
          > added on the third block instead.

          This part should be fixed now:
          http://svn.apache.org/viewvc?rev=637057&view=rev

          The "pending marks" have not been removed from the layout context which caused the border-after to be considered twice in space resolution, on time in a conditional context which reset the border to 0.

          Show
          Jeremias Maerki added a comment - (In reply to comment #0) > On the following: > <fo:block>Before the block</fo:block> > <fo:block border="4pt solid black" break-before="page" break-after="page">A > block with > borders and break-before and break-after.</fo:block> > <fo:block>After the block</fo:block> > > The border-after on the second block is missing, although the block is finished. > It looks like its conditionality is (wrongly) taken into account, as setting > border-after-width.conditionality="retain" make it re-appear. The problem also > doesn't show up if break-after is removed from the second block and break-before > added on the third block instead. This part should be fixed now: http://svn.apache.org/viewvc?rev=637057&view=rev The "pending marks" have not been removed from the layout context which caused the border-after to be considered twice in space resolution, on time in a conditional context which reset the border to 0.
          Hide
          Jeremias Maerki added a comment -

          (In reply to comment #2)
          > Created an attachment (id=21531) [details]
          > Missing border-before when break-before set
          >
          > Another problematic situation: when break-before is set on a block, the before
          > border of the enclosing block is not rendered.

          I'm not sure this is really wrong. Unexpected maybe. The spec says that fo:block produces one or more areas. Now if the first child of this block causes a break-before the block should probably still create an area on the (current) page before the break (but with bpd=0), i.e. with only before borders. This doesn't happen now. I'll go through the spec again just to be sure. But at any rate, I believe the bug here is not that the border before is missing on the second page, but that it's missing on the first.

          Show
          Jeremias Maerki added a comment - (In reply to comment #2) > Created an attachment (id=21531) [details] > Missing border-before when break-before set > > Another problematic situation: when break-before is set on a block, the before > border of the enclosing block is not rendered. I'm not sure this is really wrong. Unexpected maybe. The spec says that fo:block produces one or more areas. Now if the first child of this block causes a break-before the block should probably still create an area on the (current) page before the break (but with bpd=0), i.e. with only before borders. This doesn't happen now. I'll go through the spec again just to be sure. But at any rate, I believe the bug here is not that the border before is missing on the second page, but that it's missing on the first.
          Hide
          Jeremias Maerki added a comment -

          (In reply to comment #4)
          > (In reply to comment #2)
          > > Created an attachment (id=21531) [details] [details]
          > > Missing border-before when break-before set
          > >
          > > Another problematic situation: when break-before is set on a block, the before
          > > border of the enclosing block is not rendered.
          >
          > I'm not sure this is really wrong. Unexpected maybe. The spec says that
          > fo:block produces one or more areas. Now if the first child of this block
          > causes a break-before the block should probably still create an area on the
          > (current) page before the break (but with bpd=0), i.e. with only before
          > borders. This doesn't happen now. I'll go through the spec again just to be
          > sure. But at any rate, I believe the bug here is not that the border before is
          > missing on the second page, but that it's missing on the first.
          >

          I've gone through the spec again and believe my initial analysis was correct. I've fixed the problem accordingly.
          http://svn.apache.org/viewvc?rev=637119&view=rev

          Show
          Jeremias Maerki added a comment - (In reply to comment #4) > (In reply to comment #2) > > Created an attachment (id=21531) [details] [details] > > Missing border-before when break-before set > > > > Another problematic situation: when break-before is set on a block, the before > > border of the enclosing block is not rendered. > > I'm not sure this is really wrong. Unexpected maybe. The spec says that > fo:block produces one or more areas. Now if the first child of this block > causes a break-before the block should probably still create an area on the > (current) page before the break (but with bpd=0), i.e. with only before > borders. This doesn't happen now. I'll go through the spec again just to be > sure. But at any rate, I believe the bug here is not that the border before is > missing on the second page, but that it's missing on the first. > I've gone through the spec again and believe my initial analysis was correct. I've fixed the problem accordingly. http://svn.apache.org/viewvc?rev=637119&view=rev
          Hide
          Vincent Hennebert added a comment -

          (In reply to comment #4)
          > (In reply to comment #2)
          > > Created an attachment (id=21531) [details] [details]
          > > Missing border-before when break-before set
          > >
          > > Another problematic situation: when break-before is set on a block, the before
          > > border of the enclosing block is not rendered.
          >
          > I'm not sure this is really wrong. Unexpected maybe. The spec says that
          > fo:block produces one or more areas. Now if the first child of this block
          > causes a break-before the block should probably still create an area on the
          > (current) page before the break (but with bpd=0), i.e. with only before
          > borders. This doesn't happen now. I'll go through the spec again just to be
          > sure. But at any rate, I believe the bug here is not that the border before is
          > missing on the second page, but that it's missing on the first.

          You seem to be right. Reading and re-reading the spec again I can no longer find a justification for the other behaviour that I was describing.

          The thing is, when I fixed breaks in tables I did implement that behaviour, thinking it was the one to be expected. Sigh.

          Now XSL Formatter puts the border on the second page where the child block is, and nothing on the first page. I know that doesn't mean anything, but...

          I'm all confused.

          Show
          Vincent Hennebert added a comment - (In reply to comment #4) > (In reply to comment #2) > > Created an attachment (id=21531) [details] [details] > > Missing border-before when break-before set > > > > Another problematic situation: when break-before is set on a block, the before > > border of the enclosing block is not rendered. > > I'm not sure this is really wrong. Unexpected maybe. The spec says that > fo:block produces one or more areas. Now if the first child of this block > causes a break-before the block should probably still create an area on the > (current) page before the break (but with bpd=0), i.e. with only before > borders. This doesn't happen now. I'll go through the spec again just to be > sure. But at any rate, I believe the bug here is not that the border before is > missing on the second page, but that it's missing on the first. You seem to be right. Reading and re-reading the spec again I can no longer find a justification for the other behaviour that I was describing. The thing is, when I fixed breaks in tables I did implement that behaviour, thinking it was the one to be expected. Sigh. Now XSL Formatter puts the border on the second page where the child block is, and nothing on the first page. I know that doesn't mean anything, but... I'm all confused.
          Hide
          Jeremias Maerki added a comment -

          (In reply to comment #6)
          <snip/>
          > Now XSL Formatter puts the border on the second page where the child block is,
          > and nothing on the first page. I know that doesn't mean anything, but...
          >
          > I'm all confused.

          Don't let yourself be confused by this. Commercial implementors don't always follow the spec because sometimes user expectations can be more important than spec conformance (see indent inheritance). As long as there's no useful spec test suite things will remain like this.

          Show
          Jeremias Maerki added a comment - (In reply to comment #6) <snip/> > Now XSL Formatter puts the border on the second page where the child block is, > and nothing on the first page. I know that doesn't mean anything, but... > > I'm all confused. Don't let yourself be confused by this. Commercial implementors don't always follow the spec because sometimes user expectations can be more important than spec conformance (see indent inheritance). As long as there's no useful spec test suite things will remain like this.
          Hide
          Vincent Hennebert added a comment -

          The fix does not work if the second attachment is slightly modified (new attachment follows).
          Plus it doesn't work with tables. See the following testcases where the failing tests are currently commented out:
          table-cell_break-before_first-row.xml
          table-cell_break-after_last-row.xml
          table-row_break-before_first-row.xml
          table-row_break-after_last-row.xml
          table_break-before_break-after.xml

          By looking at the changes made in BlockStackingLayoutManager I have no real clue of what needs to be done in TableLayoutManager.

          Show
          Vincent Hennebert added a comment - The fix does not work if the second attachment is slightly modified (new attachment follows). Plus it doesn't work with tables. See the following testcases where the failing tests are currently commented out: table-cell_break-before_first-row.xml table-cell_break-after_last-row.xml table-row_break-before_first-row.xml table-row_break-after_last-row.xml table_break-before_break-after.xml By looking at the changes made in BlockStackingLayoutManager I have no real clue of what needs to be done in TableLayoutManager.
          Hide
          Vincent Hennebert added a comment -

          Attachment break_border-before_missing_2.fo has been added with description: When adding the block with the red border the black one is again missing

          Show
          Vincent Hennebert added a comment - Attachment break_border-before_missing_2.fo has been added with description: When adding the block with the red border the black one is again missing
          Hide
          Jeremias Maerki added a comment -

          (In reply to comment #9)
          > Created an attachment (id=21676) [details]
          > When adding the block with the red border the black one is again missing
          >

          I can't reproduce that. The result looks fine to me (including the element list). No missing borders.

          Show
          Jeremias Maerki added a comment - (In reply to comment #9) > Created an attachment (id=21676) [details] > When adding the block with the red border the black one is again missing > I can't reproduce that. The result looks fine to me (including the element list). No missing borders.
          Hide
          Jeremias Maerki added a comment -

          Attachment table-cell-child-break-before.diff has been added with description: Start of a patch for properly handling break-before of a child of a table-cell

          Show
          Jeremias Maerki added a comment - Attachment table-cell-child-break-before.diff has been added with description: Start of a patch for properly handling break-before of a child of a table-cell
          Hide
          Jeremias Maerki added a comment -

          (In reply to comment #8)
          > Plus it doesn't work with tables. See the following testcases where the failing
          > tests are currently commented out:
          > table-cell_break-before_first-row.xml
          > table-cell_break-after_last-row.xml
          > table-row_break-before_first-row.xml
          > table-row_break-after_last-row.xml
          > table_break-before_break-after.xml
          >
          > By looking at the changes made in BlockStackingLayoutManager I have no real
          > clue of what needs to be done in TableLayoutManager.

          The patch I've just attached should show you how to port the child break-before behaviour from BlockStackingLM to TableCellLM. But that's not the whole thing, yet (I've only looked at the first case in table-cell_break-before_first-row.xml for now). This creates an empty box that will cause the generation of a 0-bpd area before the break. For BlockStackingLM, this is enough, but for tables the element list combination is added. This patch alone behaves correctly but shows a short-coming in the handling of our rule that every cell needs to contribute at least one part before the first break possibility in a table-row. Currently, the algorithm doesn't detect that the first cell is contributing nothing (a 0-length box is nothing). So the second cell shouldn't contribute it's first part, yet. I hope that gets you going.

          Ideally, of course, the table LMs would be improved so the getNextKnuthElements() can be called multiple times and can break early when a forced break is encountered (like other LMs do). I guess this will be required anyway once the inline/block-level layout interaction is addressed. I don't know if Simon has already dared looking into this not quite trivial task.

          Show
          Jeremias Maerki added a comment - (In reply to comment #8) > Plus it doesn't work with tables. See the following testcases where the failing > tests are currently commented out: > table-cell_break-before_first-row.xml > table-cell_break-after_last-row.xml > table-row_break-before_first-row.xml > table-row_break-after_last-row.xml > table_break-before_break-after.xml > > By looking at the changes made in BlockStackingLayoutManager I have no real > clue of what needs to be done in TableLayoutManager. The patch I've just attached should show you how to port the child break-before behaviour from BlockStackingLM to TableCellLM. But that's not the whole thing, yet (I've only looked at the first case in table-cell_break-before_first-row.xml for now). This creates an empty box that will cause the generation of a 0-bpd area before the break. For BlockStackingLM, this is enough, but for tables the element list combination is added. This patch alone behaves correctly but shows a short-coming in the handling of our rule that every cell needs to contribute at least one part before the first break possibility in a table-row. Currently, the algorithm doesn't detect that the first cell is contributing nothing (a 0-length box is nothing). So the second cell shouldn't contribute it's first part, yet. I hope that gets you going. Ideally, of course, the table LMs would be improved so the getNextKnuthElements() can be called multiple times and can break early when a forced break is encountered (like other LMs do). I guess this will be required anyway once the inline/block-level layout interaction is addressed. I don't know if Simon has already dared looking into this not quite trivial task.
          Hide
          Vincent Hennebert added a comment -

          (In reply to comment #10)
          > (In reply to comment #9)
          > > Created an attachment (id=21676) [details] [details]
          > > When adding the block with the red border the black one is again missing
          > >
          >
          > I can't reproduce that. The result looks fine to me (including the element
          > list). No missing borders.

          Grmblbl. My bad, sorry, my local copy was probably not up-to-date.

          Show
          Vincent Hennebert added a comment - (In reply to comment #10) > (In reply to comment #9) > > Created an attachment (id=21676) [details] [details] > > When adding the block with the red border the black one is again missing > > > > I can't reproduce that. The result looks fine to me (including the element > list). No missing borders. Grmblbl. My bad, sorry, my local copy was probably not up-to-date.
          Hide
          Vincent Hennebert added a comment -

          (In reply to comment #12)
          > (In reply to comment #8)
          > > Plus it doesn't work with tables. See the following testcases where the failing
          > > tests are currently commented out:
          > > table-cell_break-before_first-row.xml
          > > table-cell_break-after_last-row.xml
          > > table-row_break-before_first-row.xml
          > > table-row_break-after_last-row.xml
          > > table_break-before_break-after.xml
          > >
          > > By looking at the changes made in BlockStackingLayoutManager I have no real
          > > clue of what needs to be done in TableLayoutManager.
          >
          > The patch I've just attached should show you how to port the child break-before
          > behaviour from BlockStackingLM to TableCellLM. But that's not the whole thing,
          > yet (I've only looked at the first case in
          > table-cell_break-before_first-row.xml for now). This creates an empty box that
          > will cause the generation of a 0-bpd area before the break. For
          > BlockStackingLM, this is enough, but for tables the element list combination is
          > added. This patch alone behaves correctly but shows a short-coming in the
          > handling of our rule that every cell needs to contribute at least one part
          > before the first break possibility in a table-row. Currently, the algorithm
          > doesn't detect that the first cell is contributing nothing (a 0-length box is
          > nothing). So the second cell shouldn't contribute it's first part, yet. I hope
          > that gets you going.

          Thanks for the patch. I understand the purpose of the empty box now. However I won't apply it since like you noticed it doesn't fit well with the merging algorithm, plus it introduces code duplication I'm not happy with (a similar change probably needs to be done also for lists –once breaks in lists are working). Leaving the bug open for now since I don't currently have time to dive further into it.

          > Ideally, of course, the table LMs would be improved so the
          > getNextKnuthElements() can be called multiple times and can break early when a
          > forced break is encountered (like other LMs do). I guess this will be required
          > anyway once the inline/block-level layout interaction is addressed. I don't
          > know if Simon has already dared looking into this not quite trivial task.

          Not sure about that. I actually removed that in TableLM and TableCellLM. I'm convinced the getNextKnuthElements method can be called only once and forced breaks handled another way. But indeed things might become clearer once working on the inline/block-level interaction.

          Vincent

          Show
          Vincent Hennebert added a comment - (In reply to comment #12) > (In reply to comment #8) > > Plus it doesn't work with tables. See the following testcases where the failing > > tests are currently commented out: > > table-cell_break-before_first-row.xml > > table-cell_break-after_last-row.xml > > table-row_break-before_first-row.xml > > table-row_break-after_last-row.xml > > table_break-before_break-after.xml > > > > By looking at the changes made in BlockStackingLayoutManager I have no real > > clue of what needs to be done in TableLayoutManager. > > The patch I've just attached should show you how to port the child break-before > behaviour from BlockStackingLM to TableCellLM. But that's not the whole thing, > yet (I've only looked at the first case in > table-cell_break-before_first-row.xml for now). This creates an empty box that > will cause the generation of a 0-bpd area before the break. For > BlockStackingLM, this is enough, but for tables the element list combination is > added. This patch alone behaves correctly but shows a short-coming in the > handling of our rule that every cell needs to contribute at least one part > before the first break possibility in a table-row. Currently, the algorithm > doesn't detect that the first cell is contributing nothing (a 0-length box is > nothing). So the second cell shouldn't contribute it's first part, yet. I hope > that gets you going. Thanks for the patch. I understand the purpose of the empty box now. However I won't apply it since like you noticed it doesn't fit well with the merging algorithm, plus it introduces code duplication I'm not happy with (a similar change probably needs to be done also for lists –once breaks in lists are working). Leaving the bug open for now since I don't currently have time to dive further into it. > Ideally, of course, the table LMs would be improved so the > getNextKnuthElements() can be called multiple times and can break early when a > forced break is encountered (like other LMs do). I guess this will be required > anyway once the inline/block-level layout interaction is addressed. I don't > know if Simon has already dared looking into this not quite trivial task. Not sure about that. I actually removed that in TableLM and TableCellLM. I'm convinced the getNextKnuthElements method can be called only once and forced breaks handled another way. But indeed things might become clearer once working on the inline/block-level interaction. Vincent
          Hide
          Vincent Hennebert added a comment -

          I noticed that this change introduces a regression in the handling of breaks. In the following situation:
          <fo:block break-before="page">
          <fo:block break-before="page">
          Some text. Some text. Some text. Some text.
          </fo:block>
          </fo:block>
          only one page break should occur. The empty box introduced by the change now triggers an additional page break. This used to work well with FOP 0.94.

          Show
          Vincent Hennebert added a comment - I noticed that this change introduces a regression in the handling of breaks. In the following situation: <fo:block break-before="page"> <fo:block break-before="page"> Some text. Some text. Some text. Some text. </fo:block> </fo:block> only one page break should occur. The empty box introduced by the change now triggers an additional page break. This used to work well with FOP 0.94.
          Hide
          Vincent Hennebert added a comment -

          Attachment break-before.fo has been added with description: Illegal empty page inserted because of two consecutive break-before

          Show
          Vincent Hennebert added a comment - Attachment break-before.fo has been added with description: Illegal empty page inserted because of two consecutive break-before
          Hide
          Jeremias Maerki added a comment -

          (In reply to comment #15)
          > Created an attachment (id=21718) [details]
          > Illegal empty page inserted because of two consecutive break-before
          >
          > I noticed that this change introduces a regression in the handling of breaks.
          > In the following situation:
          > <fo:block break-before="page">
          > <fo:block break-before="page">
          > Some text. Some text. Some text. Some text.
          > </fo:block>
          > </fo:block>
          > only one page break should occur. The empty box introduced by the change now
          > triggers an additional page break. This used to work well with FOP 0.94.
          >

          I've looked into this but I'm not so entirely sure if this is wrong. That 0.94 didn't produce an empty page was more or less a coincidence since an element list with only a penalty(p=-INF) does not trigger page production. But now that the parent fo:block of the block issuing the break-before creates a box(w=0), a new page with only a zero-height block area is produced (ID production, optional borders/padding). The constraints defined in http://www.w3.org/TR/xsl11/#keepbreak are satisfied. The key part when talking about break-before is:
          "A break-before condition is satisfied if the first area generated and returned by the formatting object is leading within a context-area." The spec doesn't say anything about how the parent FO should behave in such a case.

          I once again tried to find hints in the spec that the two break-before properties should effectively be merged. But I didn't find anything.

          In the end, if tables are implemented to merge the break-befores together but the other block-level FOs don't do that, then IMO that's merely a behaviour inconsistency inside FOP rather than a bug in one or the other parts. I believe this needs some more discussion on fop-dev before we do any more about this bug.

          Show
          Jeremias Maerki added a comment - (In reply to comment #15) > Created an attachment (id=21718) [details] > Illegal empty page inserted because of two consecutive break-before > > I noticed that this change introduces a regression in the handling of breaks. > In the following situation: > <fo:block break-before="page"> > <fo:block break-before="page"> > Some text. Some text. Some text. Some text. > </fo:block> > </fo:block> > only one page break should occur. The empty box introduced by the change now > triggers an additional page break. This used to work well with FOP 0.94. > I've looked into this but I'm not so entirely sure if this is wrong. That 0.94 didn't produce an empty page was more or less a coincidence since an element list with only a penalty(p=-INF) does not trigger page production. But now that the parent fo:block of the block issuing the break-before creates a box(w=0), a new page with only a zero-height block area is produced (ID production, optional borders/padding). The constraints defined in http://www.w3.org/TR/xsl11/#keepbreak are satisfied. The key part when talking about break-before is: "A break-before condition is satisfied if the first area generated and returned by the formatting object is leading within a context-area." The spec doesn't say anything about how the parent FO should behave in such a case. I once again tried to find hints in the spec that the two break-before properties should effectively be merged. But I didn't find anything. In the end, if tables are implemented to merge the break-befores together but the other block-level FOs don't do that, then IMO that's merely a behaviour inconsistency inside FOP rather than a bug in one or the other parts. I believe this needs some more discussion on fop-dev before we do any more about this bug.
          Hide
          Andreas L. Delmelle added a comment -

          (In reply to comment #16)
          > (In reply to comment #15)
          > > Created an attachment (id=21718) [details] [details]
          > > Illegal empty page inserted because of two consecutive break-before
          >
          > I've looked into this but I'm not so entirely sure if this is wrong. That 0.94
          > didn't produce an empty page was more or less a coincidence since an element
          > list with only a penalty(p=-INF) does not trigger page production. But now that
          > the parent fo:block of the block issuing the break-before creates a box(w=0), a
          > new page with only a zero-height block area is produced (ID production,
          > optional borders/padding). The constraints defined in
          > http://www.w3.org/TR/xsl11/#keepbreak are satisfied. The key part when talking
          > about break-before is:
          > "A break-before condition is satisfied if the first area generated and returned
          > by the formatting object is leading within a context-area." The spec doesn't
          > say anything about how the parent FO should behave in such a case.

          I lean into the direction of merging the breaks.
          Re-reading the spec, I have to agree that producing an empty page looks like equally correct behavior. I think it also demonstrates why break-before and break-after are non-inherited. If they were, specifying a forced break on the outer block would lead to a new page being generated before/after each descendant FO (unless when explicitly reset to "auto")

          On the other hand, and this is what made me lean towards the merging of both breaks:

          • the outer and inner block each generate one or more normal block-areas
          • the break-condition only applies to the first/last of those

          The break-conditions for the outer and inner block are satisfied in both cases.
          The only difference is that with the current behavior, the inner block's first normal block area is a child of the outer block's second normal block area, instead of the first.

          It depends more on whether we consider the outer block to have a descendant empty line area before the inner block's first normal block area.

          Since I do not believe this to be the case here (default white-space- and linefeed-treatment), I still think merging the breaks is the expected result. If one were to activate white-space preservation, there would be a line with some space characters before the inner block, and a new page would have to be generated, since the inner block's first area would no longer be leading in the context area.

          Show
          Andreas L. Delmelle added a comment - (In reply to comment #16) > (In reply to comment #15) > > Created an attachment (id=21718) [details] [details] > > Illegal empty page inserted because of two consecutive break-before > > I've looked into this but I'm not so entirely sure if this is wrong. That 0.94 > didn't produce an empty page was more or less a coincidence since an element > list with only a penalty(p=-INF) does not trigger page production. But now that > the parent fo:block of the block issuing the break-before creates a box(w=0), a > new page with only a zero-height block area is produced (ID production, > optional borders/padding). The constraints defined in > http://www.w3.org/TR/xsl11/#keepbreak are satisfied. The key part when talking > about break-before is: > "A break-before condition is satisfied if the first area generated and returned > by the formatting object is leading within a context-area." The spec doesn't > say anything about how the parent FO should behave in such a case. I lean into the direction of merging the breaks. Re-reading the spec, I have to agree that producing an empty page looks like equally correct behavior. I think it also demonstrates why break-before and break-after are non-inherited. If they were, specifying a forced break on the outer block would lead to a new page being generated before/after each descendant FO (unless when explicitly reset to "auto") On the other hand, and this is what made me lean towards the merging of both breaks: the outer and inner block each generate one or more normal block-areas the break-condition only applies to the first/last of those The break-conditions for the outer and inner block are satisfied in both cases. The only difference is that with the current behavior, the inner block's first normal block area is a child of the outer block's second normal block area, instead of the first. It depends more on whether we consider the outer block to have a descendant empty line area before the inner block's first normal block area. Since I do not believe this to be the case here (default white-space- and linefeed-treatment), I still think merging the breaks is the expected result. If one were to activate white-space preservation, there would be a line with some space characters before the inner block, and a new page would have to be generated, since the inner block's first area would no longer be leading in the context area.
          Hide
          Vincent Hennebert added a comment -

          (In reply to comment #17)
          > (In reply to comment #16)
          > > (In reply to comment #15)
          > > > Created an attachment (id=21718) [details] [details] [details]
          > > > Illegal empty page inserted because of two consecutive break-before
          > >
          > > I've looked into this but I'm not so entirely sure if this is wrong. That 0.94
          > > didn't produce an empty page was more or less a coincidence since an element
          > > list with only a penalty(p=-INF) does not trigger page production. But now that
          > > the parent fo:block of the block issuing the break-before creates a box(w=0), a
          > > new page with only a zero-height block area is produced (ID production,
          > > optional borders/padding). The constraints defined in
          > > http://www.w3.org/TR/xsl11/#keepbreak are satisfied. The key part when talking
          > > about break-before is:
          > > "A break-before condition is satisfied if the first area generated and returned
          > > by the formatting object is leading within a context-area." The spec doesn't
          > > say anything about how the parent FO should behave in such a case.
          >
          > I lean into the direction of merging the breaks.
          > Re-reading the spec, I have to agree that producing an empty page looks like
          > equally correct behavior. I think it also demonstrates why break-before and
          > break-after are non-inherited. If they were, specifying a forced break on the
          > outer block would lead to a new page being generated before/after each
          > descendant FO (unless when explicitly reset to "auto")
          >
          > On the other hand, and this is what made me lean towards the merging of both
          > breaks:
          > - the outer and inner block each generate one or more normal block-areas
          > - the break-condition only applies to the first/last of those
          >
          > The break-conditions for the outer and inner block are satisfied in both cases.
          > The only difference is that with the current behavior, the inner block's first
          > normal block area is a child of the outer block's second normal block area,
          > instead of the first.

          I agree, and for one time I’d say the specification sounds clear to me. The name ‘break-before’ is given to the property because it corresponds to the common understanding. But the description doesn’t talk about breaks at all, but instead about leading areas (see the section Jeremias cited). Technically speaking, an empty page wouldn’t break the spec since the first areas generated by both the outer and the inner blocks are leading within the page (more precisely the ‘normal-flow-reference-area’). But a valid layout can be created /without/ generating this empty page, which makes it preferable.

          I think this rule should be taken with the same spirit as for space resolution, which allow stylesheet writers to specify spaces for every element without worrying about the context in which they appear (is the paragraph preceded by a section title, a list, another paragraph, etc. where the space-before would differ in each case).

          > It depends more on whether we consider the outer block to have a descendant
          > empty line area before the inner block's first normal block area.
          >
          > Since I do not believe this to be the case here (default white-space- and
          > linefeed-treatment), I still think merging the breaks is the expected result.
          > If one were to activate white-space preservation, there would be a line with
          > some space characters before the inner block, and a new page would have to be
          > generated, since the inner block's first area would no longer be leading in the
          > context area.

          Very good point. Although I think it would go against comment #4 and give a jusitication for putting the before border of the enclosing block on the new page, along with the inner block, in attachment #21531. I think our best bet is to ask for clarification on xsl-editors@. Will do in a couple of days if nobody else chimes in.

          Vincent

          Show
          Vincent Hennebert added a comment - (In reply to comment #17) > (In reply to comment #16) > > (In reply to comment #15) > > > Created an attachment (id=21718) [details] [details] [details] > > > Illegal empty page inserted because of two consecutive break-before > > > > I've looked into this but I'm not so entirely sure if this is wrong. That 0.94 > > didn't produce an empty page was more or less a coincidence since an element > > list with only a penalty(p=-INF) does not trigger page production. But now that > > the parent fo:block of the block issuing the break-before creates a box(w=0), a > > new page with only a zero-height block area is produced (ID production, > > optional borders/padding). The constraints defined in > > http://www.w3.org/TR/xsl11/#keepbreak are satisfied. The key part when talking > > about break-before is: > > "A break-before condition is satisfied if the first area generated and returned > > by the formatting object is leading within a context-area." The spec doesn't > > say anything about how the parent FO should behave in such a case. > > I lean into the direction of merging the breaks. > Re-reading the spec, I have to agree that producing an empty page looks like > equally correct behavior. I think it also demonstrates why break-before and > break-after are non-inherited. If they were, specifying a forced break on the > outer block would lead to a new page being generated before/after each > descendant FO (unless when explicitly reset to "auto") > > On the other hand, and this is what made me lean towards the merging of both > breaks: > - the outer and inner block each generate one or more normal block-areas > - the break-condition only applies to the first/last of those > > The break-conditions for the outer and inner block are satisfied in both cases. > The only difference is that with the current behavior, the inner block's first > normal block area is a child of the outer block's second normal block area, > instead of the first. I agree, and for one time I’d say the specification sounds clear to me. The name ‘break-before’ is given to the property because it corresponds to the common understanding. But the description doesn’t talk about breaks at all, but instead about leading areas (see the section Jeremias cited). Technically speaking, an empty page wouldn’t break the spec since the first areas generated by both the outer and the inner blocks are leading within the page (more precisely the ‘normal-flow-reference-area’). But a valid layout can be created /without/ generating this empty page, which makes it preferable. I think this rule should be taken with the same spirit as for space resolution, which allow stylesheet writers to specify spaces for every element without worrying about the context in which they appear (is the paragraph preceded by a section title, a list, another paragraph, etc. where the space-before would differ in each case). > It depends more on whether we consider the outer block to have a descendant > empty line area before the inner block's first normal block area. > > Since I do not believe this to be the case here (default white-space- and > linefeed-treatment), I still think merging the breaks is the expected result. > If one were to activate white-space preservation, there would be a line with > some space characters before the inner block, and a new page would have to be > generated, since the inner block's first area would no longer be leading in the > context area. Very good point. Although I think it would go against comment #4 and give a jusitication for putting the before border of the enclosing block on the new page, along with the inner block, in attachment #21531. I think our best bet is to ask for clarification on xsl-editors@. Will do in a couple of days if nobody else chimes in. Vincent
          Hide
          Andreas L. Delmelle added a comment -

          (In reply to comment #18)
          > (In reply to comment #17)
          > > It depends more on whether we consider the outer block to have a descendant
          > > empty line area before the inner block's first normal block area.
          > >
          > > Since I do not believe this to be the case here (default white-space- and
          > > linefeed-treatment), I still think merging the breaks is the expected result.
          > > If one were to activate white-space preservation, there would be a line with
          > > some space characters before the inner block, and a new page would have to be
          > > generated, since the inner block's first area would no longer be leading in the
          > > context area.
          >
          > Very good point. Although I think it would go against comment #4 and give a
          > jusitication for putting the before border of the enclosing block on the new
          > page, along with the inner block, in attachment #21531 [details].

          If the construct is

          <fo:block border="4pt solid black">
          <fo:block break-before="page">...</fo:block>
          </fo:block>

          case #1: Supposing the outer block's first area is already leading in a context area, no extra page-break needed. No real issue, if I'm correct.
          case #2: If the outer block's first area is not leading in a context area, the break-condition for the inner block would not be satisfied if its first area is a descendant of the outer block's first area. Generation of a second block area is necessary. The border-traits do apply to both generated areas for the outer block, but given a default conditionality of 'discard', the border-before should only appear on the first area.

          In the example, we're dealing with case #2, due to the preceding block.
          Jeremias' conclusion in comment #4 seems correct to me: the bug is that the border-before is missing on the first page.
          If conditionality is set to 'retain', and the border is not rendered on the second page, that would also be a bug.

          Turning on white-space-preservation for the outer block would make no real difference in case #2, apart from the fact that the first area of the outer block is now also non-empty, as it contains a line-area with one space that survives white-space-collapse. That area should not have an after-border, since that should appear only on the last area (unless it is retained).
          In case #1 white-space-preservation would also lead to the generation of a second block area, without before-border.

          Show
          Andreas L. Delmelle added a comment - (In reply to comment #18) > (In reply to comment #17) > > It depends more on whether we consider the outer block to have a descendant > > empty line area before the inner block's first normal block area. > > > > Since I do not believe this to be the case here (default white-space- and > > linefeed-treatment), I still think merging the breaks is the expected result. > > If one were to activate white-space preservation, there would be a line with > > some space characters before the inner block, and a new page would have to be > > generated, since the inner block's first area would no longer be leading in the > > context area. > > Very good point. Although I think it would go against comment #4 and give a > jusitication for putting the before border of the enclosing block on the new > page, along with the inner block, in attachment #21531 [details] . If the construct is <fo:block border="4pt solid black"> <fo:block break-before="page">...</fo:block> </fo:block> case #1: Supposing the outer block's first area is already leading in a context area, no extra page-break needed. No real issue, if I'm correct. case #2: If the outer block's first area is not leading in a context area, the break-condition for the inner block would not be satisfied if its first area is a descendant of the outer block's first area. Generation of a second block area is necessary. The border-traits do apply to both generated areas for the outer block, but given a default conditionality of 'discard', the border-before should only appear on the first area. In the example, we're dealing with case #2, due to the preceding block. Jeremias' conclusion in comment #4 seems correct to me: the bug is that the border-before is missing on the first page. If conditionality is set to 'retain', and the border is not rendered on the second page, that would also be a bug. Turning on white-space-preservation for the outer block would make no real difference in case #2, apart from the fact that the first area of the outer block is now also non-empty, as it contains a line-area with one space that survives white-space-collapse. That area should not have an after-border, since that should appear only on the last area (unless it is retained). In case #1 white-space-preservation would also lead to the generation of a second block area, without before-border.
          Hide
          Jeremias Maerki added a comment -

          Ok, there seems to be a tendency towards merging the breaks. I personally lean towards not merging them. But we're a democracy.

          I just noticed one thing that might be speaking against merging the breaks:
          <fo:block break-before="column">
          <fo:block break-before="page">
          Some text. Some text. Some text. Some text.
          </fo:block>
          </fo:block>
          The spec definitely doesn't say anything about break conflicts, i.e. which break "wins" in the above situation if they are to be merged. For space resolution, for example, the spec is pretty verbose about conflict resolution. To me, this is a further indication that the breaks should not be merged. But of course, I understand the arguments that have been brought up for the merging and don't disagree with them.

          Vincent, if you can do the clarification with xsl-editors@ that'd be fantastic.

          I've been asked to take the issue to me. I'll document our decision on the Wiki once we've reached one and will then work on the issue during the next few weeks (on Trunk).

          Show
          Jeremias Maerki added a comment - Ok, there seems to be a tendency towards merging the breaks. I personally lean towards not merging them. But we're a democracy. I just noticed one thing that might be speaking against merging the breaks: <fo:block break-before="column"> <fo:block break-before="page"> Some text. Some text. Some text. Some text. </fo:block> </fo:block> The spec definitely doesn't say anything about break conflicts, i.e. which break "wins" in the above situation if they are to be merged. For space resolution, for example, the spec is pretty verbose about conflict resolution. To me, this is a further indication that the breaks should not be merged. But of course, I understand the arguments that have been brought up for the merging and don't disagree with them. Vincent, if you can do the clarification with xsl-editors@ that'd be fantastic. I've been asked to take the issue to me. I'll document our decision on the Wiki once we've reached one and will then work on the issue during the next few weeks (on Trunk).
          Hide
          Andreas L. Delmelle added a comment -

          (In reply to comment #20)
          >
          > I just noticed one thing that might be speaking against merging the breaks:
          > <fo:block break-before="column">
          > <fo:block break-before="page">
          > Some text. Some text. Some text. Some text.
          > </fo:block>
          > </fo:block>
          > The spec definitely doesn't say anything about break conflicts, i.e. which
          > break "wins" in the above situation if they are to be merged.

          I'd say it depends. If the column-break for the outer block coincides a page-break, the break-condition for the inner block is satisfied by that break as well. If the column-break stays within the same page, then we would need an additional page-break for the inner block.

          Show
          Andreas L. Delmelle added a comment - (In reply to comment #20) > > I just noticed one thing that might be speaking against merging the breaks: > <fo:block break-before="column"> > <fo:block break-before="page"> > Some text. Some text. Some text. Some text. > </fo:block> > </fo:block> > The spec definitely doesn't say anything about break conflicts, i.e. which > break "wins" in the above situation if they are to be merged. I'd say it depends. If the column-break for the outer block coincides a page-break, the break-condition for the inner block is satisfied by that break as well. If the column-break stays within the same page, then we would need an additional page-break for the inner block.
          Hide
          Andreas L. Delmelle added a comment -

          (In reply to comment #21)
          > (In reply to comment #20)
          > >
          > > I just noticed one thing that might be speaking against merging the breaks:
          > > <fo:block break-before="column">
          > > <fo:block break-before="page">
          > > Some text. Some text. Some text. Some text.
          > > </fo:block>
          > > </fo:block>
          > > The spec definitely doesn't say anything about break conflicts, i.e. which
          > > break "wins" in the above situation if they are to be merged.
          >
          > I'd say it depends. If the column-break for the outer block coincides a
          > page-break, the break-condition for the inner block is satisfied by that break
          > as well. If the column-break stays within the same page, then we would need an
          > additional page-break for the inner block.

          Just noticed: it's actually not so much merging the breaks themselves, but rather merging the break-conditions. There would be no conflict, no winner. Both conditions should always be satisfied by the outcome.

          In case you have 25 nested blocks with break-before="page" with the same basic structure as the example, then the 25 break-conditions can be satisfied by one effective break. Generating 25 breaks would be equally valid, but unnecessary.

          Show
          Andreas L. Delmelle added a comment - (In reply to comment #21) > (In reply to comment #20) > > > > I just noticed one thing that might be speaking against merging the breaks: > > <fo:block break-before="column"> > > <fo:block break-before="page"> > > Some text. Some text. Some text. Some text. > > </fo:block> > > </fo:block> > > The spec definitely doesn't say anything about break conflicts, i.e. which > > break "wins" in the above situation if they are to be merged. > > I'd say it depends. If the column-break for the outer block coincides a > page-break, the break-condition for the inner block is satisfied by that break > as well. If the column-break stays within the same page, then we would need an > additional page-break for the inner block. Just noticed: it's actually not so much merging the breaks themselves, but rather merging the break-conditions. There would be no conflict, no winner. Both conditions should always be satisfied by the outcome. In case you have 25 nested blocks with break-before="page" with the same basic structure as the example, then the 25 break-conditions can be satisfied by one effective break. Generating 25 breaks would be equally valid, but unnecessary.
          Hide
          Vincent Hennebert added a comment -

          (In reply to comment #20)
          > Ok, there seems to be a tendency towards merging the breaks. I personally lean
          > towards not merging them. But we're a democracy.
          >
          > I just noticed one thing that might be speaking against merging the breaks:
          > <fo:block break-before="column">
          > <fo:block break-before="page">
          > Some text. Some text. Some text. Some text.
          > </fo:block>
          > </fo:block>
          > The spec definitely doesn't say anything about break conflicts, i.e. which
          > break "wins" in the above situation if they are to be merged.

          Right. I took on me to implement a ‘conflict’ resolution in o.a.f.util.BreakUtil#compareBreakClasses. In your example the final break would be a page break, since a page break also implies a column break. Otherwise, Andreas’ comment #22 has a point. The idea is to generate as few breaks as necessary that still comply with all of the break specifications in the document.

          The only unsure thing is regarding borders (comment #4 vs comment #6), and I'll send a request for clarification on this soon.

          <snip/>

          Vincent

          Show
          Vincent Hennebert added a comment - (In reply to comment #20) > Ok, there seems to be a tendency towards merging the breaks. I personally lean > towards not merging them. But we're a democracy. > > I just noticed one thing that might be speaking against merging the breaks: > <fo:block break-before="column"> > <fo:block break-before="page"> > Some text. Some text. Some text. Some text. > </fo:block> > </fo:block> > The spec definitely doesn't say anything about break conflicts, i.e. which > break "wins" in the above situation if they are to be merged. Right. I took on me to implement a ‘conflict’ resolution in o.a.f.util.BreakUtil#compareBreakClasses. In your example the final break would be a page break, since a page break also implies a column break. Otherwise, Andreas’ comment #22 has a point. The idea is to generate as few breaks as necessary that still comply with all of the break specifications in the document. The only unsure thing is regarding borders (comment #4 vs comment #6), and I'll send a request for clarification on this soon. <snip/> Vincent
          Hide
          Andreas L. Delmelle added a comment -

          (In reply to comment #23)
          >
          > Right. I took on me to implement a ‘conflict’ resolution in
          > o.a.f.util.BreakUtil#compareBreakClasses. In your example the final break would
          > be a page break, since a page break also implies a column break.

          Hmm... Not sure I agree entirely. At any rate, this is one of those examples that demonstrates that it's actually not really a merge I'm thinking of.

          As stated in comment #21, I think it depends...
          The outer block's break-condition can be satisfied by a column-break. That should be the first effective break. Whether we need a second effective page-break depends on whether the column-break moves to a new column on the same page, or already coincides with a page-break. Only in the latter case, the result is identical to what is proposed above.

          Supposing a two-column layout:

          <fo:block>...</fo:block>
          <fo:block break-before="column" border="1pt solid red">
          <fo:block break-before="page" border="0.5pt solid blue">
          ...

          The result I'd expect would be:

          • content of the first block in page#1, column#1
          • top border of the second (outer) block on page#1 , column#2
          • third (inner) block on page#2
          Show
          Andreas L. Delmelle added a comment - (In reply to comment #23) > > Right. I took on me to implement a ‘conflict’ resolution in > o.a.f.util.BreakUtil#compareBreakClasses. In your example the final break would > be a page break, since a page break also implies a column break. Hmm... Not sure I agree entirely. At any rate, this is one of those examples that demonstrates that it's actually not really a merge I'm thinking of. As stated in comment #21, I think it depends... The outer block's break-condition can be satisfied by a column-break. That should be the first effective break. Whether we need a second effective page-break depends on whether the column-break moves to a new column on the same page, or already coincides with a page-break. Only in the latter case, the result is identical to what is proposed above. Supposing a two-column layout: <fo:block>...</fo:block> <fo:block break-before="column" border="1pt solid red"> <fo:block break-before="page" border="0.5pt solid blue"> ... The result I'd expect would be: content of the first block in page#1, column#1 top border of the second (outer) block on page#1 , column#2 third (inner) block on page#2
          Hide
          Vincent Hennebert added a comment -

          (In reply to comment #18)
          > page, along with the inner block, in attachment #21531 [details]. I think our best bet is
          > to ask for clarification on xsl-editors@. Will do in a couple of days if nobody
          > else chimes in.

          Question: up to how many days can you put in ‘a couple of days’? Candy offered to who provides the answer first.

          Request for clarification sent: http://lists.w3.org/Archives/Public/xsl-editors/2008AprJun/0003.html

          Show
          Vincent Hennebert added a comment - (In reply to comment #18) > page, along with the inner block, in attachment #21531 [details] . I think our best bet is > to ask for clarification on xsl-editors@. Will do in a couple of days if nobody > else chimes in. Question: up to how many days can you put in ‘a couple of days’? Candy offered to who provides the answer first. Request for clarification sent: http://lists.w3.org/Archives/Public/xsl-editors/2008AprJun/0003.html
          Hide
          Jeremias Maerki added a comment -

          Regression fix for empty pages caused by multiple collapsible breaks.
          No more empty block areas if a break-before occurs on the first child of an FO to match the behaviour of tables and other FO implementations (clarification by XSL WG pending).
          Added an accessor interface for break-before/-after to avoid long if..else lists in BlockStackingLayoutManager.
          http://svn.apache.org/viewvc?rev=669118&view=rev

          Show
          Jeremias Maerki added a comment - Regression fix for empty pages caused by multiple collapsible breaks. No more empty block areas if a break-before occurs on the first child of an FO to match the behaviour of tables and other FO implementations (clarification by XSL WG pending). Added an accessor interface for break-before/-after to avoid long if..else lists in BlockStackingLayoutManager. http://svn.apache.org/viewvc?rev=669118&view=rev
          Hide
          Glenn Adams added a comment -

          (In reply to comment #25)
          > (In reply to comment #18)
          > > page, along with the inner block, in attachment #21531 [details]. I think our best bet is
          > > to ask for clarification on xsl-editors@. Will do in a couple of days if nobody
          > > else chimes in.
          >
          > Question: up to how many days can you put in ‘a couple of days’? Candy offered
          > to who provides the answer first.
          >
          > Request for clarification sent:
          > http://lists.w3.org/Archives/Public/xsl-editors/2008AprJun/0003.html

          vincent, could you move this bug to resolved (in some flavor), or does it need additional work?

          Show
          Glenn Adams added a comment - (In reply to comment #25) > (In reply to comment #18) > > page, along with the inner block, in attachment #21531 [details] . I think our best bet is > > to ask for clarification on xsl-editors@. Will do in a couple of days if nobody > > else chimes in. > > Question: up to how many days can you put in ‘a couple of days’? Candy offered > to who provides the answer first. > > Request for clarification sent: > http://lists.w3.org/Archives/Public/xsl-editors/2008AprJun/0003.html vincent, could you move this bug to resolved (in some flavor), or does it need additional work?
          Hide
          Glenn Adams added a comment -

          resetting P2 open bugs to P3 pending further review

          Show
          Glenn Adams added a comment - resetting P2 open bugs to P3 pending further review
          Hide
          Vincent Hennebert added a comment -

          (In reply to comment #27)
          > vincent, could you move this bug to resolved (in some flavor), or does it need
          > additional work?

          The bug still shows up in with tables.

          Show
          Vincent Hennebert added a comment - (In reply to comment #27) > vincent, could you move this bug to resolved (in some flavor), or does it need > additional work? The bug still shows up in with tables.

            People

            • Assignee:
              Unassigned
              Reporter:
              Vincent Hennebert
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:

                Development