LibPDF: Clip stroke for B / B* operators

Fixes pages 17-19 on
https://www.iro.umontreal.ca/~feeley/papers/ChevalierBoisvertFeeleyECOOP15.pdf

Calling the fill handler after painting the stroke as previously doesn't
work, since we need to set up the clip before both stroke and fill, and
unset it after both. The duplication is a bit unfortunate, but also
minor.
This commit is contained in:
Nico Weber 2024-03-07 20:02:23 -05:00 committed by Tim Flynn
parent 7c322ec710
commit 24951a039e

View file

@ -388,22 +388,38 @@ RENDERER_HANDLER(path_fill_evenodd)
RENDERER_HANDLER(path_fill_stroke_nonzero)
{
begin_path_paint();
if (state().stroke_style.has<NonnullRefPtr<Gfx::PaintStyle>>()) {
m_anti_aliasing_painter.stroke_path(m_current_path, state().stroke_style.get<NonnullRefPtr<Gfx::PaintStyle>>(), line_width());
} else {
m_anti_aliasing_painter.stroke_path(m_current_path, state().stroke_style.get<Color>(), line_width());
}
return handle_path_fill_nonzero(args);
m_current_path.close_all_subpaths();
if (state().paint_style.has<NonnullRefPtr<Gfx::PaintStyle>>()) {
m_anti_aliasing_painter.fill_path(m_current_path, state().paint_style.get<NonnullRefPtr<Gfx::PaintStyle>>(), 1.0, Gfx::Painter::WindingRule::Nonzero);
} else {
m_anti_aliasing_painter.fill_path(m_current_path, state().paint_style.get<Color>(), Gfx::Painter::WindingRule::Nonzero);
}
end_path_paint();
return {};
}
RENDERER_HANDLER(path_fill_stroke_evenodd)
{
begin_path_paint();
if (state().stroke_style.has<NonnullRefPtr<Gfx::PaintStyle>>()) {
m_anti_aliasing_painter.stroke_path(m_current_path, state().stroke_style.get<NonnullRefPtr<Gfx::PaintStyle>>(), line_width());
} else {
m_anti_aliasing_painter.stroke_path(m_current_path, state().stroke_style.get<Color>(), line_width());
}
return handle_path_fill_evenodd(args);
m_current_path.close_all_subpaths();
if (state().paint_style.has<NonnullRefPtr<Gfx::PaintStyle>>()) {
m_anti_aliasing_painter.fill_path(m_current_path, state().paint_style.get<NonnullRefPtr<Gfx::PaintStyle>>(), 1.0, Gfx::Painter::WindingRule::EvenOdd);
} else {
m_anti_aliasing_painter.fill_path(m_current_path, state().paint_style.get<Color>(), Gfx::Painter::WindingRule::EvenOdd);
}
end_path_paint();
return {};
}
RENDERER_HANDLER(path_close_fill_stroke_nonzero)