PDFViewer.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2021-2022, Matthew Olsson <mattco@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/HashMap.h>
  9. #include <LibGUI/AbstractScrollableWidget.h>
  10. #include <LibGfx/Bitmap.h>
  11. #include <LibPDF/Document.h>
  12. #include <LibPDF/Renderer.h>
  13. static constexpr size_t initial_zoom_level = 8;
  14. struct PageDimensionCache {
  15. // Fixed for a given document
  16. struct PageInfo {
  17. Gfx::FloatSize size;
  18. int rotation;
  19. };
  20. // Based on PageInfo, also depends on some dynamic factors like
  21. // zoom level and app size
  22. struct RenderInfo {
  23. Gfx::FloatSize size;
  24. float total_height_before_this_page;
  25. };
  26. Vector<PageInfo> page_info;
  27. Vector<RenderInfo> render_info;
  28. float max_width;
  29. float total_height;
  30. };
  31. class PDFViewer : public GUI::AbstractScrollableWidget {
  32. C_OBJECT(PDFViewer)
  33. public:
  34. enum class PageViewMode {
  35. Single,
  36. Multiple,
  37. };
  38. virtual ~PDFViewer() override = default;
  39. ALWAYS_INLINE u32 current_page() const { return m_current_page_index; }
  40. void set_current_page(u32 current_page);
  41. ALWAYS_INLINE RefPtr<PDF::Document> const& document() const { return m_document; }
  42. PDF::PDFErrorOr<void> set_document(RefPtr<PDF::Document>);
  43. Function<void(u32 new_page)> on_page_change;
  44. Function<void(u32 page, PDF::Errors const& errors)> on_render_errors;
  45. void zoom_in();
  46. void zoom_out();
  47. void reset_zoom();
  48. void rotate(int degrees);
  49. PageViewMode page_view_mode() const { return m_page_view_mode; }
  50. void set_page_view_mode(PageViewMode);
  51. bool show_rendering_diagnostics() const { return m_rendering_preferences.show_diagnostics; }
  52. void set_show_rendering_diagnostics(bool);
  53. bool show_clipping_paths() const { return m_rendering_preferences.show_clipping_paths; }
  54. void set_show_clipping_paths(bool);
  55. bool show_images() const { return m_rendering_preferences.show_images; }
  56. void set_show_images(bool);
  57. bool clip_images() const { return m_rendering_preferences.clip_images; }
  58. void set_clip_images(bool);
  59. bool clip_paths() const { return m_rendering_preferences.clip_paths; }
  60. void set_clip_paths(bool);
  61. bool clip_text() const { return m_rendering_preferences.clip_text; }
  62. void set_clip_text(bool);
  63. protected:
  64. PDFViewer();
  65. virtual void paint_event(GUI::PaintEvent&) override;
  66. virtual void resize_event(GUI::ResizeEvent&) override;
  67. virtual void mousewheel_event(GUI::MouseEvent&) override;
  68. virtual void mousedown_event(GUI::MouseEvent&) override;
  69. virtual void mouseup_event(GUI::MouseEvent&) override;
  70. virtual void mousemove_event(GUI::MouseEvent&) override;
  71. virtual void timer_event(Core::TimerEvent&) override;
  72. private:
  73. struct RenderedPage {
  74. NonnullRefPtr<Gfx::Bitmap> bitmap;
  75. int rotation;
  76. };
  77. PDF::PDFErrorOr<NonnullRefPtr<Gfx::Bitmap>> get_rendered_page(u32 index);
  78. PDF::PDFErrorOr<NonnullRefPtr<Gfx::Bitmap>> render_page(u32 page_index);
  79. PDF::PDFErrorOr<void> cache_page_dimensions(bool recalculate_fixed_info = false);
  80. void change_page(u32 new_page);
  81. RefPtr<PDF::Document> m_document;
  82. u32 m_current_page_index { 0 };
  83. Vector<HashMap<u32, RenderedPage>> m_rendered_page_list;
  84. u8 m_zoom_level { initial_zoom_level };
  85. PageDimensionCache m_page_dimension_cache;
  86. PageViewMode m_page_view_mode;
  87. PDF::RenderingPreferences m_rendering_preferences;
  88. Gfx::IntPoint m_pan_starting_position;
  89. int m_rotations { 0 };
  90. };