Line.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/AnyOf.h>
  9. #include <AK/Noncopyable.h>
  10. #include <AK/Vector.h>
  11. #include <LibVT/Attribute.h>
  12. #include <LibVT/Position.h>
  13. #include <LibVT/XtermColors.h>
  14. namespace VT {
  15. class Line {
  16. AK_MAKE_NONCOPYABLE(Line);
  17. AK_MAKE_NONMOVABLE(Line);
  18. public:
  19. explicit Line(size_t length);
  20. ~Line() = default;
  21. struct Cell {
  22. u32 code_point { ' ' };
  23. Attribute attribute;
  24. bool operator!=(Cell const& other) const { return code_point != other.code_point || attribute != other.attribute; }
  25. };
  26. Attribute const& attribute_at(size_t index) const { return m_cells[index].attribute; }
  27. Attribute& attribute_at(size_t index) { return m_cells[index].attribute; }
  28. Cell& cell_at(size_t index) { return m_cells[index]; }
  29. Cell const& cell_at(size_t index) const { return m_cells[index]; }
  30. void clear(Attribute const& attribute = Attribute())
  31. {
  32. m_terminated_at.clear();
  33. clear_range(0, m_cells.size() - 1, attribute);
  34. }
  35. void clear_range(size_t first_column, size_t last_column, Attribute const& attribute = Attribute());
  36. bool has_only_one_background_color() const;
  37. bool is_empty() const
  38. {
  39. return !any_of(m_cells, [](auto& cell) { return cell != Cell(); });
  40. }
  41. size_t length() const
  42. {
  43. return m_cells.size();
  44. }
  45. void set_length(size_t);
  46. void rewrap(size_t new_length, Line* next_line, CursorPosition* cursor, bool cursor_is_on_next_line = true);
  47. u32 code_point(size_t index) const
  48. {
  49. return m_cells[index].code_point;
  50. }
  51. void set_code_point(size_t index, u32 code_point)
  52. {
  53. if (m_terminated_at.has_value()) {
  54. if (index > *m_terminated_at) {
  55. m_terminated_at = index + 1;
  56. }
  57. }
  58. m_cells[index].code_point = code_point;
  59. }
  60. bool is_dirty() const { return m_dirty; }
  61. void set_dirty(bool b) { m_dirty = b; }
  62. Optional<u16> termination_column() const { return m_terminated_at; }
  63. void set_terminated(u16 column) { m_terminated_at = column; }
  64. private:
  65. void take_cells_from_next_line(size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor);
  66. void push_cells_into_next_line(size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor);
  67. Vector<Cell> m_cells;
  68. bool m_dirty { false };
  69. // Note: The alignment is 8, so this member lives in the padding (that already existed before it was introduced)
  70. [[no_unique_address]] Optional<u16> m_terminated_at;
  71. };
  72. }