Porytiles
Loading...
Searching...
No Matches
color_palette_printer.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <ranges>
5#include <vector>
6
11
12namespace {
13
14using namespace porytiles;
15
16template <std::size_t N>
17std::vector<std::string> print_palette_with_highlights_impl(
18 const Palette<Rgba32, N> &pal, const std::vector<std::size_t> &highlight_slots, const TextFormatter *format)
19{
20 std::vector<std::string> lines{};
21
22 // JASC pal front matter
23 lines.emplace_back(" JASC-PAL");
24 lines.emplace_back(" 0100");
25 lines.push_back(format->format(" {}", FormatParam{pal.size()}));
26
27 for (std::size_t i = 0; i < pal.size(); ++i) {
28 const bool is_highlighted = std::ranges::find(highlight_slots, i) != highlight_slots.end();
29
30 std::string prefix;
31 if (is_highlighted) {
32 prefix = format->format("{}", FormatParam{"➞ ", Style::bold | Style::yellow});
33 }
34 else {
35 prefix = " ";
36 }
37
38 std::string slot_str;
39 if (pal.is_wildcard(i)) {
40 slot_str = format->format("{}{}", FormatParam{prefix}, FormatParam{"*"});
41 }
42 else {
43 const Rgba32 color = pal.at(i);
44 const Style color_style = rgb_fg_style(color.red(), color.green(), color.blue());
45
46 if (is_highlighted) {
47 const std::string color_text =
48 format->style(color.to_jasc_str(), Style::bold | Style::italic | Style::yellow | color_style);
49 slot_str = format->format("{}{}", FormatParam{prefix}, FormatParam{color_text});
50 }
51 else {
52 const std::string color_text = format->style(color.to_jasc_str(), color_style);
53 slot_str = format->format("{}{}", FormatParam{prefix}, FormatParam{color_text});
54 }
55 }
56
57 lines.push_back(slot_str);
58 }
59
60 return lines;
61}
62
63} // namespace
64
65namespace porytiles {
66
68{
69 return print_palette_with_highlights_impl(pal, {}, format_);
70}
71
72std::vector<std::string> ColorPalettePrinter::print_rgba_pal(const Palette<Rgba32> &pal) const
73{
74 return print_palette_with_highlights_impl(pal, {}, format_);
75}
76
78 const Palette<Rgba32> &pal, const std::vector<std::size_t> &slots) const
79{
80 return print_palette_with_highlights_impl(pal, slots, format_);
81}
82
84 const Palette<Rgba32, pal::max_size> &pal, const std::vector<std::size_t> &slots) const
85{
86 return print_palette_with_highlights_impl(pal, slots, format_);
87}
88
90 const PaletteHint &hint, const std::vector<std::size_t> &slots) const
91{
92 std::vector<std::string> lines{};
93
94 // JASC pal front matter
95 lines.push_back(format_->format("name: \"{}\"", FormatParam{hint.name(), Style::bold}));
96 lines.emplace_back("colors:");
97
98 for (std::size_t i = 0; i < hint.pal().size(); ++i) {
99 const bool is_highlighted = std::ranges::find(slots, i) != slots.end();
100
101 std::string prefix;
102 if (is_highlighted) {
103 prefix = format_->format("{}", FormatParam{"➞ ", Style::bold | Style::yellow});
104 }
105 else {
106 prefix = " ";
107 }
108
109 std::string slot_str;
110 if (hint.pal().is_wildcard(i)) {
111 panic("illegal wildcard in pal hint '" + hint.name() + "' at index '" + std::to_string(i) + "'");
112 }
113 const Rgba32 color = hint.pal().at(i);
114 const Style color_style = rgb_fg_style(color.red(), color.green(), color.blue());
115
116 if (is_highlighted) {
117 const std::string color_text =
118 format_->style(color.to_csv_str(), Style::bold | Style::italic | color_style);
119 slot_str = format_->format("{} - [ {} ]", FormatParam{prefix}, FormatParam{color_text});
120 }
121 else {
122 const std::string color_text = format_->style(color.to_csv_str(), color_style);
123 slot_str = format_->format("{} - [ {} ]", FormatParam{prefix}, FormatParam{color_text});
124 }
125
126 lines.push_back(slot_str);
127 }
128
129 return lines;
130}
131
132[[nodiscard]] std::vector<std::string> ColorPalettePrinter::print_rgba_palette_covered_missing(
133 const Palette<Rgba32, pal::max_size> &pal, std::set<Rgba32> covered_colors, std::set<Rgba32> missing_colors) const
134{
135 // Build highlight_slots from covered_colors
136 std::vector<std::size_t> highlight_slots;
137 const auto index_to_color = pal.index_to_color_map();
138 for (const auto &[index, color] : index_to_color) {
139 if (covered_colors.contains(color)) {
140 highlight_slots.push_back(index);
141 }
142 }
143
144 // Use the common implementation for palette printing with highlights
145 std::vector<std::string> lines = print_palette_with_highlights_impl(pal, highlight_slots, format_);
146
147 // Append missing colors section if needed
148 if (!missing_colors.empty()) {
149 lines.push_back(format_->format("{}", FormatParam{"------ Palette Still Missing ------", Style::bold}));
150 for (const auto &color : missing_colors) {
151 const Style color_style = rgb_fg_style(color.red(), color.green(), color.blue());
152 const std::string color_text = format_->style(color.to_jasc_str(), color_style);
153 lines.push_back(format_->format("{}", FormatParam{color_text}));
154 }
155 }
156
157 return lines;
158}
159
160std::vector<std::string>
161ColorPalettePrinter::print_rgba_counts(const std::vector<std::pair<Rgba32, unsigned int>> &colors_counts) const
162{
163 std::vector<std::string> lines{};
164 for (const auto &[color, count] : colors_counts) {
165 const Style color_style = rgb_fg_style(color.red(), color.green(), color.blue());
166 const std::string color_text = format_->style(color.to_jasc_str(), color_style);
167 lines.push_back(format_->format("{} ➞ {} pixel(s)", FormatParam{color_text}, FormatParam{count}));
168 }
169 return lines;
170}
171
172} // namespace porytiles
std::vector< std::string > print_rgba_pal(const Palette< Rgba32, pal::max_size > &pal) const override
std::vector< std::string > print_rgba_pal_with_highlights(const Palette< Rgba32 > &pal, const std::vector< std::size_t > &slots) const override
std::vector< std::string > print_rgba_palette_covered_missing(const Palette< Rgba32, pal::max_size > &pal, std::set< Rgba32 > covered_colors, std::set< Rgba32 > missing_colors) const override
std::vector< std::string > print_rgba_counts(const std::vector< std::pair< Rgba32, unsigned int > > &colors_counts) const override
std::vector< std::string > print_pal_hint_with_highlights(const PaletteHint &hint, const std::vector< std::size_t > &slots) const override
A text parameter with associated styling for formatted output.
Represents a palette hint for the palette packing algorithm.
const std::string & name() const
const Palette< Rgba32 > & pal() const
A generic palette container for colors that support transparency checking.
Definition palette.hpp:47
std::map< PaletteIndex, ColorType > index_to_color_map() const
Creates a map from palette indices to their colors.
Definition palette.hpp:346
std::size_t size() const
Returns the number of slots in the palette.
Definition palette.hpp:229
ColorType at(std::size_t index) const
Gets the color at a specific index.
Definition palette.hpp:276
bool is_wildcard(std::size_t index) const
Checks if a slot is a wildcard.
Definition palette.hpp:198
Represents a 32-bit RGBA color.
Definition rgba32.hpp:23
std::string to_csv_str() const
Definition rgba32.cpp:29
std::uint8_t red() const
Definition rgba32.hpp:81
std::uint8_t blue() const
Definition rgba32.hpp:91
std::string to_jasc_str() const
Definition rgba32.cpp:24
std::uint8_t green() const
Definition rgba32.hpp:86
Text styling class supporting formatting, foreground colors, and background colors.
static const Style italic
Italic text formatting.
static const Style yellow
Yellow foreground color.
static const Style bold
Bold text formatting.
Abstract base class for applying text styling with context-aware formatting.
virtual std::string style(const std::string &text, Style styles) const =0
Applies styling to a text string.
virtual std::string format(const std::string &format_str, const std::vector< FormatParam > &params) const
Formats a string with styled parameters using fmtlib syntax.
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.
Definition panic.cpp:43
constexpr Style rgb_fg_style(std::uint8_t r, std::uint8_t g, std::uint8_t b)
Creates a Style value with a custom RGB foreground color.