// Formatting library for C++ - color support // // Copyright (c) 2018 - present, Victor Zverovich and fmt contributors // All rights reserved. // // For the license information refer to format.h.
// rgb is a struct for red, green and blue colors. // Using the name "rgb" makes some editors show the color in a tooltip. struct rgb {
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {}
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
FMT_CONSTEXPR rgb(uint32_t hex)
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
FMT_CONSTEXPR rgb(color hex)
: r((uint32_t(hex) >> 16) & 0xFF),
g((uint32_t(hex) >> 8) & 0xFF),
b(uint32_t(hex) & 0xFF) {}
uint8_t r;
uint8_t g;
uint8_t b;
};
namespace detail {
// color is a struct of either a rgb color or a terminal color. struct color_type {
FMT_CONSTEXPR color_type() noexcept : is_rgb(), value{} {}
FMT_CONSTEXPR color_type(color rgb_color) noexcept : is_rgb(true), value{} {
value.rgb_color = static_cast<uint32_t>(rgb_color);
}
FMT_CONSTEXPR color_type(rgb rgb_color) noexcept : is_rgb(true), value{} {
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) |
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
}
FMT_CONSTEXPR color_type(terminal_color term_color) noexcept
: is_rgb(), value{} {
value.term_color = static_cast<uint8_t>(term_color);
} bool is_rgb; union color_union {
uint8_t term_color;
uint32_t rgb_color;
} value;
};
} // namespace detail
/// A text style consisting of foreground and background colors and emphasis. class text_style { public:
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
: set_foreground_color(), set_background_color(), ems(em) {}
FMT_CONSTEXPR autooperator|=(const text_style& rhs) -> text_style& { if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} elseif (rhs.set_foreground_color) { if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
report_error("can't OR a terminal color");
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
}
if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} elseif (rhs.set_background_color) { if (!background_color.is_rgb || !rhs.background_color.is_rgb)
report_error("can't OR a terminal color");
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
}
template <typenameChar> struct ansi_color_escape {
FMT_CONSTEXPR ansi_color_escape(color_type text_color, constchar* esc) noexcept { // If we have a terminal color, we need to output another escape code // sequence. if (!text_color.is_rgb) { bool is_background = esc == string_view("\x1b[48;2;");
uint32_t value = text_color.value.term_color; // Background ASCII codes are the same as the foreground ones but with // 10 more. if (is_background) value += 10u;
size_t index = 0;
buffer[index++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('[');
if (value >= 100u) {
buffer[index++] = static_cast<Char>('1');
value %= 100u;
}
buffer[index++] = static_cast<Char>('0' + value / 10u);
buffer[index++] = static_cast<Char>('0' + value % 10u);
/** * Formats arguments and returns the result as a string using ANSI escape * sequences to specify text formatting. * * **Example**: * * ``` * #include <fmt/color.h> * std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), * "The answer is {}", 42); * ```
*/ template <typename... T> inlineauto format(const text_style& ts, format_string<T...> fmt, T&&... args)
-> std::string { return fmt::vformat(ts, fmt.str, vargs<T...>{{args...}});
}
/// Formats a string with the given text_style and writes the output to `out`. template <typename OutputIt,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> auto vformat_to(OutputIt out, const text_style& ts, string_view fmt,
format_args args) -> OutputIt { auto&& buf = detail::get_buffer<char>(out);
detail::vformat_to(buf, ts, fmt, args); return detail::get_iterator(buf, out);
}
/** * Formats arguments with the given text style, writes the result to the output * iterator `out` and returns the iterator past the end of the output range. * * **Example**: * * std::vector<char> out; * fmt::format_to(std::back_inserter(out), * fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
*/ template <typename OutputIt, typename... T,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> inlineauto format_to(OutputIt out, const text_style& ts,
format_string<T...> fmt, T&&... args) -> OutputIt { return vformat_to(out, ts, fmt.str, vargs<T...>{{args...}});
}
bool has_style = false; if (ts.has_emphasis()) {
has_style = true; auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
out = detail::copy<Char>(emphasis.begin(), emphasis.end(), out);
} if (ts.has_foreground()) {
has_style = true; auto foreground =
detail::make_foreground_color<Char>(ts.get_foreground());
out = detail::copy<Char>(foreground.begin(), foreground.end(), out);
} if (ts.has_background()) {
has_style = true; auto background =
detail::make_background_color<Char>(ts.get_background());
out = detail::copy<Char>(background.begin(), background.end(), out);
}
out = formatter<T, Char>::format(arg.value, ctx); if (has_style) { auto reset_color = string_view("\x1b[0m");
out = detail::copy<Char>(reset_color.begin(), reset_color.end(), out);
} return out;
}
};
/** * Returns an argument that will be formatted using ANSI escape sequences, * to be used in a formatting function. * * **Example**: * * fmt::print("Elapsed time: {0:.2f} seconds", * fmt::styled(1.23, fmt::fg(fmt::color::green) | * fmt::bg(fmt::color::blue)));
*/ template <typename T>
FMT_CONSTEXPR auto styled(const T& value, text_style ts)
-> detail::styled_arg<remove_cvref_t<T>> { return detail::styled_arg<remove_cvref_t<T>>{value, ts};
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.