move character iteration logic from BufferView to BufferLineWalker
This commit is contained in:
parent
65df0c2320
commit
3d4e8230fe
101
src/core/BufferLineWalker.cc
Normal file
101
src/core/BufferLineWalker.cc
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include "BufferLineWalker.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a BufferLineWalker.
|
||||||
|
*/
|
||||||
|
BufferLineWalker::BufferLineWalker(
|
||||||
|
std::shared_ptr<Buffer> buffer,
|
||||||
|
CharacterWidthDeterminer & character_width_determiner)
|
||||||
|
: m_buffer(buffer),
|
||||||
|
m_character_width_determiner(character_width_determiner)
|
||||||
|
{
|
||||||
|
m_width = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the view width.
|
||||||
|
*
|
||||||
|
* @param width View width.
|
||||||
|
*/
|
||||||
|
void BufferLineWalker::set_width(int width)
|
||||||
|
{
|
||||||
|
m_width = std::max(1, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke the callback for each character in the buffer line, wrapping to the
|
||||||
|
* next screen line and taking into account multi-column characters.
|
||||||
|
*
|
||||||
|
* Callback parameters:
|
||||||
|
* - row_offset
|
||||||
|
* - screen column
|
||||||
|
* - virtual column
|
||||||
|
* - character width
|
||||||
|
* - buffer iterator
|
||||||
|
* If the callback function returns true, iteration continues. Otherwise
|
||||||
|
* iteration is terminated.
|
||||||
|
*
|
||||||
|
* @param start_of_line Buffer iterator pointing to the beginning of the buffer line.
|
||||||
|
* @param callback Function to call for each character in the line.
|
||||||
|
*/
|
||||||
|
void BufferLineWalker::walk_line(
|
||||||
|
const Buffer::Iterator & start_of_line,
|
||||||
|
std::function<bool(int, int, int, int, const Buffer::Iterator &)> callback)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!callback(row_offset, screen_column, virtual_column, c_width, i))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
29
src/core/BufferLineWalker.h
Normal file
29
src/core/BufferLineWalker.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef BUFFERLINEWALKER_H
|
||||||
|
#define BUFFERLINEWALKER_H
|
||||||
|
|
||||||
|
#include "Buffer.h"
|
||||||
|
#include "CharacterWidthDeterminer.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides functionality to walk a line of a buffer taking into account the
|
||||||
|
* view width and multi-column characters.
|
||||||
|
*/
|
||||||
|
class BufferLineWalker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BufferLineWalker(
|
||||||
|
std::shared_ptr<Buffer> buffer,
|
||||||
|
CharacterWidthDeterminer & character_width_determiner);
|
||||||
|
void set_width(int width);
|
||||||
|
void walk_line(
|
||||||
|
const Buffer::Iterator & start_of_line,
|
||||||
|
std::function<bool(int, int, int, int, const Buffer::Iterator &)> callback);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<Buffer> m_buffer;
|
||||||
|
CharacterWidthDeterminer & m_character_width_determiner;
|
||||||
|
int m_width;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -23,60 +23,3 @@ void BufferView::set_scroll_offset(int scroll_offset)
|
|||||||
{
|
{
|
||||||
m_scroll_offset = std::max(0, scroll_offset);
|
m_scroll_offset = std::max(0, scroll_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferView::iter_cols(const Buffer::Iterator & start_of_line, std::function<void(int, int, int, int, const Buffer::Iterator &)> callback)
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -18,7 +18,6 @@ public:
|
|||||||
void resize(int width, int height);
|
void resize(int width, int height);
|
||||||
void set_scroll_offset(int scroll_offset);
|
void set_scroll_offset(int scroll_offset);
|
||||||
void iter_lines(std::function<bool(const Buffer::Iterator &)> callback);
|
void iter_lines(std::function<bool(const Buffer::Iterator &)> callback);
|
||||||
void iter_cols(const Buffer::Iterator & start_of_line, std::function<void(int, int, int, int, const Buffer::Iterator &)> callback);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Buffer> m_buffer;
|
std::shared_ptr<Buffer> m_buffer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user