Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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