Skip to content

Commit

Permalink
Merge pull request #17 from alfattack/page-break-inside
Browse files Browse the repository at this point in the history
Re-perform layout on page break avoid
  • Loading branch information
mstancombe authored Aug 20, 2024
2 parents 2da1da5 + 179da6a commit 4cfdf87
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
<div style="page-break-inside: avoid; height: 1500px; background-color: blue; padding: 10px;">
This is on page 4.

<div style="height: 500px; background-color: yellow;">
<div style="height: 200px; background-color: yellow;">
This is also on page 4
</div>
<div style="height: 100px; background-color: brown; page-break-inside: avoid;">
This is also on page 4.
</div>

<div style="height: 700px; background-color: aqua; page-break-inside: avoid;">
<div style="height: 300px; background-color: aqua; page-break-inside: avoid;">
This is on page 4
</div>
<div style="height:400px; background-color: orangered; page-break-inside: avoid;">
This is on page 5
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion Source/Demos/HtmlRenderer.Demo.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
foreach (var htmlSample in samples)
{
////Just doing one test here. Comment this for all of them.
if (!htmlSample.FullName.Contains("37")) continue;
if (!htmlSample.FullName.Contains("37") && !htmlSample.FullName.Contains("34")) continue;

//await skia.GenerateSampleAsync(htmlSample);
//await svgSkia.GenerateSampleAsync(htmlSample);
Expand Down
40 changes: 30 additions & 10 deletions Source/HtmlRenderer/Core/Dom/CssBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ internal class CssBox : CssBoxProperties, IDisposable
/// Flag that indicates that CssTable algorithm already made fixes on it.
/// </remarks>
internal bool _tableFixed;

/// <summary>
/// Flag indicating that we're on a second pass for laying out the element after
/// avoiding a page break.
/// </summary>
internal bool _pageBreakAvoided;

protected bool _wordsSizeMeasured;
private CssBox _listItemBox;
Expand Down Expand Up @@ -651,7 +657,9 @@ protected virtual async Task PerformLayoutImpAsync(RGraphics g)
Size = new RSize(width - ActualMarginLeft - ActualMarginRight, Size.Height);
}

if (Display != CssConstants.TableCell)
// Don't recalculate the element's position if we're
// on our second pass after avoiding a page break.
if (Display != CssConstants.TableCell && !_pageBreakAvoided)
{
double left;
double top;
Expand Down Expand Up @@ -700,15 +708,6 @@ protected virtual async Task PerformLayoutImpAsync(RGraphics g)
{
this.BreakPage(true);
}
else if (this.PageBreakInside == CssConstants.Avoid && prevSibling != null)
{
// handle page break avoiding.
var pageLocationY = Location.Y % HtmlContainer.PageSize.Height;
if (ActualHeight + pageLocationY > HtmlContainer.PageSize.Height)
{
this.BreakPage(true);
}
}

//Start with the assumption this is zero height.
ActualBottom = Location.Y;
Expand Down Expand Up @@ -754,6 +753,27 @@ protected virtual async Task PerformLayoutImpAsync(RGraphics g)

if (!IsFixed && !IsAbsolute)
{
if (PageBreakInside == CssConstants.Avoid
&& prevSibling != null
&& Display != CssConstants.TableCell
&& !_pageBreakAvoided)
{
// handle page break avoiding.
var pageLocationY = Location.Y % HtmlContainer.PageSize.Height;
if (Size.Height + pageLocationY > HtmlContainer.PageSize.Height)
{
// if we break page, we'll do another pass at PerformLayoutAsync
// so that child elements are re-positioned correctly.
BreakPage(true);
_pageBreakAvoided = true;
await this.PerformLayoutAsync(g);

// We'll set this flag back to false as this element
// might need re-positioning by its parent.
_pageBreakAvoided = false;
}
}

var actualWidth = Math.Max(GetMinimumWidth() + GetWidthMarginDeep(this), Size.Width < 90999 ? ActualRight - HtmlContainer.Root.Location.X : 0);
HtmlContainer.ActualSize = CommonUtils.Max(HtmlContainer.ActualSize, new RSize(actualWidth, ActualBottom - HtmlContainer.Root.Location.Y));
}
Expand Down

0 comments on commit 4cfdf87

Please sign in to comment.