feat: Multiple border style. (#202)

This commit is contained in:
Arthur Sonzogni
2021-09-12 00:36:59 +02:00
committed by GitHub
parent 4d50dadb41
commit b5c3b17b3f
8 changed files with 506 additions and 40 deletions

View File

@@ -1,4 +1,5 @@
#include <iostream> // for operator<<, stringstream, basic_ostream, flush, cout, ostream
#include <map>
#include <memory> // for allocator
#include <sstream> // IWYU pragma: keep
@@ -88,6 +89,228 @@ void UpdatePixelStyle(std::stringstream& ss,
previous = next;
}
struct TileEncoding {
unsigned int left : 2;
unsigned int top : 2;
unsigned int right : 2;
unsigned int down : 2;
unsigned int round : 1;
bool operator<(const TileEncoding& other) const {
union Converter {
TileEncoding input;
uint16_t output = 0;
};
Converter a, b;
a.input = *this;
b.input = other;
return a.output < b.output;
}
};
// clang-format off
const std::map<std::string, TileEncoding> tile_encoding = {
{"", {1, 0, 1, 0, 0}},
{"", {2, 0, 2, 0, 0}},
{"", {0, 1, 0, 1, 0}},
{"", {0, 2, 0, 2, 0}},
{"", {0, 0, 1, 1, 0}},
{"", {0, 0, 2, 1, 0}},
{"", {0, 0, 1, 2, 0}},
{"", {0, 0, 2, 2, 0}},
{"", {1, 0, 0, 1, 0}},
{"", {2, 0, 0, 1, 0}},
{"", {1, 0, 0, 2, 0}},
{"", {2, 0, 0, 2, 0}},
{"", {0, 1, 1, 0, 0}},
{"", {0, 1, 2, 0, 0}},
{"", {0, 2, 1, 0, 0}},
{"", {0, 2, 2, 0, 0}},
{"", {1, 1, 0, 0, 0}},
{"", {2, 1, 0, 0, 0}},
{"", {1, 2, 0, 0, 0}},
{"", {2, 2, 0, 0, 0}},
{"", {0, 1, 1, 1, 0}},
{"", {0, 1, 2, 1, 0}},
{"", {0, 2, 1, 1, 0}},
{"", {0, 1, 1, 2, 0}},
{"", {0, 2, 1, 2, 0}},
{"", {0, 2, 2, 1, 0}},
{"", {0, 1, 2, 2, 0}},
{"", {0, 2, 2, 2, 0}},
{"", {1, 1, 0, 1, 0}},
{"", {2, 1, 0, 1, 0}},
{"", {1, 2, 0, 1, 0}},
{"", {1, 1, 0, 2, 0}},
{"", {1, 2, 0, 2, 0}},
{"", {2, 2, 0, 1, 0}},
{"", {2, 1, 0, 2, 0}},
{"", {2, 2, 0, 2, 0}},
{"", {1, 0, 1, 1, 0}},
{"", {2, 0, 1, 1, 0}},
{"", {1, 0, 2, 1, 0}},
{"", {2, 0, 2, 1, 0}},
{"", {1, 0, 1, 2, 0}},
{"", {2, 0, 1, 2, 0}},
{"", {1, 0, 2, 2, 0}},
{"", {2, 0, 2, 2, 0}},
{"", {1, 1, 1, 0, 0}},
{"", {2, 1, 1, 0, 0}},
{"", {1, 1, 2, 0, 0}},
{"", {2, 1, 2, 0, 0}},
{"", {1, 2, 1, 0, 0}},
{"", {2, 2, 1, 0, 0}},
{"", {1, 2, 2, 0, 0}},
{"", {2, 2, 2, 0, 0}},
{"", {1, 1, 1, 1, 0}},
{"", {2, 1, 1, 1, 0}},
{"", {1, 1, 2, 1, 0}},
{"", {2, 1, 2, 1, 0}},
{"", {1, 2, 1, 1, 0}},
{"", {1, 1, 1, 2, 0}},
{"", {1, 2, 1, 2, 0}},
{"", {2, 2, 1, 1, 0}},
{"", {1, 2, 2, 1, 0}},
{"", {2, 1, 1, 2, 0}},
{"", {1, 1, 2, 2, 0}},
{"", {2, 2, 2, 1, 0}},
{"", {2, 1, 2, 2, 0}},
{"", {2, 2, 1, 2, 0}},
{"", {1, 2, 2, 2, 0}},
{"", {2, 2, 2, 2, 0}},
{"", {3, 0, 3, 0, 0}},
{"", {0, 3, 0, 3, 0}},
{"", {0, 0, 3, 1, 0}},
{"", {0, 0, 1, 3, 0}},
{"", {0, 0, 3, 3, 0}},
{"", {3, 0, 0, 1, 0}},
{"", {1, 0, 0, 3, 0}},
{"", {3, 0, 0, 3, 0}},
{"", {0, 1, 3, 0, 0}},
{"", {0, 3, 1, 0, 0}},
{"", {0, 3, 3, 0, 0}},
{"", {3, 1, 0, 0, 0}},
{"", {1, 3, 0, 0, 0}},
{"", {3, 3, 0, 0, 0}},
{"", {0, 1, 3, 1, 0}},
{"", {0, 3, 1, 3, 0}},
{"", {0, 3, 3, 3, 0}},
{"", {3, 1, 0, 1, 0}},
{"", {1, 3, 0, 3, 0}},
{"", {3, 3, 0, 3, 0}},
{"", {3, 0, 3, 1, 0}},
{"", {1, 0, 1, 3, 0}},
{"", {3, 0, 3, 3, 0}},
{"", {3, 1, 3, 0, 0}},
{"", {1, 3, 1, 0, 0}},
{"", {3, 3, 3, 0, 0}},
{"", {3, 1, 3, 1, 0}},
{"", {1, 3, 1, 3, 0}},
{"", {3, 3, 3, 3, 0}},
{"", {0, 0, 1, 1, 1}},
{"", {1, 0, 0, 1, 1}},
{"", {1, 1, 0, 0, 1}},
{"", {0, 1, 1, 0, 1}},
{"", {1, 0, 0, 0, 0}},
{"", {0, 1, 0, 0, 0}},
{"", {0, 0, 1, 0, 0}},
{"", {0, 0, 0, 1, 0}},
{"", {2, 0, 0, 0, 0}},
{"", {0, 2, 0, 0, 0}},
{"", {0, 0, 2, 0, 0}},
{"", {0, 0, 0, 2, 0}},
{"", {1, 0, 2, 0, 0}},
{"", {0, 1, 0, 2, 0}},
{"", {2, 0, 1, 0, 0}},
{"", {0, 2, 0, 1, 0}},
};
// clang-format on
template <class A, class B>
const std::map<B, A> InvertMap(const std::map<A, B> input) {
std::map<B, A> output;
for (const auto& it : input)
output[it.second] = it.first;
return output;
}
const std::map<TileEncoding, std::string> tile_encoding_inverse =
InvertMap(tile_encoding);
void UpgradeLeftRight(std::string& left, std::string& right) {
const auto it_left = tile_encoding.find(left);
if (it_left == tile_encoding.end())
return;
const auto it_right = tile_encoding.find(right);
if (it_right == tile_encoding.end())
return;
if (it_left->second.right == 0 && it_right->second.left != 0) {
TileEncoding encoding_left = it_left->second;
encoding_left.right = it_right->second.left;
const auto it_left_upgrade = tile_encoding_inverse.find(encoding_left);
if (it_left_upgrade != tile_encoding_inverse.end())
left = it_left_upgrade->second;
}
if (it_right->second.left == 0 && it_left->second.right != 0) {
TileEncoding encoding_right = it_right->second;
encoding_right.left = it_left->second.right;
const auto it_right_upgrade = tile_encoding_inverse.find(encoding_right);
if (it_right_upgrade != tile_encoding_inverse.end())
right = it_right_upgrade->second;
}
}
void UpgradeTopDown(std::string& top, std::string& down) {
const auto it_top = tile_encoding.find(top);
if (it_top == tile_encoding.end())
return;
const auto it_down = tile_encoding.find(down);
if (it_down == tile_encoding.end())
return;
if (it_top->second.down == 0 && it_down->second.top != 0) {
TileEncoding encoding_top = it_top->second;
encoding_top.down = it_down->second.top;
const auto it_top_down = tile_encoding_inverse.find(encoding_top);
if (it_top_down != tile_encoding_inverse.end())
top = it_top_down->second;
}
if (it_down->second.top == 0 && it_top->second.down != 0) {
TileEncoding encoding_down = it_down->second;
encoding_down.top = it_top->second.down;
const auto it_down_top = tile_encoding_inverse.find(encoding_down);
if (it_down_top != tile_encoding_inverse.end())
down = it_down_top->second;
}
}
} // namespace
/// A fixed dimension.
@@ -234,21 +457,13 @@ void Screen::ApplyShader() {
// Left vs current.
std::string& left = pixels_[y][x-1].character;
if (left.size() == 3u) {
if (cur == "" && left == "") cur = "";
if (cur == "" && left == "") cur = "";
if (cur == "" && left == "") left = "";
if (cur == "" && left == "") left = "";
}
if (left.size() == 3u)
UpgradeLeftRight(left, cur);
// Top vs current.
std::string& top = pixels_[y-1][x].character;
if (top.size() == 3u) {
if (cur == "" && top == "") cur = "";
if (cur == "" && top == "") cur = "";
if (cur == "" && top == "") top = "";
if (cur == "" && top == "") top = "";
}
if (top.size() == 3u)
UpgradeTopDown(top, cur);
}
}
}