skullc-peripherals/Utility/Inc/utility_pixelbuffer_effects.hpp
Erki 60bad24319
Some checks failed
continuous-integration/drone/push Build is failing
The great renaming, part 1
2021-06-08 23:18:56 +03:00

119 lines
2.8 KiB
C++

//
// Created by erki on 16.05.21.
//
#ifndef SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP_
#define SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP_
#include <cstdint>
#include <string_view>
#include <tuple>
#include <type_traits>
namespace Utility
{
namespace Effects
{
template<std::size_t W, std::size_t H, typename TP, typename F>
struct TextScroll
{
static constexpr std::size_t width = W;
static constexpr std::size_t height = H;
using parent_type = std::decay_t<TP>;
using font = std::decay_t<F>;
static constexpr std::size_t chars_per_view = width / (font::width + 1);
parent_type& parent;
std::string_view string;
typename parent_type::value color;
typename parent_type::value background;
TextScroll() = delete;
TextScroll(parent_type& parent, const typename parent_type::value& color, const typename parent_type::value& background)
: parent(parent), color(color), background(background)
{}
TextScroll(const TextScroll&) = delete;
TextScroll(TextScroll&&) = delete;
TextScroll& operator=(const TextScroll&) = delete;
TextScroll& operator=(TextScroll&&) = delete;
void setText(const std::string_view& text)
{
string = text;
current_begin = text.cbegin();
toBuffer_(current_begin);
}
void scrollCharacter(const std::size_t& step = 1)
{
if (string.size() <= chars_per_view)
return;
current_begin++;
if (current_begin == string.cend())
current_begin = string.cbegin();
toBuffer_(current_begin);
}
auto view()
{
return parent.template view<width, height>({0, 0});
}
private:
std::string_view::const_iterator current_begin;
void toBuffer_(std::string_view::const_iterator begin)
{
std::uint32_t x = 0;
const std::uint32_t y = 0;
auto iterate_begin = [&begin, this]() {
begin++;
if (string.size() > chars_per_view && begin == string.cend())
begin = string.cbegin();
};
auto is_over = [this](const std::size_t& ci, const std::string_view::const_iterator& it) -> bool {
if (string.size() <= chars_per_view)
return it != string.cend();
else
return ci < chars_per_view;
};
for (std::size_t ci = 0; is_over(ci, begin); ci++, iterate_begin())
{
const auto [c_start, c_stop] = font::getCharacterBytes(*begin);
for (auto it = c_start; it != c_stop; it++, x++)
{
const std::uint8_t& column_byte = *it;
if (x >= width)
return;
for (std::uint32_t i = 0; i < font::height && i + y < height; i++)
{
parent.at(x, y + i) = column_byte & (1 << i) ? color : background;
}
}
x++;
}
}
};
template<std::size_t W, std::size_t H>
class ScreenScroll
{
};
}// namespace Effects
}// namespace Utility
#endif//SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP_