Skip to content

Commit 059afcb

Browse files
committed
Fix PaintHarness after rebase: paint from the fragment tree, not deleted CssBox.Paint
PR ArthurHub#262's PaintHarness.PaintBox (merged into master while this branch was in flight) called box.Paint(g) directly - the old live-tree paint entry point. This branch's own F3 stage later deleted CssBox.Paint/PaintImp entirely once FragmentPainter became the sole paint path, so rebasing this branch onto master (which now carries PaintHarness) fails to compile: git's line-based merge can't catch an API a fresh commit calls having been removed by an earlier one in this branch's own history. Fix: PaintHarness.PaintBox now locates the CssBox's own BoxFragment in container.FragmentTree (searching every fragmentainer, in case the box was relocated onto a later page) and paints it via a new FragmentPainter test entry point, FragmentPainter.PaintFragmentSubtree - a thin wrapper that sets the painter's band-top before delegating to its existing private PaintFragment, letting a test get "just this box's draw calls" without duplicating the real paint walk. This is the same widen-for-test-use precedent already applied to CssBox.PaintBackground/PaintWord/PaintDecoration. Full three-project suite passes after the rebase: HtmlRenderer.Test (2367), HtmlRenderer.IntegrationTest (146), HtmlRenderer.PdfSharp.Test (30) - 0 failed.
1 parent 1be6c4f commit 059afcb

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

‎Source/HtmlRenderer/Core/Paint/FragmentPainter.cs‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ internal void Paint(RGraphics g, FragmentainerFragment fragmentainer)
123123
PaintFragment(g, fragmentainer.Root);
124124
}
125125

126+
/// <summary>
127+
/// Test-support entry point: paints one box fragment (and its descendants) directly, without
128+
/// painting the rest of its fragmentainer - mirrors what the old live-tree <c>CssBox.Paint(g)</c>
129+
/// did for an arbitrary box, for tests that want the draw-call log of just one subtree.
130+
/// <paramref name="bandTop"/> should be the owning fragmentainer's own
131+
/// <see cref="FragmentainerFragment.LocalOriginY"/>.
132+
/// </summary>
133+
internal void PaintFragmentSubtree(RGraphics g, BoxFragment fragment, double bandTop = 0)
134+
{
135+
_bandTop = bandTop;
136+
PaintFragment(g, fragment);
137+
}
138+
126139
/// <summary>
127140
/// Paints one box fragment: display/visibility gate, fixed-position clip suspension, and the
128141
/// same "is this rect actually in the visible area" cull the old live-tree walk used, before

‎Source/Test/HtmlRenderer.IntegrationTest/TestSupport/PaintHarness.cs‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using TheArtOfDev.HtmlRenderer.Adapters.Entities;
22
using TheArtOfDev.HtmlRenderer.Core;
33
using TheArtOfDev.HtmlRenderer.Core.Dom;
4+
using TheArtOfDev.HtmlRenderer.Core.Fragments;
5+
using TheArtOfDev.HtmlRenderer.Core.Paint;
46

57
namespace HtmlRenderer.IntegrationTest.TestSupport;
68

@@ -68,8 +70,45 @@ internal static void PaintBox(HtmlContainerInt container, CssBox box, RecordingG
6870
g.PushClip(new RRect(container.MarginLeft, container.MarginTop, container.PageSize.Width, container.PageSize.Height));
6971
}
7072

71-
box.Paint(g);
73+
var (fragment, bandTop) = FindFragment(container, box);
74+
new FragmentPainter(container).PaintFragmentSubtree(g, fragment, bandTop);
7275

7376
g.PopClip();
7477
}
78+
79+
/// <summary>
80+
/// Locates <paramref name="box"/>'s own <see cref="BoxFragment"/> in <paramref name="container"/>'s
81+
/// fragment tree (built by <see cref="HtmlContainerInt.PerformLayout"/>), searching every fragmentainer
82+
/// since a box relocated onto a later page won't be found on the first one. Paint now reads geometry
83+
/// from the fragment tree exclusively (<c>CssBox.Paint</c>/<c>PaintImp</c> were deleted once
84+
/// <see cref="FragmentPainter"/> became the only paint path), so a harness that wants "the draw calls
85+
/// for this one box" has to find its fragment first, the same way <see cref="FragmentPainter.Paint"/>
86+
/// itself starts from a fragmentainer's own <c>Root</c> fragment rather than a live <c>CssBox</c>.
87+
/// </summary>
88+
private static (BoxFragment Fragment, double BandTop) FindFragment(HtmlContainerInt container, CssBox box)
89+
{
90+
foreach (var fragmentainer in container.FragmentTree.Fragmentainers)
91+
{
92+
var found = FindFragment(fragmentainer.Root, box);
93+
if (found != null)
94+
return (found, fragmentainer.LocalOriginY);
95+
}
96+
97+
throw new InvalidOperationException("No fragment found for the given box - is it display:none, or otherwise never laid out?");
98+
}
99+
100+
private static BoxFragment? FindFragment(BoxFragment fragment, CssBox box)
101+
{
102+
if (ReferenceEquals(fragment.Box, box))
103+
return fragment;
104+
105+
foreach (var child in fragment.Children)
106+
{
107+
var found = FindFragment(child, box);
108+
if (found != null)
109+
return found;
110+
}
111+
112+
return fragment.MarkerFragment != null ? FindFragment(fragment.MarkerFragment, box) : null;
113+
}
75114
}

0 commit comments

Comments
 (0)