display

Layout and Rendering TUI library
git clone git://git.dimitrijedobrota.com/display.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit3de3fb64e8f9d6d905972e16419088edaafa266c
parentf5707488a04d7c0d01ad26ee6bdf1eb54f7ed87f
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateSat, 1 Mar 2025 21:49:02 +0100

Fix comparason with constants, prevent underflow

Diffstat:
MCMakeLists.txt|+-
Mexample/example.cpp|+++++++++++++-------------
Mexample/navig/navig.cpp|+-
Minclude/display/layout_rigid.hpp|++++++++++----------
Minclude/display/types.hpp|++++++++++++++++------------
Msource/window_pivot.cpp|++++----

6 files changed, 45 insertions(+), 41 deletions(-)


diff --git a/CMakeLists.txt b/CMakeLists.txt

@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)

project(
display
VERSION 0.2.0
VERSION 0.3.0
DESCRIPTION "TUI library"
HOMEPAGE_URL "git://git.dimitrijedobrota.com/display.git"
LANGUAGES CXX

diff --git a/example/example.cpp b/example/example.cpp

@@ -63,23 +63,23 @@ public:

const auto [m, n] = get_grid();
const auto valid = [&](std::size_t xpos, std::size_t ypos)
{ return xpos >= 0 && xpos < n.value() && ypos >= 0 && ypos < m.value(); };
{ return xpos < n && ypos < m; };
const auto get = [&](std::size_t xpos, std::size_t ypos) -> std::uint8_t
{ return valid(xpos, ypos) ? layout[xpos][ypos] : 0xFF; };
for (std::size_t i = 0; i <= n.value(); i++) {
for (std::size_t j = 0; j <= m.value(); j++) {
for (std::size_t i = 0; i <= n; i++) {
for (std::size_t j = 0; j <= m; j++) {
const std::uint8_t ptl = get(i - 1, j - 1);
const std::uint8_t ptr = get(i - 1, j);
const std::uint8_t pbl = get(i, j - 1);
const std::uint8_t pbr = get(i, j);
uint8_t mask = 0;
mask |= ((ptl != ptr) ? 1U : 0U) << 0U; // Top
mask |= ((ptr != pbr) ? 1U : 0U) << 1U; // Right
mask |= ((pbr != pbl) ? 1U : 0U) << 2U; // Bottom
mask |= ((pbl != ptl) ? 1U : 0U) << 3U; // Left
mask |= static_cast<uint8_t>(((ptl != ptr) ? 1U : 0U) << 0U); // Top
mask |= static_cast<uint8_t>(((ptr != pbr) ? 1U : 0U) << 1U); // Right
mask |= static_cast<uint8_t>(((pbr != pbl) ? 1U : 0U) << 2U); // Bottom
mask |= static_cast<uint8_t>(((pbl != ptl) ? 1U : 0U) << 3U); // Left
m_corners.emplace_back(mask, wth_t(j), hgt_t(i));
}

@@ -170,16 +170,16 @@ private:

};
// clang-format on
corner_t(std::uint8_t mask, wth_t wigth, hgt_t height) // NOLINT
: mask(mask)
, wigth(wigth)
, height(height)
corner_t(std::uint8_t maskv, wth_t wigth, hgt_t height) // NOLINT
: mask(maskv)
, wth(wigth)
, hgt(height)
{
}
std::uint8_t mask;
wth_t wigth;
hgt_t height;
wth_t wth;
hgt_t hgt;
};
std::vector<corner_t> m_corners;

diff --git a/example/navig/navig.cpp b/example/navig/navig.cpp

@@ -58,7 +58,7 @@ public:

}
if (evnt.key() == 'j') {
if (m_selected + 1 < m_menu.items.size()) {
if (m_selected + 1U < m_menu.items.size()) {
m_selected++;
}
evnt.type() = display::event::Type::NONE;

diff --git a/include/display/layout_rigid.hpp b/include/display/layout_rigid.hpp

@@ -97,16 +97,16 @@ std::size_t LayoutRigid<T>::count_and_pad(layout_t& layout) const

{
std::unordered_set<std::uint8_t> ust;
for (std::size_t i = 0U; i < m_grid.height.value(); i++) {
for (std::size_t j = 0U; j < m_grid.width.value(); j++) {
for (std::size_t i = 0U; i < m_grid.height; i++) {
for (std::size_t j = 0U; j < m_grid.width; j++) {
ust.insert(layout[i][j]);
}
layout[i].emplace_back(0xFF);
}
layout.emplace_back(m_grid.width.value(), 0xFF);
for (std::size_t i = 0U; i < m_grid.height.value(); i++) {
for (std::size_t j = 0U; j < m_grid.width.value(); j++) {
for (std::size_t i = 0U; i < m_grid.height; i++) {
for (std::size_t j = 0U; j < m_grid.width; j++) {
if (layout[i][j] >= ust.size()) {
throw std::runtime_error("Invalid layout [Number]");
}

@@ -121,11 +121,11 @@ void LayoutRigid<T>::handle_cols(const layout_t& layout)

{
const auto [m, n] = get_grid();
for (std::size_t i = 0U; i < n.value(); i++) {
for (std::size_t i = 0U; i < n; i++) {
m_recs[layout[i][m.value() - 1]].addw = true;
auto cnt = wth_t(1);
for (std::size_t j = 0; j < m.value(); j++) {
for (std::size_t j = 0; j < m; j++) {
const auto crnt = layout[i][j];
if (crnt == layout[i][j + 1]) {

@@ -137,7 +137,7 @@ void LayoutRigid<T>::handle_cols(const layout_t& layout)

auto& pos = m_recs[crnt].start.x;
const auto total = xpos_t(j) - cnt + 1;
if (count.value() != 0) {
if (count != 0) {
if (pos != total || count != cnt) {
throw std::runtime_error("Invalid layout [Shape Col]");
}

@@ -156,11 +156,11 @@ void LayoutRigid<T>::handle_rows(const layout_t& layout)

{
const auto [m, n] = get_grid();
for (std::size_t j = 0U; j < m.value(); j++) {
for (std::size_t j = 0U; j < m; j++) {
m_recs[layout[n.value() - 1][j]].addh = true;
auto cnt = hgt_t(1);
for (std::size_t i = 0; i < n.value(); i++) {
for (std::size_t i = 0; i < n; i++) {
const auto crnt = layout[i][j];
if (crnt == layout[i + 1][j]) {

@@ -172,7 +172,7 @@ void LayoutRigid<T>::handle_rows(const layout_t& layout)

auto& pos = m_recs[crnt].start.y;
const auto total = ypos_t(i) - cnt + 1;
if (count.value() != 0) {
if (count != 0) {
if (pos != total || count != cnt) {
throw std::runtime_error("Invalid layout [Shape Row]");
}

diff --git a/include/display/types.hpp b/include/display/types.hpp

@@ -35,25 +35,25 @@ struct val_t

auto& value() { return v; }
// clang-format off
val_t operator+(val_t rhs) const { return val_t(static_cast<sz_t>(v + rhs.v)); }
val_t operator-(val_t rhs) const { return val_t(static_cast<sz_t>(v - rhs.v)); }
val_t operator*(val_t rhs) const { return val_t(static_cast<sz_t>(v * rhs.v)); }
val_t operator/(val_t rhs) const { return val_t(static_cast<sz_t>(v / rhs.v)); }
val_t operator+(val_t rhs) const { return val_t(v + rhs.v); }
val_t operator-(val_t rhs) const { return val_t(v > rhs.v ? v - rhs.v : 0); }
val_t operator*(val_t rhs) const { return val_t(v * rhs.v); }
val_t operator/(val_t rhs) const { return val_t(v / rhs.v); }
val_t operator+(int rhs) const { return val_t(static_cast<sz_t>(v + rhs)); }
val_t operator-(int rhs) const { return val_t(static_cast<sz_t>(v - rhs)); }
val_t operator*(int rhs) const { return val_t(static_cast<sz_t>(v * rhs)); }
val_t operator/(int rhs) const { return val_t(static_cast<sz_t>(v / rhs)); }
val_t operator+(std::size_t rhs) const { return *this + val_t(rhs); }
val_t operator-(std::size_t rhs) const { return *this - val_t(rhs); }
val_t operator*(std::size_t rhs) const { return *this * val_t(rhs); }
val_t operator/(std::size_t rhs) const { return *this / val_t(rhs); }
auto& operator+=(val_t rhs) { v += rhs.v; return *this; }
auto& operator-=(val_t rhs) { v -= rhs.v; return *this; }
auto& operator*=(val_t rhs) { v *= rhs.v; return *this; }
auto& operator/=(val_t rhs) { v /= rhs.v; return *this; }
auto& operator+=(int rhs) { v += rhs; return *this; }
auto& operator-=(int rhs) { v -= rhs; return *this; }
auto& operator*=(int rhs) { v *= rhs; return *this; }
auto& operator/=(int rhs) { v /= rhs; return *this; }
auto& operator+=(std::size_t rhs) { return *this += val_t(rhs); }
auto& operator-=(std::size_t rhs) { return *this -= val_t(rhs); }
auto& operator*=(std::size_t rhs) { return *this *= val_t(rhs); }
auto& operator/=(std::size_t rhs) { return *this /= val_t(rhs); }
auto& operator++() { return *this += 1; }
auto& operator--() { return *this -= 1; }

@@ -62,6 +62,10 @@ struct val_t

val_t operator--(int) { return val_t(v--); }
auto operator<=>(const val_t&) const = default;
bool operator==(const val_t&) const = default;
auto operator<=>(std::size_t rhs) const { return *this <=> val_t(rhs); }
bool operator==(std::size_t rhs) const { return *this == val_t(rhs); }
friend std::ostream& operator<<(std::ostream& ost, val_t cord) {
return ost << cord.value();

diff --git a/source/window_pivot.cpp b/source/window_pivot.cpp

@@ -21,12 +21,12 @@ plc_t WindowPivot::place(plc_t aplc, piv_t piv, dim_t dim)

end.width = add_lim(start.width, wth, awth);
break;
case PvtX::Center:
start.width = sub_lim((awth / 2), (wth / 2), wth_t(0));
start.width = awth / 2 - wth / 2;
end.width = add_lim(start.width, wth, awth);
break;
case PvtX::Right:
end.width = awth;
start.width = sub_lim(end.width, wth, wth_t(0));
start.width = end.width - wth;
break;
}

@@ -36,12 +36,12 @@ plc_t WindowPivot::place(plc_t aplc, piv_t piv, dim_t dim)

end.height = add_lim(start.height, hgt, ahth);
break;
case PvtY::Center:
start.height = sub_lim((ahth / 2), (hgt / 2), hgt_t(0));
start.height = ahth / 2 - hgt / 2;
end.height = add_lim(start.height, hgt, ahth);
break;
case PvtY::Bottom:
end.height = ahth;
start.height = sub_lim(end.height, hgt, hgt_t(0));
start.height = end.height - hgt;
break;
}