diff --git a/src/core/BufferView.cc b/src/core/BufferView.cc index abb8708..8c9d92b 100644 --- a/src/core/BufferView.cc +++ b/src/core/BufferView.cc @@ -1,13 +1,14 @@ #include "BufferView.h" BufferView::BufferView(std::shared_ptr buffer, - std::shared_ptr iterator) + std::shared_ptr iterator, + CharacterWidthDeterminer & character_width_determiner) : m_buffer(buffer), - m_iterator(iterator) + m_iterator(iterator), + m_character_width_determiner(character_width_determiner) { m_width = 1; m_height = 1; - m_tabstop = 1; } void BufferView::resize(int width, int height) @@ -16,7 +17,59 @@ void BufferView::resize(int width, int height) m_height = std::max(1, height); } -void BufferView::set_tabstop(int tabstop) +void BufferView::iter_cols(const Buffer::Iterator & start_of_line, std::function callback) { - m_tabstop = std::max(1, tabstop); + int row_offset = 0; + int screen_column = 0; + int virtual_column = 0; + Buffer::Iterator i = start_of_line; + for (;;) + { + uint32_t code_point = *i; + if ((code_point == '\n') || (!i.valid())) + { + callback(row_offset, screen_column, virtual_column, 0, i); + break; + } + int c_width; + if (code_point == '\t') + { + uint8_t tabstop = m_buffer->tabstop(); + c_width = tabstop - virtual_column % tabstop; + } + else + { + c_width = m_character_width_determiner(code_point); + if (((screen_column + c_width) > m_width) && + (screen_column > 0)) + { + row_offset++; + screen_column = 0; + } + } + callback(row_offset, screen_column, virtual_column, c_width, i); + virtual_column += c_width; + if (code_point == '\t') + { + screen_column += c_width; + while (screen_column >= m_width) + { + screen_column -= m_width; + row_offset++; + } + } + else + { + if ((screen_column + c_width) >= m_width) + { + row_offset++; + screen_column = 0; + } + else + { + screen_column += c_width; + } + } + i.go_forward(); + } } diff --git a/src/core/BufferView.h b/src/core/BufferView.h index defe8e2..c19a1ac 100644 --- a/src/core/BufferView.h +++ b/src/core/BufferView.h @@ -2,6 +2,8 @@ #define BUFFERVIEW_H #include "Buffer.h" +#include "CharacterWidthDeterminer.h" +#include /** * Tracks a "view" of a buffer, which is a two-dimensional grid of characters @@ -11,16 +13,17 @@ class BufferView { public: BufferView(std::shared_ptr buffer, - std::shared_ptr iterator); + std::shared_ptr iterator, + CharacterWidthDeterminer & character_width_determiner); void resize(int width, int height); - void set_tabstop(int tabstop); + void iter_cols(const Buffer::Iterator & start_of_line, std::function callback); protected: std::shared_ptr m_buffer; std::shared_ptr m_iterator; + CharacterWidthDeterminer & m_character_width_determiner; int m_width; int m_height; - int m_tabstop; }; #endif