Skip to content

Commit

Permalink
Merge pull request #13 from alfattack/absolute-positioning
Browse files Browse the repository at this point in the history
Support absolute positioning
  • Loading branch information
mstancombe authored Jul 24, 2024
2 parents e2fd2d2 + 71e21af commit d936de6
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<html>
<body>
<div style="position: absolute; top: 700px; left: 90px; width: 75px; height: 75px; background-color: black;"></div>

<div style="position: relative;">
<div style="width: 200px; height: 200px; background-color: green;"></div>
<div style="width: 50px; height: 50px; background-color: red; position: absolute; top: 30px; left: 400px;"></div>
</div>

<div style="width: 400px; height: 200px; margin-left: 80px; background-color: purple"></div>

<div style="width: 600px; height: 300px; background-color: white; position: relative;">
<div style="width: 50px; height: 50px; background-color: brown; top: 50px; left: 25px; position: absolute; "></div>
</div>

</body>
</html>
8 changes: 4 additions & 4 deletions Source/Demos/HtmlRenderer.Demo.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
foreach (var htmlSample in samples)
{
////Just doing one test here. Comment this for all of them.
if (!htmlSample.FullName.Contains("16", StringComparison.OrdinalIgnoreCase)) continue;
if (!htmlSample.FullName.Contains("37", StringComparison.OrdinalIgnoreCase)) continue;

await skia.GenerateSampleAsync(htmlSample);
await svgSkia.GenerateSampleAsync(htmlSample);
//await pdfSharp.GenerateSampleAsync(htmlSample);
//await skia.GenerateSampleAsync(htmlSample);
//await svgSkia.GenerateSampleAsync(htmlSample);
await pdfSharp.GenerateSampleAsync(htmlSample);
}


Expand Down
42 changes: 38 additions & 4 deletions Source/HtmlRenderer/Core/Dom/CssBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,17 @@ public virtual bool IsFixed
}
}

/// <summary>
/// Gets a value indicating whether this instance has Position = absolute.
/// </summary>
/// <value>
/// <c>true</c> if this instance is fixed; otherwise, <c>false</c>.
/// </value>
public virtual bool IsAbsolute
{
get => Position == CssConstants.Absolute;
}

/// <summary>
/// Get the href link of the box (by default get "href" attribute)
/// </summary>
Expand Down Expand Up @@ -650,6 +661,26 @@ protected virtual async Task PerformLayoutImpAsync(RGraphics g)
left = 0;
top = 0;
}
else if (Position == CssConstants.Absolute)
{
// find the first positioned parent.
CssBox currentParent = ParentBox;
CssBox positionedAncestor = null;
while(currentParent != null && string.IsNullOrEmpty(currentParent.Position))
{
currentParent = currentParent.ParentBox;
}
positionedAncestor = currentParent;

if (positionedAncestor != null)
{
var location = GetActualLocation(this.Left, this.Top);
left = positionedAncestor.Location.X + location.X;
top = positionedAncestor.Location.Y + location.Y;

Location = new RPoint(left, top);
}
}
else
{
left = ContainingBlock.Location.X + ContainingBlock.ActualPaddingLeft + ActualMarginLeft + ContainingBlock.ActualBorderLeftWidth;
Expand Down Expand Up @@ -709,11 +740,11 @@ protected virtual async Task PerformLayoutImpAsync(RGraphics g)
ActualBottom = prevSibling.ActualBottom;
}
}
ActualBottom = Math.Max(ActualBottom, Location.Y + ActualHeight);

ActualBottom = Math.Max(ActualBottom, Location.Y + ActualHeight);
await CreateListItemBoxAsync(g);

if (!IsFixed)
if (!IsFixed && !IsAbsolute)
{
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 Expand Up @@ -1192,12 +1223,15 @@ private double CalculateActualRight()
private double MarginBottomCollapse()
{
double margin = 0;

// Get the last child box that doesn't have absolute or fixed positioning.
var lastChildBox = _boxes.Where(b => b.Position != CssConstants.Fixed && b.Position != CssConstants.Absolute).LastOrDefault();
if (ParentBox != null && ParentBox.Boxes.IndexOf(this) == ParentBox.Boxes.Count - 1 && _parentBox.ActualMarginBottom < 0.1)
{
var lastChildBottomMargin = _boxes[_boxes.Count - 1].ActualMarginBottom;
var lastChildBottomMargin = lastChildBox?.ActualMarginBottom ?? 0;
margin = Height == "auto" ? Math.Max(ActualMarginBottom, lastChildBottomMargin) : lastChildBottomMargin;
}
return Math.Max(ActualBottom, _boxes[_boxes.Count - 1].ActualBottom + margin + ActualPaddingBottom + ActualBorderBottomWidth);
return Math.Max(ActualBottom, (lastChildBox?.ActualBottom ?? 0) + margin + ActualPaddingBottom + ActualBorderBottomWidth);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Source/HtmlRenderer/Core/Utils/DomUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public static CssBox GetPreviousSibling(CssBox b)
sib = b.ParentBox.Boxes[index - ++diff];
}

return (sib.Display == CssConstants.None || sib.Position == CssConstants.Fixed) ? null : sib;
return (sib.Display == CssConstants.None || sib.Position == CssConstants.Absolute || sib.Position == CssConstants.Fixed) ? null : sib;
}
}
return null;
Expand Down

0 comments on commit d936de6

Please sign in to comment.