LibPDF: Fix path coordinates calculation

Paths rendering was buggy because the map() function that translates
points from user space to bitmap space applied the vertical flip
conversion that the current transformation matrix already considers;
Hence, all paths were upside down. The only exception was the "re"
instruction, which manually adjusted the Y coordinate of its points to
be flipped again (and had a FIXME saying that this should be
unnecessary).

This commit fixes the map() function that maps userspace points to
bitmap coordinates. The "re" operator implementation has also been
simplified creating a rectangle first and mapping *that* instead of
mapping each point individually.
This commit is contained in:
Rodrigo Tobar 2022-11-26 12:53:32 +08:00 committed by Andreas Kling
parent 21f500937b
commit d04613d252
Notes: sideshowbarker 2024-07-18 01:43:16 +09:00

View file

@ -42,10 +42,18 @@ static Gfx::Path rect_path(float x, float y, float width, float height)
return path; return path;
} }
template<typename T>
static void rect_path(Gfx::Path& path, Gfx::Rect<T> rect)
{
return rect_path(path, rect.x(), rect.y(), rect.width(), rect.height());
}
template<typename T> template<typename T>
static Gfx::Path rect_path(Gfx::Rect<T> rect) static Gfx::Path rect_path(Gfx::Rect<T> rect)
{ {
return rect_path(rect.x(), rect.y(), rect.width(), rect.height()); Gfx::Path path;
rect_path(path, rect);
return path;
} }
Renderer::Renderer(RefPtr<Document> document, Page const& page, RefPtr<Gfx::Bitmap> bitmap, RenderingPreferences rendering_preferences) Renderer::Renderer(RefPtr<Document> document, Page const& page, RefPtr<Gfx::Bitmap> bitmap, RenderingPreferences rendering_preferences)
@ -229,14 +237,8 @@ RENDERER_HANDLER(path_close)
RENDERER_HANDLER(path_append_rect) RENDERER_HANDLER(path_append_rect)
{ {
auto pos = map(args[0].to_float(), args[1].to_float()); auto rect = Gfx::FloatRect(args[0].to_float(), args[1].to_float(), args[2].to_float(), args[3].to_float());
auto size = map(Gfx::FloatSize { args[2].to_float(), args[3].to_float() }); rect_path(m_current_path, map(rect));
// FIXME: Why do we need to flip the y axis of rectangles here? The coordinates
// in the PDF file seem to be correct, with the same flipped-ness as
// everything else in a PDF file.
pos.set_y(m_bitmap->height() - pos.y() - size.height());
rect_path(m_current_path, pos.x(), pos.y(), size.width(), size.height());
return {}; return {};
} }
@ -624,8 +626,7 @@ RENDERER_TODO(compatibility_end)
template<typename T> template<typename T>
Gfx::Point<T> Renderer::map(T x, T y) const Gfx::Point<T> Renderer::map(T x, T y) const
{ {
auto mapped = state().ctm.map(Gfx::Point<T> { x, y }); return state().ctm.map(Gfx::Point<T> { x, y });
return { mapped.x(), static_cast<T>(m_bitmap->height()) - mapped.y() };
} }
template<typename T> template<typename T>