Skip to content

Commit 55a21d6

Browse files
committed
Fix outlines on images, rules, split boxes and invert
- Paint the outline for replaced elements and <hr> - Copy the outline when a box gets cloned - Treat outline-color: invert as currentColor
1 parent 940f3aa commit 55a21d6

4 files changed

Lines changed: 48 additions & 0 deletions

File tree

‎Source/HtmlRenderer/Core/Dom/CssBoxProperties.cs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ public RColor ActualOutlineColor
793793
// treated the same as unset, since an invisible-by-default outline would defeat the point
794794
// of the property entirely.
795795
return string.IsNullOrEmpty(OutlineColor) || OutlineColor == "transparent"
796+
|| OutlineColor.Equals("invert", StringComparison.OrdinalIgnoreCase)
796797
? ActualColor
797798
: GetActualColor(OutlineColor);
798799
}
@@ -1997,6 +1998,9 @@ protected void InheritStyle(CssBox p, bool everything)
19971998
_borderRightStyle = p._borderRightStyle;
19981999
_borderBottomStyle = p._borderBottomStyle;
19992000
_borderLeftStyle = p._borderLeftStyle;
2001+
_outlineStyle = p._outlineStyle;
2002+
_outlineColor = p._outlineColor;
2003+
_outlineWidth = p._outlineWidth;
20002004
_bottom = p._bottom;
20012005
_borderTopLeftRadius = p._borderTopLeftRadius;
20022006
_borderTopRightRadius = p._borderTopRightRadius;

‎Source/HtmlRenderer/Core/Paint/Content/HrFragmentPainter.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using TheArtOfDev.HtmlRenderer.Adapters.Entities;
33
using TheArtOfDev.HtmlRenderer.Core.Dom;
44
using TheArtOfDev.HtmlRenderer.Core.Fragments;
5+
using TheArtOfDev.HtmlRenderer.Core.Handlers;
56

67
namespace TheArtOfDev.HtmlRenderer.Core.Paint.Content
78
{
@@ -25,6 +26,7 @@ public void Paint(FragmentPainter painter, RGraphics g, BoxFragment fragment)
2526
var rect = fragment.PrimaryRect;
2627
rect.Offset(offset);
2728
box.DrawHrContent(g, rect);
29+
OutlineDrawHandler.Draw(g, box, rect);
2830
}
2931
}
3032
}

‎Source/HtmlRenderer/Core/Paint/Content/ReplacedFragmentPainter.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public void Paint(FragmentPainter painter, RGraphics g, BoxFragment fragment)
3131

3232
box.PaintBackground(g, rect, true, true);
3333
BordersDrawHandler.DrawBoxBorders(g, box, rect, true, true);
34+
OutlineDrawHandler.Draw(g, box, rect);
3435

3536
DrawContent(g, fragment, painter.LiveTreeOffset(box.IsFixed));
3637

‎Source/Test/HtmlRenderer.IntegrationTest/Painting/OutlineStylePaintIntegrationTests.cs‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,45 @@ public void OutlineOffset_PushesTheRingFurtherFromTheBorderBox()
130130

131131
Assert.AreEqual(borderBox.Y - 10 - 5, top.Y, 0.1);
132132
}
133+
134+
[TestMethod]
135+
public void OutlineColorInvert_FallsBackToCurrentColor()
136+
{
137+
var (_, container) = PaintHarness.Layout(PaintHarness.Wrap(
138+
"<div style='width:100px;height:50px;color:rgb(51,51,51);outline:5px solid invert'></div>"));
139+
140+
var g = PaintHarness.PaintPage(container);
141+
var rects = g.Log.OfType<RecordingGraphics.DrawRectCall>()
142+
.Where(r => r.Color == RColor.FromArgb(51, 51, 51)).ToList();
143+
144+
Assert.AreEqual(4, rects.Count);
145+
}
146+
147+
[TestMethod]
148+
[DataRow("<img id='e' style='width:20px;height:20px;outline:5px solid rgb(51,51,51)'>")]
149+
[DataRow("<hr id='e' style='outline:5px solid rgb(51,51,51)'>")]
150+
public void ReplacedAndRuleElements_PaintTheirOutline(string element)
151+
{
152+
var (_, container) = PaintHarness.Layout(PaintHarness.Wrap(element));
153+
154+
var g = PaintHarness.PaintPage(container);
155+
var rects = g.Log.OfType<RecordingGraphics.DrawRectCall>()
156+
.Where(r => r.Color == RColor.FromArgb(51, 51, 51)).ToList();
157+
158+
Assert.AreEqual(4, rects.Count);
159+
}
160+
161+
[TestMethod]
162+
public void InlineSplitAroundABlock_KeepsTheOutlineOnEveryPart()
163+
{
164+
// The span gets split into a part before and a part after the block, and both parts are copies.
165+
var (_, container) = PaintHarness.Layout(PaintHarness.Wrap(
166+
"<span style='outline:2px solid rgb(51,51,51)'>before<div>block</div>after</span>"));
167+
168+
var g = PaintHarness.PaintPage(container);
169+
var rects = g.Log.OfType<RecordingGraphics.DrawRectCall>()
170+
.Where(r => r.Color == RColor.FromArgb(51, 51, 51)).ToList();
171+
172+
Assert.IsGreaterThanOrEqualTo(8, rects.Count, "both the part before and the part after the block need a ring");
173+
}
133174
}

0 commit comments

Comments
 (0)