From 5b35a35b24fe5a9f927c09e49fe328586817a47a Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 3 Sep 2017 17:31:56 -0400 Subject: [PATCH] BufferView stores all lines in view after update() --- src/core/BufferView.cc | 27 ++++++++++++++++++++------- src/core/BufferView.h | 39 +++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/core/BufferView.cc b/src/core/BufferView.cc index eae9a8f..bc49de2 100644 --- a/src/core/BufferView.cc +++ b/src/core/BufferView.cc @@ -66,21 +66,34 @@ void BufferView::update() m_cursor_screen_row = std::min(rows_above, m_cursor_screen_row); /* Determine the first line that is visible in this view. */ - m_first_line = std::make_shared(*m_iterator); - m_first_line_row_offset = m_cursor_screen_row - m_cursor_row_offset; - if (m_first_line_row_offset <= 0) + auto line_iterator = std::make_shared(*m_iterator); + int row_offset = m_cursor_screen_row - m_cursor_row_offset; + if (row_offset <= 0) { - m_first_line->go_start_of_line(); + line_iterator->go_start_of_line(); } else for (auto rows_iterator_pair : backward_lines) { - m_first_line_row_offset -= rows_iterator_pair.first; - m_first_line = rows_iterator_pair.second; - if (m_first_line_row_offset <= 0) + row_offset -= rows_iterator_pair.first; + line_iterator = rows_iterator_pair.second; + if (row_offset <= 0) { break; } } + + /* Now start with first visible line and build up all lines visible in the view. */ + m_lines.clear(); + while ((row_offset < m_height) && (line_iterator->valid())) + { + LineDescriptor ld; + ld.row_offset = row_offset; + ld.n_rows = calculate_rows_in_line(line_iterator); + ld.line = std::make_shared(*line_iterator); + m_lines.push_back(ld); + row_offset += ld.n_rows; + line_iterator->go_next_line(); + } } int BufferView::calculate_rows_in_line(std::shared_ptr start_of_line) diff --git a/src/core/BufferView.h b/src/core/BufferView.h index 3476690..a48f72f 100644 --- a/src/core/BufferView.h +++ b/src/core/BufferView.h @@ -5,6 +5,7 @@ #include "CharacterWidthDeterminer.h" #include #include "BufferLineWalker.h" +#include /** * Tracks a "view" of a buffer, which is a two-dimensional grid of characters @@ -18,11 +19,7 @@ public: public: Iterator(BufferView & bv) : m_buffer_view(bv) { - if (bv.m_iterator->valid()) - { - m_iterator = std::make_shared(*m_buffer_view.m_first_line); - m_row_offset = m_buffer_view.m_first_line_row_offset; - } + m_index = 0u; } void operator++() { @@ -30,32 +27,28 @@ public: } void operator++(int unused) { - if (is_valid()) - { - m_row_offset += m_buffer_view.calculate_rows_in_line(m_iterator); - if ((m_row_offset >= m_buffer_view.m_height) || (!m_iterator->go_next_line())) - { - m_iterator.reset(); - } - } + m_index++; } bool is_valid() { - return (bool)m_iterator; + return m_index < m_buffer_view.m_lines.size(); } int row_offset() const { - return m_row_offset; + return m_buffer_view.m_lines[m_index].row_offset; + } + int n_rows() const + { + return m_buffer_view.m_lines[m_index].n_rows; } std::shared_ptr iterator() const { - return m_iterator; + return m_buffer_view.m_lines[m_index].line; } protected: BufferView & m_buffer_view; - std::shared_ptr m_iterator; - int m_row_offset; + size_t m_index; }; BufferView(std::shared_ptr buffer, @@ -75,8 +68,6 @@ public: protected: std::shared_ptr m_buffer; std::shared_ptr m_iterator; - std::shared_ptr m_first_line; - int m_first_line_row_offset; int m_width; int m_height; int m_scroll_offset; @@ -86,6 +77,13 @@ protected: int m_cursor_row_offset; CharacterWidthDeterminer & m_character_width_determiner; + struct LineDescriptor + { + int row_offset; + int n_rows; + std::shared_ptr line; + }; + int effective_scroll_offset() { return std::min(m_scroll_offset, (m_height - 1) / 2); @@ -97,6 +95,7 @@ protected: int screen_rows_above_line( std::shared_ptr line, std::list>> & backward_lines); + std::vector m_lines; }; #endif