summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Nilsson <brainbomb@gmail.com>2022-01-03 00:24:11 +0100
committerAndreas Kling <kling@serenityos.org>2022-01-06 21:25:02 +0100
commiteb97617ff0a1a4dcb759101cdc52739189ebdad7 (patch)
tree867790a8142631d0b207431552018a748a5b2cc4
parentcecbed467bf2f365c6c48eaea89f35a57e671b4b (diff)
downloadserenity-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.cpp18
-rw-r--r--Userland/Applications/PDFViewer/PDFViewer.h9
-rw-r--r--Userland/Applications/PDFViewer/PDFViewerWidget.cpp14
-rw-r--r--Userland/Applications/PDFViewer/PDFViewerWidget.h2
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;