diff options
author | Marcus Nilsson <brainbomb@gmail.com> | 2022-01-03 00:24:11 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-01-06 21:25:02 +0100 |
commit | eb97617ff0a1a4dcb759101cdc52739189ebdad7 (patch) | |
tree | 867790a8142631d0b207431552018a748a5b2cc4 | |
parent | cecbed467bf2f365c6c48eaea89f35a57e671b4b (diff) | |
download | serenity-eb97617ff0a1a4dcb759101cdc52739189ebdad7.zip |
PDFViewer: Add actions to rotate the displayed PDF
This implements the rotate cw/ccw actions in PDFViewer.
Since the rendered pages are stored in a HashMap for caching,
the bitmap is wrapped in a struct with the current rotation.
This way the caching works as expected while zooming, and a new bitmap
is rendered when the page is rotated.
-rw-r--r-- | Userland/Applications/PDFViewer/PDFViewer.cpp | 18 | ||||
-rw-r--r-- | Userland/Applications/PDFViewer/PDFViewer.h | 9 | ||||
-rw-r--r-- | Userland/Applications/PDFViewer/PDFViewerWidget.cpp | 14 | ||||
-rw-r--r-- | Userland/Applications/PDFViewer/PDFViewerWidget.h | 2 |
4 files changed, 36 insertions, 7 deletions
diff --git a/Userland/Applications/PDFViewer/PDFViewer.cpp b/Userland/Applications/PDFViewer/PDFViewer.cpp index 3fed2b229a..ccc79e544e 100644 --- a/Userland/Applications/PDFViewer/PDFViewer.cpp +++ b/Userland/Applications/PDFViewer/PDFViewer.cpp @@ -29,7 +29,7 @@ void PDFViewer::set_document(RefPtr<PDF::Document> document) m_rendered_page_list.ensure_capacity(document->get_page_count()); for (u32 i = 0; i < document->get_page_count(); i++) - m_rendered_page_list.unchecked_append(HashMap<u32, RefPtr<Gfx::Bitmap>>()); + m_rendered_page_list.unchecked_append(HashMap<u32, RenderedPage>()); update(); } @@ -38,11 +38,11 @@ RefPtr<Gfx::Bitmap> PDFViewer::get_rendered_page(u32 index) { auto& rendered_page_map = m_rendered_page_list[index]; auto existing_rendered_page = rendered_page_map.get(m_zoom_level); - if (existing_rendered_page.has_value()) - return existing_rendered_page.value(); + if (existing_rendered_page.has_value() && existing_rendered_page.value().rotation == m_rotations) + return existing_rendered_page.value().bitmap; auto rendered_page = render_page(m_document->get_page(index)); - rendered_page_map.set(m_zoom_level, rendered_page); + rendered_page_map.set(m_zoom_level, { rendered_page, m_rotations }); return rendered_page; } @@ -167,6 +167,12 @@ void PDFViewer::reset_zoom() update(); } +void PDFViewer::rotate(int degrees) +{ + m_rotations = (m_rotations + degrees + 360) % 360; + update(); +} + RefPtr<Gfx::Bitmap> PDFViewer::render_page(const PDF::Page& page) { auto zoom_scale_factor = static_cast<float>(zoom_levels[m_zoom_level]) / 100.0f; @@ -181,8 +187,8 @@ RefPtr<Gfx::Bitmap> PDFViewer::render_page(const PDF::Page& page) PDF::Renderer::render(*m_document, page, bitmap); - if (page.rotate != 0) { - int rotation_count = (page.rotate / 90) % 4; + if (page.rotate + m_rotations != 0) { + int rotation_count = ((page.rotate + m_rotations) / 90) % 4; if (rotation_count == 3) { bitmap = bitmap->rotated(Gfx::RotationDirection::CounterClockwise).release_value_but_fixme_should_propagate_errors(); } else { diff --git a/Userland/Applications/PDFViewer/PDFViewer.h b/Userland/Applications/PDFViewer/PDFViewer.h index 5b884b46c1..5182fca5e3 100644 --- a/Userland/Applications/PDFViewer/PDFViewer.h +++ b/Userland/Applications/PDFViewer/PDFViewer.h @@ -52,6 +52,7 @@ public: void zoom_in(); void zoom_out(); void reset_zoom(); + void rotate(int degrees); protected: PDFViewer(); @@ -64,14 +65,20 @@ protected: virtual void timer_event(Core::TimerEvent&) override; private: + struct RenderedPage { + RefPtr<Gfx::Bitmap> bitmap; + int rotation; + }; + RefPtr<Gfx::Bitmap> get_rendered_page(u32 index); RefPtr<Gfx::Bitmap> render_page(const PDF::Page&); RefPtr<PDF::Document> m_document; u32 m_current_page_index { 0 }; - Vector<HashMap<u32, RefPtr<Gfx::Bitmap>>> m_rendered_page_list; + Vector<HashMap<u32, RenderedPage>> m_rendered_page_list; u8 m_zoom_level { initial_zoom_level }; Gfx::IntPoint m_pan_starting_position; + int m_rotations { 0 }; }; diff --git a/Userland/Applications/PDFViewer/PDFViewerWidget.cpp b/Userland/Applications/PDFViewer/PDFViewerWidget.cpp index 618dfd63b2..dcc11b4f65 100644 --- a/Userland/Applications/PDFViewer/PDFViewerWidget.cpp +++ b/Userland/Applications/PDFViewer/PDFViewerWidget.cpp @@ -130,13 +130,25 @@ void PDFViewerWidget::create_toolbar() m_viewer->reset_zoom(); }); + m_rotate_counterclockwise_action = GUI::CommonActions::make_rotate_counterclockwise_action([&](auto&) { + m_viewer->rotate(-90); + }); + + m_rotate_clockwise_action = GUI::CommonActions::make_rotate_clockwise_action([&](auto&) { + m_viewer->rotate(90); + }); + m_zoom_in_action->set_enabled(false); m_zoom_out_action->set_enabled(false); m_reset_zoom_action->set_enabled(false); + m_rotate_counterclockwise_action->set_enabled(false); + m_rotate_clockwise_action->set_enabled(false); toolbar.add_action(*m_zoom_in_action); toolbar.add_action(*m_zoom_out_action); toolbar.add_action(*m_reset_zoom_action); + toolbar.add_action(*m_rotate_counterclockwise_action); + toolbar.add_action(*m_rotate_clockwise_action); } void PDFViewerWidget::open_file(int fd, String const& path) @@ -167,6 +179,8 @@ void PDFViewerWidget::open_file(int fd, String const& path) m_zoom_in_action->set_enabled(true); m_zoom_out_action->set_enabled(true); m_reset_zoom_action->set_enabled(true); + m_rotate_counterclockwise_action->set_enabled(true); + m_rotate_clockwise_action->set_enabled(true); if (document->outline()) { auto outline = document->outline(); diff --git a/Userland/Applications/PDFViewer/PDFViewerWidget.h b/Userland/Applications/PDFViewer/PDFViewerWidget.h index 92840d3852..b482f1876c 100644 --- a/Userland/Applications/PDFViewer/PDFViewerWidget.h +++ b/Userland/Applications/PDFViewer/PDFViewerWidget.h @@ -38,6 +38,8 @@ private: RefPtr<GUI::Action> m_zoom_in_action; RefPtr<GUI::Action> m_zoom_out_action; RefPtr<GUI::Action> m_reset_zoom_action; + RefPtr<GUI::Action> m_rotate_counterclockwise_action; + RefPtr<GUI::Action> m_rotate_clockwise_action; bool m_sidebar_open { false }; ByteBuffer m_buffer; |