mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:37:44 +00:00
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.
This commit is contained in:
parent
cecbed467b
commit
eb97617ff0
4 changed files with 36 additions and 7 deletions
|
@ -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 {
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue