separate print and string generation functions
string generation during image processing now have their own functions
This commit is contained in:
parent
9969dd1cff
commit
e636a03c13
1 changed files with 73 additions and 16 deletions
87
src/tiv.cpp
87
src/tiv.cpp
|
@ -422,18 +422,14 @@ int best_index(int value, const int STEPS[], int count) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printTermColor(int r, int g, int b, const int8_t &flags) {
|
std::string emitTermColor(const int8_t &flags, int r, int g, int b) {
|
||||||
r = clamp_byte(r);
|
r = clamp_byte(r), g = clamp_byte(g), b = clamp_byte(b);
|
||||||
g = clamp_byte(g);
|
|
||||||
b = clamp_byte(b);
|
|
||||||
|
|
||||||
const bool bg = (flags & FLAG_BG);
|
const bool bg = (flags & FLAG_BG);
|
||||||
|
|
||||||
if ((flags & FLAG_MODE_256) == 0) {
|
if (!(flags & FLAG_MODE_256)) {
|
||||||
// 2 means we output true (RGB) colors
|
// 2 means we output true (RGB) colors
|
||||||
std::cout << (bg ? "\x1b[48;2;" : "\x1b[38;2;") << r << ';' << g << ';'
|
return std::format("\x1b[{};2;{};{};{}m", bg ? 48 : 38, r, g, b);
|
||||||
<< b << 'm';
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute predefined color index from all 256 colors we should use
|
// Compute predefined color index from all 256 colors we should use
|
||||||
|
@ -460,10 +456,10 @@ void printTermColor(int r, int g, int b, const int8_t &flags) {
|
||||||
color_index = 232 + gri; // 1..24 -> 232..255
|
color_index = 232 + gri; // 1..24 -> 232..255
|
||||||
}
|
}
|
||||||
// 38 sets the foreground color and 48 sets the background color
|
// 38 sets the foreground color and 48 sets the background color
|
||||||
std::cout << (bg ? "\x1B[48;5;" : "\u001B[38;5;") << color_index << "m";
|
return std::format("\x1b[{};5;{}m", bg ? 48 : 38, color_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printCodepoint(int codepoint) {
|
void emitCodepoint(int codepoint) {
|
||||||
if (codepoint < 128) {
|
if (codepoint < 128) {
|
||||||
std::cout << static_cast<char>(codepoint);
|
std::cout << static_cast<char>(codepoint);
|
||||||
} else if (codepoint < 0x7ff) {
|
} else if (codepoint < 0x7ff) {
|
||||||
|
@ -483,21 +479,82 @@ void printCodepoint(int codepoint) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printImage(const cimg_library::CImg<unsigned char> &image,
|
std::string emitImage(const cimg_library::CImg<unsigned char> &image,
|
||||||
const int8_t &flags) {
|
const int8_t &flags) {
|
||||||
|
std::string ret;
|
||||||
CharData lastCharData;
|
CharData lastCharData;
|
||||||
for (int y = 0; y <= image.height() - 8; y += 8) {
|
for (int y = 0; y <= image.height() - 8; y += 8) {
|
||||||
for (int x = 0; x <= image.width() - 4; x += 4) {
|
for (int x = 0; x <= image.width() - 4; x += 4) {
|
||||||
|
// Create CharData for the current 4x8 area of the image
|
||||||
|
// If only half-block chars are allowed, use predefined codepoint
|
||||||
CharData charData =
|
CharData charData =
|
||||||
flags & FLAG_NOOPT
|
flags & FLAG_NOOPT
|
||||||
? createCharData(image, x, y, 0x2584, 0x0000ffff)
|
? createCharData(image, x, y, 0x2584, 0x0000ffff)
|
||||||
: findCharData(image, x, y, flags);
|
: findCharData(image, x, y, flags);
|
||||||
if (x == 0 || charData.bgColor != lastCharData.bgColor)
|
if (x == 0 || charData.bgColor != lastCharData.bgColor)
|
||||||
printTermColor(charData.bgColor[0], charData.bgColor[1],
|
ret += emitTermColor(flags | FLAG_BG, charData.bgColor[0],
|
||||||
charData.bgColor[2], flags | FLAG_BG);
|
charData.bgColor[1], charData.bgColor[2]);
|
||||||
if (x == 0 || charData.fgColor != lastCharData.fgColor)
|
if (x == 0 || charData.fgColor != lastCharData.fgColor)
|
||||||
printTermColor(charData.fgColor[0], charData.fgColor[1],
|
ret += emitTermColor(flags | FLAG_FG, charData.fgColor[0],
|
||||||
charData.fgColor[2], flags | FLAG_FG);
|
charData.fgColor[1], charData.fgColor[2]);
|
||||||
|
ret += (charData.codePoint);
|
||||||
|
lastCharData = charData;
|
||||||
|
}
|
||||||
|
ret += "\x1b[0m\n"; // clear formatting until next batch
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper function to print a codepoint in a terminal-friendly way
|
||||||
|
*
|
||||||
|
* @param codepoint The codepoint to print
|
||||||
|
*/
|
||||||
|
void printCodepoint(int codepoint) {
|
||||||
|
if (codepoint < 128) { // ASCII
|
||||||
|
std::cout << static_cast<char>(codepoint);
|
||||||
|
} else if (codepoint < 0x7ff) { // 2-byte UTF-8
|
||||||
|
std::cout << static_cast<char>(0xc0 | (codepoint >> 6));
|
||||||
|
std::cout << static_cast<char>(0x80 | (codepoint & 0x3f));
|
||||||
|
} else if (codepoint < 0xffff) { // 3-byte UTF-8
|
||||||
|
std::cout << static_cast<char>(0xe0 | (codepoint >> 12));
|
||||||
|
std::cout << static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f));
|
||||||
|
std::cout << static_cast<char>(0x80 | (codepoint & 0x3f));
|
||||||
|
} else if (codepoint < 0x10ffff) { // 4-byte UTF-8
|
||||||
|
std::cout << static_cast<char>(0xf0 | (codepoint >> 18));
|
||||||
|
std::cout << static_cast<char>(0x80 | ((codepoint >> 12) & 0x3f));
|
||||||
|
std::cout << static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f));
|
||||||
|
std::cout << static_cast<char>(0x80 | (codepoint & 0x3f));
|
||||||
|
} else { //???
|
||||||
|
std::cerr << std::format(
|
||||||
|
"Error: Codepoint 0x{:08x} is out of range, skipping this pixel",
|
||||||
|
codepoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Outputs the given image.
|
||||||
|
*
|
||||||
|
* @param image The image to output.
|
||||||
|
* @param flags
|
||||||
|
*/
|
||||||
|
void printImage(const cimg_library::CImg<unsigned char> &image,
|
||||||
|
const int8_t &flags) {
|
||||||
|
CharData lastCharData;
|
||||||
|
for (int y = 0; y <= image.height() - 8; y += 8) {
|
||||||
|
for (int x = 0; x <= image.width() - 4; x += 4) {
|
||||||
|
// Create CharData for the current 4x8 area of the image
|
||||||
|
// If only half-block chars are allowed, use predefined codepoint
|
||||||
|
CharData charData =
|
||||||
|
flags & FLAG_NOOPT
|
||||||
|
? createCharData(image, x, y, 0x2584, 0x0000ffff)
|
||||||
|
: findCharData(image, x, y, flags);
|
||||||
|
if (x == 0 || charData.bgColor != lastCharData.bgColor)
|
||||||
|
std::cout << emitTermColor(flags | FLAG_BG, charData.bgColor[0],
|
||||||
|
charData.bgColor[1], charData.bgColor[2]);
|
||||||
|
if (x == 0 || charData.fgColor != lastCharData.fgColor)
|
||||||
|
std::cout << emitTermColor(flags | FLAG_FG, charData.fgColor[0],
|
||||||
|
charData.fgColor[1], charData.fgColor[2]);
|
||||||
printCodepoint(charData.codePoint);
|
printCodepoint(charData.codePoint);
|
||||||
lastCharData = charData;
|
lastCharData = charData;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue