gtk_renderer.hpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #pragma once
  2. #include "lumacs/editor_core.hpp"
  3. #include "lumacs/window.hpp"
  4. #include "lumacs/theme.hpp"
  5. #include <gtkmm.h>
  6. #include <pangomm.h>
  7. #include <memory>
  8. #include <optional>
  9. namespace lumacs {
  10. // Forward declarations
  11. class EditorCore;
  12. class Window;
  13. // Constants for padding
  14. static constexpr double PADDING_LEFT = 8.0;
  15. static constexpr double PADDING_TOP = 8.0;
  16. static constexpr double PADDING_RIGHT = 8.0;
  17. static constexpr double PADDING_BOTTOM = 8.0;
  18. class GtkRenderer {
  19. public:
  20. GtkRenderer(EditorCore& core, Gtk::Widget& context_widget);
  21. void initialize_font_metrics();
  22. void apply_face_attributes(Pango::AttrList& attr_list, const FaceAttributes& face, int start_index, int end_index);
  23. std::optional<Position> resolve_screen_pos(std::shared_ptr<Window> window, double x, double y);
  24. void on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height,
  25. std::shared_ptr<Window> active_window_cache, bool cursor_visible_state);
  26. void draw_window(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height,
  27. std::shared_ptr<Window> window, Gtk::Widget* widget,
  28. std::shared_ptr<Window> active_window_cache, bool cursor_visible_state);
  29. void render_modeline_for_window(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height,
  30. std::shared_ptr<Window> window,
  31. std::shared_ptr<Window> active_window_cache);
  32. void render_minibuffer(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height);
  33. /// @brief Gets the screen coordinates and dimensions of the minibuffer area.
  34. /// @param x Output parameter for the X coordinate.
  35. /// @param y Output parameter for the Y coordinate.
  36. /// @param width Output parameter for the width.
  37. /// @param height Output parameter for the height.
  38. /// @return True if the coordinates could be determined, false otherwise.
  39. bool get_minibuffer_coords(int& x, int& y, int& width, int& height) const;
  40. /// @brief Clears the internal render cache, forcing a full redraw.
  41. /// Useful when the theme changes.
  42. void invalidate_cache();
  43. /// @brief Set the font size in points.
  44. void set_font_size(int size);
  45. /// @brief Get the current font size in points.
  46. [[nodiscard]] int font_size() const { return font_size_; }
  47. /// @brief Get the current line height in pixels.
  48. [[nodiscard]] double line_height() const { return line_height_; }
  49. /// @brief Get the current scale factor (for HiDPI).
  50. [[nodiscard]] int scale_factor() const { return scale_factor_; }
  51. private:
  52. /// @brief Convert character position to byte index for UTF-8 string.
  53. static size_t char_to_byte_index(const std::string& str, size_t char_pos);
  54. struct LineCacheEntry {
  55. std::string text_content;
  56. std::vector<StyledRange> styles; // Check if styles changed
  57. Cairo::RefPtr<Cairo::ImageSurface> surface;
  58. int width = 0;
  59. int height = 0;
  60. int scale = 1; // Scale factor when surface was created
  61. };
  62. // Map Window ID (or ptr) -> (Line Index -> Cache Entry)
  63. std::unordered_map<Window*, std::unordered_map<size_t, LineCacheEntry>> render_cache_;
  64. EditorCore& core_;
  65. Gtk::Widget& context_widget_;
  66. Pango::FontDescription font_desc_;
  67. bool font_initialized_ = false;
  68. int font_size_ = 12;
  69. int scale_factor_ = 1; // HiDPI scale factor
  70. double char_width_ = 0;
  71. double line_height_ = 0;
  72. double ascent_ = 0;
  73. double descent_ = 0;
  74. };
  75. } // namespace lumacs